How to use shared resource file between projects in one solution? - c#

I have a problem with resource files.
I have a solution with two projects. The first project contains ImageResource.resx file with the images that I use. Every Form in this project can access this file from the designer. But I can see in the designer ImageResource.resx file to use it from second project (Reference to second project is present).
I have added the ImageResource.resx file as a link to my second project. And I saw it in the designer! But when I use an image from this resource in the second project Visual Studio modified my original file (It sets the namespaces, and other..) and my solution breaks. Also Visual Studio tells me that ImageResource.resx is present in two dll's first_project.dll and second_project.dll
Can anybody help me with How to correctly use shared resources between projects?

The correct way to share resources is to create a global shared project. Create a new Project with the name Resources:
Next we must add some resources (such as icons) to the project. Do this as usual. Go to the projects setting, select tab Resources and Add Existing File… to the project. We can see that the icon is added to the project and was copied to the local folder:
Next step consists of adding this icon to the other project(s). Note the important difference, you need to add this icon as a link!
Adding as a link avoids the resource duplication. Create a new Project within the same solution and name it e.g. Main. Create some folder in this new project, naming it Resources (the logical name for our purpose). Then right click on this folder, select Add Existing Item… and choose the image file from the shared project folder. Make sure to use Add As Link here! If done correctly the icon of the newly added file will look slightly different (see below):
Added resource's icon must look like this
Now we must set the Build Action for this file to None. For this select the file and go to the Properties Window. There choose None for Build Action. We need to do this to avoid embedding this icon into the assembly:
Finally we need to add the linked files to the Resources of the corresponding project. Open the project Properties for the project where we just added the files. Choose the Resource tab and drag the linked file there:
These are the five simple steps you must perform to share icons between projects. You might ask "What are the benefits of this?" The benefits are:
We store resources in one place, and
It is easy to replace an icon with a new one.

This didn't work for me and I found another (VS2015+) approach.
See https://stackoverflow.com/a/45471284/4151626
In short, the shared project is directly included into the peripheral project. Thus, even though the IDE does not support <Resource> elements in the shared project. <Resource> elements can be added to the shared project, via a text editor. They are then incorporated into the peripheral project during the build.
(Apologies for the hyper-link. I would just repost the answer for clarity, but the stackoverflow editors crack down on this, deleting duplicate answers to save you from ???.)

Can you use a symbolic link to share the file into multiple folders?
windows:
mklink linked_location\ImageResource.resx original_location\ImageResource.resx
C:\Users\preet>mklink
Creates a symbolic link.
MKLINK [[/D] | [/H] | [/J]] Link Target
/D Creates a directory symbolic link. Default is a file
symbolic link.
/H Creates a hard link instead of a symbolic link.
/J Creates a Directory Junction.
Link specifies the new symbolic link name.
Target specifies the path (relative or absolute) that the new link
refers to.

If a resource file is really shared between projects, you should put it in a shared project.
Solution 'Sample'
Project Sample.Data
Project Sample.Business
Project Sample.UI
Project Sample.Resource //shared resources are put in a shared project

You can't see the resource if it is not public, and it is default set to "Friend". You can set the "Access Modifier" in the Visual Designer (upper right-hand corner).

Related

How to organise C# source files in subfolders?

