进程Kill后代码停滞,如何实现结束应用、更新exe并重启?
问题分析与解决方案
你的核心问题是:你正在杀死的进程就是当前运行这段代码的程序本身。当proc.Kill()执行后,当前程序直接终止,后面的删除文件、复制新版本、重启的代码根本没机会执行。
为什么会出现这个问题?
因为Process.GetProcessesByName(processName)会把当前正在运行的这个程序进程也包含进去,你循环执行proc.Kill()的时候把自己的进程也干掉了,程序直接停止运行,自然不会继续执行后续的更新逻辑。
解决思路
必须把更新操作交给独立于当前程序的外部进程来完成,流程如下:
- 当前程序先启动一个外部辅助程序/脚本,传递更新所需的参数(旧文件路径、新文件路径、目标启动路径)
- 当前程序主动退出,释放文件占用
- 由外部辅助进程完成删除旧文件、复制新版本、启动新程序的操作
示例实现(用临时VBScript作为辅助工具)
可以在当前程序中生成一个临时VBS脚本,启动它后立即退出自身:
If CurExeVersion <> ServerVersion Then If MessageBox.Show("Update is ready to install", "Do you want to continue?", MessageBoxButtons.YesNo, MessageBoxIcon.Question) = Windows.Forms.DialogResult.Yes Then Dim processName As String = "Admin Management" Dim GetFilesFrom As String = "\\Bdpc\inhouse apps\Admin Management\Application Files\Admin Management_1_0_0_0\Admin Management.exe" Dim downloadPath As String = "D:\Admin Management_1_0_0_0\Admin Management.exe" ' 生成临时更新脚本 Dim tempScriptPath As String = IO.Path.Combine(IO.Path.GetTempPath(), "UpdateHelper.vbs") ' 转义路径中的引号,避免脚本语法错误 Dim escapedSource = GetFilesFrom.Replace("""", """""") Dim escapedTarget = downloadPath.Replace("""", """""") Dim scriptContent As String = $@" WScript.Sleep 2000 ' 等待原程序完全退出并释放文件锁 On Error Resume Next ' 忽略临时错误 Kill ""{escapedTarget}"" Copy ""{escapedSource}"" ""{escapedTarget}"" CreateObject(""WScript.Shell"").Run ""{escapedTarget}"" Kill WScript.ScriptFullName ' 更新完成后删除自身脚本 " IO.File.WriteAllText(tempScriptPath, scriptContent) ' 启动更新脚本,然后立即退出当前程序 Process.Start(tempScriptPath) Application.Exit() End If End If
额外建议
- 优先使用
Application.Exit()代替proc.Kill()退出自身程序,确保程序正常释放资源 - 给脚本添加等待时间,避免原进程还没完全退出就尝试操作文件导致权限错误
- 若追求更高稳定性,可以编写一个小型的控制台程序作为专用更新工具,替代VBS脚本
内容的提问来源于stack exchange,提问作者Raffy
相关产品推荐
相关产品推荐

