Ash-Bash32
Ash-Bash32

Reputation: 433

C# .Net can access the bcdboot commands via Process()

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

Answers (3)

It all makes cents
It all makes cents

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

user7085621
user7085621

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

ExhoAR22
ExhoAR22

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

Related Questions