1

I'm re-writting a batch file that combined powershell and cmd commands to be strictly a powershell script, and I'm looking for a way to minimize/close the API confirmation window which pops up in the user's web browser after the application the script calls on starts.

My original batch file code looked like this using a shell object to minimize everything before moving on to the next command:

cd /d "%userprofile%\Desktop\streamblastoff\libraries\binaries\Snip"
start Snip.exe
timeout /t 1 /nobreak
powershell -command "(new-object -com shell.application).minimizeall()"

And this is what I have so far:

Push-Location -Path $PSScriptRoot\libraries\binaries\snip
Start-Process .\Snip.exe; (new-object -com shell.application).minimizeall()
Pop-Location

It doesn't work though, everything minimizes before the browser window appears ... which I guess I should have seen coming. Ideally I'd like to do it all a bit cleaner in my new script, and be able to close/minimize the specific tab once the window pops up in the users default browser, but I'm not sure if that'd be possible ...

letivalo
  • 11
  • 2

1 Answers1

0

needing to minimize a users default browser window after the first application starts

# First application. 
$bar = "powershell"

# First application starts. 
Start-Process -FilePath $bar

# Get Default Browser
$foo = Get-ItemPropertyValue -Path "Registry::HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\Shell\Associations\UrlAssociations\http\UserChoice" -Name 'ProgId' | 
  ForEach-Object {
    Get-ItemPropertyValue -Path "Registry::HKEY_CLASSES_ROOT\$_\shell\open\command" -Name '(default)'
  } | 
  ForEach-Object {
    $_ -match '^"([^"]+\.exe)"' | Out-Null 
    $matches[1]
  } | 
  ForEach-Object {
    Get-Item -Path $_
  } | 
  ForEach-Object {
    $_.BaseName
  }
# End Get Default Browser

Function minimizeProcess
{
    Param(
        [Parameter(Mandatory=$true,
        ValueFromPipeline=$true,
        HelpMessage="Input a System.Diagnostics.Process object.")]
        [System.Diagnostics.Process] $Process
    )

    Begin
    {
        # P/Invoke Definition 
        $signature = '[DllImport("user32.dll")] public static extern bool ShowWindowAsync(IntPtr hWnd, int nCmdShow);'

        # Compile new class. 
        $myType = Add-Type -MemberDefinition $signature -Name MyClass -Namespace MyNamespace -PassThru
    }

    Process
    {
        # Minimize the window. 
        # For different display actions see: 
        # https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-showwindow
        $myType::ShowWindowAsync($Process.MainWindowHandle, 7) | Out-Null
    }
}

# Minimize $foo if $bar is running. 
if ((Get-Process | ForEach-Object { $_.Name }) -contains $bar)
{
    Get-Process -Name $foo | 
      ForEach-Object {
        $process = Get-CimInstance Win32_Process -Filter "ProcessID = '$($_.Id)'"
        $owner = Invoke-CimMethod -InputObject $process -MethodName GetOwner
        Add-Member -InputObject $_ -NotePropertyName Owner -NotePropertyValue $owner.User 
        $_ 
      } | 
      # Only minimize processes that belong to the user. 
      Where-Object { $_.Owner -like $env:USERNAME } | 
      ForEach-Object {
        minimizeProcess $_
        # foo minimizes. 
      }
}



everything minimizes before the browser window appears

The error you were making was you did not copy the sleep.

Push-Location -Path $PSScriptRoot\libraries\binaries\snip

Start-Process .\Snip.exe

# timeout /t 1 /nobreak
Start-Sleep 1 

(new-object -com shell.application).minimizeall()

Pop-Location

When creating macros, you have to insert sleeps to accommodate delays in the graphical user interface.


be able to close/minimize the specific tab

  • Thank you for this very detailed response, it's provided some very helpful insights into the work I'm looking to do. However the code as it currently stands, while it completes cleanly without issue, it doesn't manage to minimize the browser window when the associated application opens. I'm unsure if there were additional steps which I needed to do to get it to work. On another note, in reference to the second half of your post: I actually originally had a 3 second sleep implemented before the shell command, and I was still dealing with everything closing. :P โ€“ letivalo Mar 09 '21 at 07:36
  • Have you updated `$bar` to point to your application? Does the running process match the name saved to `$bar`? Do the default Web browser setting and the Web browser being launched match? Does the Web browser minimize if you manually run the `# Minimize $foo ...` section? Does the Web browser process belong to the [current user](https://i.imgur.com/APGgjLs.png)? Try using `Get-Process` to identify the Web browser being used and then set `$foo` to that value. For example `get-process | select name | out-file "C:\Users\$env:USERNAME\Desktop\vynvko.txt"` and `$foo = "msedge"` โ€“  Mar 11 '21 at 06:48
  • "when the associated application opens" Your question is phrased 'do x *after* y happens' which is the question I've answered. 'Doing x *when* y happens' is a different problem. Try manually setting `$foo` and running `# Minimize $foo ...` to see if this code is working. โ€“  Mar 11 '21 at 06:55