topbanner_forum
  *

avatar image

Welcome, Guest. Please login or register.
Did you miss your activation email?

Login with username, password and session length
  • Friday April 19, 2024, 6:50 pm
  • Proudly celebrating 15+ years online.
  • Donate now to become a lifetime supporting member of the site and get a non-expiring license key for all of our programs.
  • donate

Author Topic: RunInTrayMod 1.33  (Read 16956 times)

MilesAhead

  • Supporting Member
  • Joined in 2009
  • **
  • Posts: 7,736
    • View Profile
    • Donate to Member
RunInTrayMod 1.33
« on: November 26, 2011, 05:40 PM »
RunInTrayMod 1.33 I found an AutoIt3 utility to run a client app minimized to tray here:

http://www.cellswort...ed/96-runintray.html

(It seems the above link may be dead. I got a 404.  But I will leave it struck out in case it is
just a network glitch.  I want to credit the original author if possible.)

I made several modifications and included a tool to generate a shortcut from the client app's shortcut.  The shortcut generator optionally runs the client to capture the exact window title for inclusion in the shortcut.

I call my mod RunInTrayMod.  The modified version with shortcut generator may be downloaded here:

http://www.milesaheadsoftware.org/

Since AutoIt3 creates a Tray Icon by default, RunInTray substituted the icon from the client exe for it's own tray icon.  Double clicking the tray icon toggled show/hide of the client app.  The program depended on the Window Title for all window manipulation.


RunInTrayMod is set up to toggle window hide/show just by left clicking the Tray Icon.

RunInTrayMod gets the title in most cases from the executable process
name. Once the client window is recognized, a window handle is stored
for window manipulations. This allows the window caption to change
without breaking the connection to the window.  Also windows are
closed rather than killed. Less chance of lost data.

Another modification is the short name to the client application is
associated with the tray icon as a ToolTip. For example if Notepad.exe
is the client, hovering the mouse on the tray icon should show "notepad"
in the ToolTip.

Note that if you have several Trayed shortcuts in StartUp Folder it may be advisable to space them out with a startup delay utility. A lot of window creation goes on at logon. A client app that minimized to tray fine when tested alone may have problems with window detection or hiding on startup.  Spacing out the opens and using exact window titles should minimize(pun intended) errors.

Also not every app is compatible. Some will leave orphaned Taskbar icons after being hidden etc..  Some apps such as DVD Flick that have a splash screen may work if the exact window title is specified during shortcut creation.  Otherwise what you get is toggle of the splash screen show/hide. :)

I recommend putting a shortcut to StartMinShortcut shortcut generator in your SendTo Folder.  That way you may right click on any app shortcut and select it from SendTo rather than the tedious process of navigating with the FileOpenDialog.
« Last Edit: April 30, 2015, 04:19 PM by MilesAhead »

MilesAhead

  • Supporting Member
  • Joined in 2009
  • **
  • Posts: 7,736
    • View Profile
    • Donate to Member
Re: RunInTrayMod 1.0
« Reply #1 on: November 27, 2011, 07:41 PM »
I didn't update the version number.  But I added a call to EmptyWorkingSet() every minute in the idle loop. It seems to cut down the memory shown in Task Manager to less than a MB. Should be acceptable for running several apps Trayed.

Stoic Joker

  • Honorary Member
  • Joined in 2008
  • **
  • Posts: 6,646
    • View Profile
    • Donate to Member
Re: RunInTrayMod 1.0
« Reply #2 on: November 28, 2011, 07:11 AM »
I added a call to EmptyWorkingSet() every minute in the idle loop.

It's my understanding that calling that excessively can actually hamper performance. I generally only use it after completing some operation that required the application to allocate resources it otherwise wouldn't need to run/function. Like after closing a settings dialog. It could also mask a resource leak that could/should be fixed (not saying you have one as I've never even seen the application in question - I'm just sort of pondering this aloud).

Hopefully someone like f0dder will correct me if I'm off in the weeds here ... I just thought the ^question^ might help.

MilesAhead

  • Supporting Member
  • Joined in 2009
  • **
  • Posts: 7,736
    • View Profile
    • Donate to Member
Re: RunInTrayMod 1.0
« Reply #3 on: November 28, 2011, 12:15 PM »
What "performance" are you referring to and what is "excessively?"

RunInTrayMod sleeps in a loop. There is no performance. Only memory usage.  Try running something trayed and watching in Task Manager rather than making theoretical objections and you may see for yourself.

MilesAhead

  • Supporting Member
  • Joined in 2009
  • **
  • Posts: 7,736
    • View Profile
    • Donate to Member
Re: RunInTrayMod 1.1
« Reply #4 on: December 02, 2011, 04:56 PM »
RunInTrayMod 1.1.0.0 Added optional -d=n delay param. Valid range is 1 to 60 seconds. 0 for no delay.  The shortcut generator pops up an input box for the delay value, then offers to run the client app to get the window title.

I tried using WinPatrol delay start but it just ran RunInTrayMod.exe with no params.
The delay just uses a call to Sleep(). In the interim you'll see the default AutoIt icon in the tray.  After launching the client the tray icon is replaced by the client's icon.

Running RunInTrayMod with no params shows a usage dialog.  But if you use the shortcut generator all that is handled for you.

MilesAhead

  • Supporting Member
  • Joined in 2009
  • **
  • Posts: 7,736
    • View Profile
    • Donate to Member
Re: RunInTrayMod 1.1
« Reply #5 on: December 10, 2011, 02:37 PM »
Here's the source to RunInTrayMod condensed to a single file. I used Obfuscator to eliminate the include files:

RunInTrayMod.au3

#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_UseUpx=n
#AutoIt3Wrapper_Res_Fileversion=1.2.0.0
#AutoIt3Wrapper_Res_Language=1033
#AutoIt3Wrapper_Res_Field=Productname|RunInTrayMod
#AutoIt3Wrapper_Res_Field=Productversion|1.2
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****


; RunInTrayMod - modified version of RunInTray utility found here:
; http://www.cellsworth.com/news/computer-related/35-uncategorizied/96-runintray.html
;
; The main modification to RunInTray is on detection of the window.
; A handle is obtained and used in Hide Show and Close operations.
; This way the client may change window caption and still respond
; to Hide, Show, and Close commands.
;
; Also Close is used instead of Kill to close the client app.
;
Global Const $__WINVER = __Ver()
Global Const $TRAY_EVENT_PRIMARYUP = -8
Global Const $tagPOINT = "long X;long Y"
Global Const $tagGUID = "dword Data1;word Data2;word Data3;byte Data4[8]"
Global Const $HGDI_ERROR = Ptr(-1)
Global Const $INVALID_HANDLE_VALUE = Ptr(-1)
Global Const $KF_EXTENDED = 0x0100
Global Const $KF_ALTDOWN = 0x2000
Global Const $KF_UP = 0x8000
Global Const $LLKHF_EXTENDED = BitShift($KF_EXTENDED, 8)
Global Const $LLKHF_ALTDOWN = BitShift($KF_ALTDOWN, 8)
Global Const $LLKHF_UP = BitShift($KF_UP, 8)
Global Const $tagNOTIFYICONDATA = 'dword Size;hwnd hWnd;uint ID;uint Flags;uint CallbackMessage;ptr hIcon;wchar Tip[128];dword State;dword StateMask;wchar Info[256];uint Version;wchar InfoTitle[64];dword InfoFlags;'
Global Const $tagPRINTDLG = 'align 2;dword_ptr Size;hwnd hOwner;ptr hDevMode;ptr hDevNames;hwnd hDC;dword Flags;ushort FromPage;ushort ToPage;ushort MinPage;ushort MaxPage;' & __Iif(@AutoItX64, 'uint', 'ushort') & ' Copies;ptr hInstance;lparam lParam;ptr PrintHook;ptr SetupHook;ptr PrintTemplateName;ptr SetupTemplateName;ptr hPrintTemplate;ptr hSetupTemplate;'

AutoItSetOption("WinTitleMatchMode", -3)
AutoItSetOption("TrayOnEventMode", 1) ; Use event trapping for tray menu
AutoItSetOption("TrayMenuMode", 3) ; Default tray menu items will not be shown.

Const $delayMin = 1, $delayMax = 60
; call EmptyWorkingSet once a minute
Const $MemCountMax = 60

Global $Dir = "", $App = "", $handle = 0, $title = "", $memCount = 0, $delay = 0, $hasDelay = False

$iMsg = "Usage: " & @CRLF & @CRLF & "RunInTrayMod [ -d=n ] ProgramPath WorkingDir [ WindowTitle ]" & @CRLF
$iMsg &= "    (  -d=n is seconds delay : Valid range for n is " & $delayMin & " to " & $delayMax & "  )" & @CRLF & @CRLF
$iMsg &= "If any params contain space(s) wrap them in double quotes" & @CRLF & @CRLF
$iMsg &= "If App will not go to Tray specify exact Window Title as last param" & @CRLF & @CRLF
$iMsg &= "( If App leaves Icon in Taskbar when Trayed, it is not compatible )"

Switch $CmdLine[0]

Case 4
If Not StringInStr($CmdLine[1], "-d=") Then _ShowUsage($iMsg)
$delay = Number(StringMid($CmdLine[1], 4))
If $delay < $delayMin Or $delay > $delayMax Then $delay = 0
$App = $CmdLine[2]
$Dir = $CmdLine[3]
$title = $CmdLine[4]

Case 3
If StringInStr($CmdLine[1], "-d=") Then
$delay = Number(StringMid($CmdLine[1], 4))
If $delay < $delayMin Or $delay > $delayMax Then $delay = 0
$App = $CmdLine[2]
$Dir = $CmdLine[3]
Else
$App = $CmdLine[1]
$Dir = $CmdLine[2]
$title = $CmdLine[3]
EndIf

