3

Я пытаюсь программно определить, работает ли скрипт .ps1 явно или нет. Если он работает явно, он должен перезапустить себя скрытым. Если он уже скрыт, не предпринимайте никаких действий.Определить, работает ли скрипт скрытым

Проблема у меня есть цикл, где он постоянно перезагружается, потому что скрытый статус не может быть определен.

Я рассматривал как командлет get-process, так и GWMI Win32_process и не вижу ничего как свойство .visible для проверки статуса.

If ($me -eq visible ???) 
{ 
$Invisible = New-Object System.Diagnostics.ProcessStartInfo 
$Invisible.FileName = "PowerShell.exe" 
$Invisible.windowStyle ="Hidden" 
$Invisible.arguments = "$myInvocation.MyCommand.Definition" 
$Invisible.Verb = 'runas' 
[System.Diagnostics.Process]::Start($Invisible) 
} 

Любая идея, какое поле я могу, если -eq против ???

+0

или, может быть, мой вопрос, как я получаю - установите WindowStyle из работающего процесса из powershell, чтобы мне не пришлось повторно ссылаться. –

+1

Я бы использовал два сценария. Один из них был бы пусковой установкой, а другой - основным сценарием. Это значительно упростит работу, особенно для отладки. По-моему, лучше быть прямым, чем умным. Тем не менее, вам все же нужно будет определить, работает ли основной скрипт. Я бы использовал объект Семафор Windows. Но это другой вопрос, поэтому я не буду здесь отвечать. Если вы задали этот вопрос («Как определить, работает ли скрипт PowerShell»), я мог бы ответить на него. –

+0

Я специально пытаюсь избежать второго файла. –

ответ

1

Вы можете получить свойство StartInfo, захватив новый процесс:

$proc = [System.Diagnostics.Process]::Start($Invisible) 
$proc.StartInfo.WindowStyle 

Вы также могли бы начать процесс и установить его StartInfo с помощью Start-Process Командлета

$proc = Start-Process powershell.exe -WindowStyle Hidden -ArgumentList $myInvocation.MyCommand.Definition -Verb runas -PassThru 
$proc.StartInfo.WindowStyle 
+0

Я тоже не смог заставить эту работу работать, но она невидимо появляется, но WindowStyle по-прежнему возвращает «Обычный», а «Пуск» не отправил WMI полную командную строку, которая сорвала обходной путь, пришлось переходить на VBS для повторного появления. –

+0

Оба примера не удались? –

+0

Да, хотя команда говорит «Скрытый», поле данных «WindowStyle» выдает Normal при запросе. –

1

Изнутри процесса вы можете определить, работает ли оно с помощью тестирования:

(get-process -Id $PID).StartInfo.WindowStyle 
+1

Это был мой первый тест, но это не сработало для меня. –

+1

Вы правы. И это выглядит багги, как черт. – mjolinor

+0

проверяя это поле, скрытые окна экземпляры powershell.exe сообщают «Normal», я подтвердил это, запустив '(get-process -Id 2716) .StartInfo' против скрытого PID. –

1

У меня есть создал кулдж, но это далеко не ответ. У этого есть некоторые ограничения в том, что он будет ложным сообщением, если путь к файлу или папке содержит в нем «Скрытый». Он также требует вызова себя из метода vbs, потому что внутренний командлет Start-Process не сообщает о правильном wmi_win32process.commandline, как это делает vbs.shell.

If ((gwmi win32_process -filter "ProcessID=$PID" | select commandline).commandline -notmatch 'Hidden') 
{ 
$INVISIBLE = $myInvocation.MyCommand.Definition 
$COMMAND = "powershell.exe -nologo -WindowStyle Hidden -command $INVISIBLE" 
[void][System.Reflection.Assembly]::LoadWithPartialName('Microsoft.VisualBasic');[Microsoft.VisualBasic.Interaction]::Shell("$COMMAND",0) 
exit 
} 

Так что это за чтение в командной строке. На правой кнопкой мыши, запустите с помощью PowerShell (он же запустить заметно), что приводит к wmi.commandline из

"C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" "-file" "B:\INVISIBLE.ps1" 

Но когда вновь породил с помощью команды VBS мы можем вычленить информацию «Недоступен», потому что VBS хорошо играет с WMI и отправляет всю команду в значение.

powershell.exe -nologo -WindowStyle Hidden -command B:\INVISIBLE.ps1 

Все еще интересуется ответом на свойство wmi, которое мы можем прочитать или метод, который мы можем переключить.

2

Попробуйте использовать функцию user32 «IsWindowVisible»

If (-not ([System.Management.Automation.PSTypeName]'My_User32').Type) { 
Add-Type -Language CSharp -TypeDefinition @" 
    using System.Runtime.InteropServices; 
    public class My_User32 
    { 
     [DllImport("user32.dll")] 
     public static extern bool IsWindowVisible(int hwnd); 
    } 
"@ 
} 

$proc = Start-Process powershell.exe -WindowStyle Hidden -ArgumentList $myInvocation.MyCommand.Definition -Verb runas -PassThru 
If ([My_User32]::IsWindowVisible($proc.MainWindowHandle)) { 
    #Window is visible 
} 
Else { 
    #Window is not visible 
} 

Обратите внимание, что возвращаемое значение для «IsWindowVisible» не является строго логическое. Он возвращает бит стиля WS_VISIBLE в окне. Поскольку значение для скрытого значения равно нулю, а значение для видимого значения не равно нулю, оно будет работать как логическое. Но если вы хотите быть в безопасности, вы можете переписать оператор If для проверки на -ne 0, чтобы определить, видимо ли это.

Также обратите внимание на использование $ proc.MainWindowHandle. Вы не можете использовать $ proc.Handle, поскольку это не дескриптор родительского окна.

Для получения дополнительной информации о «IsWindowVisible» функции см Microsoft документации по адресу:
http://msdn.microsoft.com/en-us/library/windows/desktop/ms633530%28v=vs.85%29.aspx

Для получения дополнительной информации о оконных стилях, обратитесь к документации Microsoft по адресу:
http://msdn.microsoft.com/en-us/library/czada357.aspx