How do I stop a running program?

0

I have created a program that compresses files using 7z and how are several files within a loop and the program should compress 1 file at a time, I used WaitForExit()

The program works perfectly, but now I'd like to put a cancel button and I'm not getting it, as I believe that WaitForExit() will not let me click the button until the process is finished. p>

How can I make this cancel button?

My code:

foreach (string currentFile in txtFiles)
{
    game = PastaDestino + 
Path.GetFileName(currentFile).Replace(Path.GetExtension(currentFile), "") + 
".7z";
    bin = currentFile;
    cue = currentFile.Replace(Path.GetExtension(currentFile), "") + ".cue";
    command = String.Format("a -t7z \"{0}\" \"{1}\" \"{2}\" -mx=9", game, 
bin, cue);

p = new ProcessStartInfo
{
    FileName = "7z.exe",
    Arguments = command,
    WindowStyle = ProcessWindowStyle.Hidden
};

    x = Process.Start(p);
    x.WaitForExit();
}

Thank you.

    
asked by anonymous 14.05.2018 / 17:47

2 answers

2

To kill the process you can call process.Kill();

However, the trick is not to call WaitForExit since this method will wait until the process finishes and thus will block your graphical interface.

In other words, you have to subscribe to the Exited event.

Due to the operation of 7zip you have the constraint of only one process at a time to add a file to the zip file. This has implications in terms of code. You can not simply browse through the files. You have to launch the process again only when the previous process is finished.

Each time a file is added you can also have a progress bar. This progress notification mechanism will also serve to determine when the process of adding all files to the zip has completed.

In this particular algorithm I do not allow the cancellation of the process itself. I simply stop adding files to the file. What this means is if you have very large files then the cancellation will only be processed once this file is added.

One way to do this is as follows:

public partial class Form1 : Form, IProgress<int>
{
    private CancellationTokenSource _cancellation;
    public Form1()
    {
        InitializeComponent();
    }

    private void ZipFiles(IList<string> files, IProgress<int> progress, CancellationToken token)
    {
        Process Zip(string file)
        {
            var cue = Path.ChangeExtension(file, ".cue");
            var process = new Process()
            {
                EnableRaisingEvents = true,
                StartInfo = new ProcessStartInfo
                {
                    FileName = "7z.exe",
                    Arguments = $"a zip.7z {file} {cue}",
                    WindowStyle = ProcessWindowStyle.Hidden
                }
            };
            process.Start();
            return process;
        }

        var count = 0;
        void Handler(object o, EventArgs a)
        {
            var p = o as Process;
            if (_cancellation.Token.IsCancellationRequested)
            {
                return;
            }
            if (count < files.Count)
            {
                var next = Zip(files[count]);
                count++;
                next.Exited += Handler;
            }
            progress.Report(count * 100 / files.Count);
            p.Exited -= Handler;
        }
        {
            var process = Zip(files[count]);
            process.Exited += Handler;
        }
    }

    private void btnZip_Click(object sender, EventArgs e)
    {
        btnZip.Enabled = false;
        _cancellation = new CancellationTokenSource();
        var files = Directory.EnumerateFiles(@"C:\code", "*.cs", SearchOption.AllDirectories)
            .Take(100)
            .ToList();
        ZipFiles(files, this, _cancellation.Token);
    }

    private void btnCancel_Click(object sender, EventArgs e)
    {
        _cancellation.Cancel();
        progressBar.Value = 0;
        btnZip.Enabled = true;
    }

    public void Report(int value)
    {
        Invoke((Action)(() =>
        {
            progressBar.Value = value;
            if (value == 100)
            {
                btnZip.Enabled = true;
            }
        }));
    }
}

The best thing would be to get all the files you want to archive inside a structure, since 7zip allows you to archive the files of a board . That way your code would be simpler.

7z a c:\archive3.zip dir2\dir3\

But if you need different directories then the code that I provided should resolve.

    
14.05.2018 / 18:02
2
x.Close()

Always read the documentation complete when using a component.

Obviously it will only run when it is possible. The WaitForExit() will prevent anything from running until the end of the process.

Ideally when you want to do something like this is to use an API instead of launching a process that you do not have control of

    
14.05.2018 / 17:54