当前位置: 首页 > news >正文

南皮网站建设公司全国的做网站的公司

南皮网站建设公司,全国的做网站的公司,茂南网站开发公司,淄博前信网络科技有限公司我公司最近升级程序经常报出更新失败问题#xff0c;究其原因#xff0c;原来是更新时#xff0c;他们可能又打开了正在被更新的文件#xff0c;导致更新文件时#xff0c;文件被其它进程占用#xff0c;无法正常更新而报错#xff0c;为了解决这个问题#xff0c;我花… 我公司最近升级程序经常报出更新失败问题究其原因原来是更新时他们可能又打开了正在被更新的文件导致更新文件时文件被其它进程占用无法正常更新而报错为了解决这个问题我花了一周时间查询多方资料及研究终于找到了一个查询进程的利器handle.exe下载地址https://technet.microsoft.com/en-us/sysinternals/bb896655.aspx我是通过它来找到被占用的进程然后KILL掉占用进程最后再来更新这样就完美的解决了更新时文件被占用报错的问题了实现方法很简单我下面都有列出主要的方法一些注意事项我也都有说明大家一看就明白了当然如果大家有更好的方案欢迎交流谢谢 IsFileUsing判断文件是否被占用 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 [DllImport(kernel32.dll)] public static extern IntPtr _lopen(string lpPathName, int iReadWrite); [DllImport(kernel32.dll)] public static extern bool CloseHandle(IntPtr hObject); public const int OF_READWRITE 2; public const int OF_SHARE_DENY_NONE 0x40; public readonly IntPtr HFILE_ERROR  new IntPtr(-1); private bool strongIsFileUsing/strong(string filePath) {     if (!File.Exists(filePath))     {         return false;     }     IntPtr vHandle _lopen(filePath, OF_READWRITE | OF_SHARE_DENY_NONE);     if (vHandle HFILE_ERROR)     {         return true;     }     CloseHandle(vHandle);     return false; } GetRunProcessInfos获取指定文件或目录中存在的(关联的)运行进程信息以便后面可以解除占用 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 /// summary /// 获取指定文件或目录中存在的(关联的)运行进程信息以便后面可以解除占用 /// /summary /// param namefilePath/param /// returns/returns private Dictionaryint, string GetRunProcessInfos(string filePath) {     Dictionaryint, string runProcInfos  new Dictionaryint, string();     string fileName Path.GetFileName(filePath);     var fileRunProcs Process.GetProcessesByName(fileName);     if (fileRunProcs ! null  fileRunProcs.Count() 0)     {         runProcInfos fileRunProcs.ToDictionary(p p.Id, p p.ProcessName);         return runProcInfos;     }     string fileDirName Path.GetDirectoryName(filePath); //查询指定路径下的运行的进程     Process startProcess  new Process();     startProcess.StartInfo.FileName RelaseAndGetHandleExePath();     startProcess.StartInfo.Arguments  string.Format(\{0}\, fileDirName);     startProcess.StartInfo.UseShellExecute  false;     startProcess.StartInfo.RedirectStandardInput  false;     startProcess.StartInfo.RedirectStandardOutput  true;     startProcess.StartInfo.CreateNoWindow  true;     startProcess.StartInfo.StandardOutputEncoding ASCIIEncoding.UTF8;     startProcess.OutputDataReceived (sender, e)     {         if (!string.IsNullOrEmpty(e.Data) e.Data.IndexOf(pid:, StringComparison.OrdinalIgnoreCase) 0)         {             //var regex new System.Text.RegularExpressions.Regex((^[\w\.\?\u4E00-\u9FA5])\spid:\s*(\d), System.Text.RegularExpressions.RegexOptions.IgnoreCase);             var regex  new System.Text.RegularExpressions.Regex((^.(?pid:))\bpid:\s(\d)\s, System.Text.RegularExpressions.RegexOptions.IgnoreCase);             if (regex.IsMatch(e.Data))             {                 var mathedResult regex.Match(e.Data);                 int procId  int.Parse(mathedResult.Groups[2].Value);                 string procFileName mathedResult.Groups[1].Value.Trim();                 if (explorer.exe.Equals(procFileName, StringComparison.OrdinalIgnoreCase))                 {                     return;                 }                 //var regex2 new System.Text.RegularExpressions.Regex(string.Format(\b{0}.*$, fileDirName.Replace(\, \\).Replace(?,\?)), System.Text.RegularExpressions.RegexOptions.IgnoreCase);                 var regex2  new System.Text.RegularExpressions.Regex(\b\w{1}:.$, System.Text.RegularExpressions.RegexOptions.IgnoreCase);                 string procFilePath (regex2.Match(e.Data).Value ?? ).Trim();                 if (filePath.Equals(procFilePath, StringComparison.OrdinalIgnoreCase) || filePath.Equals(PathJoin(procFilePath, procFileName), StringComparison.OrdinalIgnoreCase))                 {                     runProcInfos[procId] procFileName;                 }                 else //如果乱码则进行特殊的比对                 {                     if (procFilePath.Contains(?) || procFileName.Contains(?)) //?乱码比对逻辑                     {                         var regex3  new System.Text.RegularExpressions.Regex(procFilePath.Replace(\, \\).Replace(., \.).Replace(?, .{1}), System.Text.RegularExpressions.RegexOptions.IgnoreCase);                         if (regex3.IsMatch(filePath))                         {                             runProcInfos[procId] procFileName;                         }                         else                         {                             string tempProcFilePath PathJoin(procFilePath, procFileName);                             regex3  new System.Text.RegularExpressions.Regex(tempProcFilePath.Replace(\, \\).Replace(., \.).Replace(?, .{1}), System.Text.RegularExpressions.RegexOptions.IgnoreCase);                             if (regex3.IsMatch(filePath))                             {                                 runProcInfos[procId] procFileName;                             }                         }                     }                     else if (procFilePath.Length filePath.Length || PathJoin(procFilePath, procFileName).Length filePath.Length) //其它乱码比对逻辑仅比对长度如果相同交由用户判断                     {                         if (MessageBox.Show(string.Format(发现文件:{0}可能被一个进程({1})占用,\n您是否需要强制终止该进程?, filePath, procFileName), 发现疑似被占用进程, MessageBoxButtons.YesNo, MessageBoxIcon.Warning) DialogResult.Yes)                         {                             runProcInfos[procId] procFileName;                         }                     }                 }             }         }     };     startProcess.Start();     startProcess.BeginOutputReadLine();     startProcess.WaitForExit();     return runProcInfos; } 上述代码逻辑简要说明创建一个建程来启动handle.exe以资源形式内嵌到项目中然后异步接收返回数据并通过正则表达式来匹配获取进程数据由于handle.exe对于中文路径或文件名兼容不好返回的数据存在或其它乱码字符故我作了一些特殊的模糊匹配逻辑 RelaseAndGetHandleExePath从项目中释放handle.exe并保存到系统的APPData目录下以便后续直接可以使用注意由于handle.exe需要授权同意后才能正常的使用该工具故我在第一次生成handle.exe时会直接运行进程让用户选择Agree后再去进行后面的逻辑处理这样虽能解决问题但有点不太友好目前一个是中文乱码、一个是必需同意才能使用handle.exe我认为如果微软解决了可能会更好 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 private string RelaseAndGetHandleExePath() {     var handleInfo  new FileInfo(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData)  \\SysUpdate\\handle.exe);     if (!File.Exists(handleInfo.FullName))     {         if (!Directory.Exists(handleInfo.DirectoryName))         {             Directory.CreateDirectory(handleInfo.DirectoryName);         }         byte[] handleExeData Properties.Resources.handle;         File.WriteAllBytes(handleInfo.FullName, handleExeData);         var handleProc Process.Start(handleInfo.FullName);//若第一次则弹出提示框需要点击agree同意才行         handleProc.WaitForExit();     }     return handleInfo.FullName; } PathJoin拼接路径不过滤特殊字符由于handle.exe对于中文路径或文件名兼容不好返回的数据存在或其它乱码字符如查采用Path.Combine方法则会报错故这里自定义一个方法只是简单的拼接 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 /// summary /// 拼接路径不过滤殊字符 /// /summary /// param namepaths/param /// returns/returns private string PathJoin(params string[] paths) {     if (paths  null || paths.Length 0)     {         return string.Empty;     }     string newPath paths[0];     for (int i 1; i paths.Length; i)     {         if (!newPath.EndsWith(\\))         {             newPath  \\;         }         if (paths[i].StartsWith(\\))         {             paths[i] paths[i].Substring(1);         }         newPath paths[i];     }     return newPath; } CloseProcessWithFile核心方法关闭指定文件被占用的进程上述所有的方法均是为了实现该方法的功能 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 private void CloseProcessWithFile(string filePath) {     if (!IsFileUsing(filePath)) return;     ShowDownInfo(string.Format(正在尝试解除占用文件 {0}, _FilePaths[_FileIndex]));     var runProcInfos GetRunProcessInfos(filePath); //获取被占用的进程     System.IO.File.WriteAllText(Path.Combine(Application.StartupPath, runProcInfos.txt), string.Join(\r\n, runProcInfos.Select(p  string.Format(ProdId:{0},ProcName:{1}, p.Key, p.Value)).ToArray()));//DEBUG用正式发布时可以去掉     var localProcesses Process.GetProcesses();     bool hasKilled  false;     foreach (var item in runProcInfos)     {         if (item.Key ! currentProcessId) //排除当前进程         {             var runProcess localProcesses.SingleOrDefault(p p.Id item.Key);             //var runProcess Process.GetProcessById(item.Key);             if (runProcess ! null)             {                 try                 {                     runProcess.Kill(); //强制关闭被占用的进程                     hasKilled  true;                 }                 catch                 { }             }         }     }     if (hasKilled)     {         Thread.Sleep(500);     } } 上述代码逻辑简要说明先判断是否被占用若被占用则获取该文件被占用的进程列表然后获取一下当前操作系统的所有进程列表最后通过进程ID查询得到排除当前程序自己的进程IDcurrentProcessId Process.GetCurrentProcess().Id列表若能获取得到表明进程仍在运行则强制终止该进程实现解除文件占用 注意KILL掉占用进程后可能由于缓存原因若直接进行文件的覆盖与替换或转移操作可能仍会报错故这里作了一个判断若有成功KILL掉进程则需等待500MS再去做更新文件之类的操作 本文转自 梦在旅途 博客园博客原文链接http://www.cnblogs.com/zuowj/p/5840567.html  如需转载请自行联系原作者
http://www.huolong8.cn/news/351384/

