1

我正在编写一个程序,该程序将通过 wsusscn2.cab 在离线环境中使 Windows 更新可用。

因为我想使用异步 BeginInstall 方法获得有关更新进展情况的反馈。我看到的问题是,在 eventArgs 参数中使用相同的更新信息调用 Callback 两次,这也意味着没有报告某些更新。加倍或丢失的更新索引因运行而异。有时它甚至没有问题。

我确实做了一个简短的测试程序来玩弄东西,代码如下。该程序在装有 Windows 10 1909 的 VMWare 工作站上运行,它正在查找 Office 2010 更新,因为我有一个未更新的 Office SP2 安装可供尝试。

    static void Main(string[] args)
    {
        Console.WriteLine("Debug");
        Console.WriteLine(String.Format("Debugger is Attached:{0}", Debugger.IsAttached));

        Update();
        Console.Write("Done!");
        Console.ReadKey();
    }

    static void Update()
    {
        EventWaitHandle waitHandle = new EventWaitHandle(false, EventResetMode.ManualReset);
        OnProgressChange onProgress = new OnProgressChange(waitHandle);
        OnComplete onComplete = new OnComplete(waitHandle);
        State state = new State();

        UpdateSession session = new UpdateSession();
        UpdateServiceManager serviceManager = session.CreateUpdateServiceManager();
        IUpdateService updateService = serviceManager.AddScanPackageService("Offline Sync Service", @"C:\wsusscn2.cab",1);
        Console.WriteLine("Adding scanpackageservice complete");

        IUpdateSearcher searcher = session.CreateUpdateSearcher();
        searcher.ServerSelection = ServerSelection.ssOthers;
        searcher.ServiceID = updateService.ServiceID;
        
        ISearchResult result = searcher.Search("IsInstalled=0");
        Console.WriteLine("Search complete");

        IUpdateInstaller installer = session.CreateUpdateInstaller();
        installer.ClientApplicationID = "TEST";
        installer.Updates = new UpdateCollection();
        foreach (IUpdate update in result.Updates)
        {
            int i = installer.Updates.Add(update);
            Console.WriteLine(String.Format("{0,2} - Adding: {1}", i, update.KBArticleIDs[0]));                            
        }

        installer.ClientApplicationID = "TEST";

        IInstallationJob installationJob = installer.BeginInstall(onProgress, onComplete, state);
        waitHandle.WaitOne();
        IInstallationResult installationResult = installer.EndInstall(installationJob);
        serviceManager.RemoveService(updateService.ServiceID);
    }
}

public class State
{

}

public class OnProgressChange : IInstallationProgressChangedCallback
{
    EventWaitHandle eventWait;
    int Counter = 0;
    public OnProgressChange(EventWaitHandle handle)
    {
        eventWait = handle;
    }
    public void Invoke(IInstallationJob installationJob, IInstallationProgressChangedCallbackArgs callbackArgs)
    {
        int CurrentUpdateIndex = callbackArgs.Progress.CurrentUpdateIndex;
        Thread.Sleep(500); // Test delay
        string Title = installationJob.Updates[CurrentUpdateIndex].Title;
        string ID = installationJob.Updates[CurrentUpdateIndex].KBArticleIDs[0];
        Console.WriteLine(String.Format("Index: {0,2} - ID: {1} --- Args {2} - Control:{3}", CurrentUpdateIndex, ID, callbackArgs.Progress.CurrentUpdateIndex,Counter++==CurrentUpdateIndex));
    }
}

public class OnComplete : IInstallationCompletedCallback
{
    EventWaitHandle eventWait;
    public OnComplete(EventWaitHandle handle)
    {            
        eventWait = handle;
    }        
    public void Invoke(IInstallationJob installationJob, IInstallationCompletedCallbackArgs callbackArgs)
    {
        eventWait.Set();
        Console.WriteLine("In End");
    }
}

该程序的典型结果如下所示:

Debug
Debugger is Attached:True
Adding scanpackageservice complete
Search complete
 0 - Adding: 2850016
 1 - Adding: 2880971
 2 - Adding: 2553154
 3 - Adding: 2956076
 4 - Adding: 2920812
 5 - Adding: 2553313
 6 - Adding: 2881029
 7 - Adding: 2956063
 8 - Adding: 3114414
 9 - Adding: 3114885
