Reputation: 433
Im trying to copy UEFI files onto a SD Card and Im trying to use Process to do most of the tasks I need to do for this to work but It seems that bcdboot command works when using the same command in the CMD Window but when you open cmd.exe via process and give it the same command it doesn't work, I've tried everything possible I think and cant seem to get it working :(
Code -:
string[] bcdArgs = new string[3];
bcdArgs[0] = "bcdboot " + @"i:\windows /s p: /f UEFI";
Process cmd = new Process();
cmd.StartInfo.FileName = "cmd.exe";
cmd.StartInfo.Verb = "runas";
cmd.StartInfo.WindowStyle = ProcessWindowStyle.Normal;
cmd.StartInfo.UseShellExecute = true;
cmd.StartInfo.RedirectStandardOutput = false;
cmd.EnableRaisingEvents = true;
foreach (string arg in bcdArgs)
{
cmd.StartInfo.Arguments += arg;
}
cmd.Start();
//Console.WriteLine(cmd.StandardOutput.ReadToEnd());
cmd.WaitForExit();
if (cmd.HasExited)
{
signWindowsFiles();
}
Upvotes: 0
Views: 395
Reputation: 4983
Ensure that you're using a fully-qualified filename. Calls to %SystemRoot% (ie: C:\Windows\System32) are re-directed when running a 32-bit process on 64-bit windows. Instead of 'C:\Windows\System32' the call is re-directed to 'C:\Windows\SysWOW64'. Need to override this behavior by using "Sysnative" in place of "System32".
Instead of "C:\Windows\system32\diskpart.exe", use "C:\Windows\Sysnative\diskpart.exe".
//Check if OS is 64-bit and this program is running
//as 32-bit.
//
//Note: For a 64-bit process, IntPtr.Size = 8
// For a 32-bit process, IntPtr.Size = 4
string folderSys32Path = string.Empty;
//Windows folder (ex: C:\Windows)
string folderWinPath = Path.GetFullPath(Environment.GetEnvironmentVariable("SystemRoot"));
//get system32 folder path
if (System.Environment.Is64BitOperatingSystem && IntPtr.Size == 4)
{
//using "Sysnative" in place of "System32"
//ensures that the 64-bit "System32" folder is
//used instead of "SysWOW64"
folderSys32Path = Path.Combine(folderWinPath, "Sysnative");
}//if
else
{
folderSys32Path = Path.Combine(folderWinPath, "System32");
}//else
Also, you may need to use an Application Manifest file, specifying that it's required to run as Administrator.
Upvotes: 2
Reputation:
You are running cmd.exe bcdboot i:\windows /s p: /f UEFI
which won't work. You need to add /c
after cmd.exe.
From cmd.exe /?
Starts a new instance of the Windows command interpreter
CMD [/A | /U] [/Q] [/D] [/E:ON | /E:OFF] [/F:ON | /F:OFF] [/V:ON | /V:OFF] [[/S] [/C | /K] string]
-> /C Carries out the command specified by string and then terminates
/K Carries out the command specified by string but remains
/S Modifies the treatment of string after /C or /K (see below)
/Q Turns echo off
...
Modified code:
string[] bcdArgs = new string[3];
bcdArgs[0] = "/c"; // cmd.exe args
bcdArgs[1] = "bcdboot.exe " + @"i:\windows /s p: /f UEFI"; // bcdboot.exe
Process cmd = new Process();
cmd.StartInfo.FileName = "cmd.exe";
cmd.StartInfo.Verb = "runas";
cmd.StartInfo.WindowStyle = ProcessWindowStyle.Normal;
cmd.StartInfo.UseShellExecute = true;
cmd.StartInfo.RedirectStandardOutput = false;
cmd.EnableRaisingEvents = true;
foreach (string arg in bcdArgs)
{
cmd.StartInfo.Arguments += arg + " "; // Adds a space after every argument
}
cmd.Start();
//Console.WriteLine(cmd.StandardOutput.ReadToEnd());
cmd.WaitForExit();
if (cmd.HasExited)
{
signWindowsFiles();
}
(CODE UNTESTED, edits are appreciated)
Upvotes: 2
Reputation: 1
You should separate your arguments by spaces. Instead of:
foreach (string arg in bcdArgs)
{
cmd.StartInfo.Arguments += arg;
}
Try this:
cmd.StartInfo.Arguments = String.Join(" ", bcdArgs);
Also, according to this, for some options you might need to run with administrator privileges. So if it still doesn't work try again as administrator.
Upvotes: 0