我正在尝试以编程方式确定.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 :(得分: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
$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属性的答案感兴趣或者我们可以切换的方法。