2010-06-08 2 views
7

임시로 디렉토리를 DLL 검색 경로에 추가하십시오. Windows 7에서이 작업을 수행하는 올바른 방법이 있습니까?Windows 7의 DLL 검색 경로에 임시로 디렉토리 추가

나는 C# 응용 프로그램을 가지고

시나리오,의는 WonderApp를 호출 할 수 있습니다.

WonderApp는 C:\MyPath에있는 C++ DLL을 호출해야합니다. 또한 DLL에 대한 디렉토리 검색에 추가해야 PATH에 디렉토리를 추가, this article에 따르면

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

: 그래서 WonderApp의 Program.Main()의 일환으로, 나는 다음과 같은 명령을 추가했다.

솔루션은 Windows XP에서 제대로 작동합니다. PATH에 디렉토리를 추가하면 DLL이로드되고 프로그램이 제대로 작동합니다. 디렉토리를 추가하지 않으면 DLL이로드되지 않고 "찾을 수 없음"오류가 발생합니다. 그래서 내가 생각

그러나,이의는 SetDllDirectory()를 사용 해보자,

윈도우 7 작동하지 않습니다. 이처럼 :

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

그리고 나중에 :

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

success의 값은 true이지만, DLL은 여전히로드 할 수 없습니다.

마지막으로 PATHC:\MyPath을 수동으로 포함하도록 설정하면 응용 프로그램을 실행하기 전에 모두 작동합니다. DLL이로드되고 정상적으로 실행됩니다.

그래서, 다시 반복 :

일시적으로 윈도우 7 아래에있는 DLL 검색 경로에 디렉토리를 추가 에 대한 올바른 방법이 있나요?

업데이트 : Process Explorer를 사용하여 응용 프로그램의 런타임 환경을 확인한 결과 "C : \ MyPath"가 PATH에있었습니다! 더구나, Helper.dll이 열린 핸들 목록에있는 것을 보았습니다. (파일이 아니라 DLL로) - 여전히 찾지 못했다고합니다.

+0

64 비트 버전입니까? 실제 경로 이름은 무엇입니까? –

+0

이것은 32 비트 Windows 7 Home입니다. DLL에 대한 전체 경로는 C : \ MyPath \ Helper.dll – scraimer

+0

다른 DLL이 누락되었습니다. "depends.exe"프로그램에서 helper.dll을로드하고 다른 DLL의 종속성을 확인하십시오. – OlimilOops

답변

0

나의 해결책은 간단하다 ... 알고,하지만 난 그것에 의지 말도 생각합니다.

환경을 수정하고 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)); 
     } 
    } 
} 

내가 더 나은 해결책을 찾을 수 있으면 좋겠다!

1

권한 문제와 관련이 있다고 생각합니다.

UAC를 끄고 코드를 다시 실행 해보십시오. 경로 업데이트가 제대로 작동하는지 확인하십시오. 이 그랬다면

, 적어도 어디서부터 시작하면

+0

아니요 - UAC를 사용 중지하지 않았습니다. 그래도 아이디어를 가져 주셔서 감사합니다. – scraimer

2

'AssemblyResolve'이벤트를 사용하여 C# 응용 프로그램에 사용자 지정 DLL로드 논리를 추가 할 수 있습니다. 당신이 한 것처럼 http://support.microsoft.com/kb/837908

, 나는 실행중인 C#을 응용 프로그램의 PATH 환경 변수를 변경하면 DLL 검색 동작에 영향을주지 않는 것으로 나타났습니다 :

이 페이지는 코드 샘플과 좋은 요약을 가지고 있습니다. 아마도 AppDomain이 시작할 때 PATH 값을 캐시합니까? AssemblyResolve 이벤트를 사용하여이 문제를 해결할 수 있습니다.

도 참조 How to add folder to assembly search path at runtime in .NET?

+0

그건 멋지다 * !!! 나에게 알려 줘서 고마워! 이것은 모든 .NET 어셈블리에서 작동하는 것처럼 들리지만 비 -.NET DLL에 대해서도 테스트해야합니다. – scraimer

+1

OK, 나쁜 소식은 .NET 어셈블리에서만 작동합니다. 그 이름을 생각하면 완벽 해. 훌륭한 솔루션이지만로드해야하는 DLL은 .NET 어셈블리가 아니기 때문에 사용할 수 없습니다. (그리고 문제를 악화 시키려면, 해당 DLL은 다른 DLL도로드해야하며, 같은 DLL에 위치해야합니다. 따라서 DLL을 검색 할 수있는 방법을 찾아야합니다. – scraimer