private void Rollback(InstallLog installLog, bool deleteChangedFiles = false) { log.DebugFormat("Rolling back log extension '{0}'", this.Name); IEnumerable<InstallItem> installedItems = installLog.Items.Where(f => f.State == InstallState.Installed); foreach (InstallItem installItem in installedItems) { if (!File.Exists(installItem.Path)) { installItem.State = InstallState.UnInstalled; continue; } ExtensionFile archiveFile = this.GetArchiveFile(installItem.Path); //// CRC of the file in the current application string currentCrc = Crc32.GetHash(installItem.Path); //// CRC of the file at the time when it was installed string originalCrc = installItem.CrcCode; //// CRC of the file in the current archive string updatedCrc = archiveFile == null ? null : archiveFile.CrcCode; if (!deleteChangedFiles && (currentCrc != originalCrc && updatedCrc != null && currentCrc != updatedCrc)) { log.WarnFormat("The file '{0}' has changed since it was installed, it will not be deleted", installItem.Path); continue; } try { File.Delete(installItem.Path); installItem.State = InstallState.UnInstalled; } catch (Exception ex) { log.Error(ex); } } installLog.Result = InstallState.UnInstalled; }
private void SaveLog(InstallLog installLog) { XmlDocument logDoc = new XmlDocument(); if (File.Exists(this.InstallLogFile)) logDoc.Load(this.InstallLogFile); else logDoc.LoadXml(string.Format("<plugin name='{0}'></plugin>", this.Name)); logDoc.DocumentElement.AppendChild(installLog.ToXml(logDoc)); logDoc.Save(this.InstallLogFile); }
public void Install() { if (this.IsInstalled) this.Uninstall(); InstallLog installLog = new InstallLog(DateTime.Now); log.DebugFormat("Installation of extension '{0}' started", this.Name); FileStream fs = File.OpenRead(this.ArchiveFileName); ZipFile extensionArchive = new ZipFile(fs); string backupDirectory = this.InstallDirectory + "." + DateTime.Now.Ticks; try { foreach (ExtensionFile file in this.AssetFiles) { string childPath = file.Name; string targetDir = Path.GetDirectoryName(file.InstallPath); Directory.CreateDirectory(targetDir); InstallItem entry = installLog.AddFile(file.InstallPath); entry.CrcCode = Crc32.GetHash(extensionArchive.GetInputStream(file.Entry)); if (File.Exists(file.InstallPath)) { if (Crc32.GetHash(file.InstallPath) != entry.CrcCode) { string backupPath = Path.Combine(backupDirectory, childPath); log.WarnFormat("Extension {1}: file '{0}' seems modified, backing it up to '{2}'.", file.InstallPath, this.Name, backupPath); Directory.CreateDirectory(Path.GetDirectoryName(backupPath)); File.Copy(file.InstallPath, backupPath); } } log.DebugFormat("Extracting '{0}' to '{1}'", file.Name, file.InstallPath); file.Extract(extensionArchive, file.InstallPath); entry.State = InstallState.Installed; } if (this.ConfigurationFile != null) { this.ConfigurationFile.Extract(extensionArchive, this.ConfigurationFile.InstallPath); } installLog.Result = InstallState.Installed; } catch (Exception ex) { log.Error(ex); installLog.Error = ex; installLog.Result = InstallState.NotInstalled; this.Rollback(installLog); } finally { fs.Close(); extensionArchive.Close(); this.SaveLog(installLog); } log.DebugFormat("Installation of extension '{0}' {1}.", this.Name, installLog.Result == InstallState.Installed ? "succeeded" : "failed"); }