How to target a specific version of the C ++ runtime?

We have a very large project, mostly written in C # with small but important components written in C ++. We target RTM.NET 2.0 as the minimum required version. So far, to satisfy this requirement, we have guaranteed that in our build window there will be only RTM.NET 2.0, so that C ++ links refer to this version.

Update: The C ++ assembly causing the problem is a C ++ mixed-mode assembly loaded into the managed process.

Unfortunately, when the customer was determined to do something from April 1, our corporate IT companies made a huge push to get all the corrected and updated data, and as a result, everything related to Service Pack 3.5 SP1 was installed in the build window. We tried to remove everything that was before, but now we can’t satisfy our minimum requirements, since everything that is built on this particular field requires .NET 2.0 SP1.

Since the window seems to be blocked by the fact that we cannot just remove the offensive versions, is there a way to build assemblies and explicitly tell them to use RTM.NET 2.0 (this is v2.0.50727.42)? I saw pages that reference the use of the manifest, but I can’t figure out how to actually implement the corresponding manifest and get it in assemblies. My experience is in a controlled world, so I lost it a bit.

Can anyone explain how I can make these assemblies target .NET 2.0 RTM SxS assemblies?

Thanks!

+4
source share
6 answers

Although I’m sure that Christopher answers and the sample code (thanks Christopher!) Is part of a more elegant solution, we were under the gun to get it out of the door and found a very similar, but different, solution.

The first step is to create a manifest for the assembly:

<assembly xmlns='urn:schemas-microsoft-com:asm.v1' manifestVersion='1.0'> <dependency> <dependentAssembly> <assemblyIdentity type='win32' name='Microsoft.VC80.DebugCRT' version='8.0.50608.0' processorArchitecture='x86' publicKeyToken='1fc8b3b9a1e18e3b' /> </dependentAssembly> </dependency> <dependency> <dependentAssembly> <assemblyIdentity type='win32' name='Microsoft.VC80.CRT' version='8.0.50608.0' processorArchitecture='x86' publicKeyToken='1fc8b3b9a1e18e3b' /> </dependentAssembly> </dependency> </assembly> 

Then you need to set the “Create manifest” parameter to “No” in the section “Configuration properties” → “Linker” → “Manifest file” and set the parameter “Insert manifest” to “No” in the section “Configuration properties” → “Manifest tool” → "Manifest"> Entry and exit.

Finally, to get a new manifest in the assembly, add the following command to the post-build phase of the project:

 mt.exe /manifest "$(ProjectDir)cppassembly.dll.manifest" /outputresource:"$(TargetDir)\cppassembly.dll";#2 -out:"$(TargetDir)\cppassembly.dll.manifest" 

After the build, we can open the DLL in Visual Studio to view the manifest under RT_MANIFEST and confirm that it has our manifest!

When I put the Christopher code in stdafx.h, he added it as an additional dependency ... the manifest was still looking for v8.0.50727.762. The generated manifest looked like this:

 <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> <dependency> <dependentAssembly> <assemblyIdentity type="win32" name="Microsoft.VC80.DebugCRT" version="8.0.50608.0" processorArchitecture="x86" publicKeyToken="1fc8b3b9a1e18e3b"></assemblyIdentity> </dependentAssembly> </dependency> <dependency> <dependentAssembly> <assemblyIdentity type="win32" name="Microsoft.VC80.DebugCRT" version="8.0.50727.762" processorArchitecture="x86" publicKeyToken="1fc8b3b9a1e18e3b"></assemblyIdentity> </dependentAssembly> </dependency> <dependency> <dependentAssembly> <assemblyIdentity type="win32" name="Microsoft.VC80.CRT" version="8.0.50727.762" processorArchitecture="x86" publicKeyToken="1fc8b3b9a1e18e3b"></assemblyIdentity> </dependentAssembly> </dependency> </assembly> 

I could not track another switch that removes or clears existing dependencies. I like that Christopher is better than a step after assembly, but for now it works. If anyone has any further information on how to clear any existing dependencies that would be good.

Thanks!

+8
source

Yes. There is a page in the project properties indicating the runtime. There is a drop-down list that lists all the available runtimes. Choose the one that suits you. (For VS 2008: right-click on the project → properties, the "Compilation" tab, the button "Advanced compiler options" → "Target structure")

