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.