Case 2
If StringInStr($CmdLine[1], "-d=") Then _ShowUsage($iMsg)
$App = $CmdLine[1]
$Dir = $CmdLine[2]

Case Else
_ShowUsage($iMsg)

EndSwitch

$proc_Name = _FileNoPath($App)
$do_Kill = True

While $delay
TraySetToolTip(String($delay) & " Sec. to Launch " & _FileBaseName($App))
Sleep(1000)
$delay -= 1
WEnd

ShellExecute($App, "", $Dir)
Sleep(1000)
If $title <> "" Then
$handle = WinWait($title, "", 4)
If $handle = 0 Then
_ShowError("Could not get Handle for Window:" & @CRLF & @CRLF & $title)
EndIf
EndIf
If $handle = 0 Then
$handle = WinGetHandle(_WinGetByPID($proc_Name))
If $handle = "" Then
$iMsg = "Could Not Get Handle To: " & $proc_Name & @CRLF & @CRLF
$iMsg &= "Try adding Window Title to Command Line or Shortcut Target line"
_ShowError($iMsg)
EndIf
EndIf

TraySetIcon($App)
TraySetClick(8)
$hTray_Show_Item = TrayCreateItem("Hide")
$hTray_Donate_Item = TrayCreateItem("Donate")
TrayCreateItem("")
TrayCreateItem("Exit")
TrayItemSetOnEvent(-1, "On_Exit")
TrayItemSetOnEvent($hTray_Show_Item, "To_Tray")
TrayItemSetOnEvent($hTray_Donate_Item, "Donate")
TraySetOnEvent($TRAY_EVENT_PRIMARYUP, "To_Tray")
TraySetToolTip(_FileBaseName($App))
To_Tray()

While 1
Sleep(1000)
If Not ProcessExists($proc_Name) Then
$do_Kill = False
Exit
EndIf
$memCount += 1
If $memCount >= $MemCountMax Then
_ReduceMemory()
$memCount = 0
EndIf
WEnd

Func On_Exit()
If $do_Kill Then WinClose(_WinAPI_GetWindowText($handle))
Exit
EndFunc   ;==>On_Exit

Func To_Tray()

If TrayItemGetText($hTray_Show_Item) = "Hide" Then
_WinAPI_ShowWindow($handle, @SW_HIDE)
TrayItemSetText($hTray_Show_Item, "Show")
Else
_WinAPI_ShowWindow($handle, @SW_SHOW)
TrayItemSetText($hTray_Show_Item, "Hide")
EndIf

EndFunc   ;==>To_Tray

Func Donate()
ShellExecute("http://www.favessoft.com/donate.html")
EndFunc   ;==>Donate

;--------------  Helper Functions Stripped from Includes  ------------

Func _WinAPI_GetWindowText($hWnd)
Local $aResult = DllCall("user32.dll", "int", "GetWindowTextW", "hwnd", $hWnd, "wstr", "", "int", 4096)
If @error Then Return SetError(@error, @extended, "")
Return SetExtended($aResult[0], $aResult[2])
EndFunc   ;==>_WinAPI_GetWindowText

Func _WinAPI_ShowWindow($hWnd, $iCmdShow = 5)
Local $aResult = DllCall("user32.dll", "bool", "ShowWindow", "hwnd", $hWnd, "int", $iCmdShow)
If @error Then Return SetError(@error, @extended, False)
Return $aResult[0]
EndFunc   ;==>_WinAPI_ShowWindow

Func __Iif($fTest, $iTrue, $iFalse)
If $fTest Then
Return $iTrue
Else
Return $iFalse
EndIf
EndFunc   ;==>__Iif

Func __Ver()
Local $tOSVI, $Ret
$tOSVI = DllStructCreate('dword Size;dword MajorVersion;dword MinorVersion;dword BuildNumber;dword PlatformId;wchar CSDVersion[128]')
DllStructSetData($tOSVI, 'Size', DllStructGetSize($tOSVI))
$Ret = DllCall('kernel32.dll', 'int', 'GetVersionExW', 'ptr', DllStructGetPtr($tOSVI))
If (@error) Or (Not $Ret[0]) Then
Return SetError(1, 0, 0)
EndIf
Return BitOR(BitShift(DllStructGetData($tOSVI, 'MajorVersion'), -8), DllStructGetData($tOSVI, 'MinorVersion'))
EndFunc   ;==>__Ver

Func _WinVersion($retAsString = 0)
Local $dwVersion = DllCall("kernel32.dll", "dword", "GetVersion")
Local $versionStr = String(BitAND($dwVersion[0], 0x00FF))
$versionStr &= "." & String(BitShift(BitAND($dwVersion[0], 0xFF00), 8))
If $retAsString Then Return $versionStr
Return Number($versionStr)
EndFunc   ;==>_WinVersion

Func _ReduceMemory($i_PID = -1)
If _WinVersion() < 5 Then Return False
If $i_PID <> -1 Then
Local $ai_Handle = DllCall("kernel32.dll", 'int', 'OpenProcess', 'int', 0x1f0fff, 'int', False, 'int', $i_PID)
Local $ai_Return = DllCall("psapi.dll", 'int', 'EmptyWorkingSet', 'long', $ai_Handle[0])
DllCall('kernel32.dll', 'int', 'CloseHandle', 'int', $ai_Handle[0])
Else
Local $ai_Return = DllCall("psapi.dll", 'int', 'EmptyWorkingSet', 'long', -1)
EndIf
Return $ai_Return[0]
EndFunc   ;==>_ReduceMemory

Func _FileBaseName($path)
If $path = "" Then Return ""
If StringLen($path) < 3 Then Return ""
Local $pos = StringInStr($path, "\", 0, -1)
$pos += 1
Local $tmp = StringMid($path, $pos)
Return StringLeft($tmp, StringInStr($tmp, ".", 0, -1) - 1)
EndFunc   ;==>_FileBaseName

Func _FileNoPath($path)
Return StringMid($path, StringInStr($path, "\", 0, -1) + 1)
EndFunc   ;==>_FileNoPath

Func _ScriptBaseName()
Return StringLeft(@ScriptName, (StringInStr(@ScriptName, ".") - 1))
EndFunc   ;==>_ScriptBaseName

Func _ShowError($errorMsg, $title = "", $quit = True, $timeOut = 0)
If $title = "" Then $title = _ScriptBaseName()
MsgBox(0x1010, $title, $errorMsg, $timeOut)
If $quit Then Exit
EndFunc   ;==>_ShowError

Func _ShowUsage($usageMsg, $title = "", $quit = True, $timeOut = 0)
If $title = "" Then $title = _ScriptBaseName()
MsgBox(0x1040, $title, $usageMsg, $timeOut)
If $quit Then Exit
EndFunc   ;==>_ShowUsage

Func _WinGetByPID($iPID, $nArray = 1)
If IsString($iPID) Then $iPID = ProcessExists($iPID)
Local $aWList = WinList(), $sHold
For $iCC = 1 To $aWList[0][0]
If WinGetProcess($aWList[$iCC][1]) = $iPID And _
BitAND(WinGetState($aWList[$iCC][1]), 2) Then
If $nArray Then Return $aWList[$iCC][0]
$sHold &= $aWList[$iCC][0] & Chr(1)
EndIf
Next
If $sHold Then Return StringSplit(StringTrimRight($sHold, 1), Chr(1))
Return SetError(1, 0, 0)
EndFunc   ;==>_WinGetByPID

Here's the source for the shortcut generator stripped of includes.  See zip attachment for custom icon.

StartMinShortcut.au3

#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_icon=lightning.ico
#AutoIt3Wrapper_UseUpx=n
#AutoIt3Wrapper_Res_Fileversion=1.1.0.0
#AutoIt3Wrapper_Res_Language=1033
#AutoIt3Wrapper_Res_Field=Productname|StartMinShortcut
#AutoIt3Wrapper_Res_Field=Productversion|1.1
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****

Global Const $tagPOINT = "long X;long Y"
Global Const $tagGUID = "dword Data1;word Data2;word Data3;byte Data4[8]"
Global Const $HGDI_ERROR = Ptr(-1)
Global Const $INVALID_HANDLE_VALUE = Ptr(-1)
Global Const $KF_EXTENDED = 0x0100
Global Const $KF_ALTDOWN = 0x2000
Global Const $KF_UP = 0x8000
Global Const $LLKHF_EXTENDED = BitShift($KF_EXTENDED, 8)
Global Const $LLKHF_ALTDOWN = BitShift($KF_ALTDOWN, 8)
Global Const $LLKHF_UP = BitShift($KF_UP, 8)
Global Const $__WINVER = __Ver()
Global Const $tagNOTIFYICONDATA = 'dword Size;hwnd hWnd;uint ID;uint Flags;uint CallbackMessage;ptr hIcon;wchar Tip[128];dword State;dword StateMask;wchar Info[256];uint Version;wchar InfoTitle[64];dword InfoFlags;'
Global Const $tagPRINTDLG = 'align 2;dword_ptr Size;hwnd hOwner;ptr hDevMode;ptr hDevNames;hwnd hDC;dword Flags;ushort FromPage;ushort ToPage;ushort MinPage;ushort MaxPage;' & __Iif(@AutoItX64, 'uint', 'ushort') & ' Copies;ptr hInstance;lparam lParam;ptr PrintHook;ptr SetupHook;ptr PrintTemplateName;ptr SetupTemplateName;ptr hPrintTemplate;ptr hSetupTemplate;'


$delayStr = "0"
$delay = 0
$exe = ""
$work = ""
$target = ""
$title = ""
$shortname = ""
$shortcut = ""
$startfolder = @AppDataCommonDir & "\Microsoft\Windows\Start Menu"

If $CmdLine[0] Then
If FileExists($CmdLine[1]) And StringInStr($CmdLine[1], ".lnk") Then
$shortcut = $CmdLine[1]
EndIf
Else
$shortcut = FileOpenDialog("Select a Shortcut to Start Minimized in Tray", $startfolder, "Shortcuts (*.lnk)", 3, $startfolder & "\*.lnk")
If @error Then _ShowUsage("No Shortcut Chosen")
EndIf

$details = FileGetShortcut($shortcut)
If IsArray($details) Then
$exe = _QuoteStr($details[0])
$work = _QuoteStr($details[1])
If $work = "" Then
$work = _QuoteStr(_FileDirNoSlash($details[0]))
EndIf
$shortname = @DesktopDir & "\" & _FileBaseName($details[0]) & "_Trayed.lnk"
$delayStr = InputBox(_FileBaseName(@ScriptName), "    Enter Start Delay in Seconds" _
& @CRLF & @CRLF & "    (  Range 1 to 60 : 0 for No Delay  )", $delayStr)

If $delayStr <> "" Then
$delay = Int($delayStr)
If $delay Then
$delayStr = "-d=" & String($delay)
Else
$delayStr = ""
EndIf
EndIf

If MsgBox(0x1024, _FileBaseName(@ScriptName), "Run Program to add Window Title ?") = 6 Then
ShellExecute($shortcut)
Sleep(4000)
$title = WinGetTitle("[Active]")
$title = InputBox(_FileBaseName(@ScriptName), "Enter Exact Window Title", $title)
EndIf
$target = $delayStr & " " & $exe & " " & $work
If $title <> "" Then $target &= " " & _QuoteStr($title)
FileCreateShortcut("RunInTrayMod.exe", $shortname, "", $target)
ShellExecute(@StartupDir)
EndIf

;--------------  Helper Functions  ---------------

Func __Iif($fTest, $iTrue, $iFalse)
If $fTest Then
Return $iTrue
Else
Return $iFalse
EndIf
EndFunc   ;==>__Iif

Func __Ver()
Local $tOSVI, $Ret
$tOSVI = DllStructCreate('dword Size;dword MajorVersion;dword MinorVersion;dword BuildNumber;dword PlatformId;wchar CSDVersion[128]')
DllStructSetData($tOSVI, 'Size', DllStructGetSize($tOSVI))
$Ret = DllCall('kernel32.dll', 'int', 'GetVersionExW', 'ptr', DllStructGetPtr($tOSVI))
If (@error) Or (Not $Ret[0]) Then
Return SetError(1, 0, 0)
EndIf
Return BitOR(BitShift(DllStructGetData($tOSVI, 'MajorVersion'), -8), DllStructGetData($tOSVI, 'MinorVersion'))
EndFunc   ;==>__Ver

Func _QuoteStr($str)
If StringInStr($str, " ") Then
Return '"' & $str & '"'
EndIf
Return $str
EndFunc   ;==>_QuoteStr

;show usage msg and optionally quit with optional timeout
Func _ShowUsage($usageMsg, $title = "", $quit = True, $timeOut = 0)
If $title = "" Then $title = _ScriptBaseName()
MsgBox(0x1040, $title, $usageMsg, $timeOut)
If $quit Then Exit
EndFunc   ;==>_ShowUsage

; Return Directory part of path without trailing slash
Func _FileDirNoSlash($path)
Return StringLeft($path, StringInStr($path, "\", 0, -1) - 1)
EndFunc   ;==>_FileDirNoSlash

; return the basename part of a file path
; works only for files with extension
; e.g. returns "test" for c:\folder\test.exe path
;
Func _FileBaseName($path)
If $path = "" Then Return ""
If StringLen($path) < 3 Then Return ""

Local $pos = StringInStr($path, "\", 0, -1)
$pos += 1
Local $tmp = StringMid($path, $pos)
Return StringLeft($tmp, StringInStr($tmp, ".", 0, -1) - 1)
EndFunc   ;==>_FileBaseName

;return @ScriptName without extension
;useful for MsgBox titles or path
;building
;
Func _ScriptBaseName()
Return StringLeft(@ScriptName, (StringInStr(@ScriptName, ".") - 1))
EndFunc   ;==>_ScriptBaseName

« Last Edit: December 10, 2011, 04:25 PM by MilesAhead »

MilesAhead

  • Supporting Member
  • Joined in 2009
  • **
  • Posts: 7,736
    • View Profile
    • Donate to Member
Re: RunInTrayMod 1.2
« Reply #6 on: December 11, 2011, 11:19 AM »
RunInTrayMod 1.2  Source cleaned up a bit more.

; RunInTrayMod - modified version of RunInTray utility found here:
; http://www.cellsworth.com/news/computer-related/35-uncategorizied/96-runintray.html
;
; The main modification to RunInTray is on detection of the window.
; A handle is obtained and used in Hide Show and Close operations.
; This way the client may change window caption and still respond
; to Hide, Show, and Close commands.
;
; Also Close is used instead of Kill to close the client app.
;
Global Const $TRAY_EVENT_PRIMARYUP = -8
Global Const $tagPOINT = "long X;long Y"
Global Const $tagGUID = "dword Data1;word Data2;word Data3;byte Data4[8]"
Global Const $HGDI_ERROR = Ptr(-1)
Global Const $INVALID_HANDLE_VALUE = Ptr(-1)
Global Const $KF_EXTENDED = 0x0100
Global Const $KF_ALTDOWN = 0x2000
Global Const $KF_UP = 0x8000
Global Const $LLKHF_EXTENDED = BitShift($KF_EXTENDED, 8)
Global Const $LLKHF_ALTDOWN = BitShift($KF_ALTDOWN, 8)
Global Const $LLKHF_UP = BitShift($KF_UP, 8)

AutoItSetOption("WinTitleMatchMode", -3)
AutoItSetOption("TrayOnEventMode", 1) ; Use event trapping for tray menu
AutoItSetOption("TrayMenuMode", 3) ; Default tray menu items will not be shown.

Const $delayMin = 1, $delayMax = 60
; call EmptyWorkingSet once a minute
Const $MemCountMax = 60

Global $Dir = "", $App = "", $handle = 0, $title = "", $memCount = 0, $delay = 0, $hasDelay = False

$iMsg = "Usage: " & @CRLF & @CRLF & "RunInTrayMod [ -d=n ] ProgramPath WorkingDir [ WindowTitle ]" & @CRLF
$iMsg &= "    (  -d=n is seconds delay : Valid range for n is " & $delayMin & " to " & $delayMax & "  )" & @CRLF & @CRLF
$iMsg &= "If any params contain space(s) wrap them in double quotes" & @CRLF & @CRLF
$iMsg &= "If App will not go to Tray specify exact Window Title as last param" & @CRLF & @CRLF
$iMsg &= "( If App leaves Icon in Taskbar when Trayed, it is not compatible )"

Switch $CmdLine[0]

Case 4
If Not StringInStr($CmdLine[1], "-d=") Then _ShowUsage($iMsg)
$delay = Number(StringMid($CmdLine[1], 4))
If $delay < $delayMin Or $delay > $delayMax Then $delay = 0
$App = $CmdLine[2]
$Dir = $CmdLine[3]
$title = $CmdLine[4]

Case 3
If StringInStr($CmdLine[1], "-d=") Then
$delay = Number(StringMid($CmdLine[1], 4))
If $delay < $delayMin Or $delay > $delayMax Then $delay = 0
$App = $CmdLine[2]
$Dir = $CmdLine[3]
Else
$App = $CmdLine[1]
$Dir = $CmdLine[2]
$title = $CmdLine[3]
EndIf

Case 2
If StringInStr($CmdLine[1], "-d=") Then _ShowUsage($iMsg)
$App = $CmdLine[1]
$Dir = $CmdLine[2]

Case Else
_ShowUsage($iMsg)

EndSwitch

$proc_Name = _FileNoPath($App)
$do_Kill = True

While $delay
TraySetToolTip(String($delay) & " Sec. to Launch " & _FileBaseName($App))
Sleep(1000)
$delay -= 1
WEnd

ShellExecute($App, "", $Dir)
Sleep(1000)
If $title <> "" Then
$handle = WinWait($title, "", 4)
If $handle = 0 Then
_ShowError("Could not get Handle for Window:" & @CRLF & @CRLF & $title)
EndIf
EndIf
If $handle = 0 Then
$handle = WinGetHandle(_WinGetByPID($proc_Name))
If $handle = "" Then
$iMsg = "Could Not Get Handle To: " & $proc_Name & @CRLF & @CRLF
$iMsg &= "Try adding Window Title to Command Line or Shortcut Target line"
_ShowError($iMsg)
EndIf
EndIf

TraySetIcon($App)
TraySetClick(8)
$hTray_Show_Item = TrayCreateItem("Hide")
$hTray_Donate_Item = TrayCreateItem("Donate")
TrayCreateItem("")
TrayCreateItem("Exit")
TrayItemSetOnEvent(-1, "On_Exit")
TrayItemSetOnEvent($hTray_Show_Item, "To_Tray")
TrayItemSetOnEvent($hTray_Donate_Item, "Donate")
TraySetOnEvent($TRAY_EVENT_PRIMARYUP, "To_Tray")
TraySetToolTip(_FileBaseName($App))
To_Tray()

While 1
Sleep(1000)
If Not ProcessExists($proc_Name) Then
$do_Kill = False
Exit
EndIf
$memCount += 1
If $memCount >= $MemCountMax Then
_EmptyWorkingSet()
$memCount = 0
EndIf
WEnd

Func On_Exit()
If $do_Kill Then WinClose(_WinAPI_GetWindowText($handle))
Exit
EndFunc   ;==>On_Exit

Func To_Tray()

If TrayItemGetText($hTray_Show_Item) = "Hide" Then
_WinAPI_ShowWindow($handle, @SW_HIDE)
TrayItemSetText($hTray_Show_Item, "Show")
Else
_WinAPI_ShowWindow($handle, @SW_SHOW)
TrayItemSetText($hTray_Show_Item, "Hide")
EndIf

EndFunc   ;==>To_Tray

Func Donate()
ShellExecute("http://www.favessoft.com/donate.html")
EndFunc   ;==>Donate

;--------------  Helper Functions Stripped from Includes  ------------

Func _WinAPI_GetWindowText($hWnd)
Local $aResult = DllCall("user32.dll", "int", "GetWindowTextW", "hwnd", $hWnd, "wstr", "", "int", 4096)
If @error Then Return SetError(@error, @extended, "")
Return SetExtended($aResult[0], $aResult[2])
EndFunc   ;==>_WinAPI_GetWindowText

Func _WinAPI_ShowWindow($hWnd, $iCmdShow = 5)
Local $aResult = DllCall("user32.dll", "bool", "ShowWindow", "hwnd", $hWnd, "int", $iCmdShow)
If @error Then Return SetError(@error, @extended, False)
Return $aResult[0]
EndFunc   ;==>_WinAPI_ShowWindow

Func _EmptyWorkingSet()
Local $result = DllCall("psapi.dll", 'int', 'EmptyWorkingSet', 'long', -1)
Return $result[1]
EndFunc   ;==>_EmptyWorkingSet

Func _FileBaseName($path)
If $path = "" Then Return ""
If StringLen($path) < 3 Then Return ""
Local $pos = StringInStr($path, "\", 0, -1)
$pos += 1
Local $tmp = StringMid($path, $pos)
Return StringLeft($tmp, StringInStr($tmp, ".", 0, -1) - 1)
EndFunc   ;==>_FileBaseName

Func _FileNoPath($path)
Return StringMid($path, StringInStr($path, "\", 0, -1) + 1)
EndFunc   ;==>_FileNoPath

Func _ScriptBaseName()
Return StringLeft(@ScriptName, (StringInStr(@ScriptName, ".") - 1))
EndFunc   ;==>_ScriptBaseName

Func _ShowError($errorMsg, $title = "", $quit = True, $timeOut = 0)
If $title = "" Then $title = _ScriptBaseName()
MsgBox(0x1010, $title, $errorMsg, $timeOut)
If $quit Then Exit
EndFunc   ;==>_ShowError

Func _ShowUsage($usageMsg, $title = "", $quit = True, $timeOut = 0)
If $title = "" Then $title = _ScriptBaseName()
MsgBox(0x1040, $title, $usageMsg, $timeOut)
If $quit Then Exit
EndFunc   ;==>_ShowUsage

Func _WinGetByPID($iPID, $nArray = 1)
If IsString($iPID) Then $iPID = ProcessExists($iPID)
Local $aWList = WinList(), $sHold
For $iCC = 1 To $aWList[0][0]
If WinGetProcess($aWList[$iCC][1]) = $iPID And _
BitAND(WinGetState($aWList[$iCC][1]), 2) Then
If $nArray Then Return $aWList[$iCC][0]
$sHold &= $aWList[$iCC][0] & Chr(1)
EndIf
Next
If $sHold Then Return StringSplit(StringTrimRight($sHold, 1), Chr(1))
Return SetError(1, 0, 0)
EndFunc   ;==>_WinGetByPID

MilesAhead

  • Supporting Member
  • Joined in 2009
  • **
  • Posts: 7,736
    • View Profile
    • Donate to Member
Re: RunInTrayMod 1.3
« Reply #7 on: December 17, 2011, 03:03 PM »
RunInTrayMod 1.3 Added "Toast" tray popup splash screen for delayed start. Thanks to Melba23 on AutoIt3 forum:

http://www.autoitscr...5-how-to-make-toast/

Removed source from zip as it would be too cluttered now.

edit: here's a screen shot of the delay splash just above task tray.

edit2: adjusted Toast so splash screen may be closed by clicking the x.

This does not cancel the delay.  The delay count down reverts to the
Tray Icon Tooltip.


toastshot.jpg


« Last Edit: December 17, 2011, 09:34 PM by MilesAhead »

MilesAhead

  • Supporting Member
  • Joined in 2009
  • **
  • Posts: 7,736
    • View Profile
    • Donate to Member
Re: RunInTrayMod 1.31
« Reply #8 on: December 21, 2011, 08:15 PM »
RunInTrayMod 1.31 Modified Tray Splash to accommodate Taskbar.

MilesAhead

  • Supporting Member
  • Joined in 2009
  • **
  • Posts: 7,736
    • View Profile
    • Donate to Member
Re: RunInTrayMod 1.33
« Reply #9 on: April 30, 2015, 04:15 PM »
I have updated the first post with my current url.  I increased the timeouts for both RunInTrayMod and StartMinShortcut to 15 seconds.  This gives more chance for the window of the trayed program to open and set its title.  My Laptop does not run quite as fast as my quad core desktop.  :)


I added a custom icon to RunInTrayMod.exe.

fowlermon

  • Participant
  • Joined in 2015
  • *
  • default avatar
  • Posts: 3
    • View Profile
    • Donate to Member
Re: RunInTrayMod 1.33
« Reply #10 on: August 13, 2015, 10:31 PM »
Hey I fixed a lot of problems with your program that you made, fixed 2 programs that weren't starting up with windows AND were not starting minimized. So 2 birds with 1 stone. Anyway I ran into an error when I tried to use your app on a VPN service (that doesn't matter) and it tried to run the program in the wrong file path.. Program Files (x86), rather than Program Files which is where the ap actually resides.error.png.

Not sure how to fix the problem other than to move the actual VPN ap into Program Files (x86). I'll let you know if that works, but it's a pretty silly work around...

MilesAhead

  • Supporting Member
  • Joined in 2009
  • **
  • Posts: 7,736
    • View Profile
    • Donate to Member
Re: RunInTrayMod 1.33
« Reply #11 on: August 14, 2015, 06:29 AM »
Hey I fixed a lot of problems with your program that you made, fixed 2 programs that weren't starting up with windows AND were not starting minimized. So 2 birds with 1 stone. Anyway I ran into an error when I tried to use your app on a VPN service (that doesn't matter) and it tried to run the program in the wrong file path.. Program Files (x86), rather than Program Files which is where the ap actually resides. (see attachment in previous post).

Not sure how to fix the problem other than to move the actual VPN ap into Program Files (x86). I'll let you know if that works, but it's a pretty silly work around...

The folder substitution is due to 32 bit emulation on a 64 bit system.  Try substituting these 64 bit exes and see if things act as expected.  Rename both x64 versions to the original filenames(without the x64 part) or the shortcut maker will not be found.

btw you cannot launch software with higher privilege form software with lower privileges.  That is why launching a service from an ordinary program will not work.  It is a Windows security measure.

Edit:  I have uploaded the zip to my site.  Link is in first post.



« Last Edit: August 14, 2015, 08:04 AM by MilesAhead »

fowlermon

  • Participant
  • Joined in 2015
  • *
  • default avatar
  • Posts: 3
    • View Profile
    • Donate to Member
Re: RunInTrayMod 1.33
« Reply #12 on: October 11, 2015, 09:46 PM »
Hey, forgot to reply that it works with the app I mentioned now. Very good tool.

The only thing is as this particular app (VPN) doesn't open a window when it starts, there is nothing to close, and so this tool gets confused and says "Cannot get handle for <app name>. Try adding command line.. etc." Useful to know, at least the first time, but annoying when it does it everytime. Basically I like to use this tool to make things start with windows when no other solution works, and this particular app does not have a window that pops up, rather it starts silently (visually). The only window available for this application is the Settings page, which is accessed by right clicking the app. But even adding Settings at the command line makes this annoying popup continue.

Appreciate your work


MilesAhead

  • Supporting Member
  • Joined in 2009
  • **
  • Posts: 7,736
    • View Profile
    • Donate to Member
Re: RunInTrayMod 1.33
« Reply #13 on: October 12, 2015, 07:44 AM »
I like to use this tool to make things start with windows when no other solution works

Hi.  Glad you get use out of RunInTrayMod.  In this situation it sounds like what you are doing is more in line with the purpose of DelayedCuts.  You feed program shortcuts to DelayedCuts and set a delay in the range 10 seconds to 10 minutes.  When this info is saved it puts a shortcut to the included DelayedLoad.exe that actually runs the programs after the delays., in the StartUp Folder

DelayedLoad has an optional "Toast" info window that shows the icon and program name of the next program that will be launched.  You can skip a program by clicking the close 'x' in the Toast window.

The reason it insists on shortcuts only is because a shortcut can be loaded with all the information the program needs to run correctly such as exe location, startup directory, command line params, run minimized maximized normal etc..  So by feeding it the one item no other info is needed other that the delay time.

It is available on my page
http://milesaheadsoftware.org/

Note that the delay is from the time DelayedCuts itself loads.


fowlermon

  • Participant
  • Joined in 2015
  • *
  • default avatar
  • Posts: 3
    • View Profile
    • Donate to Member
Re: RunInTrayMod 1.33
« Reply #14 on: October 14, 2015, 08:06 AM »
Oh thanks! Just tried out DelayedCuts and it's pretty cool. Seemed easy enough to use; even got the rid of the toast window since I didn't really need all that information particularly. Appreciate your time

-James

MilesAhead

  • Supporting Member
  • Joined in 2009
  • **
  • Posts: 7,736
    • View Profile
    • Donate to Member
Re: RunInTrayMod 1.33
« Reply #15 on: October 14, 2015, 08:11 AM »
Oh thanks! Just tried out DelayedCuts and it's pretty cool. Seemed easy enough to use; even got the rid of the toast window since I didn't really need all that information particularly. Appreciate your time

-James

Glad it worked for you.   :Thmbsup: