临时将目录添加到Windows 7的DLL搜索路径

我想暂时添加一个目录到DLL搜索路径 - 在Windows 7下有没有正确的方法来做到这一点?

脚本

我有一个C#应用程序,我们称之为WonderApp。

WonderApp需要调用位于C:MyPath的C ++ DLL。 所以作为WonderApp的Program.Main() ,我添加了以下命令:

Environment.SetEnvironmentVariable("PATH",
   "C:MyPath;" + Environment.GetEnvironmentVariable("PATH"));

根据这篇文章,添加一个目录到PATH也应该将它添加到目录搜索DLL。

该解决方案在Windows XP中工作正常:如果我将该目录添加到PATH ,则加载DLL并且程序工作得很好。 如果我不添加该目录,则DLL不会加载,并出现“找不到”错误。

但是,这不适用于Windows 7。

所以我想,让我们尝试使用SetDllDirectory() 。 喜欢这个:

[System.Runtime.InteropServices.DllImport("kernel32.dll", SetLastError = true)]
private static extern bool SetDllDirectory(string lpPathName);

而且,稍后:

 bool success = SetDllDirectory(Util.Paths.GetApplicationDataDir());

success的价值是true ,但DLL仍然无法加载。

最后,如果我将PATH手动设置为包含C:MyPath ,那么在运行应用程序之前,它一切正常! 该DLL加载,并运行得很好。

所以,重新迭代:

有没有正确的方法临时添加一个目录到Windows 7下的DLL搜索路径?

更新:使用Process Explorer,我检查了应用程序的运行时环境,并且“C: MyPath”确实在PATH ! 此外,我看到Helper.dll在打开的句柄列表中(作为一个DLL,而不仅仅是一个文件) - 它仍然声称不会找到它。


您可以使用'AssemblyResolve'事件将自定义的DLL加载逻辑添加到C#应用程序中。

此页面有一个很好的总结,代码示例:http://support.microsoft.com/kb/837908

就像你所做的一样,我发现改变正在运行的C#应用​​程序的PATH环境变量不会影响DLL搜索行为。 也许AppDomain在启动时缓存PATH值? 您可以使用AssemblyResolve事件来解决此问题。

另请参见如何在运行时将.NET文件夹添加到程序集搜索路径中?


我认为这与权限问题有关。

尝试关闭UAC并再次运行您的代码。 检查是否更新路径工作。

如果是这样,至少你知道从哪里开始......


我的解决方案很简单,但我觉得这很荒唐。

我编写了另一个程序集“Shell”,它修改了环境,运行WonderApp并退出。

通过在运行主应用程序(WonderApp)之前修改PATH ,主应用程序的DLL搜索路径包括添加到修改的PATH的目录。

它看起来像这样:

namespace shell
{
   static class program
   {
      [dllimport("kernel32.dll", charset = charset.auto, setlasterror = true)]
      public static extern bool setenvironmentvariable(string lpname, string lpvalue);

      private static string joinargstosinglestring(string[] args)
      {
         string s = string.empty;
         for (int i = 0; i < args.length; ++i)
         {
            if (!string.isnullorempty(s))
            {
               s += " ";
            }
            s += """ + args[i] + """;
         }
         return s;
      }

      [stathread]
      static void main(string[] args)
      {    
         string pathbefore = environment.getenvironmentvariable("path");
         string wewant = util.paths.getapplicationdatadir() + ";" + pathbefore;
         setenvironmentvariable("path", wewant);

         Process process = Process.Start(".WonderApp.exe", joinArgsToSingleString(args));
      }
   }
}

我希望我能找到更好的解决方案!

链接地址: http://www.djcxy.com/p/1179.html

上一篇: Adding a directory temporarily to Windows 7's DLL search paths

下一篇: Authenticating SQL connection using certificates in .NET