Gianluca Administrator Posts: 1345
19 hours ago
|
Hi Space! It's simply impossible. SyMenu has an option to start a program maximized or minimized, but PAF programs use a launcher (the portabilizer), and SyMenu can't do anything beyond asking the launcher to start in a specific state. Unfortunately, apart from the splash screen, the launcher doesn't have a window and doesn't pass the request about window state to the actual program, so there's no solution.
Well, actually, there are two possible solutions... but be warned, they're not exactly simple.
1) Ask John  This is a limitation of the PAF launcher. Ideally, you should be able to run it with a command-line argument to tell it to launch the real app minimized... but I fear they haven't considered this. Try checking the documentation here to be sure: https://portableapps.com/manuals/PortableApps.comLauncher/ref/launcher.ini/launch.html Anyway, ask John, he's always super kind and might implement the feature in no time.
2) Hack it Strangely enough, I had a similar need with Firefox. I wanted Firefox to open maximized and move to my primary monitor (I use two). So I created a customizable PowerShell script, which I’ve attached below. In SyMenu, you just need to create a SyProgram where the Path is "powershell.exe" and the Arguments are: -File [full path to the PS script] -processName [name of your program] You can run it after launching Thunderbird, or use it to launch Thunderbird and minimize it directly.
Of course, feel free to modify the script however you like and maybe share it here once it's done. You could even make it non-generic by hardcoding the process name, but I kept it generic so it can be reused for other programs. Or you could add a parameter to specify whether the program should be maximized or minimized. Just my two cents for further improvements.
# -------------------------------------------------------------------------------------------------------------- # Created by : Gianluca Negrelli # Copyright : 2025.03.27 # -------------------------------------------------------------------------------------------------------------- # Maximizes the window of a process and moves it to the primary monitor, which in my # case is the one on the right. # The process name is passed without extension as an argument. E.g. firefox. # The script is used by SyMenu in the autoexec after launching certain programs. # --------------------------------------------------------------------------------------------------------------
#$processName = $args[0] # Get the process name from the command line if provided (e.g. -processName firefox). param ( [string]$processName ) # For debugging # $processName = "firefox"
# Definition of Win32 functions as a custom type. $signature = @" using System; using System.Runtime.InteropServices; public class Win32 { [DllImport("user32.dll", SetLastError = true)] public static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
[DllImport("user32.dll", SetLastError = true)] public static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags);
[DllImport("user32.dll")] public static extern bool GetWindowRect(IntPtr hWnd, out RECT lpRect);
[DllImport("user32.dll")] public static extern bool GetWindowPlacement(IntPtr hWnd, ref WINDOWPLACEMENT lpwndpl);
public const int SW_MAXIMIZE = 3; public const int SW_MINIMIZE = 6; public const int SW_RESTORE = 9; public const uint SWP_NOZORDER = 0x0004; public const uint SWP_NOACTIVATE = 0x0010; public const uint SWP_SHOWWINDOW = 0x0040;
[StructLayout(LayoutKind.Sequential)] public struct RECT { public int Left; public int Top; public int Right; public int Bottom; }
[StructLayout(LayoutKind.Sequential)] public struct WINDOWPLACEMENT { public int length; public int flags; public int showCmd; public POINT ptMinPosition; public POINT ptMaxPosition; public RECT rcNormalPosition; }
[StructLayout(LayoutKind.Sequential)] public struct POINT { public int x; public int y; } } "@
# Load the Windows Forms assembly and the custom Win32 type. Add-Type -AssemblyName System.Windows.Forms Add-Type -TypeDefinition $signature
if (-not $processName ){ Write-Host "Missing process name to search for (e.g. firefox)" return }
# Query the system to check if more than one screen is present. $screens = [System.Windows.Forms.Screen]::AllScreens
# Delay allows programs to start before performing window operations. Write-Host "Waiting 5 seconds to allow $processName to activate..." Start-Sleep -Seconds 5
# Get all processes matching the provided $processName that have a window ($_.MainWindowHandle -ne 0). $windows = Get-Process -Name $processName | Where-Object { $_.MainWindowHandle -ne 0 } foreach($window in $windows) { # Get the window handle $mainWindowHandle = $window.MainWindowHandle
# Check if the window is already on the primary screen. $screen = [System.Windows.Forms.Screen]::FromHandle($mainWindowHandle) Write-Output "The window '$($window.ProcessName)' is on screen: $($screen.DeviceName)"
if ($screens.Count -ne 1 -and $screen.DeviceName -eq "\\.\DISPLAY2") { # More than one screen is present and it's not on monitor 2, so repositioning is needed.
# If maximized, restore first because taskbar differences between screens affect sizing. $placement = New-Object Win32+WINDOWPLACEMENT $placement.length = [System.Runtime.InteropServices.Marshal]::SizeOf($placement) if ([Win32]::GetWindowPlacement($mainWindowHandle, [ref]$placement)) { if ($placement.showCmd -eq [Win32]::SW_MAXIMIZE) { # Window is maximized, needs to be restored. [Win32]::ShowWindow($mainWindowHandle, [Win32]::SW_RESTORE) } }
# Get the current rectangle of the restored window to replicate size and position on the primary screen. $rect = New-Object Win32+RECT [Win32]::GetWindowRect($mainWindowHandle, [ref]$rect)
# Calculate current width and height of the window. $width = $rect.Right - $rect.Left $height = $rect.Bottom - $rect.Top
# Calculate window position on the left monitor, assuming secondary is mapped at x = -1920 $left = $rect.Left + 1920 $top = $rect.Top
# Move the window to the primary monitor. $windowPosFlags = [Win32]::SWP_NOZORDER -bor [Win32]::SWP_NOACTIVATE -bor [Win32]::SWP_SHOWWINDOW [Win32]::SetWindowPos($mainWindowHandle, [IntPtr]::Zero, $left, $top, $width, $height, $windowPosFlags) }
# Maximize the window [Win32]::ShowWindow($mainWindowHandle, [Win32]::SW_MAXIMIZE) }
|