Стоп-Процесс против TaskKill - PullRequest
       5

Стоп-Процесс против TaskKill

2 голосов
/ 08 октября 2019

Я автоматизирую обновление кэша значков и вижу интересную разницу между TaskKill и Stop-Process. В целом, я предпочитаю использовать встроенный PowerShell вместо командной строки DOS, запущенной из PowerShell, поэтому я бы предпочел использовать Stop-Process -name:explorer над Start-Process TaskKill "/f /im explorer.exe" -NoNewWindow, чтобы остановить Explorer.exe, чтобы файлы БД больше не «использовались» и могли быть удалены. Однако первый позволяет Explorer.exe перезагружаться мгновенно, поэтому файлы значков БД, которые мне нужно удалить, все еще используются, и я не могу их удалить. Последний действительно убивает Explorer.exe, и я должен использовать Start-Process позже. Есть ли способ получить поведение TaskKill с помощью Stop-Process, или это редкая ситуация, когда старое школьное замешательство также является единственным способом, который работает?

Ответы [ 2 ]

0 голосов
/ 08 октября 2019

По умолчанию 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

Если вы 'на более старой версии PowerShell, которая не понимает параметр -Type, это должно работать:

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

Затем в своем коде остановите процесс исследования, удалите файлы значков БД и снова запустите проводник процесса.

Завершите, сбросив значение реестра в 1

Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" -Name "AutoRestartShell" -Value 1 -Type DWord
0 голосов
/ 08 октября 2019

Я провел некоторое исследование, и вам лучше завершить работу проводника, отправив сообщение.

С сообщением об этом 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 завершился изящно.

Это полностью лучше, чем вообще использовать kill!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...