Example #1
0
        void updateHelper_PipeServerDisconnected(object sender, UpdateHelperData e)
        {
            // wyUpdate should only ever exit after success or failure
            // otherwise it is a premature exit (and needs to be treated as an error)
            if (UpdateStepOn == UpdateStepOn.Checking ||
                UpdateStepOn == UpdateStepOn.DownloadingUpdate ||
                UpdateStepOn == UpdateStepOn.ExtractingUpdate ||
                e.UpdateStep == UpdateStep.RestartInfo)
            {
                if (e.UpdateStep == UpdateStep.RestartInfo)
                {
                    if (ClosingAborted != null)
                    {
                        ClosingAborted(this, EventArgs.Empty);
                    }

                    ClosingForInstall = false;
                }

                // wyUpdate premature exit error
                UpdateStepFailed(UpdateStepOn, new FailArgs {
                    wyUpdatePrematureExit = true, ErrorTitle = e.ExtraData[0], ErrorMessage = e.ExtraData[1]
                });
            }
        }
Example #2
0
        void SafeProcessReceivedMessage(byte[] message)
        {
            // Cast the data to the type of object we sent:
            UpdateHelperData data = UpdateHelperData.FromByteArray(message);

            if (BufferResponse)
            {
                lock (receivedBuffer)
                {
                    // only buffer important messages
                    if (data.ResponseType != Response.Progress)
                    {
                        receivedBuffer.Add(data);
                    }
                }

                // checks if we're still buffering responses, if so don't process it now
                if (BufferResponse)
                {
                    return;
                }
            }

            ProcessReceivedMessage(data);
        }
Example #3
0
        void SendAsync(UpdateHelperData uhd)
        {
            lock (_lock)
            {
                if (isDisposed)
                {
                    return;
                }

                // if currently working, add the new message to the stack
                if (bw != null)
                {
                    sendBuffer.Push(uhd);
                }
                else
                {
                    RecreateBackgroundWorker();

                    // process immediately
                    UpdateStep = uhd.UpdateStep == UpdateStep.ForceRecheckForUpdate ? UpdateStep.CheckForUpdate : uhd.UpdateStep;

                    // begin sending to the client
                    bw.RunWorkerAsync(uhd);
                }
            }
        }
Example #4
0
        public void RestartInfo(string fileToExecute, string autoUpdateID, string argumentsForFiles, bool isAService)
        {
            lock (_lock)
            {
                if (isDisposed)
                {
                    return;
                }

                UpdateHelperData uhd = new UpdateHelperData(UpdateStep.RestartInfo);

                uhd.ExtraData.Add(fileToExecute);
                uhd.ExtraDataIsRTF.Add(isAService);

                if (!string.IsNullOrEmpty(autoUpdateID))
                {
                    uhd.ExtraData.Add(autoUpdateID);
                    uhd.ExtraDataIsRTF.Add(false);

                    if (!string.IsNullOrEmpty(argumentsForFiles))
                    {
                        uhd.ExtraData.Add(argumentsForFiles);
                        uhd.ExtraDataIsRTF.Add(false);
                    }
                }

                SendAsync(uhd);
            }
        }
Example #5
0
        bool StartClient()
        {
            if (string.IsNullOrEmpty(m_CompleteWULoc))
            {
                throw new Exception("The wyUpdate executable path supplied is not valid. Make sure wyUpdate exists on disk.");
            }

            // get the unique pipe name (the last 246 chars of the complete path)
            string pipeName = UpdateHelperData.PipenameFromFilename(m_CompleteWULoc);

            // first try to connect to the pipe
            if (!pipeClient.Connected)
            {
                pipeClient.Connect(pipeName);
            }

            if (pipeClient.Connected)
            {
                // request the processId
                if (!RetrySend((new UpdateHelperData(UpdateAction.GetwyUpdateProcessID)).GetByteArray()))
                {
                    throw new Exception("Failed to get the wyUpdate Process ID.");
                }

                return(true);
            }

            if (!File.Exists(m_CompleteWULoc))
            {
                throw new Exception("The wyUpdate executable was not found: " + m_CompleteWULoc);
            }

            ClientProcess = new Process
            {
                StartInfo =
                {
                    FileName    = m_CompleteWULoc,

                    // start the client in automatic update mode (a.k.a. wait mode)
                    Arguments   = "/autoupdate",

                    WindowStyle = ProcessWindowStyle.Hidden
                }
            };

            if (!string.IsNullOrEmpty(ExtraArguments))
            {
                ClientProcess.StartInfo.Arguments += " " + ExtraArguments;
            }

            ClientProcess.Start();

            TryToConnectToPipe(pipeName);

            return(pipeClient.Connected);
        }
