How to run a program from one of the projects as a build step?

The problem is this: my VS2015 solution has several projects, including A and B.

A is a regular project that contains a program / service / code that can translate certain source files into compiled resources (the idea is that the source is human-controlled and managed by the source, but the received resource is optimized by the machine, but not under the control of the source )

Project B contains one such source file, and instead of being put verbatim in the assembly of project B, I want the program to โ€œcompileโ€ it into a resource file and only put it in assembly B (along with other code in project B, which usually compiles).

+-------------------+ +-----------------+ |Project A | |Assembly A | | | +----------------> | | | | | | +-------------------+ +-------+---------+ | | +--------------------------------+------+ | | +-------------------+ +-----------------+ |Project B | | |Assembly B | | | +----+---+ | +-----v--+ | |src.txt|| +----------------> | |res.txt|| | | || | | || | +--------| | +--------| +-------------------+ +-----------------+ 

How to do this in Visual Studio 2015?

+5
source share
2 answers

The basic principle is simple and can be implemented as such: make sure that A builds to B and then uses A.exe as the pre-build step in B.

To build the build order correctly: open .sln with two projects in VS, right-click projectB, select "Build Dependencies-> Project Dependencies ..." and make projectB depend on projectA. check on the assembly order tab that A will be built before B.

Now open projectB in a text editor, scroll to the end and add something like this before the </Project> :

 <Target Name="GenerateSomeFile" BeforeTargets="Build"> <PropertyGroup> <SourceFile>$(MsBuildThisFileDirectory)\in.cs</SourceFile> <TargetFile>$(MsBuildThisFileDirectory)\out.cs</TargetFile> </PropertyGroup> <Exec Command="/path/to/projectAOutputDir/A.exe $(SourceFile) $(TargetFile)" </Target> 
+1
source

You can implement this using a custom Visual Studio tool, rather than a step before and after the build. Actually, this is not such a compilation step as the transformation of the designer, but he should still solve the question that I think you are asking. This creates a custom code generator, similar to how Visual Studio converts resource strings from a .resx constructor to compiled C # code.

You did not specify which version of .NET you are using for targeting, but it is assumed that you are targeting .NET 4.5. Here's a good tutorial here for creating your own custom tool on which the following is based. Note that this article was written for Visual Studio 2012, so some of the registry keys are different.

A brief description of what all of this does:

  • Embed Microsoft.VisualStudio.TextTemplating.VSHost.BaseCodeGenerator in Project A. This does everything you do to convert from the src.txt input file to the src.txt output file.
  • Register your generator from step 1 as a custom VS2015 tool.
  • Set the properties of your src.txt in Project B to use your own tool. From now on, every time you save or modify src.txt , Visual Studio will generate your res.txt for you, which you can embed in your B assembly or whatever. Just remember that if you need to make changes to Project A later, you will need to repeat step 2 and restart VS.

Implement Code Generator:

  • Add a link to Microsoft.VisualStudio.TextTemplating.VSHost.14.0 for project A.
  • Open the AssemblyInfo.cs file for Project A and change [assembly: ComVisible(false)] to [assembly: ComVisible(true)]
  • Create a new code generator class as shown below

     [ComVisible(true)] [Guid("C43E4E36-289C-40C8-9B87-7F79E2B57B0E")] // TODO: replace with your own random GUID public class MyResConverter : Microsoft.VisualStudio.TextTemplating.VSHost.BaseCodeGenerator { public override string GetDefaultExtension() { // TODO: file extension of the resulting resource file return ".res.txt"; } protected override byte[] GenerateCode(string inputFileName, string inputFileContent) { // TODO: your "compile" step that converts `src.txt` to `res.txt` return Encoding.UTF8.GetBytes(inputFileContent.ToUpper()); } } 

Register the code generator:

  • Compile project A and copy the resulting assemblies to another folder. If you leave them in the assembly output directory, the files will be locked later, since Visual Studio will load them into memory after registering the user tool with VS and restarting VS.
  • Use regasm to register your project A as a COM assembly, run from the command line as an administrator: C:\Windows\Microsoft.NET\Framework\v4.0.30319\regasm.exe /codebase C:\Path\To\ProjectA.dll
  • Create a new install.reg text file to configure VS to recognize your new custom tool from Project A, substituting TODO accordingly:

     Windows Registry Editor Version 5.00 ; TODO: Replace with your GUID [HKEY_CURRENT_USER\SOFTWARE\Microsoft\VisualStudio\14.0_Config\CLSID\{C43E4E36-289C-40C8-9B87-7F79E2B57B0E}] "InprocServer32"="C:\\Windows\\System32\\mscoree.dll" "ThreadingModel"="Both" "Class"="ProjectA.MyResConverter" ; TODO: Replace with your assembly "Assembly"="ProjectA, Version=1.0.0.0, Culture=neutral" ; TODO: Replace with your dll file "CodeBase"="file:///C:\\Path\\To\\ProjectA.dll" ; TODO: Replace with your tool name [HKEY_CURRENT_USER\Software\Microsoft\VisualStudio\14.0_Config\Generators\{FAE04EC1-301F-11D3-BF4B-00C04F79EFBC}\MyResConverter] ; TODO: Replace with your GUID "CLSID"="{C43E4E36-289C-40C8-9B87-7F79E2B57B0E}" "GeneratesDesignTimeSource"=dword:00000001 ; TODO: Replace with your description @="My Custom Tool" 
    • Note that this is different from the tutorial mentioned above that you are targeting the 14.0_Config key, since this is VS2015.
    • The string {FAE... is the GUID for C # code generators and is not related to any GUID that you create for your custom code generator.
    • Please note that this install.reg file must be an ANSI-encoded file, otherwise regedit.exe will reject with the error "invalid registry file". If you create the install.reg file inside VS as a text file, it will be encoded as UTF8, so just create it in the notepad.exe file or whatever you like.
  • Run install.reg to update the registry.
  • Restart Visual Studio

Use your custom tool:

  • Right click on your src.txt in Project B, then Properties
  • Change the "Custom Tool" property to your tool name that you specified in install.reg, for example. MyResConverter
  • Save the src.txt file to generate the source converted resource file (you can simply open src.txt and click File> Save to make the code generator work). You should now see src.res.txt under your src.txt . You can change the properties in the generated file to insert it as a resource in your assembly or whatever.

Now, when you modify src.txt , VS will regenerate the resource file for you, which you can embed in your project B.

+2
source

Source: https://habr.com/ru/post/1259419/


All Articles