"Add as Link" for folders in Visual Studio projects - visual-studio

In Visual Studio, we can "Add as link" to add a link to a file in another project in the solution.
Is there any way to do this for entire folders, so that an entire folder in project A will be visible in project B, without the need to manually link to new items in that folder?

As this blogpost stated, it is possible.
<ItemGroup>
<Compile Include="any_abs_or_rel_path\**\*.*">
<Link>%(RecursiveDir)%(FileName)%(Extension)</Link>
</Compile>
</ItemGroup>
But be aware, the files will not be copied.

In VS2012 and later, you can drag a folder to another project with alt key pressed. It's just the same as adding each file as link manually but faster.
upd:
Consider using Shared Projects if you are using VS2013 update 2 (with Shared Project Reference Manager) or VS2015.

One addition to the answer from mo. and the comment from Marcus, if you are linking content items you will need to include the file extension:
<ItemGroup>
<Compile Include="any_abs_or_rel_path\**\*.*">
<Link>%(RecursiveDir)%(FileName)%(Extension)</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Compile>
</ItemGroup>

Regarding the part of the original query to have a linked folder appear in the IDE, it is kind of possible to achieve this so there is a folder in the solution explorer with all linked files inside, instead of all the files appearing in the root of the solution. To achieve this, include the addition:
<ItemGroup>
<Compile Include="..\anypath\**\*.*">
<Link>MyData\A\%(RecursiveDir)%(FileName)%(Extension)</Link>
</Compile>
</ItemGroup>
This will include all files from the linked directory in a new folder in the solution explorer called MyData. The 'A' in the code above can be called anything but must be there in order for the folder to appear.

If you want to add a folder as a reference and you don't want to compile it, use:
<Content Include="any_path\**\*.*">
<Link>folder_in_B_project\%(RecursiveDir)%(FileName)%(Extension)</Link>
</Content>

Even when there are so many solutions it took me a while to understand it. Here I will try to explain it a little bit more.
I needed link to the whole folder so my final result is:
<ItemGroup>
<Content Include="..\Gym.Management.Api\TestFolder\**\*.*">
<Link>TestFolder\%(RecursiveDir)%(FileName)%(Extension)</Link>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
</ItemGroup>
where:
..\Gym.Management.Api\TestFolder\ represents path to the other project containing the folder I want to link
TestFolder\ in <link> tag is the final(destination) folder in my current project where I want to link it
TIP:
When you are not sure how to get the proper Include path then in your current project right click on project->click Add->Existing item->navigate to one of those files from folder you want to link-> instead of Add, press the dropdown arrow next to it->click Add as link.
This link is inserted in your .csproj file and from there you can extract the Include path.

If what you are looking for is to add another folder to your current workspace for easy access & development experience.
you can do this by just clicking file -> Add Folder to Workspace option in vscode.

Bust out the shell and add a symbolic link.
runas Administrator then
mklink /d LinkToDirectory DirectoryThatIsLinkedTo
BAM symbolic link!
/d specifies directory link.
Works in Vista on up out of the box. Can be backported to XP.
Documentation here: http://technet.microsoft.com/en-us/library/cc753194%28WS.10%29.aspx
For those not familiar with symbolic links, it's essentially a pointer to another file or directory. It's transparent to applications. One copy on disk, several ways to address it. You can also make a "hard link" which is not a pointer to another address, but an actual file ID entry in NTFS for the same file.
NOTE: as stated in the comments, this would only work on the computer where you created the symlink and wouldn't work in a Version Control System like git.

Related

How to add existing item to Visual Studio project, copy to output but change it's original name?

I added a chm help file as link to the application's project but it's file name is not good for releasing to the public ("Compiled help.chm"). Unfortunately it's maintained in a different git submodule by other people and it's name is an automated output from their help builder.
After adding file as link there is no option to change the file name. Is there a csproj xml feature allowing user to rename a file link, possibly without breaking WiX installers depending on it and other undesired consequences?
I was a bit curious about this one, so I gave it a try myself, and I think I was able to get something that will work for you:
If you have the file already in your project as a link, skip to 2; o/w, drag the file over your project in Visual Studio and - while holding down both Ctrl and Shift - drop the file on your project, creating a link.
Close the solution and project
Using notepad or some other text editor, edit the .csproj file, then locate your logical link by looking for the filename you just added.
Edit the link node as follows:
<ItemGroup>
<None Include="....\OtherTeamOutputFolder\Compiled help.chm">
<Link>Super Cool Production Product Name.chm</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
Build your project; witness the glory.
If you control WiX project, you can specify file name in the file element:
<Component…>
<File Id=”FILE_MyProgramDir_SomeAssemblyDLL”
Name=”SomeNewNameForAssembly.dll”
Source=”SomeAssembly.dll”
KeyPath=”yes” />
</Component>
However, you should consider the new name while accessing to renamed resources both from your executable/class libraries and from other stuff.

