Joaolvcm
Joaolvcm

Reputation: 1993

c# 7za.exe process status

I'm running a 7za.exe process to 7zip a file like this:

ProcessStartInfo proc = new ProcessStartInfo();
proc.FileName = zip_Path;
proc.Arguments = "a -t7z ziped.7z file.bak";
proc.RedirectStandardInput = true;
proc.RedirectStandardOutput = true;
proc.UseShellExecute = false;
proc.CreateNoWindow = true;
p = Process.Start(proc); 
while (!p.HasExited)
{   
    res = p.StandardOutput.ReadLine();
    texto += "\n" + res;
}
 MessageBox.Show(texto + "\n" + "ErrorCode:" + p.ExitCode);
 p.Close();

This works fine, but when I run the 7za.exe on the console manually, I can see the zipping progress. Is there any way to output it in real time on my application?

Upvotes: 3

Views: 3029

Answers (4)

Bjørn
Bjørn

Reputation: 36

Hej, I was having the very same problem today. So here to all those searching for an answer and hitting this site (I suppose as you posted the question in 2014 you'll have no use for this information any more) here is how I got around the problem:

The core to this is that 7-Zip uses different streams to write to the output and C# only gets one of them. But you can force 7-Zip to use only one stream by using the command-line arguments

-bsp1 -bse1 -bso1

in addition to what else you need. Then just capture the percentage part like this:

private static void CreateZip(string path, string zipFilename, Action<int> onProgress) {
    Regex REX_SevenZipStatus = new Regex(@"(?<p>[0-9]+)%");

    Process p = new Process();
    p.StartInfo.FileName = "7za.exe";
    p.StartInfo.Arguments = string.Format("a -y -r -bsp1 -bse1 -bso1 {0} {1}", 
        zipFilename, path);
    p.StartInfo.UseShellExecute = false;
    p.StartInfo.RedirectStandardOutput = true;

    p.OutputDataReceived += (sender, e) => {
        if (onProgress != null) {
            Match m = REX_SevenZipStatus.Match(e.Data ?? "");
            if (m != null && m.Success) {
                int procent = int.Parse(m.Groups["p"].Value);
                onProgress(procent);
            }
        }
    };

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

This method compresses a folder into a 7-Zip file. You can use the onProgress parameter (called in another thread) to process the status - it will contain the percentage of the status.

Upvotes: 2

gizmo
gizmo

Reputation: 82

I know this is an old question but I found the answer here https://stackoverflow.com/a/4291965/4050735

Code sample from answer:

var proc = new Process {
StartInfo = new ProcessStartInfo {
    FileName = "program.exe",
    Arguments = "command line arguments to your executable",
    UseShellExecute = false,
    RedirectStandardOutput = true,
    CreateNoWindow = true
}

proc.Start();
while (!proc.StandardOutput.EndOfStream) {
    string line = proc.StandardOutput.ReadLine();
    // do something with line
}

I found that this returned every line you would normally see in the console such as each file that was compressed one at a time.

Upvotes: 2

Lummo
Lummo

Reputation: 1169

Depending on how it interacts with the console ReadLine() may not be sufficient as it will only return if a new line character is output.

7za.exe may be be manipulating the current line to display progress in which case you should be able to use Read().

If you want a better insight into what is going on with the compression you can look into using the LZMA C# SDK - check out SevenZipSharp.

Upvotes: 0

Eric
Eric

Reputation: 401

Instead of:

proc.CreateNoWindow = true;

try:

proc.WindowStyle = ProcessWindowStyle.Hidden;

Upvotes: 0

Related Questions