2012-01-26 2 views
11

.NET 응용 프로그램에서 오작동하는 타사 DLL을 언로드하려고 시도하고 있습니다. 응용 프로그램을 다시 시작하여 문제가 발생하는 것으로 보입니다. 응용 프로그램을 다시 시작하기보다는 DLL을 제거하고 다시로드하고 싶습니다.어셈블리에서 DLL을 강제로 언로드합니다.

LoadLibrary을 사용하여 DLL을로드하고 FreeLibrary (P/Invoke 웹 사이트에서 가져온 DllImport을 사용)을 사용하여 DLL을 제거합니다. LoadLibrary()을 호출하면 DLL이 프로세스 탐색기의 DLL 목록에 나타나고 FreeLibrary()을 호출하면 예상대로 DLL이 DLL 목록에서 사라지는 것을 볼 수 있습니다.

그러나 서드 파티 라이브러리의 Initialize() 함수를 호출하면 FreeLibrary()은 미리 해당 Deinit() 메서드를 호출하더라도 더 이상 목록에서 DLL을 제거하지 않습니다. 라이브러리에서 다른 함수를 호출해도이 문제가 발생하지 않습니다. 그러나, 사용하기 전에 라이브러리 Initialise()해야합니다!

DLL을 자체적으로 AppDomain으로 생성하여 DLL을 격리 한 다음 DLL을 해제 한 후이 도메인을 언로드하려고했습니다.

은 내가 LoadLibrary() 또는 FreeLibrary() 또는 만들거나 AppDomain을 언로드, Initialize() 또는 Deinit()에서 오류 리턴 코드 또는 예외를 얻을.

string pathToDll = Assembly.GetExecutingAssembly().CodeBase; 
m_Domain = AppDomain.CreateDomain("MyAppDomain", null, new AppDomainSetup { PrivateBinPath = pathToDll }); 
m_Module = (ThirdPartyModule)m_Domain.CreateInstanceFromAndUnwrap(pathToDll, typeof(ThirdPartyModule).FullName); 
m_Module.Init(); 

이 deinitialise하고 AppDomain 언로드 :

m_Module.Free(); 
m_Module = null; 
if (m_Domain != null) 
{ 
    AppDomain.Unload(m_Domain); 
    m_Domain = null; 
} 

마지막으로, 내 ThirdPartyModule 어셈블리 클래스 :

internal class ThirdPartyModule : MarshalByRefObject 
{ 
    [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)] 
    internal static extern IntPtr LoadLibrary(string lpFileName); 

    [DllImport("kernel32.dll", SetLastError = true)] 
    [return: MarshalAs(UnmanagedType.Bool)] 
    internal static extern bool FreeLibrary(IntPtr hModule); 

    public IntPtr Module { get; set; } 

    public ThirdPartyModule() 
    { 
     Module = LoadLibrary("Misbehaving.dll"); 
    } 

    public void Free() 
    { 
     FreeLibrary(Module); 
     Module = IntPtr.Zero; 
    } 

    // ... 
} 

은 내가 AppDomain를 만들고 초기화하려면 다음 코드를 사용

다음과 같이 작동해야합니다. 기대했다? 그렇지 않다면이 DLL이 내 프로세스에 의해 완전히 언로드되도록하는 다른 방법이 있습니까?

편집 : 더 많은 정보

  • DLL은 가능성이 C에서 컴파일 된 네이티브 코드를 포함/C++
  • 불행하게도 내 프로세스가 .NET 2 만 (그래서 아무 WCF 솔루션)를 사용하여 제한됩니다.
  • WinXP Pro x64 SP2를 사용하고 있지만 솔루션은 XP, Win7 x32/x64 등 호환 가능해야합니다.
  • DLL은 내가 별도의 프로세스 (EXE) 응용 프로그램 실행되고있는 차례로 DLL로드를 구현하는 것이 좋습니다
+0

DLL은 기본 DLL입니까? – Yahia

+4

다른 프로세스에서 DLL을 실행하고 WCF를 통해 DLL과 통신 할 수 있습니까? 프로세스를 언로드 할 때 전체 프로세스를 죽일 수 있습니다. – CodingBarfield

+0

@Yahia - 네, C/C++ DLL이라고 생각합니다. –

답변

4

토큰 USB와 통신하는 데 사용됩니다.

필요하면 언제든지 프로세스를 종료 할 수 있습니다.

나는 의사 소통을하는 방법에 대한 몇 가지 옵션을 볼 수 - 예를 들어 : (당신이 out-of-process COM 서버로 구현하는 경우)

  • 당신이 (공유 메모리를 사용할 수있는 COM을 사용할 수 있습니다 매우 당신이 방법은 여러 Windows 버전과 호환 가능해야 함을 쓰기 때문에 고성능,)는 .NET이 래퍼

을 연습에 대한 thisthis을보고 일부는 내가 이리저리 삼가 것입니다 데스크탑 방화벽 함께 IPC는 "networky"를 사용합니다.

관련 문제