c# – 防止Windows 10在以编程方式更新后自动重新启动

前端之家收集整理的这篇文章主要介绍了c# – 防止Windows 10在以编程方式更新后自动重新启动前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
问题:是否有一种编程方式可以防止 Windows 10在更新后自动重启?

我们致力于在Windows中运行的“任务关键型”软件.一般情况下,如果Windows自动更新中断我们的流程是很糟糕的,因为它可能意味着报废材料中的损失(您无法停止和恢复以后,工作必须从头到尾不间断地工作).

在过去,我们能够通过让我们的软件安装程序在Windows注册表中设置一个参数(在用户安装程序的同意下)来防止在用户登录自动更新后自动重启.我们能够解决这个问题.对于自动更新,将通知用户存在需要重新启动的更新并且在准备好它时单击按钮.这适用于Windows Vista,7和8 / 8.1.但是,对于最新的Windows 10(我正在使用Creators的更新),该参数似乎不再有效,因为我观察到我的计算机经历了自动更新,我知道该注册表项已经生效.

在我的研究中,我发现似乎是一个希望的地方,可以选择一个设置,其中Windows将为用户提供安排更新的机会,而不是仅在Windows认为合适时自动执行(信息here) .但是,我不确定如何以编程方式设置Windows,以便安排更新的选项成为默认选项.

是否有一种编程方式来设置Windows 10(最好以友好的方式),以便它不会自动重启?

解决方法

尝试关闭块原因API. ShutdownBlockReasonCreate

API文档引用CD刻录作为示例,但同样适用于您的“任务关键型”过程.

Applications should call this function as they begin an operation that cannot be interrupted,such as burning a CD or DVD. When the operation has completed,call the ShutdownBlockReasonDestroy function to indicate that the system can be shut down.

请注意,该文档专门引用了用户关闭,但我不明白为什么它也不应该也适用于更新重启.

注意:记得检查功能是否成功;并在进程完成时销毁关闭原因.

根据您的评论,您似乎需要使用Windows API例程的帮助.我建议你在适当的库中声明外部函数. (但你可以毫无顾虑地在同一个单位进行测试.)

  1. function ShutdownBlockReasonCreate(hWnd: HWND; Reason: LPCWSTR): BOOL; stdcall; external user32;
  2. function ShutdownBlockReasonDestroy(hWnd: HWND): BOOL; stdcall; external user32;

以下演示了如何使用API​​.注意:注意错误检查.我已经演示了如何获取错误信息.你用它做什么取决于你.

要指出的另一个重要的事情(在评论中重复)是你不应该阻止主线程.有关详细信息,请参阅Vista here中首次引入这些更改时的Microsoft文档.

  1. procedure TForm1.JobStartClick(Sender: TObject);
  2. var
  3. LErr: Cardinal;
  4. begin
  5. ListBox1.Items.Add('Attempting to block shutdown:');
  6. if (not ShutdownBlockReasonCreate(Application.MainForm.Handle,'Super Critical Job')) then
  7. begin
  8. LErr := GetLastError;
  9. ListBox1.Items.Add('... Failed: ' + SysErrorMessage(LErr));
  10. //Probably not safe to start your job in this case,but perhaps you
  11. //choose to give it a shot anyway.
  12. Exit;
  13. end;
  14. ListBox1.Items.Add('... success');
  15.  
  16. FJobRunning := True;
  17. //Start the job.
  18. //However,NB do not run the job here.
  19. //If it takes a long time and is not asynchronous,you should probably
  20. //run your job on a separate thread. ***Do not block the main thread
  21. // otherwise Windows will still kill your app for not responding***
  22. end;
  23.  
  24. procedure TForm1.JobEndClick(Sender: TObject);
  25. var
  26. LErr: Cardinal;
  27. begin
  28. if (not FJobRunning) then Exit;
  29. //End the job.
  30. //Again,do not block the main thread,so perhaps this is rather something
  31. //to do after you already know the job is done.
  32. FJobRunning := False;
  33.  
  34. ListBox1.Items.Add('Allow shutdown');
  35. if (not ShutdownBlockReasonDestroy(Application.MainForm.Handle)) then
  36. begin
  37. LErr := GetLastError;
  38. ListBox1.Items.Add('... Failed: ' + SysErrorMessage(LErr));
  39. end;
  40. end;
  41.  
  42. //Declare the handler for the WM_QUERYENDSESSION message as follows.
  43. //procedure WMQueryEndSession(var AMsg : TWMQueryEndSession); message WM_QUERYENDSESSION;
  44. procedure TForm1.WMQueryEndSession(var AMsg: TWMQueryEndSession);
  45. begin
  46. ListBox1.Items.Add('WMQueryEndSession');
  47. if (FJobRunning) then
  48. //NB: This is very important.
  49. //You still need to confirm that your application wants to block
  50. //shutdown whenever you receive this message.
  51. AMsg.Result := 0
  52. else
  53. inherited;
  54. end;

猜你在找的C#相关文章