Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# and WUAPI: BeginDownload function

Tags:

c#

First things first: I have no experience in object-oriented programming, whatsoever. I created my share of VB scripts and a bit of Java in school, but that's it. So my problem most likely lies there. But nevertheless, for the past few days, I've been trying to get a little application together that allows me to scan for, select and install Windows updates. So far I've been able to understand most of the references and with the help of a few posts around the internet and I'm now at the point where I can select and download updates.

So far I've been able to download a collection of updates using the following code:

UpdateCollection CurrentInstallCollection = (UpdateCollection)e.Argument;
UpdateDownloader CurrentDownloader = CurrentSession.CreateUpdateDownloader();
CurrentDownloader.Updates = CurrentInstallCollection;

This is run in a background worker and returns once the download is done. It works just fine, I can see the updates getting downloaded on the file system but there isn't really a way to display the progress within the application. To do such a thing, there is the IDownloadJob interface that allows me to use the .BeginDownload method of the downloader.

UpdateSession.CreateUpdateDownloader I think, at least. And here comes the problem: I have now tried for about 6 hours to get the code working, but no matter what I tried nothing worked. Also, there isn't much information around on the internet about the .BeginDownload method (or at least it seems that way), but my call of the method doesn't work:

IDownloadJob CurrentDownloadJob = CurrentDownloader.BeginDownload();

I have no clue what arguments to supply. I've tried methods, objects...to no avail. The complete block of code looks like this:

UpdateCollection CurrentInstallCollection = (UpdateCollection)e.Argument;
UpdateDownloader CurrentDownloader = CurrentSession.CreateUpdateDownloader();
CurrentDownloader.Updates = CurrentInstallCollection;
IDownloadJob CurrentDownloadJob = CurrentDownloader.BeginDownload();
IDownloadProgress CurrentJobProgess = CurrentDownloadJob.GetProgress();
tbStatus.Text = Convert.ToString(CurrentJobProgess.PercentComplete);

I've found one source on the internet that called the method with .BeginDownload(this, this, this), which does not report any error in the code editor but probably won't help with reporting as it is my understanding, that the arguments supplied are the methods that are called when the described event occurs (progress has changed or the download has finished).

I also tried this, but it didn't work either:

http://social.msdn.microsoft.com/Forums/en/csharpgeneral/thread/636a8399-2bc1-46ff-94df-a58cebfe688c

A detailed description of the BeginDownload method:

http://msdn.microsoft.com/en-us/library/aa386132(v=VS.85).aspx

WUAPI Reference:

Unfortunately, I'm not allowed to post the link, but the link to the BeginDownload method goes to the same place.

I know, it's quite a bit to ask, but if someone could point me in the right direction (as in which arguments to pass and how), it'd be very much appreciated.

like image 223
Laurus Schluep Avatar asked Dec 08 '11 14:12

Laurus Schluep


People also ask

What C is used for?

C programming language is a machine-independent programming language that is mainly used to create many types of applications and operating systems such as Windows, and other complicated programs such as the Oracle database, Git, Python interpreter, and games and is considered a programming foundation in the process of ...

What is C in C language?

What is C? C is a general-purpose programming language created by Dennis Ritchie at the Bell Laboratories in 1972. It is a very popular language, despite being old. C is strongly associated with UNIX, as it was developed to write the UNIX operating system.

Is C language easy?

Compared to other languages—like Java, PHP, or C#—C is a relatively simple language to learn for anyone just starting to learn computer programming because of its limited number of keywords.

What is the full name of C?

In the real sense it has no meaning or full form. It was developed by Dennis Ritchie and Ken Thompson at AT&T bell Lab. First, they used to call it as B language then later they made some improvement into it and renamed it as C and its superscript as C++ which was invented by Dr.


2 Answers

