pouët.net

Visual studio 2008 and vcredist_x86.exe requirements

category: code [glöplog]
thanks for the help Guybrush !
still crawling a lot tho..vs2010 is compiling very slow aswell !
i mostly find myself using vc2008express again !
also: free licenses plz !
sleepy looks nice.
added on the 2010-07-30 04:03:02 by raer raer
too drunk to try it now though... ;)
added on the 2010-07-30 04:03:29 by raer raer
Quote:
If you need bigger guns, AMD CodeAnalyst profiler is still free and integrates with Visual Studio.

My bad. It does not seem to integrate with Express. At least not 2008. You can still use externally like you do with the profiler Ryg pointed out.
added on the 2010-07-30 17:31:04 by Yomat Yomat
Hi,

still trying to fix this issue, although I'm not sure how to check if it is fixed or not.

Something that I noticed was that my previous .exes had "Generate debug info" turned on while in release mode. This made the exe about twice as big. I turned it off. Is that related?
added on the 2010-08-02 10:41:44 by Navis Navis
No.

Use depends.exe to see which DLLs are being loaded. (Windows\system32\)MSVCR.dll is the version originally installed with the OS afaik, the other ones are called (Windows\winsxs\<LONG_REDIST_VERSION_FOLDER>\)MSVCRxx.dll. Or get a VM or another PC without the redist to try the application. Windows Vista already has the VC 2008 redist (non SP1, if I'm not mistaken) installed btw.
added on the 2010-08-02 10:59:13 by raer raer
with xx being the VS version. 2005 = 8.0, 2008 == 9.0
added on the 2010-08-02 11:00:41 by raer raer
Interestingly:

after changing the "generate debug info" and running through depends.exe there is a difference between the two versions:

the first version has four dependencies on c:\windows\winsxs\...\MSVCP80.dll, MSVCR80.dll, VCOMP.dll and GDIPLUS.dll. all others are on c:\windows\system32\...

the second version has just one \winsxs\..\ dependency, that being GDIPLUS.dll .

I wonder if this solves my problems, or GDIPLUS would still require the redist...

(btw thanks for the very informative answers)
added on the 2010-08-02 11:20:11 by Navis Navis
Dunno. Is it in the same dir as the MSVC files? GDI+ is probably used for loading images. See what functions are needed and maybe you can get around using the DLL that way.
added on the 2010-08-02 11:54:24 by raer raer
There may also be a way to get rid of redist usage while not needing to link statically by prefacing all API function calls with "::" (and then adjusting some settings). But I'm not sure how to do it.

I have a small project here that checks for the redists which is also statically linked. Works quite well...
added on the 2010-08-02 12:01:02 by raer raer
Didn't VS2010 also drop the whole manifest nonsense, at least for C/C++?
added on the 2010-08-02 13:41:04 by sagacity sagacity
Yes. Thank god. That is DLLhell^2...
added on the 2010-08-02 13:53:36 by raer raer
What RareWtFailWhale said, +, Navis, if you can afford to release a demo with 1.2Mo of crt dll, or you need definitely them, you can put them in the same directory than your exe with a special manifest on the side. The sequence is to avoid vcredist_x86.exe install is :

1) Get the application manifest from your exe (whatever, using CFFExplorer or a resource browser, or even set the options in VC to not embed the manifest in the exe)
From the manifest you should have something like this :
Code: <?xml version="1.0" encoding="UTF-8" standalone="yes"?> <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3"> <security> <requestedPrivileges> <requestedExecutionLevel level="asInvoker" uiAccess="false"></requestedExecutionLevel> </requestedPrivileges> </security> </trustInfo> <dependency> <dependentAssembly> <assemblyIdentity type="win32" name="Microsoft.VC90.CRT" version="9.0.21022.8" processorArchitecture="x86" publicKeyToken="1fc8b3b9a1e18e3b"></assemblyIdentity> </dependentAssembly> </dependency> </assembly>


