【问题标题】:Stop-Process vs TaskKill停止进程与 TaskKill
【发布时间】:2020-10-03 01:39:03
【问题描述】:

我正在自动刷新图标缓存,我发现TaskKillStop-Process 之间存在有趣的区别。一般来说,我更喜欢使用原生 PowerShell 而不是从 PowerShell 启动的 DOS 命令行内容,所以我宁愿使用 Stop-Process -name:explorer 而不是 Start-Process TaskKill "/f /im explorer.exe" -NoNewWindow 来停止 Explorer.exe,这样 DB 文件就不再“正在使用”并且可以被删除。 但是,前者允许 Explorer.exe 立即重新启动,因此我需要删除的图标数据库文件仍在使用中,我无法删除它们。后者真正杀死了 Explorer.exe,我必须稍后使用 Start-Process。有没有办法使用 Stop-Process 来获得 TaskKill 行为,或者这是一种罕见的情况,老派的 kludge 也是唯一有效的方法?

【问题讨论】:

  • @christian-müller,感谢您提供的链接。我觉得这不是重复的,从某种意义上说,我不想永久更改机器的配置,我只想让进程停止更长时间。但它表明这是一个使用命令行破解的地方。我可以忍受。
  • 你使用的是taskkill /force,stop-process -force怎么样?
  • 除非你需要等待,否则没有理由使用 start-process。

标签: powershell


【解决方案1】:

我做了一些研究,你最好通过发送消息来结束浏览器。

特别是针对此 WM_EXITEXPLORER (1460) 的消息,您可以告诉资源管理器关闭。

我的代码适用于 Windows 10:

$code = @'
[DllImport("user32.dll", EntryPoint = "PostMessage", CharSet =  CharSet.Unicode)] public static extern IntPtr PostMessage(IntPtr hWnd, int Msg, uint wParam, string lParam);
[DllImport("user32.dll", EntryPoint = "FindWindowW", CharSet = CharSet.Unicode)] public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
'@
$myAPI = Add-Type -MemberDefinition $code -Name myAPI -PassThru
$myAPI::PostMessage($myAPI::FindWindow("Shell_TrayWnd", $Null),1460,0,0)

Start-Sleep -Seconds 10

最好等待资源管理器窗口关闭,也许我明天会添加。现在 10 秒的等待应该足以让 explorer.exe 优雅地结束。

这完全比使用杀戮更好!

【讨论】:

  • 我在第 6 行遇到错误,在 Windows 10 上。我还没有在 Windows 7 中尝试过。
  • 请再试一次。我打错字了。请确保启动新的 ISE 或 Powershell Windows。否则 DLLImport 可能不起作用。正如所料
【解决方案2】:

默认情况下,Explorer.exe 在被Stop-Process 停止时会自动重启。这由注册表 DWORD 设置 AutoRestartShell 在键 HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon 中处理。

您当然可以通过使用

来阻止这种行为
Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" -Name "AutoRestartShell" -Value 0 -Type DWord

如果您使用的是不理解参数 -Type 的旧 PowerShell 版本,这应该可以:

[Microsoft.Win32.Registry]::SetValue("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon","AutoRestartShell",0,[Microsoft.Win32.RegistryValueKind]::DWord)

然后在您的代码中,停止探索进程,删除图标 DB 文件并再次启动进程浏览器。

通过将注册表值重置为1来完成

Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" -Name "AutoRestartShell" -Value 1 -Type DWord

【讨论】:

  • 这里的问题是,如果我的脚本在完成之前被终止,我会让机器处于与我发现它不同的状态,资源管理器不会自动启动。我宁愿不这样做,我希望 Stop-Process 允许像 TaskKill 那样的行为,重新启动会使机器保持与以前相同的状态。
【解决方案3】:

如果您只想让资源管理器保持足够长的时间以便您删除文件,只需将 stop-process 添加到 while 循环中。像这样:

While (1 -eq 1) {
    stop-process -force -name "explorer"
}

您可以在完成后按 Ctrl+C 来停止循环。

【讨论】:

  • 这似乎是一个 hacky 和手动的解决方案。阅读问题,需要一个自动化的解决方案
猜你喜欢
  • 2014-05-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-02-18
  • 2012-07-22
  • 2012-09-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多