2010-09-24 38 views
1

我有一個依賴於DLL的Windows服務。無論服務是否正在運行,它的可執行文件都會保留該DLL的句柄,這會阻止我自動更新它。如何釋放一個由未運行的exe引用的DLL?

這是爲什麼,我該如何以編程方式刪除該句柄(最好通過.Net)?

更新: 我知道服務的可執行文件是帶有句柄的可執行文件,因爲我在dll上運行了handle.exe,並且只有服務的exe文件出現了。當我在exe上運行它時,沒有什麼能夠起作用,並且我知道服務沒有運行,因爲我檢查了服務列表。沒有別的東西會使用我能想到的dll。

+0

您如何知道它是保持打開的非運行服務? – CodingGorilla 2010-09-24 20:35:57

+0

你是如何確定它是甚至沒有運行時引用DLL的服務可執行文件? – 2010-09-24 20:37:18

+0

爲什麼投票的人被轉移到超級用戶? OP正在尋求一個編程解決方案 – JaredPar 2010-09-24 20:38:30

回答

1

這是一個討厭的小問題。該服務有兩個線程,其中一個執行一個非常微妙的,不常用的功能,我沒有注意到它在共享資源上發生死鎖。所以它無限期地掛起來,這是讓我的可執行文件保持運行狀態,儘管服務被關閉了。解決這個問題解決了我的文件處理問題。

感謝您的建議,所有。

2

這是不可能的。只有正在運行的進程才能擁有文件句柄。

您可以使用Process Explorer找出哪個進程的句柄DLL打開:

  1. 啓動Process Explorer的
  2. 按Ctrl + F和搜索DLL名稱
  3. 等待搜索完成
  4. 您將看到哪個進程有一個打開的DLL句柄。
1

沒有辦法讓EXE從另一個進程中刪除DLL的句柄。它幾乎肯定有句柄,因爲該DLL正在被該進程積極使用。真正可用的唯一選擇是從服務中殺死EXE進程。這可以通過Process.Kill方法完成。

雖然殺死你不擁有的其他進程通常是在編程世界中說不好的行爲。爲什麼你的節目比他們的更好?

+0

那麼,至少可以讓這個過程從外部釋放庫,但這顯然不是一個非常明智的選擇。 – 2010-09-24 20:40:47

2

該DLL被加載並映射到虛擬內存中。這會對文件進行鎖定。開始或停止服務不會改變這一點。服務EXE完全一樣。

你將不得不動態加載和卸載DLL來解決這個問題。 LoadLibrary和FreeLibrary。但是,只有在非託管DLL的情況下才有效。如果使用pinvoke,風險很大,因爲CLR在卸載後不會再自動加載DLL。

如果它是一個託管DLL,只有在另一個AppDomain中加載它時才能卸載它。沒有玫瑰花牀。

+0

我確實關閉了我卸載的應用程序域中的服務。我還卸載安裝該服務的應用程序域。我可以嘗試卸載啓動它的域。你認爲這可能有幫助嗎? – 2010-09-24 21:04:44

+0

原來我已經這麼做了。 – 2010-09-25 07:23:16

+0

這就是玫瑰花刺的地方,很難與廣告一起工作,而且不能在兩個領域都加載類型。你需要在一個單獨的程序集中聲明的接口,你可以在兩者中加載。也許是一個新問題的好主題。 – 2010-09-25 07:32:30