Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Managed assembly with additional Win32 resources #824

Open
KalleOlaviNiemitalo opened this issue Sep 24, 2022 · 4 comments
Open

Managed assembly with additional Win32 resources #824

KalleOlaviNiemitalo opened this issue Sep 24, 2022 · 4 comments

Comments

@KalleOlaviNiemitalo
Copy link

KalleOlaviNiemitalo commented Sep 24, 2022

How can I use Nerdbank.GitVersioning for the Win32 version resource in a managed assembly that needs to have other Win32 resources as well?

Specifically, I need to build a managed-code DLL that includes a Win32 manifest resource for registration-free COM purposes. As described in How to: Configure .NET Framework-Based COM Components for Registration-Free Activation and Assembly Searching Sequence, the resource ID must be 1 (CREATEPROCESS_MANIFEST_RESOURCE_ID) so that, when the manifest of the application references this DLL, Windows loads the manifest of the DLL and makes the COM classes available to the application without requiring the application to use the Activation Context API.

I cannot use the C# compiler feature that embeds a manifest resource, because that one uses resource ID 2 (ISOLATIONAWARE_MANIFEST_RESOURCE_ID) when the file is a DLL rather than an EXE. I must instead provide a .res file, but then the C# compiler won't generate a version resource either, and I must place that in the .res file as well. I have a Visual C++ utility project that only runs the resource compiler to build the .res file, from an .rc file that references the manifest XML file and lists the version information. The C# project then depends on this C++ project and feeds the built .res file to the C# compiler.

I'd like to start using NBGV to generate the version information in the .rc file (or in a separate file that I would then #include), but when I try to use the Nerdbank.GitVersioning package, it fails outright:

…\packages\Nerdbank.GitVersioning.3.5.113\build\Nerdbank.GitVersioning.targets(165,5): error : Unsupported ConfigurationType 'Utility'. Only 'Application' and 'DynamicLibrary' are supported at this time.

this.Log.LogError("Unsupported ConfigurationType '{0}'. Only 'Application' and 'DynamicLibrary' are supported at this time.", this.ConfigurationType);

Also, I'd like to have "LegalTrademarks" in the StringFileInfo block but I don't see how to add that if NBGV generates the VERSIONINFO resource.

Should I disable the GenerateNativeNBGVVersionInfo target by setting GenerateAssemblyVersionInfo=false and then implement a custom MSBuild target that writes only #define directives?

@KalleOlaviNiemitalo
Copy link
Author

KalleOlaviNiemitalo commented Sep 24, 2022

It seems I can hack this up like so:

  • Add a custom target that runs before GenerateNativeNBGVVersionInfo and changes ConfigurationType to DynamicLibrary, which GenerateNativeNBGVVersionInfo is happy to work with.
  • Add a custom target that runs after GenerateNativeNBGVVersionInfo and changes ConfigurationType back to Utility.
  • Add a custom target that runs after GenerateNativeNBGVVersionInfo and removes $(VersionSourceFile) from the ResourceCompile item type.
  • Add $(IntermediateOutputPath) to the AdditionalIncludeDirectories metadata of the ResourceCompile item of the .rc file that references the side-by-side assembly manifest.
  • In the .rc file that references the side-by-side assembly manifest, do #undef RC_INVOKED and then #include the file generated by the GenerateNativeNBGVVersionInfo target. Undefining RC_INVOKED causes that to only #define the version information macros and not define the VERSIONINFO resource. My .rc file can then reference those macros when it defines its own VERSIONINFO resource with LegalTrademarks and whatever.

@KalleOlaviNiemitalo
Copy link
Author

I think what this needs is a property that a project can set to ask Nerdbank.GitVersioning.targets to generate just the #define directives and skip the VERSIONINFO resource. In this mode, the NativeVersionInfo task would omit the NBGV_FILE_TYPE macro if it does not recognize the value of the ConfigurationType parameter.

@AArnott
Copy link
Collaborator

AArnott commented Oct 22, 2022

I'd accept a PR that adds the property you describe to work for your scenario. Bonus points if you add a test that preserves that behavior so we don't break it later when I forget why it's there. But a code comment might suffice.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants