public async Task InstallPlugin(PluginEntry plugin, IProgress<double?> progress = null, CancellationToken cancellation = default(CancellationToken)) {
var destination = GetPluginDirectory(plugin.Id);
try {
plugin.IsInstalling = true;
var data = await CmApiProvider.GetDataAsync($"plugins/get/{plugin.Id}", progress, cancellation);
if (data == null || cancellation.IsCancellationRequested) return;
await Task.Run(() => {
if (Directory.Exists(destination)) {
FileUtils.Recycle(destination);
}
using (var stream = new MemoryStream(data, false))
using (var archive = new ZipArchive(stream)) {
archive.ExtractToDirectory(destination);
}
}, cancellation);
if (cancellation.IsCancellationRequested) return;
plugin.InstalledVersion = plugin.Version;
File.WriteAllText(Path.Combine(destination, ManifestName), JsonConvert.SerializeObject(plugin));
if (plugin.IsEnabled) {
PluginEnabled?.Invoke(this, new AppAddonEventHandlerArgs { PluginId = plugin.Id });
}
} catch (Exception e) {
NonfatalError.Notify(ToolsStrings.Plugins_CannotInstall, e);
} finally {
plugin.IsInstalling = false;
}
}