We have a c++ application which I recently ported from Linux/gcc to build on Windows with Visual Studio 2005. The app uses a 3rd party library which only provides DLLs which use the optimised CRT DLL (i.e. they don't provide equivalents which link to the debug CRT DLL). With VS2005 this didn't seem to be a problem = the debug build found the optimised CRT DLL in the System32 dir.
I'm now trying to build and run our app with VS2008 and the debug build fails to run because it can't locate the optimised CRT DLL (msvc690.dll). The VC9 CRT DLLs are squirreled away in directories with a GUID style name - i believe this is an side-by-side assembly and the app is supposed to locate it using the app's manifest. However the manifest that gets built and embedded in the app exe only specifies the debug CRT assembly:
<?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' />
</requestedPrivileges>
</security>
</trustInfo>
<dependency>
<dependentAssembly>
<assemblyIdentity type='win32' name='Microsoft.VC90.DebugCRT' version='9.0.21022.8' processorArchitecture='x86' publicKeyToken='1fc8b3b9a1e18e3b' />
</dependentAssembly>
</dependency>
</assembly>
I'm not a Windows expert (not any more at least) so this is all new to me. What is the correct solution here? Do i need to tell the manifest compiler to add the optimised CRT DLL to the assembly? If so how do i do this?
Ok. If you open the 3rd party library dll in VS 2008 (make sure it chooses OpenWith>Resource Editor) does it contain a manifest of its own?
If it does, or even if it does not, its also useful to get DependencyWalker to see which exact runtime dlls this third party library is attempting to link to.
The fact that it worked with VS2005, and not VS2008, implies the dll wants to use the releasemode versions of the VS2005 runtime: msvcr80.dll
You mention msvc690.dll, which doesn't ring a bell with me: Visual Studio 6 used the simply named msvcrt.dll - the first version of Visual Studio to use a versioned dll runtime was VS 2003 .NET or something: msvcrt7.dll
Anyhow, IF the 3rd party library does not contain its own manifest resource, then the easiest thing to do would be to add the dependent assembly references to your applications manifest.
There are a number of ways of doing this - you can create a manifest fragement as a XML file and add it to your applications "Configuration Properties > Manifest Tool > Input and Output > Additional Manifest Files"
I find the most convenient way of merging additional dependent assembly directives in VS2008 is to use the linkers /manifestdependency command line option.
If you add the following code snippet to a file in your project, it will give the linker the necessary hint:
#define X_CRT_ASSEMBLY_VERSION "9.0.21022.8"
#pragma comment(linker,"/manifestdependency:\"type='win32' "\
"name='"Microsoft.VC80.CRT' "
"version='8.0.??.??' " \
"processorArchitecture='x86' " \
"publicKeyToken='????????'\"")
The ??'s are there because I don't know the version numbers or public key token of the VS2005 libraries off hand. if you can look them up and fill them in, it should go swimmingly.
Related
I have a common project that I build and create a nuget package from, for consumption in my other applications.
The build process for the common project both creates a nuget package, deploys it to our private nuget repo and pushes the symbols to our internal symbol server.
In my "other applications", in this specific case an ASP.NET website, I pull in the nuget package from our repo but when I try to step into code in that assembly it just skips over it. I cleared my local symbol cache and as soon as I start debugging VS pulls in all the symbols from the symbol server so I know that bit is working.
Can anyone help me?
You need to publish Nuget package with symbols and refer to them using the Symbols under Tools->Options->Debugging->Symbols.
See HOW TO DEBUG A .NET CORE NUGET PACKAGE?
Other members also asked the similar issue before:
How to debug code in a nuget package created by me
Update:
Since you want to step into code in the assembly, you still need to provide the source code file in the NuGet package alongside the dll.
As we know:
A symbol is a file containing metadata that represent the link between
your original source code and the machine code that has been
translated by a compiler.
In the Microsoft world, a symbol is represented by a .PDB (Program DataBase) file. It is the heart of the debugging process because thanks to these metadata, the debugging tools are able to correlate the instructions executing in the application to the original source code and providing features like breakpoint or variable watchers.
So if you only provide the dll and .pdb file, you still not step into the code, you also need provide the source code, then add the source code to the Debug Source Files for the solution that references the package:
More detail on providing the source code:
If you're currently packaging without a Nuspec, you'll need to create a Nuspec, then add the pdb to the list of files in the lib folder and source file in the src folder. "NuGet spec" may be a useful command for generating the initial spec as defined in NuGet docs. Below is my .nuspec file, you can check it:
<?xml version="1.0"?>
<package >
<metadata>
<id>MyTestPackage</id>
<version>1.0.3</version>
<authors>Admin</authors>
<owners>Admin</owners>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>Package description</description>
<releaseNotes>Summary of changes made in this release of the package.</releaseNotes>
<copyright>Copyright 2017</copyright>
<tags>Tag1 Tag2</tags>
</metadata>
<files>
<file src="bin\Debug\MyTestPackage.dll" target="lib\Net46" />
<file src="bin\Debug\MyTestPackage.pdb" target="lib\Net46" />
<file src="Class1.cs" target="src" />
</files>
</package>
More detail on add the source code to the Debug Source Files:
When you have a solution open, right click on Solution, select Properties...Common Properties...Debug Source Files, and add the root source directory for the relevant binary reference:
Pasted the following into a exe.manifest file for a VS10 Win32 project from code found here:
<application xmlns="urn:schemas-microsoft-com:asm.v3">
<windowsSettings xmlns:ws2="http://schemas.microsoft.com/SMI/2016/WindowsSettings">
<ws2:longPathAware>true</ws2:longPathAware>
</windowsSettings>
Building generated the linker warning:
warning 81010002: Unrecognized Element "longPathAware" in namespace "http://schemas.microsoft.com/SMI/2016/WindowsSettings".
Understandable, based on the age of the bundled mt.exe as explained in this similar issue.
Question is, will this in any way affect the long path awareness of the application on a platform where the attribute is known?
Downloaded the 2.4 Gb W10 SDK, thanks to Sera's suggestion, and copied the 1 mb file mt.exe over to Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin. Warning not generated with the new mt. (Minor issues with the Environment variables set for the 7.1 SDK in Program Files\Microsoft SDKs\Windows\v7.1\Bin added in some extra flavour and texture to the operation)
Another way is to disable manifest generation in the projects linker options and manually create an external manifest. It must be named like "YourApplication.exe.manifest" and be located next to "YourApplication.exe".
I had to copy the manifest via post-build event as VS always deleted the manifest when doing a clean build.
I have a .net 4.0 DLL (class library) which is used to execute some operations for a windows service I've created. The executable of the service references this DLL by adding a project reference to the project of the executable. I have also tried a binary reference but the result is the same: InstallUtil fails to install the Windows Service from the EXE since it's unable to locate the DLL.
The system I'm working on is not using GAC registration for locating DLLs. Rather, at post-build the DLL gets copied to a child directory of the one in which the service EXE is located named "lib", and that exe has a matching .config file in which "lib" is referenced using:
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<probing privatePath="lib" />
</assemblyBinding>
</runtime>
We have multiple .exes and .dlls working like that. The project properties and .config file definitions for all these DLLs and matching EXEs are identical for all we could see.
However, whereas for all others InstallUtil has no problem locating the DLL, here it fails. When I move the DLL to the same location as the EXE, however, all works fine.
The .config file we're discussing is successfully referred for other purposes.
If you have any specific questions please share and I'll answer.
We're clueless.
Background:
Windows shared run-time libraries located at C:\windows\Winsxs folder
Inside Winsxs, there are two important sub folders also located as policies and Manifests
Other than that, there are plenty of run-time assemblies located in side each other sub folders.
All the sub-folders inside Winsxs and policies having same naming format.
Eg Folder Names:
Run times: x86_Microsoft.VC90.CRT_1fc8b3b9a1e18e3b_9.0.30729.1_x-ww_6f74963e
Policies: x86_policy.9.0.Microsoft.VC90.CRT_1fc8b3b9a1e18e3b_x-ww_b7353f75
As I know first part of the name (x86_Microsoft.VC90.CRT_1fc8b3b9a1e18e3b_9.0.30729.1) describe "processorArchitecture"(x86) , "Name" (Microsoft.VC90.CRT), "publicKeyToken" (1fc8b3b9a1e18e3b) and "Version"(9.0.30729.1) of the assembly or policy.
Question:
What is the last part of the assembly(x-ww_6f74963e) or policy(x-ww_b7353f75) folder name describes?
Ok here is the original issue (but quite long story). I deployed my C++ MFC application in windows XP computer that previously installed some of C++ redistribute packages and some security patches of run-time assemblies. So these pre-installed C++ redistribute packages automatically deployed some run-time policies in Winsxs/policies. those policies force to use new run-time assemblies instead of the one uses and deployed by my application. But some times these newer DLLs not there because of some other application removal or assemblies can be corrupted. So I'm finding a way to deploy run time assemblies specifically use for my application (it means my app must use the once deployed by it and ignore the policies). So I think this last part of the sub directory name associate with the identity of application. I need to find it.
If you can't trust global cache (and on WinXP it is super easy to corrupt it), you might have to install private copies of assemblies and override them in your application config.
Here is a hack I am using to override some assemblies for debugging purposes:
In your exe folder, drop the file named yourexename.exe.config with policy information redirecting real assembly version to something that will never exist in global cache. For example:
<configuration>
<windows>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity type="win32" name="someassemblyname" processorArchitecture="x86" publicKeyToken="sometoken"/>
<bindingRedirect oldVersion="1.0.0.0-1.0.999.998" newVersion="1.0.999.999"/>
</dependentAssembly>
</assemblyBinding>
</windows>
</configuration>
Take contents of the assembly that you want to use, drop it into the same folder and edit manifest to have the version you used above. For example
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<noInheritable></noInheritable>
<assemblyIdentity type="win32" name="someassemblyname" version="1.0.999.999" processorArchitecture="x86" publicKeyToken="sometoken"></assemblyIdentity>
<file name="somedll.dll"/>
</assembly>
In the end you will get following files in your install folder:
yourexename.exe
yourexename.exe.config
somedll.dll
someassemblyname.manifest
And your executable will pick up private copy of the dll.
More info here: Application Configuration Files
EDIT: if you have problems like "the application failed to initialize properly" or "side by side configuration is incorrect" (and you will have them once you start playing with sxs), use sxstrace tool for diagnostics (not available on Windows XP though). That will tell you exactly which assembly causes problems.
My application ( C++, compiled with Mingw, using mainly wxWidgets, Boost and SFML ), which runs smoothly on Windows 7 or Vista, does not work properly on Windows XP SP3. I have a .manifest file which allows the executable to use Windows XP/Vista/7 look'n'feel:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly
xmlns="urn:schemas-microsoft-com:asm.v1"
manifestVersion="1.0">
<assemblyIdentity
name="Game Develop Editor.Release - Edittime.App"
processorArchitecture="x86"
version="1.0.0.0"
type="win32"/>
<description>Executable</description>
<dependency>
<dependentAssembly>
<assemblyIdentity
type="win32"
name="Microsoft.Windows.Common-Controls"
version="6.0.0.0"
processorArchitecture="x86"
publicKeyToken="6595b64144ccf1df"
language="*"
/>
</dependentAssembly>
</dependency>
</assembly>
If I remove/rename the manifest file, I can launch the executable with Windows XP SP3 ( But with ugly outdated controls ). If I let the manifest file, it run without problems with Vista/7 but with Windows XP SP3, the application is loaded in memory ( I can see it in task manager ) but do nothing. No error message, it does not even crash.
If I recompile it to display a console, the latter does not show anything.
If I use gdb to debug it, the debugger display "Starting program:..." and is then blocked ( Control+C does not work ).
I tried to use Dependency Walker on the executable.
Here is the log with the manifest file: http://pastebin.com/J6T8KBH8
( Here is the log without the manifest: http://pastebin.com/zrYzRaWE / In this case, the application loaded without problems and is still running at the end of the log. )
I've highlighted the line which is displayed in red in Dependency Walker, which refers to a missing procedure in comctl32. Moreover, the log seems to be interrupted without specific errors.
Have you got any idea about why the application seems to be interrupted without even a crash or an message when using a manifest?
It turned out that the problem appeared only when using a recent version of the SFML library.
Precisely, SFML libraries names have changed from "sfml-xxx.dll" to "sfml-xxx-2.dll" in a recent release.
When linking to the latest version of the libraries, with the new name, the application does not want to start on Windows XP SP3. I've tweaked the CmakeList.txt file used to compile SFML so as to use the old name for the libraries ( sfml-xxxx.dll ) and, when linking to these libraries, the program works perfectly.
The only thing that is different is the libraries name. However, in Dependency Walker, I saw that when using the new name ( sfml-xxxx-2.dll ), SFML libraries are presented before wxWidgets and windows related libraries. When I use the old name ( sfml-xxxx.dll ), SFML libraries are presented at the end of the list.