0

I'm running an exe file through Process, which generates binary data, and I want to save that data into a file.

while using usual proposed methods of doing so (Sync and async) I've ran across couple of hurdles, and I hope you can help me out.

I've run the commands through code, and through prompt, and here are my observations

1) When using sync methods, the file is by default encoded with UTF-8 (File ends up larger than the prompt one 2) when changing the encoding method to ASCII/default the encoding seems to be handled properly and file seems to be similar in size to the prompt one, unfortunately the process designed to read that file considers it "errored" 3) using async method and saving using BinaryWriter creates a seemingly accurate file, but still cant be read by output. I believe my error might be how I append "new line"

below is my code for async method. While sync one just has "Output.ReadToEnd()" between start/stop.

code:

        private void createOCTree()
    {
        //Create process
        var cmd = @"oconv.exe";                         //OUTPUT IS C++ binary
        var arguments = @" C:\RadianceGeometry.rad";
        var outputFile = @"C:\test.oct";
        var workingDir = m_FileData.TemporaryFilesFolder;

        ProcessStartInfo cmdStartInfo = new ProcessStartInfo();
        cmdStartInfo.RedirectStandardInput = false;
        cmdStartInfo.RedirectStandardError = false;
        cmdStartInfo.RedirectStandardOutput = true;
        cmdStartInfo.UseShellExecute = false;
        cmdStartInfo.CreateNoWindow = true;
        cmdStartInfo.FileName = cmd;                    ////file name
        cmdStartInfo.Arguments = arguments;             ////arguments
        cmdStartInfo.WorkingDirectory = @"C:\";         ////working dir

        using (StreamWriter writer = new StreamWriter("C:\\testStream.oct"))
        {
        }

        var process = new Process();
        process.StartInfo = cmdStartInfo;

        process.OutputDataReceived += new DataReceivedEventHandler(OutputHandler);
        process.Start();
        process.BeginOutputReadLine();
        process.WaitForExit();
    }

    private void OutputHandler(object sendingProcess, DataReceivedEventArgs outLine)
    {
        try
        {
            byte[] bytes = Encoding.Default.GetBytes(outLine.Data);
            byte[] newLine = Encoding.Default.GetBytes("\n");                       
            AppendData("C:\\testStream.oct", bytes);
            AppendData("C:\\testStream.oct", newLine);     ////otherwise all is in one line     
        }
        catch { }   ////possibly last line is not properly handled
    }

    private static void AppendData(string filename, byte[] bits)
    {
        using (var fileStream = new FileStream(filename, FileMode.Append, FileAccess.Write, FileShare.None))
        using (var bw = new BinaryWriter(fileStream))
        {
            bw.Write(bits);
        }
    }

my suspicion is that either I'm missing something with my "Try/Catch", or that newlines should be parsed differently. Set all paths to c:\ just to make it easier to read (instead of using variables, or actual paths).

edit:addition; I've noticed when comparing prompt output with the one from code, and they are the same, except that first char of some lines "output" is "?" instead of random "glyphs" in the working file.

edit: added comparison screen shots. code comparison:

with newline: https://ibb.co/HpztQ0Q

without newline: https://ibb.co/Lvcr9pH

Lilith5th
  • 29
  • 1
  • 5
  • There are no lines in binary data. Check file size of source and destination to see if they are same. Using Beyond Compare will help determine where differences are occurring. Never, Never ,Never use Encoding on binary data it will corrupt the data. Encoding will change and delete characters. Even UTF8 will change the character 0x80. Just save steam using BinaryWriter. – jdweng Sep 23 '19 at 11:51
  • thanx for the reply. I first tried without new line, but output seemed much more in line with the prompt result when using NL. using new line https://ibb.co/HpztQ0Q without new line https://ibb.co/Lvcr9pH The code difference is that at certain places bits get replaced with "?", and I don't know what to do about it. – Lilith5th Sep 23 '19 at 12:11
  • You can't use new line on binary. Use List and then AddRange to append data. – jdweng Sep 23 '19 at 12:25
  • tried it with list, but no major difference; https://ibb.co/Pmh1GG7 (note 156 extra bytes compared to "functioning" file) – Lilith5th Sep 23 '19 at 12:53
  • With binary any differences (even one character) is an issue. Check if the difference is with receive data or just write. – jdweng Sep 23 '19 at 13:32
  • could it be caused by carriage return type? notepad++ tells me that "prompt" file uses Unix LF, while c# output is Windows (CR LF). – Lilith5th Sep 23 '19 at 13:44
  • The only thing I know is FTP when in ASCII mode does the conversion. If using FTP then set it to binary before transfer. – jdweng Sep 23 '19 at 14:09

1 Answers1

0

the way I Got it to work is use cmd as the command, and in the argument field, I used /c" flag as described here: What does cmd /C mean?

    String exeFileName = @"cmd.exe";
    String Arguments = @"/c oconv.exe C:\test\radgeom.rad > c:\test\scene.oct"; 
Lilith5th
  • 29
  • 1
  • 5