确定脚本是否正在隐藏运行

时间:2013-12-21 09:32:55

标签: powershell wmi powershell-v2.0 powershell-v3.0 powershell-v4.0

我正在尝试以编程方式确定.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反对???

4 个答案:

答案 0 :(得分: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样式位。因为hidden的值为零且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

答案 1 :(得分:1)

您可以通过捕获新进程来获取StartInfo属性:

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

您也可以使用Start-Process cmdlet

启动该过程并设置其StartInfo
$proc = Start-Process powershell.exe -WindowStyle Hidden -ArgumentList $myInvocation.MyCommand.Definition -Verb runas -PassThru
$proc.StartInfo.WindowStyle

答案 2 :(得分:1)

在流程中,您可以通过测试确定其是否正在运行:

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

答案 3 :(得分:1)

我创造了一个kludge,但它远非一个答案。它有一些限制,如果文件或文件夹路径包含" Hidden"它会报错。在里面。它还需要从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运行(也称为可见运行),它会生成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属性的答案感兴趣或者我们可以切换的方法。