當文件操作遇上進程占用時


  近日做文件操作時,老是拋異常說文件正在被另一個進程占用着,很無奈,給我知道是哪個進程占用的話,就把它給Kill掉,當然這樣做在一定程度上是有危險的,萬一占用文件的進程是那么那么地重要,就不該Kill了,因此這樣的做法只能在確保安全的情況下去做,或者是Kill了進程之后帶來的不良后果也無關痛癢。上網找了一下,在別的進程占用文件下讀寫文件的文章很多,但獲取占用文章的進程就比較少,在百度上就有人說過用unlocker這種工具,這工具我沒去看,感覺也不太適合在這里用吧,如果有dll,提供API那還不錯。后來就在谷歌里找到了只那么一篇文章而已,看了之后還終究要用到別的exe,還得另外開進程啊。

       這個工具叫handler,從微軟里面下載的。只是一個控制台程序而已,雙擊它運行就可以查看當前系統中正在運行的進程,進程ID,占用的文件等信息。如果給他輸入文件名的參數,那就可以知道到時是那些進程在占用着這個文件了,列舉的信息中有進程ID,這個很關鍵,有了pid,那Process就有希望了。

 1             //要檢查被那個進程占用的文件
 2             string fileName = @"C:\Users\Administrator\Desktop\temp\..\temp\WF英文文檔(MSDN).doc";
 3             //先格式化一下路徑,免得有上面那種路徑的話,程序識別不出來
 4             fileName = new FileInfo(fileName).FullName;
 5             Process tool = new Process();
 6             //下面這段就配置一下啟動進程的相關了
 7             tool.StartInfo.FileName = @"C:\Users\Administrator\Desktop\temp\handle.exe";
 8             tool.StartInfo.Arguments = fileName + " /accepteula";
 9             tool.StartInfo.UseShellExecute = false;
10             //這里為了在運行的時候不會給那個程序冒出來
11             //Win7下不用也行,但XP就需要了
12             tool.StartInfo.RedirectStandardOutput = true;
13             tool.Start();
14             tool.WaitForExit();
15             string outputTool = tool.StandardOutput.ReadToEnd();
16 
17             //正則提取出進程的pid
18             string matchPattern = @"(?<=\s+pid:\s+)\b(\d+)\b(?=\s+)";
19             MatchCollection mc = Regex.Matches(outputTool, matchPattern);
20             foreach (Match match in mc)
21             {
22                 //有了pid,想把進程怎么弄就怎么弄。
23                 
24 
25             }

  這里還插一個題外話吧,就是在關進程的時候,用Process類的話有兩種方式,一種比較溫柔的CloseMainWindow()方法,另一種則是比較野蠻的,Kill()方法,除非WinForm程序的,只能比較野蠻了,之前聽同事說是即使用了Kill(),進程還是會殺不干凈的,對Kill()和CloseMainWindow()的內部實現機制還不了解,看那個同事是說用進程通訊去關的,要知道那個窗體標題,其實這樣感覺挺像用CloseMainWindow()了,但單純地用進程通訊去關也是有缺陷的,原本那窗體的標題叫Form1的,經過一系列操作之后窗體名改了,或者加上“(未響應)”,單純寫死一個標題太不科學了。用Process實例的MainWindowTitle屬性就可以獲取到主窗體的標題,可萬一碰到的是子窗體用ShowDialog的形式啟動時,想關閉子窗體時,CloseMainWindow()、Kill()、進程通訊都做不到了。用Process實例的MainWindowHandle屬性可以獲取進程的IntPtr對象,這個相當於在進程通信前調用系統API的FindWindow方法,這樣用來發送一個WM_CLOSE消息也跟使用MainWindowTitle屬性調用FindWindow的差不多,使用IntPtr對象的適用范圍更廣,其實用Kill()還是用WM_CLOSE消息,哪個強力一點,干凈一點,我真知道,如果Kill()萬一跟WM_CLOSE效果差不多的話,那也是Kill方便,免了聲明系統API方法,IntPtr或標題那幾個操作。求高人點。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM