I have a VB application, which starts several instances of a third party non-GUI application. To keep track of these multiple instances, I update their title, using the SetWindowText()
function. This application however has the nasty habit of continuously updating the title, so each SetWindowText works only temporary. As soon as you click anywhere in the screen, the tile is changed back.
I found a way to update the title through PowerShell, using the following code:
$titletext = "My Title"
# Start a thread job to change the window title to $titletext
$null = Start-ThreadJob { param( $rawUI, $windowTitle )
Start-Sleep -s 2
if ( $rawUI.WindowTitle -ne $windowTitle ) {
$rawUI.WindowTitle = $windowTitle
}
}-ArgumentList $host.ui.RawUI, $titletext
& 'c:\Program Files\Application\Application.exe' '-id=userid -pass=password'
This works perfectly and the title change is permanent, so exactly what I want. The only problem is that everything is being logged in the Windows PowerShell log, including the parameters -id= and -pass=. A solution would be if I can start application.exe through my VB application and do the rename through a PowerShell script, but I don't know if that is possible through a ThreadJob. Is it possible to start a ThreadJob and rename another window, maybe through it's handle?
Changing the console title from inside that console is your best bet, which is what your PowerShell code does.
While it is possible to call the SetWindowText()
API function to set another process' console-window title, this change isn't guaranteed to stay in effect, because any subsequent interaction with such a window causes the original window title to be restored (this behavior seems to be built into conhost.exe
, the console host underlying regular console windows on Windows).
By contrast, setting the title of the console window associated with the current process, does stay in effect (unless overridden again later), which is what the SetConsoleWindow()
WinAPI function does (which shell- and API-based mechanisms such as title
in cmd.exe
, and [Console]::Title
/ $hostUI.RawUI.WindowTitle
in PowerShell presumably ultimately call).
Therefore, stick with your PowerShell approach and avoid the password-logging problem with the help of an environment variable, as detailed below.
Windows PowerShell's script-block logging - see about_Logging - logs the source code of code being created.
Therefore:
Make your VB.NET application (temporarily) set an environment variable that contains the password. (Perhaps needless to say, storing and passing plain-text passwords is best avoided).
In your PowerShell script, refer to that environment variable instead of passing a literal password - that way, the actual password will not be shown in the logs.
For example, assuming that your VB.NET application has created environment variable MYPWD
containing the password, before launching the PowerShell script:
$titletext = "My Title"
# Start a thread job to change the window title to $titletext
$null = Start-ThreadJob { param( $rawUI, $windowTitle )
Start-Sleep -s 2
if ( $rawUI.WindowTitle -ne $windowTitle ) {
$rawUI.WindowTitle = $windowTitle
}
} -ArgumentList $host.ui.RawUI, $titletext
# Note:
# * Assumes that your VB.NET application has set env. var. "MYPWD".
# * The arguments must be passed *individually*, not inside a single string.
& 'c:\Program Files\Application\Application.exe' -id=userid "-pass=$env:MYPWD"