0

When I try to run cmd command 'efwmgr C: -commit' from C#, got empty log file without any information, and when check manually 'ewfmgr C:', got 'Boot Command NO_CMD', so commit not run.

Same code just changed Arguments = "/C chkdsk C:" it runs and works well, inserted whole output into my log.

Method which I used.

public static void StartProcess()
{
    var procStartInfo = new ProcessStartInfo
    {
        CreateNoWindow = false,
        WindowStyle = ProcessWindowStyle.Normal,
        FileName = "cmd",
        Arguments = "/C ewfmgr C: -commit",
        UseShellExecute = false,
        RedirectStandardOutput = true,
        RedirectStandardInput = true,
        RedirectStandardError = true
    };

    var process = new Process { StartInfo = procStartInfo, EnableRaisingEvents = true };

    using (StreamWriter writer = new StreamWriter(@"D:\commitFile.txt"))
    {
        process.OutputDataReceived += (sender, e) =>
        {
            writer.WriteLine(e.Data);
        };

        process.Start();
        process.BeginOutputReadLine();
        process.WaitForExit();
    }
}

This is the nearly example I found on https://social.msdn.microsoft.com/Forums/vstudio/en-US/4e014365-8e8f-4f93-998a-156f2e55ebab/how-to-get-and-write-ewf-current-to-text-file-using-c?forum=csharpgeneral

stasiaks
  • 1,268
  • 2
  • 14
  • 31
Milan
  • 1
  • 3
  • Try to add `process.ErrorDataReceived += (sender, e) => {writer.WriteLine(e.Data);};` – Renatas M. Aug 14 '18 at 12:37
  • I've tried, didn't get anything in my log, still is empty. – Milan Aug 14 '18 at 12:42
  • @Reniuz I forgot to add also process.BeginErrorReadLine(); now got the error "'ewfmgr' is not recognized as an internal or external command, operable program or batch file." – Milan Aug 14 '18 at 12:50
  • Then case closed :) – Renatas M. Aug 14 '18 at 13:12
  • Ok, but why did I get this error. When run ewfmgr C: -commit manually from cmd it runs and got 'Boot Command Commit' in that case works, otherwise not. – Milan Aug 14 '18 at 13:26

2 Answers2

0

You probably getting an error in process error output stream. Append your log in ErrorDataReceived event handler. And for the 'ewfmgr' is not recognized as an internal or external command you should edit process environment variable or specify full path to your application. This is how you code should look like:

var procStartInfo = new ProcessStartInfo
{
    CreateNoWindow = false,
    WindowStyle = ProcessWindowStyle.Normal,
    FileName = "cmd",

    //Append PATH environment variable bellow if you use this
    Arguments = "/C ewfmgr C: -commit",

    //Or use full path to application without changing environment variable
    //Arguments = "/C c:\full\path\to\application\ewfmgr C: -commit",

    UseShellExecute = false,
    RedirectStandardOutput = true,
    RedirectStandardInput = true,
    RedirectStandardError = true
 };
procStartInfo.EnvironmentVariables["PATH"] += @";c:\full\path\to\application\";
var process = new Process { StartInfo = procStartInfo, EnableRaisingEvents = true };

using (StreamWriter writer = new StreamWriter(@"D:\commitFile.txt"))
{
   process.OutputDataReceived += (sender, e) =>
   {
      writer.WriteLine(e.Data);
   };
   process.ErrorDataReceived+= (sender, e) =>
   {
      writer.WriteLine(e.Data);
   };
   process.Start();
   process.BeginOutputReadLine();
   process.BeginErrorReadLine();
   process.WaitForExit();
}
Renatas M.
  • 11,694
  • 1
  • 43
  • 62
  • Tried this code but still is the main issue "'ewfmgr' is not recognized as an internal or external command, operable program or batch file." Probably is some problem with efwmgr cause is not system command, other system commands like 'chkdsk' I mentioned, work fine. – Milan Aug 14 '18 at 13:56
  • Yes, like this Arguments = "/C c:\Windows\System32\ewfmgr.exe C: -commit" not working, but when I copy ewfmgr.exe on D: disc and set FileName = @"ewfmgr.exe", Arguments = "C: -commit" it works. Probably some problem with permissions when trying to access directly on C:\Windows\System32. – Milan Aug 14 '18 at 14:13
  • Oh this might be the issue that you are actually running command prompt (by setting File="cmd") with arguments. Try to set File="c:\Windows\System32\ewfmgr.exe" and Arguments="C: -commit" – Renatas M. Aug 14 '18 at 14:21
  • Not working with your last proposal, just says: "Windows can not find 'c:\Windows\System32\ewfmgr.exe'. Make sure you typed the name correclty, and then try again. – Milan Aug 14 '18 at 14:27
  • Very strange. Well at least you find how to do it :) – Renatas M. Aug 14 '18 at 15:19
0

Just wanted to point out an update regarding this issue for anyone that might encounter this, or any other file "missing" from Windows/System32 directory:

First things to check is your system architecture, and your process architecture:

There are several posts about this feature (although I prefer to call it issue), I can safely say that this one explains it correclty, and that ewfmgr.exe works just fine if you set your architecture correclty.

In order not to rely on another post/link, I'll rewrite/copy the answer from David there:

There is one explanation that makes sense:

  1. You are executing the program on a 64 bit machine.
  2. Your C# program is built as x86.
  3. The bcdedit.exe file exists in C:\Windows\System32.
  4. Although C:\Windows\System32 is on your system path, in an x86 process you are subject to the File System Redirector. Which means that C:\Windows\System32 actually resolves to C:\Windows\SysWOW64.
  5. There is no 32 bit version of bcdedit.exe in C:\Windows\SysWOW64.

The solution is to change your C# program to target AnyCPU or x64.

As a side note I'd like to also add that by default, VS projects for C# are set as "Any CPU" configuration, however there's checkbox ticked in project properties on the build tab, that says "Prefer 32-bit": This needs to be unchecked/disabled, or "Any cpu" build will result in 32 bit application as well.

Other than that, I've successfully implemented fully working EWF manager into our service application. Unfortunatelly I haven't had any luck using pInvoke and ewfapi dll, since it didn't seem to return correct results. I'm not sure yet whether there was an issue in implementation, or whether the EWF api itself is broken (to be honest, its really buggy and unreliable. For us specifically, the "Disable" command does nothing - after reboot, ewf is still enabled. The only way to disable it is to Disable and Commit, or use CommitAndDisableLive, which both unfortunatelly commit current state onto the drive, so I had to use fallback and reboot the machine before disabling protection, to be sure its in clean state), so I went the route to call it using command line, and parse response parameters to control it. Unfortunatelly it was time critical and I needed production ready solution, so I had to make a workaround, but I'll post a separate question about the pInvoke, and then put on GitHub altogether as a final solution.

I'll come back and edit this post to include the GitHub link once I have the time to upload it. Should someone need it right away, I'm happy to send it over as-is.

Hope it helps.

That Marc
  • 1,134
  • 3
  • 19
  • 42