通过批处理文件重新启动到特定 OS 在 C# 控制台应用程序中不起作用

Rebooting to specific OS via batch file not working in C# console app

我的 PC 上安装了多个操作系统,以下批处理文件重新启动到参数中指定的 OS:

Reboot.bat

@echo off

COMMENT

Argument Mapping:

{default} is for Default OS
{56273db4-58e5-11ec-924b-c48ee7d6e76a} is for Second OS
{56273dac-58e5-11ec-924b-c48ee7d6e76a} is for Third OS

ENDCOMMENT

bcdedit /bootsequence %1 /addfirst
Shutdown /r /t 0

并且 运行 带有指定目标字段的快捷方式的批处理文件工作正常,并重新启动到第二个 OS,无需任何用户输入:

%USERPROFILE%\Dropbox\Misc\Reboot.bat {56273db4-58e5-11ec-924b-c48ee7d6e76a}

但是,运行 在下面所示的 C# 控制台应用程序中带有上述指定参数的 bat 文件只是重新启动到 Choose An Operating System 屏幕,我必须在其中手动选择 OS。我什至以管理员身份尝试 运行 编译的 exe 文件,但它做了同样的事情。

代码可能有什么问题?我是 运行 最新版本的 Windows 10 Pro。

internal class Program
{
   private static void Main(string[] args)
   {
       Console.Write("Which OS do you want to reboot to?:");
       Console.WriteLine();
       Console.WriteLine();
       Console.WriteLine("[1] Default");
       Console.WriteLine("[2] Second OS");
       Console.WriteLine("[3] Third OS");
    
       var choice = Console.ReadLine();
    
       if (!String.IsNullOrEmpty(choice))
       {
           switch (choice)
           {
              case "1":
                  choice = "{default}";
                  break;
    
              case "2":
                  choice = "{56273db4-58e5-11ec-924b-c48ee7d6e76a}";
                  break;
    
              case "3":
                  choice = "{56273dac-58e5-11ec-924b-c48ee7d6e76a}";
                  break;
    
              default:
                  return;
           }
       }
                
       var command = $@"{Environment.GetEnvironmentVariable("USERPROFILE")}\Dropbox\Misc\Reboot.bat {choice}";
                
       ExecuteCommand(command);
   }
    
   public static void ExecuteCommand(string command)
   {
       int exitCode;
       ProcessStartInfo processInfo;
       Process process;
    
       processInfo = new ProcessStartInfo("cmd.exe", "/c " + command);
       processInfo.CreateNoWindow = true;
       processInfo.UseShellExecute = false;
       process = Process.Start(processInfo);
       process.WaitForExit();
       exitCode = process.ExitCode;
       process.Close();
   }
}

我发现了问题。事实证明,我之前的代码并没有像我怀疑的那样以管理员模式启动 cmd.exe 进程。我做了以下更改,我直接执行了 cmd 命令,而不是使用 bat 文件:

internal class Program
{
    private static void Main(string[] args)
    {
        Console.WriteLine("Which OS do you want to reboot to?:\n");
        Console.WriteLine("[1] Default");
        Console.WriteLine("[2] Second OS");
        Console.WriteLine("[3] Third OS");

        var choice = Console.ReadLine();

        if (!String.IsNullOrEmpty(choice))
        {
            switch (choice)
            {
                case "1":
                    choice = "default";
                    break;

                case "2":
                    choice = "56273db4-58e5-11ec-924b-c48ee7d6e76a";
                    break;

                case "3":
                    choice = "56273dac-58e5-11ec-924b-c48ee7d6e76a";
                    break;

                default:
                    return;
            }
        } 
        else
        {
            return;
        }
       
        ExecuteCommand($@"bcdedit /bootsequence {{{choice}}} /addfirst & shutdown /r /t 0");
                    
    }
    
    public static void ExecuteCommand(string command)
    {
        Process process = new Process();
        ProcessStartInfo startInfo = new ProcessStartInfo
        {
            WorkingDirectory = @"C:\Windows\System32",
            FileName = "cmd.exe",
            UseShellExecute = true,
            CreateNoWindow = false,
            Verb = "runas",
            Arguments = "/c " + command
        };
        process.StartInfo = startInfo;
        process.Start();
        process.WaitForExit();
        process.Close();
    }
}

进行这些更改后,我 运行 遇到另一个问题,即命令提示符无法识别 bcdedit 命令。这是由 32 位进程 运行 对 64 位 windows 的文件系统重定向的影响造成的。因此,我必须将控制台应用程序的目标平台设置为 X64This SO question 有帮助。