Unwanted changes in .csproj file on build - visual-studio-2010

I'm trying to auto-detect web.configs as part of a transform pre-build event in one of my web application project files, this code goes up one folder level from my project file and gets all web.configs in every directory and sub directory:
<ItemGroup>
<WebConfigsRelativePath Include ="..\**\Web.config"/>
</ItemGroup>
This works great but everytime I build and exit Visual Studio, I get a prompt asking me if I want to save changes made to my solution file. If I select yes, and open the project file, the above code is changed to the locations of each web.config
<ItemGroup>
<WebConfigsRelativePath Include="..\Web\Decade\Web.config" />
<WebConfigsRelativePath Include="..\Web\Matrix\RiskAnalysis\Web.config" />
<WebConfigsRelativePath Include="..\Web\Service\Web.config" />
<WebConfigsRelativePath Include="..\Web\Web.config" />
</ItemGroup>
This would be fine but the whole reason I'm auto-detecting web.configs pre-build is so I can add and remove web.configs as I please without having to hardcode their locations, and everytime I exit VS, the locations will be hardcoded in the project file....
Does anyone know why this ItemGroup changes every time I exit Visual Studio?

If I take an existing web project but use the <Content /> rather than the custom <WebConfigsRelativePath /> in your sample, then I see the expected behavior.
Try using this:
<Content Include="..\**\Web.config">
<SubType>Designer</SubType>
</Content>
Edit:
If you have special handling for the WebConfigsRelativePath item group, post that in an update to your question.

While I can't explain why VS decides to output a list of files retrieved by the wildcard each time my solution is built, I can show you how I got around this issue:
<PropertyGroup>
<WebConfigsSearchString>..\**\Web.config</WebConfigsSearchString>
</PropertyGroup>
<ItemGroup>
<WebConfigsRelativePath Include ="$(WebConfigsSearchString)"/>
</ItemGroup>
By defining the search string in a property (which always stays static) and referencing the property in the item group's list of files to include, the item group code is never modified but the web.config search is carried out each time a build is run

Related

Where are ASP.NET temporary files stored in Kestrel?

On our dot net core project we are using ViewComponents.
When we change the View referenced by one of our ViewComponents, when "dotnet run watch" is running the end result does not update until we restart dotnet. Creating a new view with the same code which our view component uses, causes it to update and works. This is very frustrating when trying to debug an error only to remember you need to restart dotnet
Can someone please tell me how we can force recompile or ignore certain directories from this cache?
This is happening on .netcoreapp 1.1 on OSX
dotnet-watch keeps an in-memory list of files that it is watching. You can inspect this list by running dotnet watch --list.
By default, dotnet-watch only restarts the process when Compile and EmbeddedResource items change. This normally only includes *.cs and *.resx files, but may include other files depending on your project.
To exclude a folder, you can set "Watch=false" on these items.
<ItemGroup>
<Compile Update="ignored_dir\**\*.cs" Watch="false" />
</ItemGroup>
You can explicitly add new filetypes to watch by adding <Watch> items to your *.csproj file. Examples:
<ItemGroup>
<Watch Include="*.js" />
<Watch Include="somefile.txt" />
<Watch Include="subdir\**\*" />
</ItemGroup>
Just for clarity's sake, dotnet-watch is independent of Kestrel.
For more details, see https://github.com/aspnet/DotNetTools/tree/1.0.1/src/Microsoft.DotNet.Watcher.Tools#msbuild

Using transformed Web.config with IIS Express during debug

I have a Visual Studio application that has multiple Solution Configurations. There is a Web.config transform file for each configuration. For example, Web.Debug.config, Web.Release.config, etc.
We also have a couple of developers working on this project that have nonstandard SQL Express instance names due to the way they installed SQL Express and rather than having them continually editing Web.Debug.config to run in their environment I have setup a Solution Configuration for each of them and added the following to the very bottom of the .csproj file. This code does work in that it triggers the creation of Web.config and MyWebApp.dll.config in the VS /obj/Debug-DeveloperName/ folder.
The transformed .config files are perfect, but IIS Express still uses the root Web.config (not transformed).
Is there a way to get IIS Express to use these transformed Web.config files while debugging locally?
<UsingTask
TaskName="TransformXml"
AssemblyFile="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v12.0\Web\Microsoft.Web.Publishing.Tasks.dll" />
<Target
Name="AfterCompile"
Condition="exists('Web.$(Configuration).config')">
<!-- Generate transformed config in intermediate directory -->
<TransformXml
Source="Web.config"
Destination="$(IntermediateOutputPath)$(TargetFileName).config"
Transform="Web.$(Configuration).config"
/>
</Target>
Using the web application's Web.Debug.Config works for most of us, but not all.
There must be a way of getting IIS Express to use the transformed Web.Debug-DeveloperName.config during local debug?
Does the transformed Web.config have to be copied into a different folder?
I faced this problem before and I found a solution. Unfortunately, the solution is not based on forcing IIS to use different name of the config, but if you follow steps below, you will just select the configuration and run you app (which is ewhat you need I think). The Web.config transform will occur before build and it will replace the original Web.config by the transformad one. Then, when the deployment (to local IIS Express) begins, it will already use the transformed one.
Here is step by step how I did this in one project (VS2012):
Right click on the project and select Unload
Right click on it again and select Edit
Go to the bottom of the file and append the follwing to the right over the "</Project>" tag (it will be last item)
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\WebApplications\Microsoft.WebApplication.targets" />
<Target Name="BeforeBuild" Condition="'$(PublishProfileName)' == '' And '$(WebPublishProfileFile)' == ''">
<TransformXml Source="Web.config" Transform="Web.$(Configuration).config" Destination="Web.config" />
</Target>
The condition there is to prevent duplicate transformation when publishing.
Save the file, right click on it and select Reload
Now, everytime you run a build, your Web.config will be transformed according to selected configuration.

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.

Automatically regenerate Text Templates that depends upon multiple files

My situation:
I have a VS 2010 project with 3 files:
content.txt
generator.tt
generated.js (generated via T4)
The project file contains them as:<None Include="generator.tt">
<Generator>TextTemplatingFileGenerator</Generator>
<LastGenOutput>generated.js</LastGenOutput>
</None>
<Content Include="content.txt" />
<Content Include="generated.js">
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
<DependentUpon>generator.tt</DependentUpon>
</Content>
The generated.js will be regenerated on every change of generator.tt
is there a way to automatically regenerating generated.js on changes to one of the other files (without using any plugin)?
I've tried to simply add another DependentUpon Element. But VS only takes care of the last one...
Thanks for your ideas
Edit:
I've forgotten one detail:
- The solution has to work with TFS. So it has to do a "Check Out for Edit..." when files are modified.

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