Click here to Skip to main content
15,890,186 members
Please Sign up or sign in to vote.
5.00/5 (1 vote)
See more:
I have a c++ win32 console application (regsvr42) that generates manifest files and is compiled with /MT. Some of the dlls it adds to the manifest are .net and some are win32. All the dotnet ones are strong named. I need to get the public strong name token from the .net dlls so that I can reference them correctly in the manifest file.

sn -T mydllname.dll displays this token, but I need to get it from an api call that can be hooked into the win32 application. I can see that it can be done in the .net environment using reflection but I cann't us .net from my application /clr and /mt compile options are not compatable

Ideally I would like a way to get the token from win32 API simular to the way I can get the version information using GetFileVersionInfo
Posted
Comments
Sergey Alexandrovich Kryukov 4-Jul-11 15:23pm    
Interesting problem, my 5. I'm curious: what's the ultimate purpose of this activity? I hope my solution can work for you, please see.
--SA
ARopo 5-Jul-11 5:45am    
Some background to this: We have a product which is a mix of win32 binaries and .net assembles. Many of the win32 modules use COM. Some .net modules are called through COM, and call some win32 modules through COM. Problem is we don't want a COM/Registry dependancy for deployment reasons, so we have to generate sidebyside manifest files and run the application COM free. We have 2 tools that generate the manifests Regsvr42 (win32 C++ console app) and GenMan (.net and deals with .net assemblies) The main exe is a win32 application so we use Regsvr42 to generate this manifest. In this generated manifest are listed all the dependancies of the exe some of which are strong named .net assemblies. Thus my question, regsvr42 is a win 32 console application written in C++ and compiled with /mt (so is incompatable with /clr i.e. cannot access .net)
Sergey Alexandrovich Kryukov 5-Jul-11 6:25am    
I used to solve some related problem, it looks different, but the idea might be useful... I used COM as .NET was not there but I did not want to use Registry and any COM binaries from Microsoft. Reasons: 1) I hate involved "accidental complexity" and dependency on Registry, which is evil, 2) I needed COM inter-operation with Unix. I did it by implementing creation of the COM object without any MS binaries. We had one single exported function "CreateObject" which was used in all COM modules. In other words, from all COM I used only IDL + MIDL, code generation and binary layout for interfaces and implementation classes. It worked out wonderfully.
--SA
Sergey Alexandrovich Kryukov 4-Jul-11 20:00pm    
Please see updated solution with added information on how to get a public key token of the assembly name (this is correct name for it).
--SA

1 solution

First, I can see you're a bit confused about .NET part of getting version information. The method GetFileVersionInfo only gets file version. The versioning system of .NET software is usually based on assembly version, which is totally independent from the file version and is defined by the assembly attribute AssemblyVersion and the file version is defined by the assembly attribute AssemblyFileVersion.

Suppose you load an assembly from file. Here is how you get the version:

C#
System.Reflection.Assembly assembly = 
    System.Reflection.Assembly.LoadFrom(fileName);
System.Version version =
    assembly.GetName().Version;


Now, let's approach getting assembly by the Win32 unmanaged code. I suggest you work around the problem. First, create a .NET assembly which retrieve the System.Version information from the assemblies the way you want. It should clone this type into some managed type understandable by your unmanaged code.

Now, the problem is to deliver the result to the unmanaged code. You will need to create some static managed method in you library assembly and export it as unmanaged; and the unmanaged code should be able to load this library as a regular unmanaged DLL and call this method.

Many would say this is impossible. This is almost true but not all the truth. It is only impossible in C# or VB.NET, but quite possible using IL assembler; and this is a part of CLR ECMA and ISO standards, not like any dirty trick.

So, the idea is to use a special attribute to mark the methods to be exported as unmanaged. The code is complied by VB.NET or C#, disassembled; then the IL code is modified according to the attributes and assembled again. This is automated using the MSBuild custom step, so no knowledge of IL assembler is required.

You can find the solution in the following CodeProject articles:
Unmanaged code can wrap managed methods[^],
How to Automate Exporting .NET Function to Unmanaged Programs[^].

[EDIT]
Same approach goes for getting a public key token of assembly strong name. You can get it using your .NET library DLL. Use System.Reflection.Assembly.GetName().GetPublicKeyToken, see http://msdn.microsoft.com/en-us/library/system.reflection.assemblyname.aspx[^].


—SA
 
Share this answer
 
v2
Comments
ARopo 5-Jul-11 5:11am    
Thank for taking the time to answer but this was exactly the sort of thing I wanted to avoid, due to time constrants. I think you could do something simpler by re-writing regsvr42 as a c++/.net console application but I don't have time for that either. My current solution involves reading a list of public key tokens from a file - not great but quick. I gave the example of GetFileVersionInfo as an example of the kind of api call I'm looking for only it might be called GetPublicKeyToken if it existed point is it would be win32 API not .net
Sergey Alexandrovich Kryukov 5-Jul-11 5:23am    
Avoid what? -- managed library to handle assembly? How can you save development time avoiding it? In .NET all code for that is ready-to-use, in native code you would do it yourself and loose all your time fixing the bugs. With the managed DLL based solution you have to assemble all together, but all pieces are already tested but someone else...

Also, I'm curious about the ultimate goals of all this activity. Why doing this tricky stuff?
--SA
ARopo 5-Jul-11 5:45am    
Avoid using .NET in this instance I was looking for a quick solution that could be used with my application's existing win32 /MT environment. Otherwise I would have just converted the application to use /clr and access .net. See earlier comments for the background and ultimate goal.
Sergey Alexandrovich Kryukov 5-Jul-11 6:13am    
I don't see how it can be quicker. Your next dirty work-around is maybe better.
--SA
ARopo 5-Jul-11 7:26am    
It only would have been quicker if an api call existed to do this. But since it doesn't then it is not a solution. For now I've avoided the problem by using sn to get the keys the put the keys in a file which I read from the win32 console application.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900