I am trying to programmatically determine if a .ps1 script is running visibly or not. If it is running visibly, it should restart itself hidden. If it is already hidden, take no action.
The problem I have is a loop where it continually restarts itself because hidden status cannot be determined.
I've been looking at both get-process cmdlet and GWMI Win32_process and see nothing like a .visible property to check status.
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)
}
Any idea what field I can If -eq against ???
You can get the StartInfo properties by capturing new the process:
You could also start the process and set its StartInfo using the
Start-Process
cmdletTry using the user32 function 'IsWindowVisible'
Note that the return value for 'isWindowVisible' isn't strictly a boolean. It returns the WS_VISIBLE style bit of a window. Because the value for hidden is zero and the value for visible is nonzero, it will work as a boolean. But if you want to be safe, you can rewrite the If statement to check for -ne 0 to determine if visible.
Also note the use of $proc.MainWindowHandle. You can't use $proc.Handle, as that is not the handle of the parent window.
For more information on the 'IsWindowVisible' function, see Microsoft documentation at:
http://msdn.microsoft.com/en-us/library/windows/desktop/ms633530%28v=vs.85%29.aspx
For more information on window styles, see Microsoft documentation at:
http://msdn.microsoft.com/en-us/library/czada357.aspx
From within the process you can deterine if it's running hidden by testing:
I've created a kludge but it is far from an answer. It has some limitations in that it will false report if the file or folder path contains "Hidden" in it. It also requires calling itself from vbs method because internal Start-Process cmdlet does not report the correct wmi_win32process.commandline like vbs.shell does.
So what it is reading in the commandline is this. On right click, run with powershell (aka run visibly) it results in a wmi.commandline of
But when re-spawned via the VBS command we can grep for 'Hidden' because VBS plays well with WMI and sends the entire command into the value.
Still interested in an answer with a wmi property we can read or method we can toggle.