首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C#和WUAPI: BeginDownload函数

C#和WUAPI: BeginDownload函数
EN

Stack Overflow用户
提问于 2011-12-08 22:45:52
回答 2查看 5.9K关注 0票数 15

首先,我没有任何面向对象编程的经验。我在学校里创建了我的VB脚本和一些Java,但仅此而已。所以我的问题很可能出在那里。尽管如此,在过去的几天里,我一直在尝试开发一个小应用程序,让我能够扫描、选择和安装Windows更新。到目前为止,我已经能够理解大多数参考资料,并在互联网上的一些帖子的帮助下,我现在可以选择和下载更新。

到目前为止,我已经能够使用以下代码下载一组更新:

代码语言:javascript
复制
UpdateCollection CurrentInstallCollection = (UpdateCollection)e.Argument;
UpdateDownloader CurrentDownloader = CurrentSession.CreateUpdateDownloader();
CurrentDownloader.Updates = CurrentInstallCollection;

它在后台工作线程中运行,并在下载完成后返回。它工作得很好,我可以看到文件系统上的更新正在下载,但实际上没有一种方法来显示应用程序中的进度。要做到这一点,有一个IDownloadJob接口,它允许我使用下载器的.BeginDownload方法。

至少我认为是UpdateSession.CreateUpdateDownloader。问题来了:我现在已经尝试了大约6个小时来让代码工作,但无论我做了什么,都没有工作。此外,互联网上关于.BeginDownload方法的信息也不多(至少看起来是这样),但我对该方法的调用不起作用:

代码语言:javascript
复制
IDownloadJob CurrentDownloadJob = CurrentDownloader.BeginDownload();

我不知道该提供什么论据。我尝试过各种方法,objects...to都没有用。完整的代码块如下所示:

代码语言:javascript
复制
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);

我在互联网上找到了一个用.BeginDownload(this, this, this)调用方法的来源,它不会在代码编辑器中报告任何错误,但可能对报告没有帮助,因为据我所知,所提供的参数是在所描述的事件发生时调用的方法(进度已更改或下载已完成)。

我也试过了,但也不起作用:

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

BeginDownload方法的详细说明:

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

WUAPI参考:

不幸的是,我不被允许发布这个链接,但是指向BeginDownload方法的链接指向相同的位置。

我知道,这是一个相当多的问题,但如果有人能给我指出正确的方向(比如传递哪些参数以及如何传递),我将非常感激。

EN

回答 2

Stack Overflow用户

发布于 2013-02-27 12:57:04

在我看来,Windows Update API (WU API Lib (WUApiLib))没有很好的文档化。搜索、下载和安装的所有任务的异步“开始”如下所示。它很难掌握,不幸的是,微软在这个阶段还没有给出任何C#代码示例。我希望我能帮助我的小应用程序。代码可以整理一下,它只是在这个阶段被黑在一起,但它服务于它的目的。您将需要一个包含四个组件的Windows窗体:

代码语言:javascript
复制
private System.Windows.Forms.TextBox textBox1;
private System.ComponentModel.BackgroundWorker EnableServicesWorker;
private System.Windows.Forms.Label toolStripStatusLabel2;
private System.Windows.Forms.Label toolStripStatusLabel1;

我的代码实现了从Microsoft网站搜索、下载和安装更新的过程的所有异步属性(抱歉,太长了):

代码语言:javascript
复制
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 ------->
票数 4
EN

Stack Overflow用户

发布于 2012-12-12 19:01:26

添加对WUApiLib的引用

代码语言:javascript
复制
 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();
    }
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8432767

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档