How do I handle relative Compile Includes in csproj of vstemplate

I have a linked file in my csproj template:
<Compile Include="..\$saferootprojectname$\Shared Files\Mvx$saferootprojectname$.cs">
However, when the template is run, instead of leaving the relative path alone, Visual Studio substitutes the path of the temporary folder that is unzipped (and subsequently deleted!!!). The result is
> Error 1 Source file 'C:\Users\tim\AppData\Local\Temp\mi0qfyf2.5lc\Okra\Shared
> Files\MvxOkra.cs' could not be found \\vmware-host\Shared
> Folders\Documents\Projects\Temp\Plugins\Okra\Okra.Mac\CSC Okra.Mac
since the resulting csproj has
<Compile Include="C:\Users\tim\AppData\Local\Temp\k4psfgjk.22c\Crab\Shared Files\MvxCrab.cs">
<Link>MvxCrab.cs</Link>
</Compile>
instead of the relative path. Is there any way to solve this without resorting to a Wizard?
Update. This can be resolved by adding <CreateInPlace>true</CreateInPlace> into the vstemplate. Then the relative path ends up right. However, I do not want this solution. I would like the solution that allows CreateInPlace to be false (it seems to be default now in VS2012), because my solution is on a network share and it triggers a "do you want to open" prompt for every project in the template (there are 8). (Even when I say don't Ask)
Maybe an alternative solution would be how I can make a network share trusted so this prompt doesn't happen.

Visual Studio: Add existing folder(s) to project

Is there a way to add existing Folders to a Visual Studio Project so that I do not have to do this file by file?
Edit
To make it clear: I want to add references not copies.
If the folder and its contents have already been created and it physically exists under the Project, you can click the Show All Files icon (at the top of the Solution Explorer windows) and then when the folder shows as a dotted icon, right-click it and choose Include In Project and the folder and all its contents are added.
VS 2019
Click on the 'Show All Files' icon at the top of Solution Explorer window.
Then the folders/files of the selected project will be displayed as dotted icons. You can right click any of them and select include in project to include them in the project.
For solution folders, click the 'Show All Files' icon then first exclude the desired folders/files and then include them.
You could open Add Existing Item dialog, select a bunch of files, click on Add's button drop-down menu and choose Add as a link. It will add files as references and won't copy them.
You can drag and drop the entire folder. If all files don't show you can repeat the drag'n'drop procedure for subfolders.
#Mark s answer is good, but if there are hundreds or thousands of files it will be quite cumbersome to add all of them. Plus, it does not provision for new files.
There is another method using the .csproj file. I have used this to add content that is part of a submodule that does not have a .csproj file of its own.
Note that I have used the <Content /> tag, as I did not need any of the linked content during compilation.
<ItemGroup>
<Content Include="..\my\submodule\directory\**" Link="Directory\In\Main\Project\%(RecursiveDir)%(Filename)%(Extension)" />
</ItemGroup>
This answer applies to visual-studio-2012 and visual-studio-2013, the most up to date versions at the time the question was asked and this answer was given. More recent versions have improved their handling and have other answers here. For someone using the old versions, this answer still applies.
Answer:
I don't think there is, but if you have all the files in one folder, you can add multiple files in one go. Just mark them all in the add file dialog.
right click the project, and choose "New Solution Explorer view", a window pops up.
and then form the toolbar of the new window ("solution explore window"), you click the "Show All Files" icon.
then include the folders of interest into your project...
If you're working in VS 2019 Community Edition, I find that you can:
Open the parent folder of whatever folder you're trying to add in windows explorer
Right-click and copy that folder
Go to the solution explorer in visual studio
Right-click then paste the folder wherever you want to in the solution tree
In Visual Studio 2019 I could not drag and drop from file explorer or 'Show All Files' and then add them. Instead, while in File Explorer, right click and choose copy, then click on the location within Visual Studio 2019 and right click and choose paste. All of the files in the folder and subfolders will be added.
kburnik's answer worked well for my use-case, but for anyone who needs a scriptable way to bring a lot of folder hierarchy back, you can modify the .*proj file to re-include the folders and files:
<?xml version="1.0" encoding="utf-8"?>
<Project ...>
...
<ItemGroup>
<Compile Include="Path\To\File1.ext" />
<Compile Include="Path\To\File2.ext" />
...
</ItemGroup>
<ItemGroup>
<Folder Include="Only\Empty\Folders\Need\To\Be\Listed\Here" />
...
</ItemGroup>
Just make sure that before you do this, you save the .*proj file if it's still open in Visual Studio.
You can drag and drop the entire folder or missing folders in the project.
If the folder and its contents have already been created and it physically exists under the Project then click on view over the project then you can see all folders and files and you just need to copy files and click on solution in the same folder view and paste all in there
It has been a while since this was originally posted, but here is an alternative answer for a solution folder that is NOT inside of a project. If you only care to be able to look at the physical files from inside visual studio and do not necessarily require to see them in the solution explorer default view, then click on the switch view button and choose the folder view and any physical directory/directories that are under your solution root folder will appear here even if they do not appear in the solution explorer default view.
If however, you want to add a folder tree that isn't too large as a virtual solution directory/directories to match your existing tree structure, do that and and then "add the existing" physical files to the virtual directory/directories. If the physical directory exists in your solution directory it will not copy the files - it will link directly to the physical files but they will appear as part of the solution virtual directories.
Possibly some of you weren't born when this question was first asked!
If you have external directories, you can add them to a solution as a "website". This gives you all the benefits of being able to search through the solution and easily add new files to the website. It doesn't have to contain html, it can be a set of word documents, for example.
So for example, I've got a single solution that contains every sql and oracle query I've ever worked on or harvested from a co-worker. Why? Because it's difficult to keep up with similar sounding field and table names across different databases when you're trying to write a new query.
This also works with TFS.
Check whether that folder is inside project folder or not, if yes:
click Show All files in solution explorer.
now you can see folder name in solution explorer. right click the folder -> Include In Project.
If the folder out of project please copy it into the project directory in the place where we want it.
If your folder exist in another project but you want to add the folder and its content to another project just
-- go to the folder location
-- Copy your desired folder
-- go back to your current project
-- right click on the project and then just paste it.
folder will be added in your current project.
you may need to fix the namspace of the copying file.
You can use the following extension to add a solution folder, which is going to have the same name and the same content as the existing one without it being moved in the file system at all.
Folder To Solution Folder
And here's the link for more information:
https://marketplace.visualstudio.com/items?itemName=CeciliaWiren-CeciliaSHARP.FolderToSolutionFolder
Just drag and drop the folder in solution explorer.

Group files in Visual Studio

I'm looking at tidying up my project layout in Visual Studio and I'm wondering if there is any hack, plugin or trick to associate an .xml file with a .cs file of the same name so they appear grouped in my solution navigator/explorer.
Similar to the way the code-behind file is associated with its aspx.
Any suggestions welcome. Thanks
In your project file :
<Compile Include="FileA.cs"/>
<Compile Include="FileA.xml">
<DependentUpon>FileA.cs</DependentUpon>
</Compile>
Or you could use Group Items command of VSCommands 2010 extension.
Edit: Just in case your file is in a folder, don't include the folder name in DependentUpon tag. For example if your file is in Helpers folder:
<Compile Include="Helpers\FileA.cs"/>
<Compile Include="Helpers\FileA.xml">
<DependentUpon>FileA.cs</DependentUpon>
</Compile>
If you do not want to slow down you IDE with heavy and proprietary VSCommands extension you can use small extension NestIn instead. It can nothing but group/ungroup files
In .NET (Core+)
<ItemGroup>
<Compile Update="FileA.*.cs">
<DependentUpon>FileA.cs</DependentUpon>
</Compile>
</ItemGroup>
Note that Update is used instead of Include where files are already (implicitly) included in the project and use of Include causes compile-time "Error NETSDKxxxx Duplicate 'Compile' items were included... The duplicate items were: 'FileA.xxxx.cs' C:\Program Files\dotnet\sdk\x.x.x.x\Sdks\Microsoft.NET.Sdk\targets\Microsoft.NET.Sdk.DefaultItems.Shared.targets"
See Is there a DependentUpon option in a .net core app?
For the simple case where the file is a "top level" file, Julien's description works perfectly. However, in the case where the DependentUpon file is in a Folder under the project, this looks different. I personally don't like it because it seems like it could lead to ambiguity, but that's an opinion.
<Compile Include="DataStructs\CKDTree.cs" />
<Compile Include="DataStructs\CClosestObjects.cs" >
<DependentUpon>CKDTree.cs</DependentUpon>
</Compile>
Notice that the dependent item does NOT include the Folder of the parent. This is true in VS2013... probably true in earlier versions but I have not verified it.
File Nesting extension for visual studio is a good one. It has about 500K downloads at the time of writing this answer. I added it personally to my VS 2015 and it was working fine (haven't tried it with VS 2017 yet).
Not sure if people are aware, but nesting files like this seemingly breaks VS's ability to rename the root file, at least when your new nested file is also a partial class. For instance here's the tree we created...
MainWindow.xaml
MainWindow.xaml.cs
MainWindow.Commands.cs
MainWindow.Commands.cs is just another partial class of MainWindow, same as MainWindow.xaml.cs. However, if you then try and rename MainWindow.xaml, instead of automatically renaming the dependent files, it throws an exception.
For completeness, I also tried naming the file MainWindow.xaml.Commands.cs but that didn't work either.
Without the extra 'commands' file, rename works fine, of course.
MainWindow.xaml
MainWindow.xaml.cs
Anyway, this was reason enough for us to abandon nesting files like this. Without the ability to rename, it's just not worth it.

In Visual Studio, how can I set the Build Action for an entire folder?

I have a project in Visual Studio. I need to deploy some 3rd party files along with my code. Typically I would put this files in a "Resources" directory and set the Build Action on each file to "Content" and the Copy To Output Directory to "Copy if newer".
Is there anyway I can set these directives at the folder level. The current project I am working with has dozens of such files and a couple of sub folders. I'd like to be able to make the entire directory as "Content" and "Copy if newer".
Create the project. Add one file as Content. Unload the project and edit the *proj file manually.
<ItemGroup>
<Content Include="myfolder**\*.dll**">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
And then in the content-ItemGroup I would replace that singe file with some MsBuild wildcard expression, *.dll, or whatever.
I use Visual Studio 2012 and you can shift-click to select multiple items in the Solution Explorer then edit each item's Copy To Output Directory property all at once in the Properties window.
Granted this isn't equivalent to the solution you are looking for functionally, but semantically it is. And hopefully the next person to stumble across this post with a humongous folder to remedy (as is with me) won't have to dive into the .csproj file.
Hope this helps!
If you happen to have the need to set the Build Action for an entire folder the best option is to just open the .csproj file and use a regex to replace all the occurences from
<Content ....
to
<None ...
That worked just perfectly for me.
I just added this to my *.csproj file (right click Edit Project File)
<ItemGroup>
<Content Include="MYCUSTOMFOLDER\**">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
I know this answer is similar to #Arve but I don't know why this extra complexity with the .dll wildcard filter.
Edit your *.csproj or .vbproj file
Add this tag
<ItemGroup>
<Folder Include="YOUR_FOLDER_NAME_HERE/">
</ItemGroup
the final file must look like this:
<Project>
<---some more tags--->
<ItemGroup>
<Folder Include="YOUR_FOLDER_NAME_HERE\" />
</ItemGroup
<---some more tags--->
</Project>
If you want to preserve the recursive folder structure it is possible to add this piece of XML:
<ItemGroup Label="bg_screens">
<_CustomResource Include="..\..\resourcedir\**\*">
<Link>resourcedir\%(RecursiveDir)%(FileName)%(Extension)</Link>
<DeploymentContent>true</DeploymentContent>
</_CustomResource>
</ItemGroup>
The the resources will keep the tree structure instead of being added in a flat manner.

Resources