我寫了個PythonRuntime.dll,把Python Embedded運行時庫,或者叫精簡綠色版的Python,用7Zip打包作為資源嵌入到DLL里面。
在DLL_PROCESS_ATTACH時釋放Python.7z到臨時目錄PyTemp,在DLL_PROCESS_DETACH時洗掉這個臨時目錄:干凈地退出。
另有一個自己的python腳本,把它用Cython轉成MyExt.pyd了,然后在PythonRuntime.Dll的MyDllFun()匯出函式中用Python C-API調MyExt.pyd,這樣,Python解釋器肯定會調LoadLibrary(hMyExt.Dll)的。
這一切都運行得很好,但是到了DLL_PROCESS_ATTACH洗掉臨時目錄PyTemp時,只有一個檔案刪不掉:我自己的擴展MyExt.pyd。加了FreeLibrary(hMyExt.pyd)也回傳成功了,但就是刪不了,等幾秒再刪也不行、死回圈FreeLibrary幾十次也不行。當然FreeLibrary()和洗掉操作是在Py_Finalize()之后進行的。
雖然Python PEP 3121里面講“Currently, extension modules are initialized usually once and then "live" forever. ”,但是我在DLL_PROCESS_ATTACH時執行釋放Python.7z、呼叫MyExt.dll、Py_Finalize()、FreeLibray(hMyExt.dll)這一系列操作之后是可以洗掉MyExt.pyd的。
參考《Windows核心編程》里面的說法,DLL Detach不保證順序的,但是我自己的MyExt.pyd總應該在Kernal32.dll之前吧?為什么FreeLibrary多次之后還是不能洗掉?
最后搞了個臨時方案:要求exe退出時呼叫ExitProcess(),我在DLL_PROCESS_ATTACH時hook自己exe的ExitProcess(),鉤到之后先FreeLibrary(hMyExt.pyd),再調Kernal32.dll的ExitProcess(),這樣就能洗掉了。也考慮過在自己的PythonRuntime.dll里面加個清理函式,但是不如上述方案好。
注1:運行環境:Python 3.5.1,VS2015 Update2,Win10
uj5u.com熱心網友回復:
MoveFileExuj5u.com熱心網友回復:
MOVEFILE_WRITE_THROUGH回傳TRUE,磁盤上的檔案名也確實改掉了,但還是刪不掉。調完之后手動刪也還是刪不掉。說是檔案正在由XXX.exe(我自己的dll呼叫方)使用
uj5u.com熱心網友回復:
更正:第四段“但是到了DLL_PROCESS_ATTACH洗掉臨時目錄”應改為“但是到了DLL_PROCESS_DETACH洗掉臨時目錄”uj5u.com熱心網友回復:
僅供參考:http://bbs.csdn.net/topics/390968755轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/153541.html
標籤:進程/線程/DLL