BACKGROUND
I'm mostly programming in embedded C/C++ but sometimes I have to do some C# programming for our API. For this I'm using Visual Studio 2017 to create an API DLL for our customers.
The C# API and our C/C++ firmware are using a common set of status codes. I have a Lua script that generates these codes to a .h (for C/C++) and a .cs (for C#) file so they always are in sync.
All source files that are shared across products and platforms are in a special project called "Common" (checked-in to Subversion).
When we create new projects and use any "common" file, we put them in a sub folder called "Common\" so we know that there is no point in messing with them. Subversion will check out these "Common" files as externals of a specific revision used by each project.
In C/C++ it's no problem at all to have source code organized in several levels of folders, all source files have a relative path to the root project folder.
THE PROBLEM
So in this C# project I organize the source code as usual:
ProjectRoot\source.cs
ProjectRoot\Common\EStatusCodes.cs
In the ProjectRoot\ we have all .cs files for this C# project, and in ProjectRoot\Common\ are the external files from subversion's "Common" project.
So after the checkout of the external EStatusCodes.cs into the ProjectRoot\Common\ folder I add it to the C# project by "Add->Add Existing..." and then I point out the ProjectRoot\Common\EStatusCodes.cs file.
The file shows up in the Project but for some reason Visual Studio has COPIED the file form the ProjectRoot\Common folder to the ProjectRoot\ folder and is then using the copy! (The file's path in properties is set to the ProjectRoot\ folder.
So If we add more status codes to the "Common" project, this C# project don't get the update because Visual Studio now always use the copied version of the file from ProjectRoot\ and don't care if ProjectRoot\Common\EStatusCodes.cs has been updated.
I tried to add the Common folder to "Properties->Reference Path", but it still copies the file every time I add it to the project.
Is it possible at all to have source files somewhere else than in the C# project's root folder?
In the Add Existing dialog, there should be a small down arrow next to the Add button. If you click this, you'll see an option to "Add As Link". This will add the file as a reference link to the original file and any changes to the original will reflect in your project.
We have a similar way in C# project: add existing file to project as "Add as link".
Please refer this link for more details:
https://grantwinney.com/visual-studio-add-file-as-link/

VS2010 (C#) Environment.SpecialFolder.ProgramFiles is where in the Solution Project?

I have created a C# WinForms application. It has some additional files that it uses, such as help files and some external data files. I want to put these files in folders under the Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles) path so that the application can find and read them.
This path doesn't get created until the application is installed right? So where do I put these files in my VS2010 project, or how do I tell my project that these files exist so that when I am running (debugging) the application from VS it will find the files.
Thanks
EDIT: I did think about adding the files as resource files, but unfortunately some files may get added after the project is built and deployed. Therefore we decided to make the program search and find the data files (and associated help files) at a specific location and load them if they exist.
Thing is that your application should not need to use 'Environment.SpecialFolder.ProgramFiles'. It "should" be location agnostic. The quick answer to your question is "from the folder that the application was launched from". The real answer is how you reference these files.
Your help files and data files need to be deployed to folder with a known relationship to the application. That is, the same folder or a child folder. Consider making the file resources.
Now if the files are user configurable or run time writable then they should not be in the program files area but be in the application data area. If so, then there is your path!
Hope this helps.
You should add these files to the main (exe) project inside your solution.
(Right click on Project Name, Select Add Existing Item)
Then set its property Copy to Output Directory = Always
(not sure of the translation because I use a localized version of VS)
Of course, it should be noted that, when you deploy your files in the Environment.SpecialFolder.ProgramFiles, you could not be able to write to them (Windows7, Vista) for security reasons.
Add the files as resources in your project. Take a look at this MSDN article. You can add resources to a project by right-clicking the Properties node under your project in Solution Explorer, clicking Open, and then clicking the Add Resource button on the Resources page in Project Designer.
You can add resources to your project either as linked resources, which are external files, or as embedded resources, which are embedded directly into the .resx file.
When you add a linked resource, the .resx file that stores your project resource information includes only a relative path to the resource file on disk. If you add images, videos, or other complex files as linked resources, you can edit them using a default editor that you associate with that file type in the Resource Designer.
When you add an embedded resource, the data is stored directly in the project's resource (.resx) file. Strings can only be stored as embedded resources.

Why does VS2010 allow for the concept of "include in project"?

I'm still learning the basics of how VS2010 sees the world. Apparently, you can optionally "include" a file in a project. I'm a bit confused by this: If a file is version-controlled, AND the file is within the project directory, shouldn't it implicitly be "included" in the project? If not, what's the use case where a version-controlled file in the project directory should NOT be included in the project?
=== Addition ===
Based on the answers I've gotten so far, maybe I should rephrased my question: What does it mean for a file to be "included" in a project?
A project needs to know about files in order for compilation and distribution to occur. Just because you have a file that's under source-control, doesn't mean that it will be compiled if the project is unaware of it.
Also, you may want to include files as part of a distribution package. We do this quite often for our web projects that we distribute using web app gallery.
Conversely, you could have documentation or sql scripts that you version control, but do not want them to be part of the project.
EDIT: In answer to your update, what it means for a file to be included in a project is that the file is actually added to the .csproj or .vbproj file and will be used during compilation and/or distribution. VS does differentiate if the file is Content or if it needs to Compile it. This can be seen by clicking on the file in Solution Explorer and looking at the Build Action property.
No, you don't want random files that happen to be in the project directory included in source control.
We do sometimes put documentation (pdfs) or drawings/schematics in the project folder and under version control but you don't need them inside the visual studio project (especially when they are not being distributed because they are for internal use only).
Excluding the file from your project can be useful if the file is related to the project but not necessarily needed in the solution.
Example
If I need some test XML for an application that i'm writing; that is designed to normally be pulling this from a WCF service, it can be useful to keep that file in the directory for a development environment where I use IO to get the XML for testing, but I don't necessarily want it in my solution which is source controlled.
When you exclude a file from a project is no longer compiled or embedded, then when you want to include it again you can do so without having lost your settings.
If you e.g. copy a file (containing a helpful class which want to have in your project) into a folder of your project, then you will see ... nothing. You have to check the option "Show all files" of the solution explorer and the copied file can be seen, but it is still "greyed out". No you can choose the menuitem Include in project and that file will be integrated in your project and a pending change (add) for your source control is added too. Visual Studio doesn't include all files it can find in the project folder automatically to the project - and that is a good feature.
One of my colleagues explained to me a scenario in which a version-controlled file should NOT be part of the project. Here's the idea:
A developer writes some new code.
The code is experimental, and not intended to be part of the normal build.
The easiest way to exclude the file from the build is to NOT include it in the project, but still version-control it.
This way, the file can be shared with other developers, but not break the build.

C# assembly - shortcuts

I have a C# project that has multiple folders: Folder1, Folder2.
I added a shortcut in 'Folder1' to an xml file that is already in 'Folder2'. In this case when I compile the project the xml file will I have two copies in the assembly?
You were not clear with your description - did you reference the file with a shortcut, or did you add it to Folder1 by using the VS Solution Explorer and adding an existing item as a link?
The two methods are quite different. If you simply went into the filesystem and added a shortcut, then that is not automatically part of the project unless you specifically add it. And if you did add it, then it obviously can't be compiled, the best you could do is just have it set to No Compile and copy to the output directory.
If you added the file to folder one via the VS solution explorer and added it as a link, then it will be part of the project, and will be included twice, but it will be placed in Folder1 under the bin/debug or bin/release folder upon building. There will be no clash because they are in different folders, and they are not compiled, simply copied to the folder structure under the output directory.
Edit: and it won't be part of the assembly unless you set it to be a Resource or Embedded Resource. If you do that then yes, it will be in the assembly, but under two different resource paths.
In the Properties(context menu) of the selected file in the Solution Explorer change Build Action property to No Compile.

How can I add Solution Folder files to a VS Project Template?

I'm trying to create a Project Template in Visual Studio. My basic Solution contains two Projects and a 'Solution Items' Solution Folder that contains (among other things) libraries (.dlls) that the two projects need as References.
My Project Template creates the two Projects, the 'Solution Items' Folder, and another Folder within 'Solution Items' (as desired). It does not, however, add the .dlls and other files that are supposed to populate 'Solution Items'.
In the .vstemplate file, I add references to the .dlls as 'ProjectItem' items directly beneath the 'TemplateContent' node, and they are ignored.
If I try adding a 'Project' node (as if my Solution Items folder were a Project), I get all kinds of errors.
Must I actually create a dummy project to hold these files?
It seems that I do need to include the Miscellaneous Files (Microsoft's term) in a Project in order to have the project generator find them. I put them into a folder and included them in one of my project Templates.
I then implemented an IWizard which I also included in the Solution Template which, after that Project had been built, would move the files where I wanted them, and modify the .csproj file so that it wouldn't miss them.
It all works fine, but it feels like the grossest of hacks...! Is anybody from MS out there?
I've never created a template before, so I can only guess at what you're doing. In our .sln files, our solution items look like this:
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "_Build", "_Build", "{45E29CA9-E213-4C73-AA54-AE9B87F79F2D}"
ProjectSection(SolutionItems) = preProject
_Build\Project.proj = _Build\Project.proj
EndProjectSection
EndProject
Where _Build is the SolutionFolder, which we map to a physical folder also called "_Build". In this case, it contains one file, the Project.proj file, which is of course mapped to the physical folder version.
Hope that's even remotely helpful..?

Categories

Resources