We are doing it right now. We would like to switch to VS 2008, but we are doing it gradually. Therefore, right now we have the VS 2008 solution, but all projects are still focused on .NET 2.0. Thus, when compiling and deploying, we do not need the .Net 3.5 data installed in our test windows.

UPDATE:

To force a native program to reference specific versions of the .dll, you probably want to use something like this:

 #pragma message ("Explicit link to generate a manifest entry for MFC.") #if defined (_DEBUG) #pragma comment(linker, "\"/manifestdependency:type='win32' name='Microsoft.VC80.DebugMFC' version='8.0.50608.0' processorArchitecture='x86' publicKeyToken='1fc8b3b9a1e18e3b'\"") #else #pragma comment(linker, "\"/manifestdependency:type='win32' name='Microsoft.VC80.MFC' version='8.0.50608.0' processorArchitecture='x86' publicKeyToken='1fc8b3b9a1e18e3b'\"") #endif 

Also, instead of MFC, you should find the correct .Net.LLL values.

It is reasonable to assume that you cannot have .Net 2.0 SP1 and .Net 2.0 in the same field. Therefore, getting it to work on this box will probably really, really hurt. Most likely, it is better to deploy a new virtual assembly into which you can install the old one that has not passed the .Net framework filtering (if you can even keep it).

Otherwise, you will need to copy all the build time files into the current field, and then make changes to the include and library paths based on your build type. This is probably a much bigger headache than it costs.

+3
source

John really set me on the right track to solve the same problem. I am making a small change for the old VS2005 C ++ project (non-CLR). My development machine has all the updates, so VS2005 created links to the latest versions of the MFC80 and MSVCx80 libraries, and the executable did not run on the target computers because these versions are not available and I cannot update these machines, so I need to manage assmelby dependencies in manifest that is embedded in the executable file. This seems to be about the same problem John is working on. Starting with his additional info, this is what worked for me.

In ProjectDir, create program.exe.debug.manifest and program.exe.release.manifest files with the appropriate build reference information. Do not add them to a project or layout to try to include them in each assembly. Then set the project properties as follows:

Linker Options -> File Manifest

  • Create manifest: None
  • Manifest file: empty
  • Additional manifests: blank
  • Allow Isolation: Yes

Manifest Tools-> Input and Output Options

  • Additional manifest files: $ (ProjectDir) $ (TargetFileName). $ (ConfigurationName) .manifest
  • Input Resource Manifest: Blank
  • Insert manifest: Yes
  • Output manifest file: (filled automatically)
  • Manifest Resource File: (automatically populated)
  • Generate files in a directory: No
  • File dependency information: $ (IntDir) \ mt.dep (populated automatically)

From my testing, it looks like this does not generate any other manifest files and inserts your manually encoded information into the EXE as the resource #__ NAME_STAN_START_START_START_EXT_START_EXT_START_EXT_1.

In the Manifest Tool parameters, " Output manifest file " and " Manifest resource file " were filled automatically, even after I cleaned them.

This apparently allows me to manage the build dependencies and run the executable on the target computers. An additional advantage is that I did not have to use the post-build step, which is used for other purposes. By controlling the Linker and Manifest Tool parameters, you can get the same result.

Sorry, I could not update the screenshots, but I am a new user and the images are not yet allowed.

+2
source

I know this is a hack, but I resorted to creating a manifest from the outside and edited it using a notepad. As a last resort, this did the trick for me. In my case, I was looking for a VC ++ 2005 application to point to .762 CRT.

Good luck Terry

+1
source

John's answer works for us. In Visual C ++ 2005, the compiler generates manifests that include versions 762 and 4053 of MFC and CRT. We removed version 4053 from the manifest and went to the manual step described above. (The internal code will actually capture 4053, since this is a recognized security fix compared to 762, but the specification is necessary, or the connection will simply fail.)

The ted blog (tedwvc.wordpress.com) posted a tip to us, but its solution did not work for us. This approach works here.

+1
source

Maybe you want CorBindToRuntime . This will allow you to specify the version of the CLR to which your C ++ is loaded.

0
source

All Articles