相关文章:

  • 技术支持:上海网站建设梅西网页设计作业
  • 特产网站开发的目的如何实现输入域名访问网站首页
  • 潍坊网站建设工作室微信运营商是哪个公司
  • 建网上商城的第三方网站哪个好seo 优化
  • 建国外网站买完域名后怎么做天猫店铺怎么开店
  • 个人买卖网站怎么做如何快捷建企业网站
  • 杭州网站设计公司有哪些网站建设用到什么
  • 网站建设祥云平台怎么自己做网站游戏
  • 怎样做网站分析iis 7.5 网站
  • ppt模板免费的网站推荐wordpress get field
  • 自己怎么做网站空间百度推广和哪些网站有合作
  • 营销型网站建设的一般过程包括哪些环节?笑话网站代码
  • 成都公司网站设计套餐北京南站地铁
  • 响应式网站弊端app store下载正版
  • 网站怎么做能赚钱吗个人网站首页布局图
  • 60天做网站qq创号申请注册网站
  • 网站 语言切换怎么做如何用手机制作游戏
  • 哈尔滨制作企业网站高端网页制作公司哪家好
  • 网站优化专家室内装修设计上海
  • php租车网站物业网站宣传册怎么做
  • 怎样创建一个国际网站江西网站建设与推广
  • 网站建设 需求模板寻找网站开发
  • 国内比较高端的设计网站临沂网站维护公司
  • 哔哩哔哩网站建设最新国际新闻 大事件
  • 如何让网站火起来唐山建设集团招聘信息网站
  • 高校网站平台建设nginx优化wordpress网站速度
  • 只做PC版网站免费建设自己的文学网站
  • 企业网站建设 新天地网络长沙网站制作有哪些公司
  • 广东省建设工程质量安全监督检测总站网站河南工程学院网站建设
  • 怎么样制作一个公司网站物联网工程就业方向及前景