简体   繁体   中英

Unpacking a .cab file and then closing the running process on windows CE 6.0 with .net mobile 3.5

I have a windows CE 6.0 program that uses a .cab file for installation. it incorporates the guide from http://msdn.microsoft.com/en-us/library/aa446487.aspx to support automatic self-updates.

the program can check for updates just fine, it downloads the update like it should, but when I try to make it unpack the .cab file it just downloaded, it fails.

this is my code:

void ResponseReceived(IAsyncResult res)
{
    try
    {
        _mResp = (HttpWebResponse)_mReq.EndGetResponse(res);
    }
    catch (WebException ex)
    {
        MessageBox.Show(ex.ToString(), "Error");
        return;
    }
    // Allocate data buffer
    _dataBuffer = new byte[DataBlockSize];
    // Set up progrees bar
    _maxVal = (int)_mResp.ContentLength;
    pgbDownloadBar.Invoke(new EventHandler(SetProgressMax));
    // Open file stream to save received data
    _mFs = new FileStream(@"\Application\CCOptimizerSetup.cab",
      FileMode.Create);
    // Request the first chunk
    _mResp.GetResponseStream().BeginRead(_dataBuffer, 0, DataBlockSize,
      OnDataRead, this);
}

void OnDataRead(IAsyncResult res)
{
    // How many bytes did we get this time
    int nBytes = _mResp.GetResponseStream().EndRead(res);
    // Write buffer
    _mFs.Write(_dataBuffer, 0, nBytes);
    // Update progress bar using Invoke()
    _pbVal += nBytes;
    pgbDownloadBar.Invoke(new EventHandler(UpdateProgressValue));
    // Are we done yet?
    if (nBytes > 0)
    {
        // No, keep reading
        _mResp.GetResponseStream().BeginRead(_dataBuffer, 0,
          DataBlockSize, OnDataRead, this);
    }
    else
    {
        // Yes, perform cleanup and update UI.
        _mFs.Close();
        _mFs = null;
        Invoke(new EventHandler(AllDone));
    }
}

private void AllDone(object sender, EventArgs e)
{
    Cursor.Current = Cursors.Default;
    DialogResult dialogresult = MessageBox.Show(@"CCOptimizer has finished downloading. Open now?", "Download complete", MessageBoxButtons.OKCancel, MessageBoxIcon.Question, MessageBoxDefaultButton.Button1);
    switch (dialogresult)
    {
        case DialogResult.OK:
            Application.Exit();
            Dispose();
            Close();
            Invoke(new EventHandler(StartProcess));
            break;
        case DialogResult.Cancel:
            Form1 oForm = new Form1();
            oForm.Show();
            Hide();
            break;
    }
}

private void StartProcess(object sender, EventArgs e)
{
    Process.Start(@"\Application\CCOptimizerSetup.cab", null);
}

It doesn't work though. wherever I place the invocation of StartProcess() , either it just shuts down with no message or I get an error during unpacking that one of the files i'm trying to update is still in use. During debugging, it just stops the program. If I try on an installed version, it very briefly flashes a window, then locks up the machine with the WaitCursor rotating and needs a reboot, although it can install just fine afterwards.

How can I close the current program and open a .cab file without having to reboot the machine?

You've got a flaw in your update logic, probably that the app you want to update is the thing checking for updates (it's not entirely clear from the question, but the behavior suggest this is the case).

An application cannot directly update itself because, for what should be fairly obvious reasons, you cannot replace the assemblies that are already loaded and running.

There are, generally speaking, two ways that I have used to get around this. Both require a second executable (which in many case I already have as a watchdog app anyway).

  1. Instead of directly launching your application, launch some "updater" application first. That application can check for updates, inform the user, download, and install/overwrite the target application because it's not yet running. The updater then runs the target application when it's done, or if no update steps are required.
  2. Instead of directly launching your application, launch some "bootstrap" application first. The bootstrap looks in local temporary storage for any update files, executes them if they exist, and then runs the normal application. Have the application itself check for updates and pull them to the temporary storage location. When updates have been pulled, have it shutdown and restart the bootstrap, which then will apply the update.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM