Powershell 停止进程vs TaskKill

Powershell 停止进程vs TaskKill,powershell,Powershell,我正在自动刷新图标缓存,我看到TaskKill和Stop Process之间有一个有趣的区别。一般来说,我更喜欢使用本机PowerShell而不是从PowerShell启动的DOS命令行,因此我更喜欢使用停止进程-名称:explorer而不是启动进程TaskKill”/f/im explorer.exe“-nonewindow来停止explorer.exe,这样DB文件就不再“在使用”并且可以删除。 但是,前者允许Explorer.exe立即重新启动,因此我需要删除的图标DB文件仍在使用中,我无

我正在自动刷新图标缓存,我看到
TaskKill
Stop Process
之间有一个有趣的区别。一般来说,我更喜欢使用本机PowerShell而不是从PowerShell启动的DOS命令行,因此我更喜欢使用
停止进程-名称:explorer
而不是
启动进程TaskKill”/f/im explorer.exe“-nonewindow
来停止explorer.exe,这样DB文件就不再“在使用”并且可以删除。
但是,前者允许Explorer.exe立即重新启动,因此我需要删除的图标DB文件仍在使用中,我无法删除它们。后者确实会杀死Explorer.exe,我以后必须使用启动进程。有没有一种方法可以使用Stop Process获得TaskKill行为,或者这是一种罕见的情况,在这种情况下,老式的kludge也是唯一有效的方法?

我做了一些研究,您最好通过发送消息来结束explorer

使用一个消息,特别是这个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结束


这完全比使用杀戮要好

默认情况下,Explorer.exe在被
停止进程
停止时将自动重新启动。这是由注册表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
如果您使用的是较旧的PowerShell版本,而该版本不理解参数
-类型
,则此操作应能正常工作:

[Microsoft.Win32.Registry]::SetValue("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon","AutoRestartShell",0,[Microsoft.Win32.RegistryValueKind]::DWord)
然后在代码中,停止浏览进程,删除图标DB文件并再次启动process explorer

最后,将注册表值重置为
1

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

如果您只是想让资源管理器长时间处于关闭状态,以便删除文件,只需将
停止进程
添加到while循环中即可。像这样:

While(1-等式1){
停止进程-强制-名称“资源管理器”
}

完成循环后,您可以按Ctrl+C键。

@christian-müller,谢谢您的链接。我觉得这不是重复的,因为我不想永久地改变机器的配置,我只想让进程停止的时间更长。但它表明,这是一个命令行黑客的工作方式的地方。我可以接受。你正在使用taskkill/force,那么停止进程-force如何?除非你需要等待,否则没有理由使用启动进程。在Windows 10上,我在第6行遇到了一个错误。我尚未在Windows 7中尝试。请重试。我打错了一些字。请确保启动新的ISE或Powershell窗口。否则DLLImport可能无法工作。正如expacted所述,这里的问题是,如果我的脚本在完成之前终止,我将使机器处于与我发现它时不同的状态,而Explorer不会自动启动。我宁愿不这样做,我希望停止进程能够允许类似TaskKill的行为,即重新启动会使机器保持与以前相同的状态。这似乎是一个黑客和手动的解决方案。阅读这个问题,需要一个自动化的解决方案