The Windows Update API (WU API Lib (WUApiLib)) is not well documented in my opinion. The Asynchronous "Begin" of all the tasks of Search, Download and Install are shown below. Its difficult to grasp and unfortunately Microsoft have not given any C# Code samples at this stage. I hope I can help with my little app. The Code could be tidied a bit, its just hacked together at this stage but it serves its purpose. You will need a Windows Form with four components on it:

private System.Windows.Forms.TextBox textBox1;
private System.ComponentModel.BackgroundWorker EnableServicesWorker;
private System.Windows.Forms.Label toolStripStatusLabel2;
private System.Windows.Forms.Label toolStripStatusLabel1;

My Code impliments all of the async properties of the process to search, download and install updates from the Microsoft Website (Sorry its long):

using System;
using WUApiLib;
using System.Data;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Windows.Forms;
using System.ComponentModel;
using System.ServiceProcess;
using System.Collections.Generic;

namespace Windows_Update_Automation
{
    public partial class Form1 : Form
    {
        public UpdateSession UpdateSession;

        #region <------- Search Section ------->

        public IUpdateSearcher iUpdateSearcher;

        public ISearchJob iSearchJob;

        public UpdateCollection NewUpdatesCollection;

        public ISearchResult NewUpdatesSearchResult;

        #endregion <------- Search Section ------->

        #region <------- Downloader Section ------->

        public IUpdateDownloader iUpdateDownloader;

        public IDownloadJob iDownloadJob;

        public IDownloadResult iDownloadResult;

        #endregion <------- Downloader Section ------->

        #region <------- Installer Section ------->

        public IUpdateInstaller iUpdateInstaller;

        public IInstallationJob iInstallationJob;

        public IInstallationResult iInstallationResult;

        #endregion <------- Installer Section ------->

        // Declare a Delegate Type for Message Notification...
        public delegate void SendNotification();

        // Create an Instance of Delegate Type...
        public SendNotification sendNotification;

        private int count = 0;

        public int Count
        {
            get { return count; }
            set { count = value; }
        }

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            // Show - or Hide...
            this.Show();

            // Encapsulate the setTextBox1 Method in Delegate SendNotification...
            sendNotification = new SendNotification(setTextBox1);

            // Set Text Box Value...
            this.toolStripStatusLabel1.Text = "Enabling Update Services...";

            // Set Text Box Value...
            this.toolStripStatusLabel2.Text = "";

            // Lets check Windows is up to that task...
            EnableServicesWorker.RunWorkerAsync();
        }

        private void EnableServicesWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            // Get Services Collection...
            ServiceController[] serviceController;
            serviceController = ServiceController.GetServices();

            // Loop through and check for a particular Service...
            foreach (ServiceController scTemp in serviceController)
            {
                switch (scTemp.DisplayName)
                {
                    case "Windows Update":
                        RestartService(scTemp.DisplayName, 5000);
                        break;
                    case "Automatic Updates":
                        RestartService(scTemp.DisplayName, 5000);
                        break;
                    default:
                        break;
                }
            }

