public bool InstallPackage(string Filename, List <byte[]> CerCertificates, InstallMode Mode, bool ZipIsMetaOnly, out string ErrorText, out PKGStatus res, out PKGRecieptData Reciept, string OtherDLL = "") { ErrorText = ""; Reciept = null; PKGRunningPackageData RunningPKG; PKGRecieptData RunningReciept = new PKGRecieptData(); RunningReciept.HeaderID = "FoxRecieptScriptV1"; res = PKGStatus.Unknown; if (CerCertificates == null) { CerCertificates = new List <byte[]>(); } CerCertificates.Add(Resources.Vulpes_Main); if (InitPackageZipFile(Filename, CerCertificates, ZipIsMetaOnly, out ErrorText, out RunningPKG, OtherDLL) == false) { return(false); } RunningPKG.ApplicationPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); if (RunningPKG.ApplicationPath.EndsWith("\\") == false) { RunningPKG.ApplicationPath += "\\"; } using (FileStream ZipFile = File.Open(Filename, FileMode.Open, FileAccess.Read, FileShare.Read)) { using (ZipArchive ZipArch = new ZipArchive(ZipFile, ZipArchiveMode.Read, true, Encoding.UTF8)) { RunningReciept.scriptsource = RunningPKG.scriptsource; RunningReciept.PackageID = RunningPKG.PackageID; RunningReciept.InstalledOn = DateTime.Now; RunningReciept.Description = RunningPKG.Description; if (Mode == InstallMode.TestPackageOnly || Mode == InstallMode.ApplyUserSettingsTest) { return(true); } if (ZipIsMetaOnly == true) { if (Mode == InstallMode.Install || Mode == InstallMode.Update) { Debug.WriteLine("Cannot install/update a Meta-Package"); ErrorText = "Cannot install/update a Meta-Package"; return(false); } } try { UpdateText("Running pre install script"); PKGInstallState inst = PKGInstallState.NotSet; switch (Mode) { case InstallMode.Install: inst = PKGInstallState.Install; break; case InstallMode.Test: inst = PKGInstallState.Test; break; case InstallMode.TestPackageOnly: inst = PKGInstallState.Test; break; case InstallMode.Update: inst = PKGInstallState.Update; break; case InstallMode.UpdateTest: inst = PKGInstallState.UpdateTest; break; } res = RunningPKG.script.CheckInstallationStatus(RunningPKG, inst); if (res == PKGStatus.DependencyFailed) { RequiredDependencies = RunningPKG.script.GetDependencies(RunningPKG); ErrorText = RunningPKG.ErrorText; return(false); } if (res == PKGStatus.NotNeeded) { ErrorText = RunningPKG.ErrorText; return(true); //no installation } if (res == PKGStatus.Failed) { ErrorText = RunningPKG.ErrorText; return(false); } if (Mode == InstallMode.Test || Mode == InstallMode.UpdateTest) { ErrorText = ""; res = PKGStatus.Success; return(true); } res = RunningPKG.script.PreInstall(RunningPKG); if (res != PKGStatus.Success) { ErrorText = RunningPKG.ErrorText; return(false); } } catch (Exception ee) { Debug.WriteLine(ee.ToString()); ErrorText = "Script Error:\r\n" + ee.ToString(); return(false); } RunningReciept.CreatedFolders = new List <string>(); RunningReciept.InstalledFiles = new List <string>(); int lasterr; CommonUtilities.ResetLastError(); List <string> DeleteFiles = new List <string>(); using (TransactionScope ts = new TransactionScope(TransactionScopeOption.RequiresNew)) { Alphaleonis.Win32.Filesystem.KernelTransaction kt = new Alphaleonis.Win32.Filesystem.KernelTransaction(); lasterr = Marshal.GetLastWin32Error(); if (lasterr != 0) { ErrorText = "Cannot start transaction 0x" + lasterr.ToString("X"); return(false); } foreach (PKGFile file in RunningPKG.Files) { string fldr = Environment.ExpandEnvironmentVariables(file.FolderName); if (fldr.EndsWith("\\") == false) { fldr += "\\"; } string fullfilename = fldr + file.FileName; string renamedfile = fldr + "FOX-" + CommonUtilities.NewGUID + ".PENDING"; bool RestartMove = false; try { if (Alphaleonis.Win32.Filesystem.File.ExistsTransacted(kt, fullfilename) == true) { try { Alphaleonis.Win32.Filesystem.File.MoveTransacted(kt, fullfilename, renamedfile); lasterr = Marshal.GetLastWin32Error(); if (lasterr != 0) { string SubErr; RollbackFiles(RunningPKG, out SubErr); kt.Rollback(); ErrorText = "Cannot move file " + fullfilename + " => " + renamedfile + " 0x" + lasterr.ToString("X") + "\r\n" + SubErr; return(false); } DeleteFiles.Add(renamedfile); } catch { RestartMove = true; string tmp = fullfilename; fullfilename = renamedfile; renamedfile = tmp; } } } catch (Exception ee) { Debug.WriteLine(ee.ToString()); UpdateText("Rolling back"); string SubErr; RollbackFiles(RunningPKG, out SubErr); kt.Rollback(); ErrorText = "Move Error:\r\n" + ee.ToString() + "\r\n" + SubErr; return(false); } UpdateText("Installing " + fullfilename); try { string mkdir = Path.GetDirectoryName(fldr); if (Alphaleonis.Win32.Filesystem.Directory.ExistsTransacted(kt, mkdir) == false) { try { Alphaleonis.Win32.Filesystem.Directory.CreateDirectoryTransacted(kt, mkdir); RunningReciept.CreatedFolders.Add(fldr); //lasterr = Marshal.GetLastWin32Error(); //if (lasterr != 0) //{ // string SubErr; // RollbackFiles(RunningPKG, out SubErr); // kt.Rollback(); // ErrorText = "Cannot create folder " + mkdir + " 0x" + lasterr.ToString("X") + "\r\n" + SubErr; // return (false); //} } catch (Exception ee) { Debug.WriteLine(ee.ToString()); } } } catch (Exception ee) { Debug.WriteLine(ee.ToString()); } CommonUtilities.ResetLastError(); try { if (OutputToFile(kt, file.SrcFile, fullfilename, ZipArch, out ErrorText) == false) { UpdateText("Rolling back"); string SubErr; RollbackFiles(RunningPKG, out SubErr); kt.Rollback(); ErrorText += "\r\n" + SubErr; return(false); } } catch (Exception ee) { Debug.WriteLine(ee.ToString()); UpdateText("Rolling back"); string SubErr; RollbackFiles(RunningPKG, out SubErr); kt.Rollback(); ErrorText = "File Output Error:\r\n" + ee.ToString() + "\r\n" + SubErr; return(false); } RunningReciept.InstalledFiles.Add(RestartMove == true ? renamedfile : fullfilename); if (RestartMove == true) { try { Alphaleonis.Win32.Filesystem.File.CopyMoveCore(false, kt, renamedfile, null, true, null, Alphaleonis.Win32.Filesystem.MoveOptions.DelayUntilReboot, null, null, null, Alphaleonis.Win32.Filesystem.PathFormat.RelativePath); Alphaleonis.Win32.Filesystem.File.CopyMoveCore(false, kt, fullfilename, renamedfile, true, null, Alphaleonis.Win32.Filesystem.MoveOptions.DelayUntilReboot, null, null, null, Alphaleonis.Win32.Filesystem.PathFormat.RelativePath); lasterr = Marshal.GetLastWin32Error(); if (lasterr != 0) { string SubErr; RollbackFiles(RunningPKG, out SubErr); kt.Rollback(); ErrorText = "Cannot pending-move file " + fullfilename + " => " + renamedfile + " 0x" + lasterr.ToString("X") + "\r\n" + SubErr; return(false); } } catch (Exception ee) { Debug.WriteLine(ee.ToString()); UpdateText("Rolling back"); string SubErr; RollbackFiles(RunningPKG, out SubErr); kt.Rollback(); ErrorText = "Restart Move Error:\r\n" + ee.ToString() + "\r\n" + SubErr; return(false); } } } try { res = RunningPKG.script.PostInstall(RunningPKG); if (res != PKGStatus.Success) { ErrorText = "PostInstall failed."; UpdateText("Rolling back"); RollbackFiles(RunningPKG, out ErrorText); kt.Rollback(); return(false); } } catch (Exception ee) { Debug.WriteLine(ee.ToString()); UpdateText("Rolling back"); string SubErr; RollbackFiles(RunningPKG, out SubErr); kt.Rollback(); ErrorText = "PostInstall Script Error:\r\n" + ee.ToString() + "\r\n" + SubErr; return(false); } try { kt.Commit(); } catch (Exception ee) { Debug.WriteLine(ee.ToString()); UpdateText("Rolling back"); string SubErr; RollbackFiles(RunningPKG, out SubErr); kt.Rollback(); ErrorText = "Commit Error:\r\n" + ee.ToString() + "\r\n" + SubErr; return(false); } } if (RunningPKG.NoReciept == false) { Reciept = RunningReciept; } else { Reciept = null; } //Clean up mess here foreach (string file in DeleteFiles) { try { File.Delete(file); } catch { CommonUtilities.PendingMove(file, null); } } res = PKGStatus.Success; } } return(true); }
static int Main() { List <int> UIRunningInSession = new List <int>(); const string PackageID = "Vulpes-SDCA1-Update"; string dir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); if (dir.EndsWith("\\") == false) { dir += "\\"; } string pkgfile = dir + "agentupdate.foxpkg"; if (File.Exists(pkgfile) == false) { return(1); } PackageInstaller pkgi = new PackageInstaller(); string Error; if (pkgi.PackageInfo(pkgfile, null, out Error) == false) { FoxEventLog.WriteEventLog("Self-Update: Error reading package file " + pkgfile + ": " + Error, EventLogEntryType.Error); return(2); } if (pkgi.PackageInfoData.PackageID != PackageID) { FoxEventLog.WriteEventLog("Self-Update: PackageID mismatch on file " + pkgfile, EventLogEntryType.Error); return(3); } FileVersionInfo fv = FileVersionInfo.GetVersionInfo(dir + "FoxSDC_Agent.exe"); Int64 sdcversion = Convert.ToInt64(fv.FileBuildPart.ToString("0000") + fv.FilePrivatePart.ToString("0000")); if (pkgi.PackageInfoData.VersionID <= sdcversion) { FoxEventLog.WriteEventLog("Self-Update: Version on package is same or older than installed for file " + pkgfile + "\r\nPackage: " + pkgi.PackageInfoData.VersionID.ToString() + "\r\nProgram: " + fv.ToString(), EventLogEntryType.Error); return(4); } ServiceController svc = new ServiceController("FoxSDCA"); try { svc.Stop(); } catch { } int i = 0; do { i++; if (i > 120 * 4) { break; } svc.Refresh(); Thread.Sleep(1000); } while (svc.Status != ServiceControllerStatus.Stopped); #region Kill Processes foreach (Process proc in Process.GetProcesses()) { try { if (proc.MainModule.FileName.ToLower() == dir.ToLower() + "foxsdc_agent_ui.exe") { if (UIRunningInSession.Contains(proc.SessionId) == false) { UIRunningInSession.Add(proc.SessionId); } proc.Kill(); } } catch { } } foreach (Process proc in Process.GetProcesses()) { try { if (proc.MainModule.FileName.ToLower() == dir.ToLower() + "foxsdc_applyusersettings.exe") { proc.Kill(); } } catch { } } foreach (Process proc in Process.GetProcesses()) { try { if (proc.MainModule.FileName.ToLower() == dir.ToLower() + "foxsdc_agent.exe") { proc.Kill(); } } catch { } } #endregion FoxEventLog.WriteEventLog("Self-Update: Updating from " + pkgfile + "\r\nPackage: " + pkgi.PackageInfoData.VersionID.ToString() + "\r\nProgram: " + sdcversion.ToString(), EventLogEntryType.Information); PKGStatus status; PKGRecieptData reciept; if (pkgi.InstallPackage(pkgfile, null, PackageInstaller.InstallMode.Test, false, out Error, out status, out reciept, "FoxSDC_Selfupdate.exe") == false) { FoxEventLog.WriteEventLog("Self-Update: Error testing the package file " + pkgfile + ": " + Error, EventLogEntryType.Error); svc = new ServiceController("FoxSDCA"); svc.Start(); return(5); } if (pkgi.InstallPackage(pkgfile, null, PackageInstaller.InstallMode.Install, false, out Error, out status, out reciept, "FoxSDC_Selfupdate.exe") == false) { FoxEventLog.WriteEventLog("Self-Update: Error installing the package file " + pkgfile + ": " + Error, EventLogEntryType.Error); svc = new ServiceController("FoxSDCA"); svc.Start(); return(6); } FoxEventLog.WriteEventLog("Self-Update: Completed updating from " + pkgfile + "\r\nPackage: " + pkgi.PackageInfoData.VersionID.ToString() + "\r\nProgram: " + sdcversion.ToString(), EventLogEntryType.Information); svc = new ServiceController("FoxSDCA"); svc.Start(); try { File.Delete(pkgfile); } catch { CommonUtilities.PendingMove(pkgfile, null); } SessionStarter.StartProgramInSessions(dir.ToLower() + "foxsdc_agent_ui.exe", UIRunningInSession); return(0); }