Подтвердить что ты не робот

С# и WUAPI: функция BeginDownload

В первую очередь: у меня нет опыта в объектно-ориентированном программировании. Я создал свою долю в сценариях VB и немного Java в школе, но это так. Так что моя проблема, скорее всего, лежит там. Но, тем не менее, за последние несколько дней я пытался собрать небольшое приложение, которое позволяет сканировать, выбирать и устанавливать обновления для Windows. До сих пор я мог понять большинство ссылок и с помощью нескольких сообщений в Интернете, и теперь я нахожусь в точке, где я могу выбирать и загружать обновления.

До сих пор мне удалось загрузить коллекцию обновлений, используя следующий код:

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 идет в том же месте.:)

Я знаю, это довольно немного, чтобы спросить, но если кто-то может указать мне в правильном направлении (как в каких аргументах пройти и как), это было бы очень признательно!:)

4b9b3361

Ответ 1

API для Windows Update API (WU API Lib (WUApiLib)), на мой взгляд, недостаточно хорошо документирован. Ниже приведена асинхронная "Начинать" всех задач поиска, загрузки и установки. Его трудно понять, и, к сожалению, на данном этапе Microsoft не выдала никаких образцов кода С#. Надеюсь, я смогу помочь с моим маленьким приложением. Кодекс можно было бы немного подобрать, его просто взломали на этом этапе, но он служит своей цели. Вам понадобится форма 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 ------->
// 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 ------->

#region <------- iUpdateDownloader.BeginDownload Object Abstract Class ------->
// 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 ------->
// 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 ------->

}
}

Ответ 2

Добавить ссылку на 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();
    }