Run Multiple Files From Single .tt File and Add the Generated Files Under the Single .tt File - t4

I have a scenario in which I need to run all template files under a given directory from one .tt file and add the generated files under this .tt file which was run.

Generating multiple output files from one .tt file is not an easy task. I guess implementing this functionality would be very time consuming.
Here is a blog post about how to use tangible T4 Editor to create multiple output files, even in different solution projects:
T4: How To Generate Multiple Output Files From A Single T4 Template

Related

Correct way to use multiple .IDL (MIDL) files within a single "Windows Runtime Component C++/WinRT" project

Visual Studio 2019. Windows Runtime Component C++/WinRT project.
How do I follow and implement the recommendation: "We recommend that you declare each runtime class in its own Interface Definition Language (IDL) (.idl) file, in order to optimize build performance when you edit an IDL file, and for logical correspondence of an IDL file to its generated source code files. Visual Studio merges all of the resulting .winmd files into a single file with the same name as the root namespace. That final .winmd file will be the one that the consumers of your component will reference."
https://learn.microsoft.com/en-us/windows/uwp/cpp-and-winrt-apis/author-apis
Within the same project I can add a second (third and so on) .IDL file using Project->Add New Item->Midl File (.idl). This seems to work ok?! I then manually add associated .h and .cpp files for each .IDL file. Build to generate stub files then manually copy and "fill in" these files before a final build which is successful. In this way I have a single IDL file per runtime class with its associated headers and implementation files including any other files (c++ .h and .cpp files) needed for the implementation. As I need to add functionality to the interface I just edit the IDL file, rebuild and add functionality to the header and implementation C++ files.
Is this what was recommended?!?
When I add the .IDL file and then manually add an associated .h and .cpp they do not appear "under" the .IDL file as the original ones did when I created the new project. Is this just a visual nicety of Solution Explorer OR is this indicating that I have something wrong?!?
I plan to have multiple "C++/WinRT WRC" projects (one for each namespace, each consisting of multiple runtimeclass interfaces with separate .IDL/.h/.cpp files as described above. Then I reference all of the projects (project to project) in my single C#/UWP App.
I am actually trying to implement a user interface to allow me to utilise a large code base of math/engineering C++ classes that implement a very specific & proprietary type of electronic circuit simulation already existing and programmed in C++ and compiled as a console app. The user data in and out is relatively small compared to the processing that takes place to generate the output.
It looks like you are handling the idl files correctly and that behavior is the same as I experienced when just adding a new Midl file directly.
If you like the look of having the .h and .cpp files "under" the .idl file in the tree you can try adding a new View Model instead of a new Midl file. This will create the .idl/.h/.cpp files all with the same name and place the .h and .cpp files visually under the Midl file. The idl template you get this way is for a basic runtime class.
When creating a new Windows Runtime Component, the .idl and the .h are usually grouped under the .cpp, not the .idl, but whatever your preference. There isn't a template to add a Runtime Class, which is pretty dumb. One fix for this could be as follows:
This is not a perfect solution, but is the easiest. Create a new Windows Runtime Component. Open Project>Export Template. Select Export Item. Select the Runtime Class under the new component. Export with Automatic Import option checked. Save your project and exit VS. Open your project. You can now add a fully templated Windows Runtime Class by simply adding item>Runtime Class. However, there will still be no dependencies (there may be a tool for custom nesting, but not in community as far as I can see). To fix this, after adding the files, save the project. Edit the project file (use notepad++ or even unload project, edit) and add the property <DependentUpon>Runtime Class.idl</DependentUpon> between your .cpp and .h file delimiters. Save the project file and reload. Probably want to do this in batches.
The alternative is to write a .vsix to either add the files and edit the project file, or have a right click command that runs on a .cpp and edits the project file, adding the DependentUpon directive. I can't find a 2022 functional .vsix for this. I will post one if I make one.

File Tracker Log file format

In Visual Studio 2010 incremental builds are done using the File Tracker (Microsoft.Build.Utilities.FileTracker). It seems that it is responsible to the creation of these *.1.tlog files on the intermediate directory.
I couldn't find any reference to the syntax of these .tlog files.
They contain a list of paths to files that are read/written while the tracker tracks the execution of some tool, in order to check which files should be compiled in an incremental build. However, these files also contain some special characters such as "^" and "|".
Another thing I noticed was that these files are sometimes edited from Visual Studio targets files. For example, in Microsoft.CppCommon.targets on CustomBuildStep target I found the following line:
<!-- Appended tlog to track custom build events -->
<WriteLinesToFile File="$(IntDir)$(ProjectName).write.1.tlog" Lines="#(CustomBuildStep->'^%(Identity)');#(CustomBuildStep->MetaData('Outputs')->FullPath()->Distinct())"/>
So this probably means that the project file is dependent on the custom build step outputs.
My questions are:
Does anyone know of a reference for the .tlog file syntax?
In which cases is the tracker-log used on Visual studio? I know of the CL and maybe Link tasks that use it, but it seems that Visual Studio IDE itself uses it in order to decide whether to run msbuild at all for a certain project.
Thanks
EDIT
Another hint:
CanonicalTrackedInputFiles Class is document as "the filetracking log interpreter for .read. tracking logs in canonical form or those that have been rooted (^) to make them canonical"
When I have time I'll dig into it a bit more. Perhaps this class and others under Microsoft.Build.Utilities could be used to help us work with tlog files instead of working with the raw text tlog files directly.
See also: CanonicalTrackedOutputFiles Class, FlatTrackingData Class and of course FileTracker Class.
This stuff doesn't seem to be documented anywhere, so I've had to figure this out based on trial and error and by staring at some example targets/xml/props files:
The reason the custom build step writes to the tlog file by hand is that Build|Clean - and probably its command line counterpart - scrapes the tlog files to find which files to delete. It seems to look for all files matching *.write.tlog, or maybe *.1.write.tlog, in the intermediate folder, read the list of file names in each, and delete the files named. So, if the custom build steps knows what its outputs are, it can simply record them in a tlog file, and interact with Build|Clean that way.
(You can try this out yourself - build your project, create some temp files, add your own tlog file to your project's intermediate folder containing the paths to the temp files, then do a Build|Clean. Your temp files will be deleted along with the usual build artefacts.)
In a tlog file, a file with no prefix is the name of an output file. These files are deleted when you do a Build|Clean.
A file with a ^ before it a comment, I think - perhaps obviously, Build|Clean doesn't touch any of these.
As for |, I've only seen it in comment lines, used to separate different file names. I suspect this is just a convention, and not some special syntax, since if you put multiple output files on line, separated by |, Build|Clean doesn't delete them.
The tlog file format is now documented here: https://learn.microsoft.com/en-us/visualstudio/extensibility/visual-cpp-project-extensibility?view=vs-2017#tlog-files
Read .tlog format
Read .tlog files (.read..tlog) contain information about source files and their dependencies.
A caret (^) at the beginning of a line indicates one or more sources. Sources that share the same dependencies are separated by a vertical bar (|).
Dependency files are listed after the sources, each on its own line. All file names are full paths.
The tlog file is generated by the file tracking system in MSBuild. It isn't specific to individual compilers, it can capture any file reference by anything done in the MSBuild process, depending on how it is configured.

merged DLLs, Intellisense not picking up separate XML doc files

I use ILMerge to merge several of my C# project DLLs into a single DLL for the whole solution. I have each project produce a .XML file of its documentation for Intellisense, and I'm having trouble getting those comments to show up when I try to use my merged DLL as a reference in another solution. I have these files all in the same directory:
MergedProjectDlls.dll
Project1.XML
Project2.XML
Project3.XML
Project4.XML
I tried renaming a single project XML file to be MergedProjectDlls.XML then removing and re-adding the reference in Visual Studio, but Intellisense still wasn't picking up on the comments that I know are there in the project XML file I renamed.
I was hoping to somehow merge all these project XML files into one titled MergedProjectDlls.XML anyway. Is that possible? Would Intellisense then pick up on it automatically when it's in the same directory as MergedProjectDlls.dll?
Edit: just found this on MSDN:
To use the generated .xml file for use with the IntelliSense feature, let the file name of the .xml file be the same as the assembly you want to support and then make sure the .xml file is in the same directory as the assembly. Thus, when the assembly is referenced in the Visual Studio project, the .xml file is found as well.
And also:
Unless you compile with /target:module, file will contain tags specifying the name of the file containing the assembly manifest for the output file of the compilation."
Der, it turns out that's just a command-line option to ILMerge:
ILMerge.exe /out:MergedProjectDlls.dll
Project1.dll Project2.dll Project3.dll
Project4.dll /ndebug /xmldocs

Working with XSLT in Visual Studio

In my C# client application, I use XSLT to transform XML into HTML.
I would like to be able to edit these files in place, without having to recompile the entire solution. I'm having trouble working out how to set up Visual Studio 2008 to allow this.
The problem is that the XSLT files must get copied to the output directory somehow. Currently this happens during the build process. (My XSLT files are set to "copy if newer".) The build process can take a few minutes, which seems excessive for making small tweaks to the HTML.
I could make my XSLT edits in the output directory itself, but the output directory is not under source control. I have accidentally wiped out my quick edits several times by building my solution.
I'd like to reduce the cycle time for debugging XSLT, while keeping my XSLT files under source control and preventing accidental overwrites.
Summary of Responses: It appears that the most practical approach for solving this problem -- given that Visual Studio doesn't have a nice way of doing it out of the box -- is to create a separate project that contains the content files. These files get copied to the output location when the project gets built. That way I don't have to compile the whole solution, just the one project with all the static information like XSLT, CSS, images, etc.
Several folks suggested using sync or batch copy tools, but while this would work for me personally, setting it up for the other members of the team too would be a lot of extra work.
I am not entirely clear about your question, but you can instruct Visual Studio to copy the file from the solution to the output folder every time that you build.
Let me try to understand your scenario:
You have the XSLT files checked into source control along with your C# code. For example, if your project is in a folder called MyProj, then the XSLT files reside in MyProj/Templates
You want to be able to edit the xslt files in the Templates folder and submit those changes to source control just like you do with .cs or other files in your project.
You want a copy of your xslt files in the bin/Debug or bin/Release folder along with your executable.
If that is the case, add the XSLT files to your Visual Studio project. Then right click on them, open Properties, and set "Build Action" = "Content" and "Copy to Output Directory" = "Always". Whenever you build your project, the latest copy of the XSLT files will be placed in your bin/Debug or bin/Release directory.
One approach is to include a C# Preprocessor Directive to point my XSLT load function to the solution directory when in debug mode, but the output directory when doing a release build.
Something like:
string viewFolder = AppDomain.CurrentDomain.BaseDirectory;
#if DEBUG
// Move up from /bin/debug
viewFolder = viewFolder + #"..\..\";
#endif
But that feels like a hack.
Apparently you're managing two concerns in one project. The first concern is your business logic (instantiating an XSLT transform, calling it to transform some XML content, outputting the HTML result....). The second concern is the Transformation itself.
So why not create a separate project for your xslt sheets? "Building" this project would consist of copying the sheets to the output folder. Changing xslt will not influence the other project, hence reduce the build time.
Separation of Concerns at project level, that is :)
You can edit the file directly in the output folder.
On another note, a lot of people don't know that rich tools are built into VS to allow debugging xslts.
http://msdn.microsoft.com/en-us/library/ms255605(VS.80).aspx
One solution that might work for you is to setup a junction to your Templates in your output folder. This would allow you to use the XSLTs directly without copying them to the output folder. A good idea is to ensure (create) the junction as a build action.
Prerequisites:
NTFS
A tool to create junctions (e.g. junction)
Create a batch file that copies your xslt's from their source-controlled location to all your bin directories (bin/debug bin/release or whatever ones you have defined)
Add the batch file as an External Tool, optionally assigning a keystroke (or chord) to execute the batch file
Edit, run tool (I'd assign a keystroke to this to make this easy), then check your webpage.
Could you use a file synchronization program (e.g. Microsoft SyncToy "is a free application that synchronizes files and folders between locations") to copy the files? This would allow you to avoid the "copy on build" step because the files are automatically copied after saved. Also, if you edited them in the output directory, the changes could be copied back into your source controled directory. Not what the best real time sync program is for this scenario is, but that could be another question.
I have exactly the same issue. I have bought a program called ViceVersa (http://www.tgrmn.com/) in which I have setup sync profiles so that my css, layout and xslt folders are synced from my machine to my dev server as soon as any changes are made. If I make any code changes then I just publish as normal.
I understand this is an older post but I found a different solution to basically the same problem.
Visual Studio allows you to 'link' files.
Right click on the folder in the solution where you want the file link to be located.
Click
'Add'
'Existing Item..'
(select the file)
Go the 'Add' Drop down and select 'Add as Link'

Run a Visual Studio custom tool at build time

I have a script that will convert a text file into a resource file, so that I can have multiple language support by having text files for different languages converted into different resources. Once I run the script to get the resx file, I then have to run a custom build tool (as described here:Link to Code Project) in order to create the Designer.cs files to use the new files.
In keeping with the philosophy that I should be able to build the entire project with a single button click, how can I remove the step where I have to explicitly call the custom build tool in order to make the codebehind files?
I've tried automatically deleting the Designer.cs files as a pre-build step, since I would think that the custom build tool would automatically run if there were no Designer.cs files, but no dice.
So, I want my build script in Visual Studio/msbuild to do:
1) convert text to resx (done)
2) move resx files to appropriate directory (done)
3) create designer.cs files using a custom build tool (not done)
It's that last step...
Unfortunately I don't think there's an easy way of doing this. Custom Build Tools only run from within VS.NET - they don't run when you build your project using MSBuild from the command line.
In general, if you have the choice of writing a build tool as a Customer Build Tool or an MSBuild Task then choose the MSBuild Task every time as these Tasks will run in VS.NET and from the command line.
The designer.cs files for resources are there to support your coding. They give you the strongly typed access into the resource file. So, as long as you create your culture invariant resources in VS.NET (and let it create the .designer.cs files) then adding additional language support later (additional .resx files) should work fine.
If, however, your text files are your primary resource files, and you're adding new resource strings into these text files first, then you'll need to find another way of generating .cs files that allow you to code against those resources. If you HAD to, generating the .designer.cs file yourself (or somethign similar) wouldn't be that difficult. Using CodeDom or T4 you could create the helper class, using an existing .designer.cs file as a template.
There is a way to generate the *.Designer.cs for *.resx as part of the build process. There is a built-in MSBuild task GenerateResource, which basically a wrapper around the SDK tool resgen.exe. Here you can find an example how to use it.
Another thing you would find useful, if the generated *.Designer.cs version is not correct, basically, GenerateResource task is not calling the desired version of resgen.exe, setting property SdkToolsPath might help you.
Have you tried adding a Exec step in Before/AfterBuild step in your csproj? You have to manually edit the file for this, but that should solve your problem.
I'm not fully clear on if you want this done before or after the build. If you need it done sometime after Pass1/Pass2, you can hook into the targets directly. Try looking into Microsoft.Build.Common.Targets to get a feel for how to do this.

Resources