zoukankan      html  css  js  c++  java
  • 当文件操作遇上进程占用时

      近日做文件操作时,老是抛异常说文件正在被另一个进程占用着,很无奈,给我知道是哪个进程占用的话,就把它给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或标题那几个操作。求高人点。

  • 相关阅读:
    linux系统常用命令
    python文件处理
    Python按行读文件
    向脚本传递参数-shift命令
    shell脚本中一些特殊符号
    标准make变量 MAKE_VERSION, CURDIR
    makefile "=" ":=" "?=" "+="
    静态资源映射
    Spring MVC的常用注解
    SpringMVC项目的快速搭建
  • 原文地址:https://www.cnblogs.com/HopeGi/p/3075006.html
Copyright © 2011-2022 走看看