Updated custom generated files on save - c#

In a .xaml file as soon as I add a new control, I am able to reference it for the xaml.cs file because VS is kind enough the generate the C# code for it in a g.i.cs file.
For example
In MainWindow.xaml I add
<Grid>
<Button x:Name="Test"/>
</Grid>
I am able to access it from MainWindow.xaml.cs like
this.Test.Content = "TestButton";
Because VS generated MainWindow.g.i.cs in the obj folder which contains
internal System.Windows.Controls.Button Test;
I have been able to have exactly the same behavior using msbuild for a custom file .xyz which is a designer view for a .cs file. I've have created a msbuild target that regenerates the .cs files on build and on project load but I'm not able to do the same thing on file save
Now my questions:
How does VS regenerate the g.i.cs on save ?
Is this a VS feature or an msbuild one ?
Can I trigger an incremental build on save?
Update:
I've also looked through a WPF .csproj and it uses the same .targets files as a class library C# project. The only differences I could spot are the DependentUpon and the SubType item metadata

How does VS regenerate the g.i.cs on save ?
AFAIK, Visual Studio invoke the XAML compiler xamlc.exe to compile the XAML files regenerate the g.i.cs on save.
Check this blog Understanding In and Out of XAML in WPF:
In the blog, the author said that compilation of XAML happened in 2 steps:
Step 1. The first step is to compile the XAML files into BAML using the xamlc.exe compiler. For example, if our project includes a file name Window1.xaml, the compiler will create a temporary file named Window1.baml and place it in the obj\Debug subfolder (in our project folder). At the same time, a partial class is created for our window, using the language of our choice. For example, if we’re using C#, the compiler will create a file named Window1.g.cs in the obj\Debug folder. The g stands for generated.
Step 2. When the XAML-to-BAML compilation stage is finished, Visual
Studio uses the appropriate language compiler to compile our code and
the generated partial class files. In the case of a C# application,
it’s the csc.exe compiler that handles this task. The compiled code
becomes a single assembly Window1.exe) and the BAML for each window is
embedded as a separate resource.
.
Is this a VS feature or an msbuild one?
This should be Visual Studio feature. As I said above, Visual Studio invoke the XAML compiler xamlc.exe to compile the .xaml files on save. Visual Studio will invoke MSBuild to compile the those file to .exe/.dll on build. Besides, when you on save not build the project, you can open your Task Manager, there is no MSBuild.exe exists, only when you build the project, it will comes up. So this should be Visual Studio feature not MSBuild on save.
Can I trigger an incremental build on save?
In the Visual Studio, the build system provides support for incremental builds. But if you want trigger an incremental build with your a custom MSBuild file .xyz, I am afraid you could not do that, because MSBuild only works on Build not save.
The [!INCLUDETLA2#tla_wpf] build system provides support for incremental builds. It is fairly intelligent about detecting changes made to markup or code, and it compiles only those artifacts affected by the change. The incremental build mechanism uses the following files
Check the Building a WPF Application (WPF) for more details.
Hope this helps.

Related

VSIX and item templates

So I'm having some trouble creating an item template and would like some help.
What I'm trying to do:
Create a template that adds 3 files. A Class.cs and two config files in the location "./Config/Acc/Config.xml" and "./Config/Prod/Config.xml".
I've managed to create the template through the wizard and editing the resulting files, but I would like an easy method of distributing the template on my teams TFS.
From some googling it seems that I should use A VSIX project to deply this easily. Problem is that I can't get it to compile. I have 2 projects: VSIXproject and ItemTemplateProject. I've set the assembly info on VSIX project to use the ItemTemplateProject and I've modified my Class.cs, but when I compile, visual studio doesn't know how to handle the Class.cs file.
What am I doing wrong? Is there a better way of including my ItemTemplate so that anyone who pulls the repo can use it?
The template project (a project that only contains Visual Studio project templates or item templates) is only used to be able to work with templates. Its output (say [myproject].dll) is not important (the project type may be C# but it's irrelevant) and you will only distribute the .vsix file in the end.
Files (.vstemplate files and any other files) in this project are like "static" files. They will also ultimately be included into the .vsix file output during build.
So, to ensure this files (.cs or other) are "static", you must make sure they have their action set to None (for example), not Compile.

T4 Run or compile tt files during runtime in C#

One of my initial requirements for templating engine is that I'm able to keep the 'raw' template files (in the case .tt files) 'outside' of the library executing/transforming them with the intended purpose of allowing a developer using said library to make small adjustments to the templates if necessary depending on the requirements of what they need generated.
The library is written in C# and so far the only way I've been able to get them to work is by using default 'pre-compiled' C# class automatically generated for each template by Visual Studio. I've had some success using the "TextTransform.exe" application to convert the .tt file directly to its intended output but this seems crude compared to a more native in code approach.
So is what I'm asking to do reasonable or did I flat out pick the wrong template engine to use for my needs? Any help is greatly appreciated.
Have exactly same situation - set of T4 templates outside the main project.
But it a bit more complicated - I have some T4 templates generated on the fly.
I do try following options:
batch (with half-manual scripting) compilation of T4 to CS and CS to DLL;
side routine which scan given directory for T4 template and build *.csproj & *.sln for directory;
using Visual Studio to manage and build a DLL with T4 templates.
All of those works fine, but currently I switch to the last one.
There is a reason:
I do debug T4 templates in Visual Studio in usual way.
I have (using T4Toolbox) highlighted T4 syntax.
I can easily manage compilation time.
To get all of the templates in project to be recompiled prior the main Build require only 5 lines to be added at the end of the *.csproj file:
<Import Project="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v14.0\TextTemplating\Microsoft.TextTemplating.targets" />
<PropertyGroup>
<TransformOnBuild>true</TransformOnBuild>
<TransformOutOfDateOnly>false</TransformOutOfDateOnly>
</PropertyGroup>
That's all.
After this you keep your 'raw' templates wherever you need them, organize them as normal items in DLL-type project and have an actual copy on each build.
P.S. Actual mean that if somebody change them outside the Visual Studio (in Notepad for example) you will have them all recompiled. This manageable by TransformOutOfDateOnly.
P.P.S. Have one problem with this - can't properly substitute CustomToolNamespace.

Is it possible to add custom properties to a .csproj file use by Visual Studio

I'm developing a creation tool that will be compiling media objects as well as C# code into a certain format
This tool will be compiling C# code directed by a standard Visual Studio csproj file. Ideally i would like to store non C# project related information alongside the information about that code structure and compile instructions, such as media locations and compile information. This extra information/content will not be built with MSBuild.
My optimum way to do this would be to store all of the compile and structure information into one project file for example a csproj file. My initial investigation into doing this lead to Visual studio complaining about unrecognized tags when loading the project.
My main question is: Is there a way for me to store extra non-MSBuild related data inside a csproj file without Visual Studio or MSBuild complaining about unrecognized XML tags.
Looks like you can extend the information inside the csproj files with custom tags/properties.
See this: Adding custom information to CSPROJ files

Add compile parameter to csc command using Visual Studio IDE

The solution consists of two projects: main.csproj and helper.csproj.
What Id'like to do is using dll which helper project will be complied into, as an embedded resource for main.dll.
For that purposes it's seems resonable to add custom compile attribute for project main: /resource: <path to dll>.
The problem is I can't find how to add this compile parameter through the Project Property.
PS Maybe someone can suggest other solution to avoid making changes in compile process.
You should be able to add the helper assembly as a resource in the main.csproj. That will make MsBuild generate the correct parameters for csc.
(MsBuild is the build engine used by .NET in general up to and including 4.x and is also used by VisualStudio.)
What you can do to set this up is:
Right click the Main project in the Visual Studio solution explorer and select Add existing item. Add the assembly to be embedded as a linked item from the bin folder of the helper project. (click the little arrow on the Add button in the selection dialog to access the option to add as a link).
In the properties for the item in the Main project, set Action to Embedded resource.
Tricky bit would be to include the correct build so that you include the debug build or the release build depending on what configuration you are building.
If you need that, you can either:
edit main.csproj file to include the ${Configuration} variable in the path for the helper dll.
Add a pre-build step to the main.csproj file to copy in the assembly to a fixed place and include the file from there (the include as link bit is no longer needed then)
To make sure you always build the helper assembly when you build the main assembly I would recommend you add a project reference to the main project.

Using an external tool for C# builds in Visual Studio

When using Visual Stdio 2008, you can make a C++ project build with an internal tool rather than having the IDE invoke MSVC directly. This improves the consistency of builds across platforms if a cross-platform build system is used.
However, I cannot figure out how to do the same as a C# project. It would be possible to simply register it as a native project with C# sources, however, you lose some of the advantages gained through having a C# project. More importantly, it will mean that allowing a project to build both directly and with an external tool (which is sadly necessary) will require two separate projects, rather than merely creating an alternate build configuration to invoke the external tool.
Does anyone know if it's possible to prevent Visual Studio from invoking csc by itself and instead call an external tool?
EDIT: Apparently there has some misunderstanding. The goal here is not to compile anything outside of Visual Studio. Instead, it's to allow Visual Studio to serve as the IDE but not the build system. There is already a (Scons-based) build system capable of compiling the C# and C++ sources, and Visual Studio has been configured to invoke Scons for compilation of C++ projects. I'm trying to configure it so that when you hit the 'Build' button, it will invoke Scons for the C# projects as well as the C++ ones.
Edit: Your question is still answered using MSBuild(if you are simply looking to compile outside the IDE). The IDE(Visual Studios) is simply a "fancy" way of constructing the build files that are built by MSBuild. Visual Studios isn't building the files, it simply is invoking MSBuild which ships with the .NET Framework 2.0 and up which compiles your code based on the project file that you create. If Scons can read and process an MSBuild file then I'm sure you can invoke it to build your project. But considering the fact that C# is a Microsoft language, I think you will be hard-pressed to find a value-add in not using MSBuild since I'd assume both the language and build tool are very tuned to work together. - End Edit
You can use MSBuild to compile your C# project. If you open your .csproj file in a text editor you will see that it is a MSBuild file. If you want to write some C# outside of the IDE you can construct a build file using the .csproj file as a starting point and invoke MSBuild to compile your apps. The IDE is just a way of abstracting the editing of the MSBuild file away for you.
If you are really industrious you can create a set of custom tasks to do things in your custom build process like move files around and versioning. MSBuild Community Tasks are a great example of using custom code to do task for you during MSBuild.
Given all the other answers, what MSBuild does when either VS or MSBuild perform a build can be found in the Targets files that ship with .Net. These can be be found in the FrameWork directory on your system. In my case:
C:\Windows\Microsoft.NET\Framework64\v3.5
Contains Microsoft.Common.targets among others. This file contains the following snippit:
<!--
============================================================
Build
The main build entry point.
============================================================
-->
<PropertyGroup>
<BuildDependsOn>
BeforeBuild;
CoreBuild;
AfterBuild
</BuildDependsOn>
</PropertyGroup>
<Target
Name="Build"
Condition=" '$(_InvalidConfigurationWarning)' != 'true' "
DependsOnTargets="$(BuildDependsOn)"
Outputs="$(TargetPath)"/>
This means that redifining this Target you can make MSBuild an VS do anything you want. The top of the mentioned file contains an important messagge:
Microsoft.Common.targets
WARNING: DO NOT MODIFY this file unless you are knowledgeable about MSBuild and have
created a backup copy. Incorrect changes to this file will make it
impossible to load or build your projects from the command-line or the IDE.
This file defines the steps in the standard build process for .NET projects. It
contains all the steps that are common among the different .NET languages, such as
Visual Basic, C#, and Visual J#.
My suggestion would be to read all you can about MSBuild and it's build file syntax and try redifining the Build target in your project(s). My impression is that after reading up on MSBuild you'll probably find an easier way to meet your requierements. You can find an example of redifining a Target like this in one of the answers of this so question .
Edit:
How to redefine a target?
Redefining is essentially defining the same target 'after' it has been defined. So for instance in your .*proj file(s) define a Build Task after the <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> line that imports all targets needed to in this case build a C# project. An example could be
<Target
Name="Build"
Condition=" '$(_InvalidConfigurationWarning)' != 'true' "
DependsOnTargets="BeforeBuild"
Outputs="$(TargetPath)">
<Exec Command="nmake" />
</Target>
I found a question in the same direction here, where it is suggested to edit the registry. I am pretty sure there is no other way to change the compiler used by Visual Studio because there is no trace of csc.exe in any solution, config, csproj file or whatsoever, nor in the Visual Studio 9.0 folder / subfolders within the Program Files dir.
Registry locations can be found in:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UserData\S-1-5-18\Components\74ACAA9F1F0087E4882A06A5E18D7D32
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UserData\S-1-5-18\Components\9055DA7481CC1024CB23A6109FD8FC9B
but those keys may differ dependng on your installation. Conclusion: changing the compiler used by VS seems next to impossible.
Addition: The following MSDN article deals with the same question for an custom C++ compiler, and Ed Dore's answer seems to confirm my theory that there's no way to choose an custom compiler for use within VS.
Under 'Tools' > 'External Tools' you should be able to define an outside tool to do activities for you. The Command should be the path to the executible for your external tool.
Hope this helps some.
You don't have to maintain different project files to build using an external tool. MSBuild is designed to build using the same project files that Visual Studio uses.
Here's an article that describes it.
Customize Your Builds in Visual Studio Using the Standalone MSBuild Tool
It's for VS2005, but should apply to VS2008 as well.
Looking through the answers, it seems clear to me that integrating scons into Visual Studio in a way that is compatible with the debugger and so on is not going to happen...
An option you might to consider, and I understand you don't want to change build systems, but bear with me, is to use a meta-build system, ie 'cmake'. http://www.cmake.org/
Cmake doeesn't actually build the project. What it does is to create build files for you, that you can use to build the project, and on Windows, the build files it creates for you are: Visual Studio project files. You can simply load those directly into your IDE, and compile, and use normally!
CMake is I feel very easy to use, and provides a high level of transparence and maintainability.
The exact same CMakeLists.txt files on linux will causes linux makefiles to be generated.
On mingw, they can generate mingw makefiles.
There are numerous generators available within cmake. The list is here:
http://www.cmake.org/cmake/help/cmake-2-8-docs.html#section_Generators
http://springrts.com is a huge opensource rts game that used to use scons as its cross-platform build system and now uses cmake.
I understand that you don't really want to have to change build systems, so it is a medium to long term solution.
Cmake is in any case one more option, to add to those of using a custom build tool, or using msbuild, or running the scons build from the commandline by hand.
Edit your project file and update the CscToolPath keys to point to the directory containing your tool and add CscToolExe keys that holds the name of the directory:
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|.NET 3.5' ">
.
.
.
<CscToolPath>path\to\custom\tool\directory</CscToolPath>
<CscToolExe>exe name</CscToolExe>
.
.
.
</PropertyGroup>
I have not tested this, and the CscToolExe key may cause problems, in which case I would simply rename the external tool executable to "csc.exe".
You can build your solution from the command line like this:
C:\WINDOWS\Microsoft.NET\Framework\v3.5>msbuild.exe "C:\path\Your Solution.sln"

Categories

Resources