Example #6
0
        void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            lock (_lock)
            {
                if (isDisposed)
                {
                    return;
                }

                bw.DoWork             -= bw_DoWork;
                bw.RunWorkerCompleted -= bw_RunWorkerCompleted;
                bw.Dispose();
                bw = null;

                // error occurs when a message fails to send or wyUpdate fails to start
                if (e.Error != null)
                {
                    // if the process is running - try to kill it
                    try
                    {
                        if (ClientProcess != null && !ClientProcess.HasExited)
                        {
                            ClientProcess.Kill();
                        }
                    }
                    catch { }

                    // set the client process to null so it can be restarted
                    // when the user retries.
                    ClientProcess = null;

                    // clear the to-send stack
                    sendBuffer.Clear();

                    // inform the AutomaticUpdater that wyUpdate is no longer running
                    if (PipeServerDisconnected != null)
                    {
                        PipeServerDisconnected(this, new UpdateHelperData(Response.Failed, UpdateStep, AUTranslation.C_PrematureExitTitle, e.Error.Message));
                    }
                }
                else
                {
                    // process the next in stack
                    if (sendBuffer.Count > 0)
                    {
                        RecreateBackgroundWorker();

                        UpdateHelperData uhd = sendBuffer.Pop();
                        UpdateStep = uhd.UpdateStep;

                        // begin sending to the client
                        bw.RunWorkerAsync(uhd);
                    }
                }
            }
        }
Example #7
0
 void updateHelper_PipeServerDisconnected(object sender, UpdateHelperData e)
 {
     // wyUpdate should only ever exit after success or failure
     // otherwise it is a premature exit (and needs to be treated as an error)
     if (UpdateStepOn == UpdateStepOn.Checking ||
         UpdateStepOn == UpdateStepOn.DownloadingUpdate ||
         UpdateStepOn == UpdateStepOn.ExtractingUpdate)
     {
         // wyUpdate premature exit error
         UpdateStepFailed(UpdateStepOn, new FailArgs {
             wyUpdatePrematureExit = true, ErrorTitle = e.ExtraData[0], ErrorMessage = e.ExtraData[1]
         });
     }
 }
Example #8
0
        void SendAsync(UpdateHelperData uhd)
        {
            // if currently working, add the new message to the stack
            if (bw.IsBusy)
            {
                sendBuffer.Push(uhd);
            }
            else
            {
                // process immediately
                UpdateStep = uhd.UpdateStep == UpdateStep.ForceRecheckForUpdate ? UpdateStep.CheckForUpdate : uhd.UpdateStep;

                // begin sending to the client
                bw.RunWorkerAsync(uhd);
            }
        }
        void ProcessReceivedMessage(UpdateHelperData data)
        {
            if (data.Action == UpdateAction.GetwyUpdateProcessID)
            {
                ClientProcess = Process.GetProcessById(data.ProcessID);
                return;
            }

            if (data.Action == UpdateAction.NewWyUpdateProcess)
            {
                // disconnect from the existing pipeclient
                pipeClient.Disconnect();

                CreateNewPipeClient();

                try {
                    ClientProcess = Process.GetProcessById(data.ProcessID);
                } catch (Exception) {
                    // inform the AutomaticUpdater that wyUpdate is no longer running
                    if (PipeServerDisconnected != null)
                    {
                        PipeServerDisconnected(this, new UpdateHelperData(Response.Failed, UpdateStep, AUTranslation.C_PrematureExitTitle, "Failed to connect to the new version of wyUpdate.exe"));
                    }
                }

                TryToConnectToPipe(data.ExtraData[0]);

                // if the process is running - try to kill it
                if (!pipeClient.Connected)
                {
                    // inform the AutomaticUpdater that wyUpdate is no longer running
                    if (PipeServerDisconnected != null)
                    {
                        PipeServerDisconnected(this, new UpdateHelperData(Response.Failed, UpdateStep, AUTranslation.C_PrematureExitTitle, "Failed to connect to the new version of wyUpdate.exe"));
                    }
                }

                // begin where we left off
                // if update step == RestartInfo, we need to send the restart info as well
                if (ResendRestartInfo != null && UpdateStep == UpdateStep.RestartInfo)
                {
                    ResendRestartInfo(this, EventArgs.Empty);
                }
                else
                {
                    SendAsync(new UpdateHelperData(UpdateStep));
                }

                return;
            }

            if (data.UpdateStep != UpdateStep)
            {
                // this occurs when wyUpdate is on a separate step from the AutoUpdater

                UpdateStep prev = UpdateStep;

                // set new update step
                UpdateStep = data.UpdateStep;

                // tell AutoUpdater that the message we sent didn't respond in kind
                // e.g. we sent RestartInfo, and wyUpdate responded with DownloadUpdate
                // meaning we can't update yet, we're just begginning downloading the update
                if (UpdateStepMismatch != null)
                {
                    UpdateStepMismatch(this, data.ResponseType, prev);
                }
            }

            // wyUpdate will give us its main Window Handle so we can pass focus to it
            if (data.Action == UpdateAction.UpdateStep && data.UpdateStep == UpdateStep.RestartInfo)
            {
                ClientWindowHandleToShow = data.ProcessID;
            }

            if (data.ResponseType != Response.Nothing && ProgressChanged != null)
            {
                ProgressChanged(this, data);
            }
        }
        void StartNewSelfAndClose()
        {
            bool checkForClients = false;

            // when this function is called in the constructor
            // (i.e. before the handle for the form is created)
            // then the pipeserver will not have yet been created
            if (!updateHelper.RunningServer)
            {
                checkForClients = true;
                updateHelper.StartPipeServer(this);
            }

            Process clientProcess = new Process
            {
                StartInfo =
                {
                    FileName    = newSelfLocation,

                    //NOTE: (Very goddamn important - change this and die)
                    // Arguments must have the "clear space" before the closing quote after
                    // baseDirectory. "Why?" you ask, because Windows is the offspring
                    // of a Unicorn and an Angel. Everyone knows that Angels don't
                    // respect backslash-quote combos.
                    // And Unicorns are racists.

                    // The non-absurd reason is that if you have a baseDirectory variable with
                    // a trailing slash then a quote character adjacent to this slash (i.e.
                    // with no space between the slash and quote) the commandline args
                    // get fubar-ed. A base directory with a trailing slash is valid
                    // input, thus the slash-space-quote combo must remain.

                    // start the client in automatic update mode (a.k.a. wait mode)
                    Arguments   =
                        "-cdata:\"" + clientFileLoc + "\" -basedir:\"" + baseDirectory +
                        " \" /autoupdate /ns",

                    WindowStyle = ProcessWindowStyle.Hidden
                }
            };

            clientProcess.Start();

            if (checkForClients)
            {
                // there must be at least one client running to receive this message
                int timeSpent = 0;

                while (updateHelper.TotalConnectedClients == 0)
                {
                    // if we've already waited 30 seconds, we've wait long enough
                    // something has gone wrong with the AutomaticUpdater control
                    // no point in waiting around any longer.
                    if (timeSpent == 30000)
                    {
                        break;
                    }

                    // wait 1/3 of a second
                    timeSpent += 300;
                    Thread.Sleep(300);
                }
            }

            // tell all the clients that there's a new wyUpdate
            updateHelper.SendNewWyUpdate(UpdateHelperData.PipenameFromFilename(newSelfLocation), clientProcess.Id);

            CancelUpdate(true);
        }
