我有一個依賴於DLL的Windows服務。無論服務是否正在運行,它的可執行文件都會保留該DLL的句柄,這會阻止我自動更新它。如何釋放一個由未運行的exe引用的DLL?
這是爲什麼,我該如何以編程方式刪除該句柄(最好通過.Net)?
更新: 我知道服務的可執行文件是帶有句柄的可執行文件,因爲我在dll上運行了handle.exe,並且只有服務的exe文件出現了。當我在exe上運行它時,沒有什麼能夠起作用,並且我知道服務沒有運行,因爲我檢查了服務列表。沒有別的東西會使用我能想到的dll。
我有一個依賴於DLL的Windows服務。無論服務是否正在運行,它的可執行文件都會保留該DLL的句柄,這會阻止我自動更新它。如何釋放一個由未運行的exe引用的DLL?
這是爲什麼,我該如何以編程方式刪除該句柄(最好通過.Net)?
更新: 我知道服務的可執行文件是帶有句柄的可執行文件,因爲我在dll上運行了handle.exe,並且只有服務的exe文件出現了。當我在exe上運行它時,沒有什麼能夠起作用,並且我知道服務沒有運行,因爲我檢查了服務列表。沒有別的東西會使用我能想到的dll。
這是一個討厭的小問題。該服務有兩個線程,其中一個執行一個非常微妙的,不常用的功能,我沒有注意到它在共享資源上發生死鎖。所以它無限期地掛起來,這是讓我的可執行文件保持運行狀態,儘管服務被關閉了。解決這個問題解決了我的文件處理問題。
感謝您的建議,所有。
這是不可能的。只有正在運行的進程才能擁有文件句柄。
您可以使用Process Explorer找出哪個進程的句柄DLL打開:
沒有辦法讓EXE從另一個進程中刪除DLL的句柄。它幾乎肯定有句柄,因爲該DLL正在被該進程積極使用。真正可用的唯一選擇是從服務中殺死EXE進程。這可以通過Process.Kill
方法完成。
雖然殺死你不擁有的其他進程通常是在編程世界中說不好的行爲。爲什麼你的節目比他們的更好?
那麼,至少可以讓這個過程從外部釋放庫,但這顯然不是一個非常明智的選擇。 – 2010-09-24 20:40:47
該DLL被加載並映射到虛擬內存中。這會對文件進行鎖定。開始或停止服務不會改變這一點。服務EXE完全一樣。
你將不得不動態加載和卸載DLL來解決這個問題。 LoadLibrary和FreeLibrary。但是,只有在非託管DLL的情況下才有效。如果使用pinvoke,風險很大,因爲CLR在卸載後不會再自動加載DLL。
如果它是一個託管DLL,只有在另一個AppDomain中加載它時才能卸載它。沒有玫瑰花牀。
我確實關閉了我卸載的應用程序域中的服務。我還卸載安裝該服務的應用程序域。我可以嘗試卸載啓動它的域。你認爲這可能有幫助嗎? – 2010-09-24 21:04:44
原來我已經這麼做了。 – 2010-09-25 07:23:16
這就是玫瑰花刺的地方,很難與廣告一起工作,而且不能在兩個領域都加載類型。你需要在一個單獨的程序集中聲明的接口,你可以在兩者中加載。也許是一個新問題的好主題。 – 2010-09-25 07:32:30
我總是在這裏遇到這樣的問題,當人們創建長時間運行的Windows服務過程,然後花費大量時間解決它創建的問題。
如果可能,您可以考慮使用Windows任務計劃程序爲此嗎?你在這裏看到爲什麼..http://pavangayakwad.blogspot.com/2010/09/windows-service-or-windows-task.html
您如何知道它是保持打開的非運行服務? – CodingGorilla 2010-09-24 20:35:57
你是如何確定它是甚至沒有運行時引用DLL的服務可執行文件? – 2010-09-24 20:37:18
爲什麼投票的人被轉移到超級用戶? OP正在尋求一個編程解決方案 – JaredPar 2010-09-24 20:38:30