DLL not found by Windows Service EXE - windows

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.

Related

Unable to step into Nuget package

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:

Organizing Dependencies

I'm trying to organize my unmanaged .dll dependencies in my Visual Studio solution but unless the DLLs are strewn about the top level of my solution they do not get built into the application's directory and then the application fails to run. I have done a lot of Googling on the subject and there seems to be a solution in the form of an app.config setting:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<runtime>
<assemblybinding xmlns="urn:schemas-microsoft-com:asm.v1">
<probing privatepath="lib" />
</assemblybinding>
</runtime>
</configuration>
I have a folder in my solution called "lib" and Copy Local is set to true for all files in the folder but the application is still unable to run. How can I keep my Visual Studio solution organized without breaking my application?
The only way I have found to solve this issue is through windows .bat files.
If there is a way to encode extra search paths into an unmanaged executable, I would like to know!
Here is an example of what I do:
SET PATH=$~dp0plugins\MY_PLUGIN\Debug;%PATH%
vcvars32.bat
devenv build\MY_PROJECT.sln
The first line adds the path of where I want visual studio to find my dll's in.
The second line ensures that the 'right' visual studio will open up. IE: if I have my environment set for VS2010, I dont want VS2012 to open up by default.
The last line invokes the IDE to open up my sln file.
The visual studio that opens up now has a path to the Debug folder of one of my plugins. When I debug my application, the correct dll will be found, loaded, and debugged with no issue - I verify this under the Debug->Windows->Modules panel.
This only works for the Debug configuration. If I want to run the release configuration, I change the .bat file to say 'Release', close Visual Studio and re-run the .bat file.
I apply this same pattern to running my executable. Set up the environment of where I want my dll's to come from and then execute my executable:
SET PATH=$~dp0plugins\Debug;%PATH%
... Repeat for other dll locations
"%~dp0Debug\MY_EXECUTABLE.exe" %*
SS64 is an invaluable resource to figure out what you can do in .bat files

What is the meaning of the folder names in Winsxs folder (windows run time assemblies directory)

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.

Visual Studio: DLL locations for release

I have a project that I am working on that references a "Common Library (DLL)". In the DevEnv it works fine, however if I build and try to organize my files it doesn't work. Basically if I have things setup like so:
C:\Program Files\MyApp\MyApp.exe
C:\Program Files\MyApp\Common\WPF Commons.dll
C:\Program Files\MyApp\Modules\SomeModule.dll
etc
MyApp.exe doesn't work. It tries to look only in the current directory for the DLL files. So how do I set it up in Visual Studio so that when I build the application knows to look for the DLLs in those other folders?
Oh, and I realize that it does work in Dev because all the DLLs are put in the same folder. I don't want to do that for release though :-/
What you need to do is add a private probing path into the application configuration file. This tells the CLR which directories to look in for extra assemblies.
http://msdn.microsoft.com/en-us/library/823z9h8w.aspx
Sample app.config
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<probing privatePath="Common;Modules"/>
</assemblyBinding>
</runtime>
</configuration>

Change Dll Folder In Visual Studio 2008 C#

I have 2 projects in my solution. The first one is a console application, and the second is a dll, used (referenced) by the console. When I build my solution (release) I get one EXE file and one DLL file, because copy local is true (if I set it to false, it doesn't run).
How can I store that DLL file in a subdirectory? If my output folder is C:\123\, and there's the EXE file, I want all my DLLs to be in C:\123\Dll\.
You should be able to use the probing element to specify which paths your application should use when attempting to resolve dll dependencies.
Example:
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<probing privatePath="123;123\dill"/>
</assemblyBinding>
</runtime>
</configuration>
Also you can use the Post-build event command line to copy your dll's to a particular directory.

Resources