VS2010 T4 auto checkout of generated files from TFS fails - visual-studio-2010

I'm trying to use such simple scheme in my project:
Item.cs -> this contains c# partial class with simple entity properties.
It has set also property "Custom Tool: T4ScriptFileGenerator" so it attaches "grouped" file Item.tt to it. Wich on its way generates Item.generated.cs, grouped to Item.tt.
So it results in a grouped tree in solution explorer:
Item.cs
˪Item.tt
˪Item.generated.cs
You can see below how it looks in .csproj file.
Whole project is connected to TFS 2010 workspace.
The problem is:
When I edit Item.cs, t4 engine recreates Item.generated.cs file, but does not check out it from tfs. It automatically checks out only first two levels of "grouped" files - Item.cs and its dependant Item.tt. The Item.generated.cs is updated, but simple overwriten, without checkout.
If I edit Item.tt file or just press "Run custom tool" on it - again two files are checked out: Item.tt and its dependant Item.generated.cs
This is weird because forces us to manually "run custom tool" on every *.tt file after editing entity class files to ensure nothing is missing from TFS.
Q: Is there any way to force it to check out whole tree of DependentUpon files when main Item.cs is edited?
Here is how it looks in .csproj file source:
<Compile Include="Entities\Item.cs">
<Generator>T4ScriptFileGenerator</Generator>
<LastGenOutput>Item.tt</LastGenOutput>
</Compile>
<None Include="Entities\Item.tt">
<Generator>TextTemplatingFileGenerator</Generator>
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
<DependentUpon>Item.cs</DependentUpon>
<LastGenOutput>Item.codegen.cs</LastGenOutput>
</None>
<Compile Include="Entities\Item.codegen.cs">
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
<DependentUpon>Item.tt</DependentUpon>
</Compile>

It's not very elegant, but you can always get VS to transform all the templates in the solution by hitting the "Transform All Templates" button at the top of the solution explorer.
See my note on the original question, as at least in VS2010 SP1, this seems to work, given the exact example project file snippet.

/// <summary>
/// (T4 template code to checkout a file path if necessary)
/// </summary>
/// <param name="fileName">The file name.</param>
private void CheckoutFileIfRequired(String fileName)
{
var sc = this.dte.SourceControl;
if (sc != null && sc.IsItemUnderSCC(fileName) && !sc.IsItemCheckedOut(fileName))
checkOutAction.EndInvoke(checkOutAction.BeginInvoke(fileName, null, null));
}

Related

Keep special ProjectReference when using "Remove unused reference"

VS2019 added a feature to remove all unused project references from the current project. This is a nice feature for all code that is visible to the analyzer that removes the reference. But for things like dynamic invocation (e.g. Activator.Create) the analyzer does not see it and removes required references.
I can remember and I can also see in the project properties window that there is a "Treat As Used" property but it is readonly. As far as I can remember there is a property that I can set, but in all places I have looked for I cannot find it.
The microsoft docs also do say nothing about this. Also the project schema definition of the csproj does not say anything.
Can someone guide me please?
In the end solution was very easy but not very obvious and also not documented.
I found the solution by selecting the Remove unused references which is available in the context menu in the Solution Explorer on every Project.
Note: You cannot perform this method solution-wide, it only works on each project independently!
Here's how to do it:
Assume you have a project reference in your project
<ItemGroup>
<ProjectReference Include="..\Test.csproj" />
</ItemGroup>
Click on "Remove unused references" in the context menu.
A dialog pops up that list each reference and you can select what to do (Keep/Remove)
If you select Remove the reference is simply removed nothing else. You can add it again if you like.
If you select Keep an additional item TreatAsUsed is added to the ProjectReference
<ItemGroup>
<ProjectReference Include="..\Test.csproj">
<TreatAsUsed>true</TreatAsUsed>
</ProjectReference>
</ItemGroup>
you can also write it in one line:
<ItemGroup>
<ProjectReference Include="..\Test.csproj" TreatAsUsed="True"/>
</ItemGroup>
In the next run of "Remove ununused references" th keep is preselected.

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.

Unwanted changes in .csproj file on build

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

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.

How to undo Visual Studio's obsession with recreating the .designer.cs file of my DBML?

This is driving me nuts. I think it is because of some connection string mismatching across the app (using MVC) but Visual Studio constantly takes my .designer.cs file and recreates it adding a '1' at the end (or 2 if it already did this before argh!). My question is two-fold: Is there a way to stop VS from doing this? But more importantly: How can I manually set it back to the original .designer.cs or is that not possible? I try to delete the new one it created (because I keep getting duplicate definition build errors) and it won't automatically associate back with the original one in the DBML file structure in solution explorer.
Does anyone have a solution for this madness?
Not an ideal solution, but a workaround would be the following. In Visual Studio, go into the properties of the .dbml file and clear out the Custom Tool property. This will prevent it from running the auto-generator against the DBML and creating the designer files. Of course further changes to the DBML won't be reflected in the designer file.
As for why it's generating multiple designer files, that's an oddity. To manually associate a file under another, you need to modify the project file. Look for a line like
<Compile Include="file.designer.cs" />
and change it to
<Compile Include="file.designer.cs">
<DependentUpon>file.dbml</DependentUpon>
</Compile>

Resources