通过批处理文件重新启动到特定 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 的文件系统重定向的影响造成的。因此,我必须将控制台应用程序的目标平台设置为 X64
。 This SO question 有帮助。
我的 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 的文件系统重定向的影响造成的。因此,我必须将控制台应用程序的目标平台设置为 X64
。 This SO question 有帮助。