void BlockLogOff(bool block) { logOffBlocked = block; if (block) { // prevent shutdown if (VistaTools.AtLeastVista()) { ShutdownBlockReasonCreate(Handle, clientLang.LogOffError); } // prevent the computer from going to sleep SetThreadExecutionState(EXECUTION_STATE.ES_CONTINUOUS | EXECUTION_STATE.ES_SYSTEM_REQUIRED); } else { // allow shutdown if (VistaTools.AtLeastVista()) { ShutdownBlockReasonDestroy(Handle); } // allow the computer to go to sleep SetThreadExecutionState(EXECUTION_STATE.ES_CONTINUOUS); } }
public frmFilesInUse(ClientLanguage cLang, string filename) { InitializeComponent(); clientLang = cLang; Text = clientLang.FilesInUseDialog.Title; btnCancel.Text = clientLang.CancelUpdate; FilenameInUse = filename; txtFile.Text = filename; if (VistaTools.AtLeastVista()) { try { runningProcesses = GetProcessesUsingFiles(new string[1] { filename }); } catch { } if (runningProcesses != null && runningProcesses.Count > 0) { UpdateList(); lblProc.Text = clientLang.FilesInUseDialog.SubTitle; btnCloseProc.Text = clientLang.ClosePrc; btnCloseAll.Text = clientLang.CloseAllPrc; lblProc.Visible = true; listProc.Visible = true; btnCloseAll.Visible = true; btnCloseProc.Visible = true; showingProcesses = true; chkProc = new Timer { Enabled = true, Interval = 2000 }; chkProc.Tick += chkProc_Tick; bw = new BackgroundWorker { WorkerSupportsCancellation = true }; bw.DoWork += bw_DoWork; bw.RunWorkerCompleted += bw_RunWorkerCompleted; bw.RunWorkerAsync(); } } SetStyle(ControlStyles.UserPaint | ControlStyles.ResizeRedraw | ControlStyles.AllPaintingInWmPaint | ControlStyles.OptimizedDoubleBuffer, value: true); UpdateSizes(); }
bool NeedElevationToUpdate() { // if only updating local user files, no elevation is needed if (IsAdmin || OnlyUpdatingLocalUser()) { return(false); } // UAC Shield on next button for Windows Vista+ if (VistaTools.AtLeastVista()) { VistaTools.SetButtonShield(btnNext, true); } return(true); }
void bw_DoWorkPreExecute(object sender, DoWorkEventArgs e) { // simply update the progress bar to show the 3rd step is entirely complete bw.ReportProgress(0, new object[] { GetRelativeProgess(3, 0), 0, string.Empty, ProgressStatus.None, null }); List <UninstallFileInfo> rollbackCOM = new List <UninstallFileInfo>(); Exception except = null; for (int i = 0; i < UpdtDetails.UpdateFiles.Count; i++) { bool unregister = (UpdtDetails.UpdateFiles[i].RegisterCOMDll & (COMRegistration.UnRegister | COMRegistration.PreviouslyRegistered)) != 0; // skip non-executing files, skip execute "after" updates if ((!UpdtDetails.UpdateFiles[i].Execute || !UpdtDetails.UpdateFiles[i].ExBeforeUpdate) && !unregister) { continue; } // form the absolute path of the file to execute or unregister string fullFile = FixUpdateDetailsPaths(UpdtDetails.UpdateFiles[i].RelativePath); if (string.IsNullOrEmpty(fullFile)) { continue; } if (!unregister) { try { // we only support starting non-elevated on Vista+ // And the user must be an admin (otherwise starting as the same elevation as wyUpdate is ample) if (UpdtDetails.UpdateFiles[i].ElevationType == ElevationType.NotElevated && IsAdmin && VistaTools.AtLeastVista()) { int exitCode = (int)LimitedProcess.Start(fullFile, string.IsNullOrEmpty(UpdtDetails.UpdateFiles[i].CommandLineArgs) ? null : ParseText(UpdtDetails.UpdateFiles[i].CommandLineArgs), false, UpdtDetails.UpdateFiles[i].WaitForExecution, UpdtDetails.UpdateFiles[i].ProcessWindowStyle); // if we're rolling back on non-zero return codes, the return code is non-zero, and it's not in the exception list if (UpdtDetails.UpdateFiles[i].RollbackOnNonZeroRet && exitCode != 0 && (UpdtDetails.UpdateFiles[i].RetExceptions == null || !UpdtDetails.UpdateFiles[i].RetExceptions.Contains(exitCode))) { except = new Exception("\"" + fullFile + "\" returned " + exitCode + "."); break; } } else // Same as wyUpdate or elevated { ProcessStartInfo psi = new ProcessStartInfo { FileName = fullFile, WindowStyle = UpdtDetails.UpdateFiles[i].ProcessWindowStyle }; // command line arguments if (!string.IsNullOrEmpty(UpdtDetails.UpdateFiles[i].CommandLineArgs)) { psi.Arguments = ParseText(UpdtDetails.UpdateFiles[i].CommandLineArgs); } // only elevate if the current process isn't already elevated if (!IsAdmin && UpdtDetails.UpdateFiles[i].ElevationType == ElevationType.Elevated) { psi.Verb = "runas"; psi.ErrorDialog = true; psi.ErrorDialogParentHandle = MainWindowHandle; } //start the process Process p = Process.Start(psi); if (UpdtDetails.UpdateFiles[i].WaitForExecution && p != null) { p.WaitForExit(); // if we're rolling back on non-zero return codes, the return code is non-zero, and it's not in the exception list if (UpdtDetails.UpdateFiles[i].RollbackOnNonZeroRet && p.ExitCode != 0 && (UpdtDetails.UpdateFiles[i].RetExceptions == null || !UpdtDetails.UpdateFiles[i].RetExceptions.Contains(p.ExitCode))) { except = new Exception("\"" + psi.FileName + "\" returned " + p.ExitCode + "."); break; } } } } catch (Exception ex) { // failure when executing the file except = new Exception("Failed to execute the file \"" + fullFile + "\": " + ex.Message, ex); break; } } else // unregistering DLL { try { RegisterDllServer(fullFile, true); // add to the rollback list rollbackCOM.Add(new UninstallFileInfo { Path = fullFile, RegisterCOMDll = COMRegistration.Register }); } catch (Exception ex) { except = ex; break; } } } // save rollback info RollbackUpdate.WriteRollbackCOM(Path.Combine(TempDirectory, "backup\\unreggedComList.bak"), rollbackCOM); if (IsCancelled() || except != null) { // rollback unregged COM bw.ReportProgress(1, false); RollbackUpdate.RollbackUnregedCOM(TempDirectory); // rollback stopped services RollbackUpdate.RollbackStoppedServices(TempDirectory); bw.ReportProgress(0, new object[] { -1, -1, string.Empty, ProgressStatus.Failure, except }); } else { // registry modification completed sucessfully bw.ReportProgress(0, new object[] { -1, -1, string.Empty, ProgressStatus.Success, null }); } }
public frmMain(string[] args) { //sets to SegoeUI on Vista Font = SystemFonts.MessageBoxFont; // check if user is an admin for windows 2000+ IsAdmin = VistaTools.IsUserAnAdmin(); InitializeComponent(); //enable Lazy SSL for all downloads FileDownloader.SetupSaneDownloadOptions(); //resize the client so its client region = 500x360 if (ClientRectangle.Width != 500) { Width = (Width - ClientRectangle.Width) + 500; } if (ClientRectangle.Height != 360) { Height = (Height - ClientRectangle.Height) + 360; } //add the panelDisplaying to form panelDisplaying.TabIndex = 0; Controls.Add(panelDisplaying); try { //process commandline argument Arguments commands = new Arguments(args); ProcessArguments(commands); // load the self update information if (!string.IsNullOrEmpty(selfUpdateFileLoc)) { //Note: always load the selfupdate data before the automatic update data LoadSelfUpdateData(selfUpdateFileLoc); ConfigureProxySettings(); //TODO: wyUp 3.0: excise this hack //if the loaded file is from RC1, then update self and bail out if (selfUpdateFromRC1) { //install the new client, and relaunch it to continue the update if (needElevation && NeedElevationToUpdate()) { //the user "elevated" as a non-admin user //warn the user of their idiocy error = clientLang.AdminError; //set to false so new client won't be launched in frmMain_Load() selfUpdateFromRC1 = false; ShowFrame(Frame.Error); } else { needElevation = false; FileAttributes atr = File.GetAttributes(oldSelfLocation); bool resetAttributes = (atr & FileAttributes.Hidden) != 0 || (atr & FileAttributes.ReadOnly) != 0 || (atr & FileAttributes.System) != 0; // remove the ReadOnly & Hidden atributes temporarily if (resetAttributes) { File.SetAttributes(oldSelfLocation, FileAttributes.Normal); } //Install the new client File.Copy(newSelfLocation, oldSelfLocation, true); if (resetAttributes) { File.SetAttributes(oldSelfLocation, atr); } //Relaunch self in OnLoad() } //bail out return; } } else // not self-updating { ConfigureProxySettings(); } //Load the client information if (clientFileType == ClientFileType.PreRC2) { //TODO: wyUp 3.0: stop supporting old client files (barely anyone uses RC2). update.OpenObsoleteClientFile(clientFileLoc); } else { update.OpenClientFile(clientFileLoc, clientLang, forcedLanguageCulture, updatePathVar, customUrlArgs); } clientLang.SetVariables(update.ProductName, update.InstalledVersion); } catch (Exception ex) { clientLang.SetVariables(update.ProductName, update.InstalledVersion); error = "Client file failed to load. The client.wyc file might be corrupt."; errorDetails = ex.Message; ShowFrame(Frame.Error); return; } //sets up Next & Cancel buttons SetButtonText(); //set header alignment, etc. panelDisplaying.HeaderImageAlign = update.HeaderImageAlign; if (update.HeaderTextIndent >= 0) { panelDisplaying.HeaderIndent = update.HeaderTextIndent; } panelDisplaying.HideHeaderDivider = update.HideHeaderDivider; // set the if (update.CustomWyUpdateTitle != null) { Text = update.CustomWyUpdateTitle; } try { if (!string.IsNullOrEmpty(update.HeaderTextColorName)) { panelDisplaying.HeaderTextColor = Color.FromName(update.HeaderTextColorName); } } catch { } //load the Side/Top images panelDisplaying.TopImage = update.TopImage; panelDisplaying.SideImage = update.SideImage; if (isAutoUpdateMode) { try { // create the temp folder where we'll store the updates long term if (tempDirectory == null) { tempDirectory = CreateAutoUpdateTempFolder(); } } catch (Exception ex) { error = clientLang.GeneralUpdateError; errorDetails = "Failed to create the automatic updater temp folder: " + ex.Message; ShowFrame(Frame.Error); return; } try { // load the previous auto update state from "autoupdate" LoadAutoUpdateData(); ConfigureProxySettings(); } catch { startStep = UpdateStepOn.Checking; } } else if (SelfUpdateState == SelfUpdateState.FullUpdate) { try { // load the server file for MinClient needed details (i.e. failure case) ServerFile = ServerFile.Load(serverFileLoc, updatePathVar, customUrlArgs); //load the self-update server file LoadClientServerFile(); clientLang.NewVersion = SelfServerFile.NewVersion; } catch (Exception ex) { error = clientLang.ServerError; errorDetails = ex.Message; ShowFrame(Frame.Error); return; } if (needElevation && NeedElevationToUpdate()) { //the user "elevated" as a non-admin user //warn the user of their idiocy error = clientLang.AdminError; ShowFrame(Frame.Error); } else { needElevation = false; //begin updating the product ShowFrame(Frame.InstallUpdates); } } //continuing from elevation or self update (or both) else if (SelfUpdateState == SelfUpdateState.ContinuingRegularUpdate) { try { //load the server file (without filling the 'changes' box & without downloading the wyUpdate Server file) LoadServerFile(false); } catch (Exception ex) { error = clientLang.ServerError; errorDetails = ex.Message; ShowFrame(Frame.Error); return; } if (needElevation && NeedElevationToUpdate()) { // the user "elevated" as a non-admin user // warn the user of their idiocy error = clientLang.AdminError; ShowFrame(Frame.Error); } else { needElevation = false; //begin updating the product ShowFrame(Frame.InstallUpdates); } } else if (!uninstalling) { startStep = UpdateStepOn.Checking; } }
void StartSelfElevated() { ProcessStartInfo psi = new ProcessStartInfo { ErrorDialog = true, ErrorDialogParentHandle = Handle }; if (SelfUpdateState == SelfUpdateState.WillUpdate) { //create the filename for the newly copied client psi.FileName = Path.Combine(tempDirectory, Path.GetFileName(VersionTools.SelfLocation)); //copy self to the temp folder File.Copy(VersionTools.SelfLocation, psi.FileName, true); } else if (SelfUpdateState == SelfUpdateState.FullUpdate) { //launch the newly updated self psi.FileName = oldSelfLocation; } else if (isAutoUpdateMode) { psi.FileName = IsNewSelf ? newSelfLocation : oldSelfLocation; // oldSelfLocation is null when elevation is needed, but no self update is taking place if (string.IsNullOrEmpty(psi.FileName)) { psi.FileName = VersionTools.SelfLocation; } } else { psi.FileName = VersionTools.SelfLocation; } if (needElevation) { // elevate to administrator psi.Verb = "runas"; // check if UAC is enabled on the computer, if not throw an error bool canUAC = false; try { if (VistaTools.AtLeastVista()) { using (RegistryKey key = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System")) { // see if UAC is enabled if (key != null) { canUAC = (int)key.GetValue("EnableLUA", null) != 0; } } } else { // Assume XP / 2000 limited user can use the RunAs box // this may or may not be true. //TODO: make this more robust // see: http://www.windowsnetworking.com/kbase/WindowsTips/Windows2003/AdminTips/Admin/DisablingtheRunAsCommand.html canUAC = true; } } catch { } if (!canUAC) { //TODO: use a more specific error to tell the user // to re-enable UAC on their computer. error = clientLang.AdminError; ShowFrame(Frame.Error); return; } } try { string selfUpdatePath = Path.Combine(tempDirectory, "selfUpdate.sup"); // write necessary info (base/temp dirs, new client files, etc.) to a file SaveSelfUpdateData(selfUpdatePath); psi.Arguments = "-supdf:\"" + selfUpdatePath + "\""; if (IsNewSelf) { psi.Arguments += " /ns"; } Process.Start(psi); Close(); } catch (Exception ex) { // the process couldn't be started. This happens for 1 of 3 reasons: // 1. The user cancelled the UAC box // 2. The limited user tried to elevate to an Admin that has a blank password // 3. The limited user tries to elevate as a Guest account error = clientLang.AdminError; errorDetails = ex.Message; ShowFrame(Frame.Error); } }
public frmFilesInUse(ClientLanguage cLang, string filename) { InitializeComponent(); clientLang = cLang; // translate the buttons & text Text = clientLang.FilesInUseDialog.Title; btnCancel.Text = clientLang.CancelUpdate; FilenameInUse = filename; txtFile.Text = filename; if (VistaTools.AtLeastVista()) { // get the list of processes using the file try { runningProcesses = GetProcessesUsingFiles(new[] { filename }); } catch { } if (runningProcesses != null && runningProcesses.Count > 0) { UpdateList(); // translate the items lblProc.Text = clientLang.FilesInUseDialog.SubTitle; btnCloseProc.Text = clientLang.ClosePrc; btnCloseAll.Text = clientLang.CloseAllPrc; // show the list box of the running processes lblProc.Visible = true; listProc.Visible = true; btnCloseAll.Visible = true; btnCloseProc.Visible = true; showingProcesses = true; chkProc = new Timer { Enabled = true, Interval = 2000 }; chkProc.Tick += chkProc_Tick; bw = new BackgroundWorker { WorkerSupportsCancellation = true }; bw.DoWork += bw_DoWork; bw.RunWorkerCompleted += bw_RunWorkerCompleted; //begin checking the for the filenames bw.RunWorkerAsync(); } } SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.OptimizedDoubleBuffer | ControlStyles.ResizeRedraw | ControlStyles.UserPaint, true); // position all the components UpdateSizes(); }
void bw_DoWorkOptimizeExecute(object sender, DoWorkEventArgs e) { // simply update the progress bar to show the 6th step is entirely complete bw.ReportProgress(0, new object[] { GetRelativeProgess(6, 0), 0, string.Empty, ProgressStatus.None, null }); List <UninstallFileInfo> rollbackCOM = new List <UninstallFileInfo>(); List <string> startedServices = new List <string>(); Exception except = null; //optimize everything but "temp" files for (int i = 0; i < UpdtDetails.UpdateFiles.Count; i++) { if (UpdtDetails.UpdateFiles[i].IsNETAssembly || (UpdtDetails.UpdateFiles[i].RegisterCOMDll & COMRegistration.Register) == COMRegistration.Register) { if (IsCancelled()) { break; } //if not a temp file if (UpdtDetails.UpdateFiles[i].RelativePath.Length >= 4 && UpdtDetails.UpdateFiles[i].RelativePath.Substring(0, 4) != "temp") { //optimize (ngen) the file string filename = FixUpdateDetailsPaths(UpdtDetails.UpdateFiles[i].RelativePath); if (UpdtDetails.UpdateFiles[i].IsNETAssembly) { //TODO: add proper rolling back of newly NGENed files if (!string.IsNullOrEmpty(filename)) { NGenInstall(filename, UpdtDetails.UpdateFiles[i]); //optimize the file } } else { try { RegisterDllServer(filename, false); // add to the rollback list rollbackCOM.Add(new UninstallFileInfo { Path = filename, RegisterCOMDll = COMRegistration.UnRegister }); } catch (Exception ex) { except = ex; break; } } } } } RollbackUpdate.WriteRollbackCOM(Path.Combine(TempDirectory, "backup\\reggedComList.bak"), rollbackCOM); bw.ReportProgress(0, new object[] { GetRelativeProgess(6, 50), 50, string.Empty, ProgressStatus.None, null }); if (!IsCancelled() && except == null) { // execute files for (int i = 0; i < UpdtDetails.UpdateFiles.Count; i++) { // skip non-executing files, skip execute "before" updates if (!UpdtDetails.UpdateFiles[i].Execute || UpdtDetails.UpdateFiles[i].ExBeforeUpdate) { continue; } // form the absolute path of the file to execute string fileToExec = FixUpdateDetailsPaths(UpdtDetails.UpdateFiles[i].RelativePath); if (string.IsNullOrEmpty(fileToExec)) { continue; } try { // we only support starting non-elevated on Vista+ // And the user must be an admin (otherwise starting as the same elevation as wyUpdate is ample) if (UpdtDetails.UpdateFiles[i].ElevationType == ElevationType.NotElevated && IsAdmin && VistaTools.AtLeastVista()) { int exitCode = (int)LimitedProcess.Start(fileToExec, string.IsNullOrEmpty(UpdtDetails.UpdateFiles[i].CommandLineArgs) ? null : ParseText(UpdtDetails.UpdateFiles[i].CommandLineArgs), false, UpdtDetails.UpdateFiles[i].WaitForExecution, UpdtDetails.UpdateFiles[i].ProcessWindowStyle); // if we're rolling back on non-zero return codes, the return code is non-zero, and it's not in the exception list if (UpdtDetails.UpdateFiles[i].RollbackOnNonZeroRet && exitCode != 0 && (UpdtDetails.UpdateFiles[i].RetExceptions == null || !UpdtDetails.UpdateFiles[i].RetExceptions.Contains(exitCode))) { except = new Exception("\"" + fileToExec + "\" returned " + exitCode + "."); break; } } else { ProcessStartInfo psi = new ProcessStartInfo { FileName = fileToExec, WindowStyle = UpdtDetails.UpdateFiles[i].ProcessWindowStyle }; // command line arguments if (!string.IsNullOrEmpty(UpdtDetails.UpdateFiles[i].CommandLineArgs)) { psi.Arguments = ParseText(UpdtDetails.UpdateFiles[i].CommandLineArgs); } // only elevate if the current process isn't already elevated if (!IsAdmin && UpdtDetails.UpdateFiles[i].ElevationType == ElevationType.Elevated) { psi.Verb = "runas"; psi.ErrorDialog = true; psi.ErrorDialogParentHandle = MainWindowHandle; } // start the process Process p = Process.Start(psi); if (UpdtDetails.UpdateFiles[i].WaitForExecution && p != null) { p.WaitForExit(); // if we're rolling back on non-zero return codes, the return code is non-zero, and it's not in the exception list if (UpdtDetails.UpdateFiles[i].RollbackOnNonZeroRet && p.ExitCode != 0 && (UpdtDetails.UpdateFiles[i].RetExceptions == null || !UpdtDetails.UpdateFiles[i].RetExceptions.Contains(p.ExitCode))) { except = new Exception("\"" + psi.FileName + "\" returned " + p.ExitCode + "."); break; } } } } catch (Exception ex) { // failure when executing the file except = new Exception("Failed to execute the file \"" + fileToExec + "\": " + ex.Message, ex); break; } } } if (!IsCancelled() && except == null) { try { // try to start services foreach (StartService service in UpdtDetails.ServicesToStart) { // skip the start service if it will be started as part of the auto-update process if (SkipStartService != null && string.Compare(SkipStartService, service.Name, StringComparison.OrdinalIgnoreCase) == 0) { continue; } using (ServiceController srvc = new ServiceController(service.Name)) { ServiceControllerStatus status = srvc.Status; if (status != ServiceControllerStatus.Running) { if (service.Arguments != null) { // parse the arguments for variables for (int i = 0; i < service.Arguments.Length; i++) { service.Arguments[i] = ParseText(service.Arguments[i]); } // start the service with the arguments srvc.Start(service.Arguments); } else // no arguments { srvc.Start(); } // report that we're waiting for the service to start so the user knows what's going on bw.ReportProgress(0, new object[] { GetRelativeProgess(6, 50), 50, "Waiting for service to start: " + srvc.DisplayName, ProgressStatus.None, null }); //TODO: periodically check if the user has cancelled -- for services that fail to start //srvc.WaitForStatus(ServiceControllerStatus.Running, TimeSpan.FromSeconds(5)); srvc.WaitForStatus(ServiceControllerStatus.Running); startedServices.Add(service.Name); } } } } catch (Exception ex) { except = ex; } // save rollback info RollbackUpdate.WriteRollbackServices(Path.Combine(TempDirectory, "backup\\startedServices.bak"), startedServices); } if (IsCancelled() || except != null) { // tell the main window we're rolling back registry bw.ReportProgress(1, true); // rollback started services RollbackUpdate.RollbackStartedServices(TempDirectory); // rollback newly regged COM dlls RollbackUpdate.RollbackRegedCOM(TempDirectory); // rollback the registry RollbackUpdate.RollbackRegistry(TempDirectory); //rollback files bw.ReportProgress(1, false); RollbackUpdate.RollbackFiles(TempDirectory, ProgramDirectory); // rollback unregged COM RollbackUpdate.RollbackUnregedCOM(TempDirectory); // rollback stopped services RollbackUpdate.RollbackStoppedServices(TempDirectory); bw.ReportProgress(0, new object[] { -1, -1, string.Empty, ProgressStatus.Failure, except }); } else { bw.ReportProgress(0, new object[] { -1, -1, string.Empty, ProgressStatus.Success, null }); } }