            // Check for iAutomaticUpdates.ServiceEnabled...
            IAutomaticUpdates iAutomaticUpdates = new AutomaticUpdates();
            if (!iAutomaticUpdates.ServiceEnabled)
            {
                iAutomaticUpdates.EnableService();
            }
        }

        private void EnableServicesWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            this.toolStripStatusLabel1.Text = "Searching for updates...";

            iUpdateSearch();
        }

        public static void RestartService(string serviceName, int timeoutMilliseconds)
        {
            ServiceController serviceController = new ServiceController(serviceName);
            try
            {
                int millisec1 = Environment.TickCount;
                TimeSpan timeout = TimeSpan.FromMilliseconds(timeoutMilliseconds);

                serviceController.Stop();
                serviceController.WaitForStatus(ServiceControllerStatus.Stopped, timeout);

                // count the rest of the timeout
                int millisec2 = Environment.TickCount;
                timeout = TimeSpan.FromMilliseconds(timeoutMilliseconds - (millisec2 - millisec1));

                serviceController.Start();
                serviceController.WaitForStatus(ServiceControllerStatus.Running, timeout);
            }
            catch
            {
                // ...
            }
        }

        #region <------- Search Methods ------->

        private void iUpdateSearch()
        {
            UpdateSession = new UpdateSession();
            iUpdateSearcher = UpdateSession.CreateUpdateSearcher();

            // Only Check Online..
            iUpdateSearcher.Online = true;

            // Begin Asynchronous IUpdateSearcher...
            iSearchJob = iUpdateSearcher.BeginSearch("IsInstalled=0 AND IsPresent=0", new iUpdateSearcher_onCompleted(this), new iUpdateSearcher_state(this));
        }

        private void iUpdateSearchComplete(Form1 mainform)
        {
            Form1 formRef = mainform;

            // Declare a new UpdateCollection and populate the result...
            NewUpdatesCollection = new UpdateCollection();
            NewUpdatesSearchResult = iUpdateSearcher.EndSearch(iSearchJob);

            Count = NewUpdatesSearchResult.Updates.Count;
            formRef.Invoke(formRef.sendNotification);

            // Accept Eula code for each update
            for (int i = 0; i < NewUpdatesSearchResult.Updates.Count; i++)
            {
                IUpdate iUpdate = NewUpdatesSearchResult.Updates[i];

                if (iUpdate.EulaAccepted == false)
                {
                    iUpdate.AcceptEula();
                }

                NewUpdatesCollection.Add(iUpdate);
            }

            foreach (IUpdate update in NewUpdatesSearchResult.Updates)
            {
                textBox1.AppendText(update.Title + Environment.NewLine);
            }

            if (NewUpdatesSearchResult.Updates.Count > 0)
            {
                iUpdateDownload();
            }
        }

        #endregion <------- Search Methods ------->

        #region <------- Downloader Methods ------->

        private void iUpdateDownload()
        {
            UpdateSession = new UpdateSession();
            iUpdateDownloader = UpdateSession.CreateUpdateDownloader();

            iUpdateDownloader.Updates = NewUpdatesCollection;
            iUpdateDownloader.Priority = DownloadPriority.dpHigh;
            iDownloadJob = iUpdateDownloader.BeginDownload(new iUpdateDownloader_onProgressChanged(this), new iUpdateDownloader_onCompleted(this), new iUpdateDownloader_state(this));
        }

        public void iDownloadComplete()
        {
            iDownloadResult = iUpdateDownloader.EndDownload(iDownloadJob);
            if (iDownloadResult.ResultCode == OperationResultCode.orcSucceeded)
            {
                this.toolStripStatusLabel1.Text = "Installing Updates...";

                iInstallation();
            }
            else
            {
                string message = "The Download has failed: " + iDownloadResult.ResultCode + ". Please check your     internet connection then Re-Start the application.";
                string caption = "Download Failed!";
                MessageBoxButtons buttons = MessageBoxButtons.OK;
                MessageBoxIcon icon = MessageBoxIcon.Error;
                MessageBox.Show(message, caption, buttons, icon);

                Application.Exit();
            }
        }

        #endregion <------- Downloader Methods ------->

        #region <------- Installation Methods ------->

        public void iInstallation()
        {
            iUpdateInstaller = UpdateSession.CreateUpdateInstaller() as IUpdateInstaller;
            iUpdateInstaller.Updates = this.NewUpdatesCollection;

            iInstallationJob = iUpdateInstaller.BeginInstall(new iUpdateInstaller_onProgressChanged(this), new iUpdateInstaller_onCompleted(this), new iUpdateInstaller_state(this));
        }

        public void iInstallationComplete()
        {
            iInstallationResult = iUpdateInstaller.EndInstall(iInstallationJob);
            if (iInstallationResult.ResultCode == OperationResultCode.orcSucceeded)
            {
                this.toolStripStatusLabel1.Text = "Installation Complete...";
            }
            else
            {
                string message = "The Installation has failed: " + iInstallationResult.ResultCode + ".";
                string caption = "DownInstallationload Failed!";
                MessageBoxButtons buttons = MessageBoxButtons.OK;
                MessageBoxIcon icon = MessageBoxIcon.Error;
                MessageBox.Show(message, caption, buttons, icon);

                Application.Exit();
            }
        }

        #endregion <------- Installation Methods ------->

        #region <------- Notification Methods ------->

        public void setTextBox1()
        {
            toolStripStatusLabel1.Text = Count + " Updates found...";
        }

        public void setTextBox1Notification(string txt)
        {
            toolStripStatusLabel1.Text = txt;
        }

        public void setTextBox2Notification(string txt)
        {
            toolStripStatusLabel2.Text = txt;
        }

        #endregion <------- Notification Methods ------->

        #region <------- iUpdateSearcher.BeginDownload Object Abstract Class's ------->
        // onCompleted [in] 
        // An ISearchCompletedCallback interface that is called when an asynchronous search operation is complete.
        public class iUpdateSearcher_onCompleted : ISearchCompletedCallback
        {
            private Form1 form1;

            public iUpdateSearcher_onCompleted(Form1 mainForm)
            {
                this.form1 = mainForm;
            }

            // Implementation of IDownloadCompletedCallback interface...
            public void Invoke(ISearchJob searchJob, ISearchCompletedCallbackArgs e)
            {
                form1.iUpdateSearchComplete(this.form1);
            }
        }

        // state [in] 
        // The caller-specific state that is returned by the AsyncState property of the ISearchJob interface.
        public class iUpdateSearcher_state
        {
            private Form1 form1;

            // Implementation of state interface...
            public iUpdateSearcher_state(Form1 mainForm)
            {
                this.form1 = mainForm;

                form1.setTextBox2Notification("State: Search Started...");
            }
        }

        #endregion <------- iUpdateSearcher.BeginDownload Object Abstract Class's ------->

        #region <------- iUpdateDownloader.BeginDownload Object Abstract Class's ------->
        // onProgressChanged [in] 
        // An IDownloadProgressChangedCallback interface that is called periodically for download progress changes before download is complete.
        public class iUpdateDownloader_onProgressChanged : IDownloadProgressChangedCallback
        {
            private Form1 form1;

            public iUpdateDownloader_onProgressChanged(Form1 mainForm)
            {
                this.form1 = mainForm;
            }

            // Implementation of IDownloadProgressChangedCallback interface...
            public void Invoke(IDownloadJob downloadJob, IDownloadProgressChangedCallbackArgs e)
            {

                decimal bDownloaded = ((e.Progress.TotalBytesDownloaded / 1024) / 1024);
                decimal bToDownloaded = ((e.Progress.TotalBytesToDownload / 1024) / 1024);
                bDownloaded = decimal.Round(bDownloaded, 2);
                bToDownloaded = decimal.Round(bToDownloaded, 2);

                form1.setTextBox1Notification("Downloading Update: "
                 + e.Progress.CurrentUpdateIndex
                 + "/"
                 + downloadJob.Updates.Count
                 + " - "
                 + bDownloaded + "Mb"
                 + " / "
                 + bToDownloaded + "Mb");
            }
        }

        // onCompleted [in] 
        // An IDownloadCompletedCallback interface (C++/COM) that is called when an asynchronous download operation is complete.
        public class iUpdateDownloader_onCompleted : IDownloadCompletedCallback
        {
            private Form1 form1;

            public iUpdateDownloader_onCompleted(Form1 mainForm)
            {
                this.form1 = mainForm;
            }

            // Implementation of IDownloadCompletedCallback interface...
            public void Invoke(IDownloadJob downloadJob, IDownloadCompletedCallbackArgs e)
            {
                form1.iDownloadComplete();
            }
        }

        // state [in] 
        // The caller-specific state that the AsyncState property of the IDownloadJob interface returns. 
        // A caller may use this parameter to attach a value to the download job object. 
        // This allows the caller to retrieve custom information about that download job object at a later time.
        public class iUpdateDownloader_state
        {
            private Form1 form1;

            // Implementation of state interface...
            public iUpdateDownloader_state(Form1 mainForm)
            {
                this.form1 = mainForm;

                form1.setTextBox2Notification("State: Download Started...");
            }
        }

        #endregion <------- iUpdateDownloader.BeginDownload Objects ------->

        #region <------- iUpdateInstaller.BeginInstall Object Abstract Class's ------->
        // onProgressChanged [in] 
        // An IDownloadProgressChangedCallback interface that is called periodically for download progress changes before download is complete.
        public class iUpdateInstaller_onProgressChanged : IInstallationProgressChangedCallback
        {
            private Form1 form1;

            public iUpdateInstaller_onProgressChanged(Form1 mainForm)
            {
                this.form1 = mainForm;
            }

            // Implementation of IDownloadProgressChangedCallback interface...
            public void Invoke(IInstallationJob iInstallationJob, IInstallationProgressChangedCallbackArgs e)
            {
                form1.setTextBox1Notification("Installing Update: "
                 + e.Progress.CurrentUpdateIndex
                 + " / "
                 + iInstallationJob.Updates.Count
                 + " - "
                 + e.Progress.CurrentUpdatePercentComplete + "% Complete");
            }
        }

        // onCompleted [in] 
        // An IDownloadCompletedCallback interface (C++/COM) that is called when an asynchronous download operation is complete.
        public class iUpdateInstaller_onCompleted : IInstallationCompletedCallback
        {
            private Form1 form1;

            public iUpdateInstaller_onCompleted(Form1 mainForm)
            {
                this.form1 = mainForm;
            }

            // Implementation of IDownloadCompletedCallback interface...
            public void Invoke(IInstallationJob iInstallationJob, IInstallationCompletedCallbackArgs e)
            {
                form1.iInstallationComplete();
            }
        }

        // state [in] 
        // The caller-specific state that the AsyncState property of the IDownloadJob interface returns. 
        // A caller may use this parameter to attach a value to the download job object. 
        // This allows the caller to retrieve custom information about that download job object at a later time.
        public class iUpdateInstaller_state
        {
            private Form1 form1;

            // Implementation of state interface...
            public iUpdateInstaller_state(Form1 mainForm)
            {
                this.form1 = mainForm;

                form1.setTextBox2Notification("State: Installation Started...");
            }
        }

#endregion <------- iUpdateInstaller.BeginInstall Objects ------->
like image 61
Rusty Nail Avatar answered Sep 28 '22 11:09

Rusty Nail


Add a reference to WUApiLib

 public UpdateSession updateSession;
 public ISearchResult searchResult;

 private void Form1_Load(object sender, EventArgs e)
    {
        //check for updates
        updateSession = new UpdateSession();
        searchResult = updateSession.CreateUpdateSearcher().Search("IsInstalled=0 and Type='Software' and IsHidden=0");


        //download updates
        UpdateDownloader downloader = updateSession.CreateUpdateDownloader();
        downloader.Updates = searchResult.Updates;
        downloader.Download();

        //collect all downloaded updates
        UpdateCollection updatesToInstall = new UpdateCollection();
        foreach (IUpdate update in searchResult.Updates)
        {
            if (update.IsDownloaded)
            {
                updatesToInstall.Add(update);
            }
        }

        //install downloaded updates
        IUpdateInstaller installer = updateSession.CreateUpdateInstaller();
        installer.Updates = updatesToInstall;
        IInstallationResult installationRes = installer.Install();
    }
like image 29
Ali Avatar answered Sep 28 '22 10:09

Ali