10 - Adding: 3191908
11 - Adding: 3203468
12 - Adding: 3213626
13 - Adding: 3213631
14 - Adding: 4011610
15 - Adding: 3115197
16 - Adding: 3115248
17 - Adding: 4022206
18 - Adding: 4022208
19 - Adding: 3213636
20 - Adding: 3114565
21 - Adding: 2553332
22 - Adding: 4461625
23 - Adding: 4484238
24 - Adding: 4484266
25 - Adding: 4484235
26 - Adding: 4032216
27 - Adding: 3203462
28 - Adding: 4484415
29 - Adding: 4484373
30 - Adding: 4484382
31 - Adding: 4484458
Index:  0 - ID: 2850016 --- Args 0 - Control:True
Index:  1 - ID: 2880971 --- Args 1 - Control:True
Index:  2 - ID: 2553154 --- Args 2 - Control:True
Index:  3 - ID: 2956076 --- Args 3 - Control:True
Index:  4 - ID: 2920812 --- Args 4 - Control:True
Index:  5 - ID: 2553313 --- Args 5 - Control:True
Index:  6 - ID: 2881029 --- Args 6 - Control:True
Index:  7 - ID: 2956063 --- Args 7 - Control:True
Index:  8 - ID: 3114414 --- Args 8 - Control:True
Index:  9 - ID: 3114885 --- Args 9 - Control:True
Index: 11 - ID: 3203468 --- Args 11 - Control:False
Index: 11 - ID: 3203468 --- Args 11 - Control:True
Index: 13 - ID: 3213631 --- Args 13 - Control:False
Index: 13 - ID: 3213631 --- Args 13 - Control:True
Index: 15 - ID: 3115197 --- Args 15 - Control:False
Index: 15 - ID: 3115197 --- Args 15 - Control:True
Index: 17 - ID: 4022206 --- Args 17 - Control:False
Index: 17 - ID: 4022206 --- Args 17 - Control:True
Index: 18 - ID: 4022208 --- Args 18 - Control:True
Index: 20 - ID: 3114565 --- Args 20 - Control:False
Index: 20 - ID: 3114565 --- Args 20 - Control:True
Index: 22 - ID: 4461625 --- Args 22 - Control:False
Index: 22 - ID: 4461625 --- Args 22 - Control:True
Index: 24 - ID: 4484266 --- Args 24 - Control:False
Index: 24 - ID: 4484266 --- Args 24 - Control:True
Index: 25 - ID: 4484235 --- Args 25 - Control:True
Index: 26 - ID: 4032216 --- Args 26 - Control:True
Index: 27 - ID: 3203462 --- Args 27 - Control:True
Index: 28 - ID: 4484415 --- Args 28 - Control:True
Index: 29 - ID: 4484373 --- Args 29 - Control:True
Index: 30 - ID: 4484382 --- Args 30 - Control:True
Index: 31 - ID: 4484458 --- Args 31 - Control:True
In End
Done!

如您所见,updateindex 10 丢失并且 11 被报告了两次。12 和 13 也是如此。这其中有多少以及哪一个因运行而异。

我所看到的是,如果我在没有附加调试器的情况下运行,它可以在更多的测试运行中工作。如果我进行发布运行,成功率接近 100%

我希望我已经解释得足够好,并且我能得到一些帮助,因为我现在已经用完了我所有的想法。

也是我在这里的第一篇文章,所以我也很乐意对我的帖子提出一些反馈:)

4

1 回答 1

0

回调不可靠。更新完成后,您可以像这样检查要安装的更新的状态:

IInstallationProgress jobProgress = job.GetProgress();

for (int updateindex = 0; updateindex < installer.Updates.Count; updateindex++)
{
    IUpdateInstallationResult updateInstallResult = jobProgress.GetUpdateResult(updateindex);

    switch (updateInstallResult.ResultCode)
    {
        case OperationResultCode.orcNotStarted:
            // ....
            break;
        
        case OperationResultCode.orcInProgress:
            // ....
            break;
        
        case OperationResultCode.orcSucceeded:
            // ....
            break;
        
        case OperationResultCode.orcSucceededWithErrors:
            // ....
            break;
        
        case OperationResultCode.orcFailed:
            // ....
            break;
        
        case OperationResultCode.orcAborted:
            // ....
            break;
    }

}
于 2021-05-20T18:18:38.940 回答