.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로드를 구현하는 것이 좋습니다
DLL은 기본 DLL입니까? – Yahia
다른 프로세스에서 DLL을 실행하고 WCF를 통해 DLL과 통신 할 수 있습니까? 프로세스를 언로드 할 때 전체 프로세스를 죽일 수 있습니다. – CodingBarfield
@Yahia - 네, C/C++ DLL이라고 생각합니다. –