views:

2199

answers:

8

I have a native VC++ project that uses a dll (which is not in a project). Now, I must to put the dll in one the "Search Path Used by Windows to Locate a DLL" link

but I don't want the dll to sit in the exectuable or current or windows or system directory.

So my only option according to that is adding the path to the %PATH% environment variable.

Is there any other way?

Is there an elegant way to do so (adding to PATH)? should I do this on installation? should I be concerned if i'm doing this?

+1  A: 

If you know where the DLL is likely to be located, you could attempt to load it at runtime using LoadLibrary() then use GetProcAddress() to bind to the functions you need to call.

J Francis
I don't want to do explicit linking.
Hanan
+1  A: 

I would not be happy if an installed application added random stuff to my global PATH. As this affects all applications and may have nasty side affects.

What I have seen done is having a starter script.
The script looks and acts like an application to the user (So you still double clock it). But the script set the appropriate path then launches the real application.

Martin York
By "the script set the appropriate path" do you mean the working directory?
Hanan
No I meant the %PATH% environment variable. Note when a script sets the value it is local to the script and its children and not globally pervasive.
Martin York
+4  A: 

Here are a few suggestions:

  • You could embed the dll as a resource in your main executable and then extract it to a temporary directory and load it from their using LoadLibrary and then get the relevant function addresses using GetProcAddress.

  • You could modify you main processes search path using SetDllDirectory() to include the location of the DLL. This avoids having to make any global changes to the system. And again use LoadLibrary/GetProcAddress to resolve the function addresses.

QAZ
SetDllDirectory is nice. I wonder if you could use delayed DLL loading in conjunction with this call to avoid LoadLibrary/GetProcAddress.http://msdn.microsoft.com/en-us/library/151kt790.aspx
Aardvark
this solution seems to work for meIm using a library (.lib) as input to my client native vc++ project, then I call SetDllDirectory with the additional path and I'm not using LoadLibrary.
Hanan
However, I can only add one path, the second path I add probably replaces the first.
Hanan
I'd guess you could pass a semicolon delimited set of paths to the call?
J Francis
haven't actually tried it but people say it won't work
Hanan
+4  A: 

Summing up all the techniques I have found:

  • If you use a managed project as the startup project (which is actually my case) use Enviroment class

string temp = "myFullDirectoryPathToDll"; string temp2 =Environment.GetEnvironmentVariable("PATH") + ";" + temp; Environment.SetEnvironmentVariable("PATH", temp2);

this, and I think MSDN should have stressed that, changes the environment variable PATH only in this process.

when debugging in VS the appPath doesn't 'work' use properties->debug->environment and merge environment variables link

  • If you use a native: do explicit linking - seems like big work for something simple, maybe use appPath registery key on deployment link, nobody had a tested-and-proved answer
Hanan
+1  A: 

If you use DelayLoad, then before calling any function that will cause the dll to load, call LoadLibrary. This will "prime" the application and it won't go searching for it. No need for GetProcAddress

Joel Lucsy
A: 

If you're launching from a Windows shortcut, you could specify the DLL's path in the "Start in" location, while specifying the .exe's full name and path in the "Target" location.

If there are DLLs in the .exe's directory that are needed, Windows should be able find them as well, because I believe that the Windows DLL search order looks in the .exe's path first (the current directory is fifth on the list).

I've used the LoadLibrary/GetProcAddress method many times, I try to avoid it, as it does entail a bit of extra work - lots of typedefs and typecasts.

Marc Bernier
A: 

The delay load method works upon the working directory at the time it decides to call LoadLibrary. You may use this to your advantage. See http://msdn.microsoft.com/en-us/library/ms682586(VS.85).aspx for details on the search path order.

spoulson
A: 

I tried to set application path in system registry. It is working fine only when the user has the rights to access regedit. And also modifying environment variable PATH. My test user does not have admin right to modify variable.