3

我試圖以編程方式確定.ps1腳本是否運行明顯或不。如果它明顯運行,它應該重新啓動自己隱藏。如果它已經隱藏,請不要採取任何行動。確定腳本是否正在運行隱藏

我遇到的問題是一個循環,它不斷重新啓動,因爲無法確定隱藏狀態。

我一直在尋找get-process cmdlet和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

或者也許我的問題是如何獲得 - 從PowerShell中設置正在運行的進程的WindowStyle,這樣我就不必重新調用了。 –

+1

我會用兩個腳本。一個將是一個啓動器,另一個將是主要腳本。這會讓事情變得更簡單,特別是對於調試。在我看來,最好是直截了當而不是聰明。但是,您仍然需要能夠檢測主腳本是否正在運行。我會使用Windows Semaphore對象。但這是一個不同的問題,所以我不會在這裏回答。如果你問這個問題(「如何確定它運行的PowerShell腳本」),我可以回答它。 –

+0

是專門試圖避免第二個文件。 –

回答

1

你可以得到StartInfo的特性通過捕獲新工藝:

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

你也可以使用Start-Process cmdlet的

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

我不能讓這一個工作,要麼,它無形產卵,但WindowStyle仍返回「正常」和啓動過程中沒有發送WMI完整命令行這挫敗瞭解決辦法,不得不去VBS重新產卵。 –

+0

這兩個例子都失敗了? –

+0

是的,即使命令說隱藏,查詢時數據字段'WindowStyle'吐出正常。 –

1

啓動進程並設置它的StartInfo從這個過程中你可以在如果它正在運行隱藏測試:

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

這是我的第一次測試,但它不適合我。 –

+1

你說得對。這看起來像越野車。 – mjolinor

+0

檢查這個字段,隱藏的窗口powershell.exe實例報告'正常',我通過對隱藏的PID運行'(get-process -Id 2716).StartInfo'來證實這一點。 –

1

我已經創建了一個kludge,但它遠沒有答案。它有一些限制,如果文件或文件夾路徑包含「隱藏」,它將會報錯。它還需要從vbs方法調用它自己,因爲內部Start-Process cmdlet不像vbs.shell那樣報告正確的wmi_win32process.commandline

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(又名明顯運行),運行它導致的

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

一個wmi.commandline但是,當通過VBS命令重新催生了我們可以grep爲「隱藏」,因爲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

相關問題