Introduction
Sharing a common file across different Visual Studio projects is extremely easy... All you need is to put the file-to-be-shared in a commonly accessible folder, than in the project select Add/Existing Item… and in the file explorer window select Add As Link…
From this point on, Visual Studio will handle it for you with no problem at all. Open. Edit. Compile. Publish. Source Control. All works perfectly…
So where is the problem?
If those files you are sharing are for UI (CSS) or client side code (JavaScript) the simple include in the HTML part will not find them, while you are debugging the project…
The Setup
Let us see ProjectA
as a sample with shared CSS file...
[frame.css has a blue-arrow indicator on its icon to tell that this is a shared file]
Now the HTML source that uses the CSS may look like this...
<!DOCTYPE html>
<html>
<head>
<title>Project A</title>
<meta charset="utf-8" />
<link href="App_Themes/Common/frame.css" rel="stylesheet" />
</head>
<body>
<div class="frame">
<h2 class="title">Hello A</h2>
</div>
</body>
</html>
When debugging in the browser, it will not find that frame.css as it only logically exists at the declared location but that’s not enough...
The problem is of course that Visual Studio has no way to tell the browser where the file actually is... but you can help it and I will show how…
The Solution - Extending The MSBuild Process
This can be done by a simple editing of the project file, that uses shared files…
Even it may be a bit inconvenient to edit a project file (but after all it is only an XML), you will touch at a single place and only once… This solution also works for all the browsers (it makes a physical copy of the shared file), and it also takes care for updates, so no further manual interference needed...
Step 1 - Open the Project File for Editing
For this, you may have a few options:
- Use Power Commands on context menu (part of Productivity Power Tools extension)
- Unload the project and then pick Edit Project from context menu
- Open the folder and use your favorite XML editor to edit the file (not to worry, Visual Studio will notice the external change and will ask you to reload the project after editing)
Step 2 - Edit the Project File
Scroll to the bottom of it until you see a comment like this:
Under this comment, but before the closing </Project>
tag, add this new target declaration:
<Target Name="CopyLinkedContentFiles" BeforeTargets="Build">
<Copy SourceFiles="%(Content.Identity)" DestinationFiles="%(Content.Link)" SkipUnchangedFiles="true"
OverwriteReadOnlyFiles="true" Condition="'%(Content.Link)' != ''" />
</Target>
That new target will copy all new/modified files, that are linked to the project to the parallel physical location…
Even it’s very self explanatory, so I add just two notes here:
BeforeTargets="Build"
. “Build
” is a pre-defined target and this part will ensure that before every build, there will be a copy to update files. Condition="'%(Content.Link)' != ''"
. This part is there to ensure that only files with Link
property will be copied (trying to copy files that are not there will throw an error and stop the build process).
To learn more about MSBuild targets, visit this location: How to: Extend the Visual Studio Build Process[^].
Last Notes
If, when finishing the tip. you asked yourself why I didn't mentioned map
files, here are some answers... Map
files are...
- nowhere near to be standard yet
- addressing only JavaScript files, but no CSS or images or other
- must be there physicaly, so you have to handle them manually
- can be created only by additional tool