在 MAC 系统下,如果在运行过程中,应用程序的文件被删除了,那么此时如果应用程序执行了 Process.Start 方法时,将会抛出 Win32Exception 异常
我写了一个工具 dotnetCampus.UpdateAllDotNetTools 用来更新所有的 dotnet tool 工具。因为 dotnetCampus.UpdateAllDotNetTools 也是一个 dotnet tool 工具,因此也会更新自身
但是有小伙伴告诉我,在使用 dotnetCampus.UpdateAllDotNetTools 更新 dotnetCampus.UpdateAllDotNetTools 到最新版本之后,其他的 dotnet tool 就都不能更新了,将会抛出 Win32Exception 异常,如下图
在更新 dotnetCampus.UpdateAllDotNetTools 将会删除当前运行的 dotnetCampus.UpdateAllDotNetTools 进程的文件,在 MAC 下是可以删除正在运行的程序的文件,但是在 .NET Core 的 Process.Start 方法里面的逻辑是需要先获取当前进程所在的文件,获取对应的文件夹,用于找到命令
例如我输入了 dotnet
命令,通过 Process.Start("dotnet")
那么 .NET 将先尝试在程序所在的文件夹寻找是否存在 “dotnet” 这个程序,如果存在,那么执行。因此第一步就是获取当前进程所在的文件
在 .NET 开源代码里面,可以在 src\libraries\System.Diagnostics.Process\src\System\Diagnostics\Process.Unix.cs
找到实际的 Process Start 逻辑
在 ResolvePath 方法将会先尝试获取当前的文件夹,具体的实现将会在 src\libraries\System.Diagnostics.Process\src\System\Diagnostics\Process.OSX.cs
文件里
在 MAC 系统的代号里面,上古版本就是 OSX 也就是 OSX 就是 MAC 系统,上面这个代码文件就是特别给 MAC 系统使用的
那么获取当前文件用的是什么方法?调用一个和 Windows 的 P/Invoke 方法差不多的方法
这个 proc_pidpath
是什么方法?这是一个获取传入的进程号拿到对应的文件路径的方法,如果传入的进程号对应的文件被删除了,那么将会抛出 Win32Exception 异常
这就是在 Unhandled exception on Mac · Issue #4 · dotnet-campus/dotnetCampus.UpdateAllDotNetTools 的问题
我尝试在 dotnet runtime 修复这个坑 Ignore the executable file be deleted in Process Start by lindexi · Pull Request #40748 · dotnet/runtime
本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。 欢迎转载、使用、重新发布,但务必保留文章署名 林德熙 (包含链接: https://blog.lindexi.com ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请与我 联系。