2) Put down on a paper the number from the manifest : version = "9.0.21022.8", publicKeyToken = "1fc8b3b9a1e18e3b"

3) Go to the directory %SystemRoot%\WinSxS and look for a directory which is named like this : x86_microsoft.vc90.crt_1fc8b3b9a1e18e3b_9.0.21022.8_none_bcb86ed6ac711f91. <= You have the publicKeyToken just after the vc90.crt following the version.

4) Copy the 3 dlls, msvcr90.dll, msvcp90.dll, msvcm90.dll, from this directory to your application directory

5) Create a Manifest file named "Microsoft.VC90.CRT.manifest" in this directory
Put the following manifest inside, chaning publicKeyToken and version accordingly:
Code: <?xml version="1.0" encoding="UTF-8" standalone="yes"?> <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> <noInheritable/> <assemblyIdentity type="win32" name="Microsoft.VC90.CRT" version="9.0.21022.8" processorArchitecture="x86" publicKeyToken="1fc8b3b9a1e18e3b" /> <file name="msvcr90.dll" /> <file name="msvcp90.dll" /> <file name="msvcm90.dll" /> </assembly>

(you can also create a directory Microsoft.VC90.CRT in your app directory, and put all those files inside)

And you are done (although you'll have more work if dependent dlls are requiring other CRT versions, but that could be solved with alias version in the manifest...)
added on the 2010-08-02 22:27:01 by xoofx xoofx
(Errata: 5) Create a Manifest file named "Microsoft.VC90.CRT.manifest" in this directory <= I mean the app directory)
added on the 2010-08-02 22:53:05 by xoofx xoofx
Quote:

I wonder if this solves my problems, or GDIPLUS would still require the redist...


yep, just get rid of GDIPLUS and try again...i bet on it being the problem !
Quote:
Getting around the manifest check in the C Runtime DLL

Today’s article is again about my “archnemesis”, the Visual Studio 2005/2008 CRT. As I mentioned in a previous article, this CRT will refuse to load if it’s not loaded with a manifest, and today I document how it checks that, and then, how to bypass it. This can be very useful, for example, to get MSVCR80.DLL to load under WINE.

The core of the manifest checking is in the _check_manifest function, which is located in crtlib.c in the CRT source. As the name suggests, this code is only linked in when compiling a DLL version of the CRT.

Here is what the code does:

1. First, it checks for the presence of the FindActCtxSectionStringW function in KERNEL32.DLL. If this step fails (i.e. GetProcAddress returns NULL), then it assumes that the OS it’s running on does not support Fusion, and returns with success.
2. Then, it checks if both of MSCOREE.DLL and PGORT90.DLL are loaded in the process’ address space, and if yes, assumes it was loaded for instrumentation and returns success.
3. It then retrieves the path of where it was loaded and of the system32 directory.
4. When the paths are retrieved, it checks explicitly that it wasn’t loaded from system32. If it was loaded from there, it immediately returns a failure.
5. Then, it checks the current activation context with FindActCtxSectionString to check if it was referenced in the manifest. If that isn’t the case, it returns a failure.
6. It then makes sure it was loaded from under the WinSxS folder in the Windows directory by doing a string compare of that path and its own path. If that is the case, it returns with success.
7. This last check happens only if the previous check failed. It will try to find a file called Microsoft.VC80.CRT.manifest (or Microsoft.VC80.DebugCRT.manifest if it’s the debug version) in the same folder from which it was loaded, and if found, will return success.
8. If it comes here, it assumes that it was wrongfully loaded and returns a failure.

Note that over the course of these checks, it uses multiple fixed-size string buffers. The one that is used to retrive the path of the Windows and the system32 directories is MAX_PATH in size, whereas the others are 8000 characters in size. If any of these buffers overflow at any time, it will just bail out of the checks and return success.

