Good morning paul-shed. Welcome to the VC newsgroup! My name is Jialiang Ge
[MSFT]. It's my pleasure to work with you on this issue.
The question is about how to specify the relative paths that the loader
should search for the dependent DLLs in Windows. I'd like to first share
several solutions that quickly emerge in my mind when I see the question. I
will research for better ones (for example, some easier settings in a
manifest file) and report back as soon as possible.
=================================================
Solution 1. Using the codebase or probe element in the configuration file
This solution only works for .NET assemblies. Because your question is
posted in dotnet.language.vc queue, I assume that your are working with
C++/CLI dll and exe. If I'm wrong, please skip this solution.
The document of the codebase element can be found at
http://msdn.microsoft.com/en-us/library/efs781xb.aspx
The codeBase element (<codeBase>) is an element used to configure an
assembly DLL that allows to download the DLL on demand from cross the
network the first time it's used by hosting application. We can set the
href value to be a path relative to the application's directory, and the
.NET runtime will search the path for the target DLL.
The document of the probe element can be found at
http://msdn.microsoft.com/en-us/library/823z9h8w.aspx
The probing element(<probing>) specifies application base subdirectories
for CLR to search when loading assemblies. This element has an attribute
called "privatePath" which specifies subdirectories of the application's
base directory that might contain assemblies. Delimit each subdirectory
with a semicolon.
=================================================
Solution 2. Delay-loading the Dlls and use the API SetDllDirectory
Generally speaking, there are three ways to load a DLL into a process.
1. Implicitly Loading (and linking) the required DLL. In this way, the
application's source code simply references symbols contained in the DLL,
and the DLL is loaded when the application is invoked.
http://msdn.microsoft.com/en-us/library/ms684184(VS.85).aspx
2. Explicitly loading the Dll with the API LoadLibrary(Ex). We can specify
the relative path to the target DLL in the lpFileName parameter, so that
the process will search the path we wanted.
http://msdn.microsoft.com/en-us/library/ms685090(VS.85).aspx
3. Delay loading the DLL.
A delay-load DLL is a DLL that is implicitly linked but not actually loaded
until your code attempts to reference a symbol contained within the DLL.
According to your post description, what you currently have is the approach
1 (Implicitly loading the Dll). Its DLL search order is
http://msdn.microsoft.com/en-us/library/ms682586(VS.85).aspx. Without a
manifest file or DLL redirection, the loader searches for the
user-specified location only when we call SetDllDirectory. SetDllDirectory
cannot be used in the approach 1 because the load of the DLLs happens
before the execution of our own codes. The solution is delay-loading the
DLLs.
Step1. In the project property page of the client app, switch to
Linker->Input0>Delay Loaded DLLs, and input the DLLs that are not in the
app folder into the textbox. These DLLs won't be loaded in the load time.
The DLL is loaded when its exported element is consumed by the client app.
Step2. If you want to allow explicit unloading of the delayed load DLLs,
please turn to the page Linker->Advanced->Delay Loaded DLL, and change the
value to Support Unload (/DELAY:UNLOAD)
Step3. In the main entry of the client app, add this code at the beginning:
SetDllDirectory(L"[relative path]");
In this way, when the DLLs in the relative path are consumed, the loader
will search for the DLL in the relative path specified in SetDllDirectory.
Please let me know whether you like this idea or not. Delay loading a DLL
has many other benefits. For example, if the application uses a lot of
DLLs, the initialization time will be slow because the loader maps all the
required DLLs into the process' address space. Delay-load DLLs spreads out
the loading of the DLLs as the process executes, thus, the initialization
will have better performance. In addition, delay-loading DLLs gives us a
chance to decide whether or not we really should/need to load a certain DLL
when the DLL is not compatible with the current environment.
You may want to try the above two solutions first. I'm looking for some
settings in the app's manifest file that can accomplish the task. I see an
element <file> that may be useful. I'm studying the use of it.
Best Regards,
Jialiang Ge (
[email protected], remove 'online.')
Microsoft Online Community Support
Delighting our customers is our #1 priority. We welcome your comments and
suggestions about how we can improve the support we provide to you. Please
feel free to let my manager know what you think of the level of service
provided. You can send feedback directly to my manager at:
(e-mail address removed).
==================================================
Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/en-us/subscriptions/aa948868.aspx#notifications.
MSDN Managed Newsgroup support offering is for non-urgent issues where an
initial response from the community or a Microsoft Support Engineer within
2 business day is acceptable. Please note that each follow up response may
take approximately 2 business days as the support professional working with
you may need further investigation to reach the most efficient resolution.
The offering is not appropriate for situations that require urgent,
real-time or phone-based interactions. Issues of this nature are best
handled working with a dedicated Microsoft Support Engineer by contacting
Microsoft Customer Support Services (CSS) at
http://msdn.microsoft.com/en-us/subscriptions/aa948874.aspx
==================================================
This posting is provided "AS IS" with no warranties, and confers no rights.