Example #11
0
        void updateHelper_ProgressChanged(object sender, UpdateHelperData e)
        {
            switch (e.ResponseType)
            {
            case Response.Failed:

                // show the error icon & menu
                // and set last successful step
                UpdateStepFailed(UpdateStepToUpdateStepOn(e.UpdateStep), new FailArgs {
                    ErrorTitle = e.ExtraData[0], ErrorMessage = e.ExtraData[1]
                });

                break;

            case Response.Succeeded:

                switch (e.UpdateStep)
                {
                case UpdateStep.CheckForUpdate:

                    AutoUpdaterInfo.LastCheckedForUpdate = DateTime.Now;

                    // there's an update available
                    if (e.ExtraData.Count != 0)
                    {
                        version = e.ExtraData[0];

                        // if there are changes, save them
                        if (e.ExtraData.Count > 1)
                        {
                            changes       = e.ExtraData[1];
                            changesAreRTF = e.ExtraDataIsRTF[1];
                        }

                        // save the changes to the AutoUpdateInfo file
                        AutoUpdaterInfo.UpdateVersion          = version;
                        AutoUpdaterInfo.ChangesInLatestVersion = changes;
                        AutoUpdaterInfo.ChangesIsRTF           = changesAreRTF;
                    }
                    else
                    {
                        // Clear saved version details for cases where we're
                        // continuing an update (the version details filled
                        // in from the AutoUpdaterInfo file) however,
                        // wyUpdate reports your app has since been updated.
                        // Thus we need to clear the saved info.
                        version       = null;
                        changes       = null;
                        changesAreRTF = false;

                        AutoUpdaterInfo.ClearSuccessError();
                    }

                    break;

                case UpdateStep.DownloadUpdate:

                    UpdateStepOn = UpdateStepOn.UpdateDownloaded;

                    break;

                case UpdateStep.RestartInfo:

                    // show client & send the "begin update" message
                    updateHelper.InstallNow();

                    // close this application so it can be updated
                    // use either the custom handler or Environment.Exit();
                    if (CloseAppNow != null)
                    {
                        CloseAppNow(this, EventArgs.Empty);
                    }
                    else
                    {
                        Environment.Exit(0);
                    }

                    return;
                }

                StartNextStep(e.UpdateStep);

                break;

            case Response.Progress:

                // call the progress changed event
                if (ProgressChanged != null)
                {
                    ProgressChanged(this, e.Progress);
                }

                break;
            }
        }