Also, WINE does have an implementation of activation contexts, found here (KERNEL32 wrappers) and here (actual implementation in NTDLL). Except for some reason, it fails to go grab MSVCR80.DLL from the WinSxS directory, instead returning with status 0xc0000135. It’s not that the functionality is not there however, as a quick look into WINE’s source (in loader.c to be exact) shows a neat little function called find_actctx_dll that gets called from find_dll_file.

So, now that you understand how it works, the solution to bypass it becomes very simple.

You can take the long route and recompile your own version of the CRT with the _check_manifest function dummyfied. A quick look at some installed apps on my computer shows that a few apps do it. Firefox has its MOZCRT19.DLL and Winamp has NSCRT.DLL, although the latter is an older version of the CRT.

The previous solution is quite complicated for such a simple detail. Also, if you wish to redistribute the DLL with your application, you have to name it something else than MSVCR80.DLL. So you still have to redistribute it even if you got rid of the manifest check.

Follow me here for a much quickier-and-dirtier hack. Basically, you just have to patch 5 bytes in the DLL file to disable the manifest checking. Disclaimer: I don’t think the EULA allows you to do that, and it would not be a good idea to redistribute those patched DLLs. Do it at your own risk.

I have tested with versions 8.0.50727.1433 and 8.0.50727.3053 of MSVCR80.DLL and it worked well. After that, I was able to drop them into my system32 directory in a WINE install and they would work flawlessly. So, you need to patch the following bytes at the following file offset:

00001D76 -> B8 01 00 00 00 C3

This effectively turns the content of the _check_manifest function into nothing more than a return TRUE.

I hope that this goes to show again that using manifests for the CRT was a really bad idea. It just pushes more people to either statically link to it, compile their own or try to find another way to get over that restriction, all of which are not really beneficial in the long term. It defeats the purpose of DLLs, which was to share code between processes.

Same trick works fine with msvcr90.dll. Just find the beginning of function _check_manifest (0x21BE0 for 9.0.30729.1) and put there mov eax, 1 / ret (B8 01 00 00 00 C3).

Open the properties of your VC++ project, and set Generate Manifest: No and Embed Manifest: No. Compile the project.

Put the patched msvcr90.dll into project .exe directory. Congratulations, you've just got rid of manifest hell in your program.

Obviously, this method is not completely legal, but it works fine.

Original article here.
added on the 2010-08-03 02:39:14 by SubV SubV
Thanks SubV, this patch is quite cool! ;)
added on the 2010-08-03 03:15:38 by xoofx xoofx
@Navis: When you fix your problem, could you update the "Rapture" download. I never understood why I couldn't run it until I installed vcredist that you bundle with "The wind under my wings".
added on the 2010-08-03 09:43:39 by duffman duffman
Wow. Nice!
My idea was to make VC actually link against the CRT version installed in the OS or the Platform SDK (afaik you can do this in VS2010). If you could do that no redist fiddling would be necessary and a simple manifest would suffice.
added on the 2010-08-03 09:53:50 by raer raer
but where does this gdiplus comes from. I've searched and searched in my project and still found nothing.

added on the 2010-08-03 10:43:15 by Navis Navis
patching files in hex editors in 2010... jesus christ...

may I just say that nothing makes sense any more to me, it could well be written in fucking chinese. I thought the msvxxxx dependencies had gone yesterday but they are back today for no reason...


added on the 2010-08-03 11:01:56 by Navis Navis
GDI+ is being delay-loaded (through some other library). At least that's the case in "Rupture".
added on the 2010-08-03 11:06:16 by raer raer
can't I just add those .dlls in my application directory without touching anything else? I don't understand what this manifest thing is
added on the 2010-08-03 11:07:26 by Navis Navis
You can see here which functions are being used:
BB Image
added on the 2010-08-03 11:07:54 by raer raer
I suppose you do NOT link against "gdiplus.lib"...
added on the 2010-08-03 11:10:56 by raer raer

login