C#和WUAPI:BeginDownload函数

第一件事:我没有面向对象编程的经验。 我在学校创建了我的VB脚本和一些Java,但就是这样。 所以我的问题很可能就在那里。 但是,在过去的几天里,我一直试图让一个小应用程序在一起,允许我扫描,选择和安装Windows更新。 到目前为止,我已经能够理解大部分参考资料,并在互联网上的一些post的帮助下,我现在可以选择和下载更新。

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

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

这在后台工作程序中运行,并在下载完成后返回。 它工作得很好,我可以看到更新下载到文件系统,但没有办法在应用程序中显示进度。 要做这样的事情,有IDownloadJob接口允许我使用下载器的.BeginDownload方法(UpdateSession.CreateUpdateDownloader)…我认为,至少。 :D这就是问题所在:我现在已经尝试了大约6个小时来使代码正常工作,但不管我做了什么都没有用。 另外,互联网上关于.BeginDownload方法的信息并不多(或者至少看起来像这样),但我对该方法的调用不起作用:

 IDownloadJob CurrentDownloadJob = CurrentDownloader.BeginDownload(); 

我不知道提供什么参数…我已经尝试过方法,对象……但无济于事。 完整的代码块如下所示:

 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方法的链接转到了同一个地方。 🙂

我知道,这有点问题,但是如果有人可以指出我正确的方向(如通过哪些参数以及如何通过),我们将非常感激! 🙂

我认为Windows Update API(WU API Lib(WUApiLib))没有详细记录。 搜索,下载和安装的所有任务的异步“开始”如下所示。 很难掌握,不幸的是微软在这个阶段没有给出任何C#代码样本。 我希望我可以帮助我的小应用程序。 该守则可以整理一下,它在这个阶段只是被黑客攻击,但它有助于它的目的。 您将需要一个包含四个组件的Windows窗体:

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

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

 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 -------> } } 

添加对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(); }