由Restart()想到的

229 阅读1分钟

官方文档:Application.Restart Method (System.Windows.Forms) | Microsoft Docs

目录

 Restart

探索

结论

启示


 Restart

当我们在.net Framework中使用它时,并没有什么特殊之处,是可以正常运行的,然而如果在.net core3.0时,则会抛出InvalidOperation异常。

Application.Restart();

 为什么同样一个方法在会出现这样的区别呢?

探索

我们先看一下异常信息:

Process was not started by this object, so requested information cannot be determined.

此对象未启动进程,因此无法确定请求的信息。

由此我们可以大致推断:此异常是和进程启动有关。而关于进程的代码,在Restart方法中一共由两处:

if (string.Equals(str + "\ieexec.exe", currentProcess.MainModule.FileName, StringComparison.OrdinalIgnoreCase))
                {
                    flag = true;
                    ExitInternal();
                    string text = AppDomain.CurrentDomain.GetData("APP_LAUNCH_URL") as string;
                    if (text != null)
                    {
                        Process.Start(currentProcess.MainModule.FileName, text);
                    }
                }

ProcessStartInfo startInfo = Process.GetCurrentProcess().StartInfo;
            startInfo.FileName = ExecutablePath;
            if (stringBuilder.Length > 0)
            {
                startInfo.Arguments = stringBuilder.ToString();
            }

            ExitInternal();
            Process.Start(startInfo);

第一处代码主要是为了执行ieexec.exe,所以我们不用重点分析。

IEexec.exe应用程序是.NET Framework附带程序,存在于多个系统白名单内。可以将IEExec.exe应用程序用作主机,以运行使用URL启动的其他托管应用程序。

接下来我们看第二处代码关于进程的部分:

ProcessStartInfo startInfo = Process.GetCurrentProcess().StartInfo;
Process.Start(startInfo);

当我执行时,果然在Process.GetCurrentProcess().StartInfo出现了InvalidOperation异常,至此我们将异常范围缩小到了StartInfo属性。

.net core 3.0版

public static Process GetCurrentProcess()
        {
            throw null;
        }

public ProcessStartInfo StartInfo
        {
            get
            {
                throw null;
            }
            set
            {
            }
        }

.net Framework版

public static Process GetCurrentProcess()
        {
            return new Process(".", isRemoteMachine: false, Microsoft.Win32.NativeMethods.GetCurrentProcessId(), null);
        }

public ProcessStartInfo StartInfo
        {
            get
            {
                if (startInfo == null)
                {
                    startInfo = new ProcessStartInfo(this);
                }

                return startInfo;
            }
            set
            {
                if (value == null)
                {
                    throw new ArgumentNullException("value");
                }

                startInfo = value;
            }
        }

结论

至此我们得出结论:在.net core3.0中,一则由于GetCurrentProcess()返回为null,二则StartInfo的get并未进行实例化,所以当后面调用StartInfo属性时无论如何都会抛出异常。

启示

.net core3.0是.net core框架中支持桌面程序的第一个大版本,存在一定的问题是正常的。但是作为一个程序员,应该以稳定性为重,不要只贪图新技术带来的快感。最后将一句老子的格言送给正在阅读的你:

我有三宝,持而守之。一曰慈、二曰俭、三曰不敢为天下先。慈固能勇;俭固能广;不敢为天下先,固能成器长。