Difference between revisions of "AutoHotkey: From FileSync open another TC instance with selected files"

From TotalcmdWiki
Jump to: navigation, search
m (date)
(cleaned up path for missing files in root dir; boUseFix_ArchiveFocusNoOpen: optional fix for TC bug unintentionally opening archives instead of focussing them (up to TC 9.50b13))
 
Line 5: Line 5:
 
*/ ; --> <code><pre>
 
*/ ; --> <code><pre>
 
; ////////////////////////////////////////////////////////////////////////////
 
; ////////////////////////////////////////////////////////////////////////////
; // TC_Sync_OpenFolderInSecondTC.ahk  V0.21 (W) StatusQuo 2008 - 2017
+
; // TC_Sync_OpenFolderInSecondTC.ahk  V0.30 (W) StatusQuo 2008 - 2020
 
; // http://ghisler.ch/board/viewtopic.php?t=19713
 
; // http://ghisler.ch/board/viewtopic.php?t=19713
 
; //  
 
; //  
 
; // open another TC instance
 
; // open another TC instance
; // with the folders of the currently selected file in cm_FileSync
+
; // with the folders of the currently selected file in cm_FileSync (Synchronize directories)
 
; // via hotkey: Ctrl+Win+T
 
; // via hotkey: Ctrl+Win+T
 
; ////////////////////////////////////////////////////////////////////////////
 
; ////////////////////////////////////////////////////////////////////////////
Line 18: Line 18:
 
#IfWinActive, ahk_class TCmpForm
 
#IfWinActive, ahk_class TCmpForm
 
; F4::
 
; F4::
^#t:: ; hotkey =  Ctrl+Win+T
+
^#t:: ; hotkey =  Ctrl+Win+T: Open selected files from SyncFiles in second TC instance (reused by recurring calls)
 
; please adjust path here; %COMMANDER_PATH% is not available outside of TC
 
; please adjust path here; %COMMANDER_PATH% is not available outside of TC
 
sTCExe := "C:\totalcmd\TOTALCMD.EXE"
 
sTCExe := "C:\totalcmd\TOTALCMD.EXE"
boAlwaysOpenNewTask := 0 ; set to 1 to not re-use TC target window (always open a new one)
+
boAlwaysOpenNewTask         := 0 ; set to 1 to not re-use TC target window (always open a new one)
boCdToFolderOnly   := 0 ; set to 0 to have cursor placed on selected files; uses Lister (experimental?)
+
boCdToFolderOnly           := 0 ; set to 0 to have cursor placed on selected files; uses Lister (experimental?)
iListerTimeOutSecs := 1 ; if using Lister: timeout after n seconds of not appearing Lister
+
iListerTimeOutSecs         := 1 ; if using Lister: timeout after n seconds of not appearing Lister
TCSync2nd_RunAsAdmin := 0 ; set to 1 to start 2nd TC as other user, e.g. administrator
+
boTCSync2nd_RunAsAdmin      := 1 ; set to 1 to start 2nd TC as other user, e.g. administrator
 +
boUseFix_ArchiveFocusNoOpen := 0 ; fixes a TC bug when using /A /O (present up to TC 9.50b13)
 +
                                ; - slower, calls target TC twice (for left/right panel separately)
 +
                                ; - set to 1 to use it
 +
                                ; - set to 0 if one of the panels is not always refreshing
 
; static pidTC2
 
; static pidTC2
 
;
 
;
Line 31: Line 35:
 
ControlGetFocus, Panel_id
 
ControlGetFocus, Panel_id
 
SendMessage, %LB_GETCARETINDEX%, 0, 0, %Panel_id%
 
SendMessage, %LB_GETCARETINDEX%, 0, 0, %Panel_id%
LB_CursorPosition := ErrorLevel
+
LB_CursorPosition := ErrorLevel ; *** 0 = line #1 (zero-based)
 +
LB_CursorPosition_Save := LB_CursorPosition ; *** for debugging only
 
VarSetCapacity(LB_String, 1024, 0)
 
VarSetCapacity(LB_String, 1024, 0)
 
SendMessage, %LB_GETTEXT%, %LB_CursorPosition%, &LB_String, %Panel_id%
 
SendMessage, %LB_GETTEXT%, %LB_CursorPosition%, &LB_String, %Panel_id%
 
LB_CursorLine := LB_String
 
LB_CursorLine := LB_String
 +
;
 
Loop ; *** find subdirectory *** only working for VISIBLE lines - after scrolling dir line out of view, LB_GETTEXT fails! (Win2k, TC8.51a)
 
Loop ; *** find subdirectory *** only working for VISIBLE lines - after scrolling dir line out of view, LB_GETTEXT fails! (Win2k, TC8.51a)
 
{
 
{
Line 43: Line 49:
 
LB_CursorPosition -= 1
 
LB_CursorPosition -= 1
 
}
 
}
; LB_SubDir := LB_String ; moved down
+
ControlGetText, sLPath, TEdit2, ahk_class TCmpForm ; *** TC <= 7.04a
ControlGetText, sLPath, TEdit2, ahk_class TCmpForm ; TC <= 7.04a
+
ControlGetText, sRPath, TEdit1, ahk_class TCmpForm ; *** TC <= 7.04a
ControlGetText, sRPath, TEdit1, ahk_class TCmpForm
 
 
boTC75 := 0 ; TC <= 7.04a
 
boTC75 := 0 ; TC <= 7.04a
 
if (sLPath . sRPath = "")
 
if (sLPath . sRPath = "")
 
{
 
{
ControlGetText, sLPath, TAltEdit2, ahk_class TCmpForm ; TC >= 7.50 rc1
+
ControlGetText, sLPath, TAltEdit2, ahk_class TCmpForm ; *** TC >= 7.50 rc1
ControlGetText, sRPath, TAltEdit1, ahk_class TCmpForm
+
ControlGetText, sRPath, TAltEdit1, ahk_class TCmpForm ; *** TC >= 7.50 rc1
 
if (sLPath . sRPath != "")
 
if (sLPath . sRPath != "")
boTC75 := 1 ; TC >= TC 7.50 rc1
+
boTC75 := 1 ; *** TC >= 7.50 rc1
 
}
 
}
if (boTC75) ; TC >= TC 7.50 rc1
+
if (boTC75) ; *** TC >= 7.50 rc1
 
{
 
{
 
if (SubStr(LB_String, 1, 7) = "DIR EQ ")
 
if (SubStr(LB_String, 1, 7) = "DIR EQ ")
Line 67: Line 72:
 
;
 
;
 
LB_SubDir := LB_String
 
LB_SubDir := LB_String
 +
if (InStr(LB_SubDir, "|") > 0) and (StrLen(LB_SubDir) >= 32) ; *** minimum string lenth: "L L to R F 1 01.02.12 11:22:33 |"
 +
LB_SubDir := "" ; *** fix: if no subdir exists: LB_SubDir = LB_CursorLine of FIRST file line (also with cursor on a line below the first)
 
;
 
;
; *** TC 8.51a:
+
; *** TC 8.51a / 9.22a:
; *** LB_CursorLine =     "2 EQ FILE.EXT 123.456 01.02.12 11:22:33 | 01.02.12 11:22:33 123.456 FILE.EXT"
+
; *** LB_CursorLine     =     2 EQ both.zip 1.118 17.01.20 10:30:32 | 17.01.20 10:30:32 1.118 both.zip
; *** LB_CursorLine =                                   "R R to L  | 01.02.12 11:22:33 123.456 FILE.EXT"
+
; *** LB_CursorLine     = L L to R left.zip 1.118 17.01.20 10:30:32 |
; *** LB_CursorLine = "L L to R FILE.EXT 123.456 01.02.12 11:22:33 |"
+
; *** LB_CursorLine    =                                  R R to L  | 17.01.20 10:30:32 1.118 right.zip
 +
; *** LB_CursorLine     =                                     R DEL  | 17.01.20 10:30:32 1.118 right.zip
 
sLDirName := "" ; *** get left path name
 
sLDirName := "" ; *** get left path name
 
if (not boCdToFolderOnly)
 
if (not boCdToFolderOnly)
Line 81: Line 89:
 
If (sLDirName = "")
 
If (sLDirName = "")
 
sLDirName := sLPath . LB_SubDir
 
sLDirName := sLPath . LB_SubDir
; ---
+
; ---
 
sRDirName := "" ; *** get right path name
 
sRDirName := "" ; *** get right path name
if (not boCdToFolderOnly)
+
if (not boCdToFolderOnly) ; *** do not focus file
 
and (SubStr(LB_CursorLine, 1, 1) != "L") ; and (SubStr(LB_CursorLine, StrLen(LB_CursorLine), 1) != "\")
 
and (SubStr(LB_CursorLine, 1, 1) != "L") ; and (SubStr(LB_CursorLine, StrLen(LB_CursorLine), 1) != "\")
 
{
 
{
Line 91: Line 99:
 
If (sRDirName = "")
 
If (sRDirName = "")
 
sRDirName := sRPath . LB_SubDir
 
sRDirName := sRPath . LB_SubDir
; ---
+
; ---
If boAlwaysOpenNewTask
+
If (boAlwaysOpenNewTask)
 
or (not WinExist("ahk_pid " . pidTC2))
 
or (not WinExist("ahk_pid " . pidTC2))
 
pidTC2 := ""
 
pidTC2 := ""
Line 101: Line 109:
 
}
 
}
 
;
 
;
sRunStr := sTCExe
+
sRunStr := sTCExe
 +
sRunStrL := ""
 +
sRunStrR := ""
 
if (sLDirName != "")
 
if (sLDirName != "")
sRunStr = %sRunStr% /A /L="%sLDirName%"
+
{
 +
sRunStr = %sRunStr% /A /L="%sLDirName%"
 +
sRunStrL = /A /L="%sLDirName%"
 +
}
 
if (sRDirName != "")
 
if (sRDirName != "")
sRunStr = %sRunStr% /A /R="%sRDirName%"
+
{
 +
sRunStr = %sRunStr% /A /R="%sRDirName%"
 +
sRunStrR = /A /R="%sRDirName%"
 +
}
 
if (sRunStr = sTCExe)
 
if (sRunStr = sTCExe)
 
Return
 
Return
 
if (pidTC2 = "")
 
if (pidTC2 = "")
 
{
 
{
if (TCSync2nd_RunAsAdmin > "0")
+
if (boTCSync2nd_RunAsAdmin)
 
{
 
{
; -- run as admin: also workaround for TC "As Administrator" bug up to TC 7.50 pubbeta 2
+
; *** run as admin: also workaround for TC "As Administrator" bug up to TC 7.50 pubbeta 2
 
sRunUser := ""
 
sRunUser := ""
 
sRunPw := ""
 
sRunPw := ""
Line 126: Line 142:
 
if ErrorLevel
 
if ErrorLevel
 
sRunUser := ""
 
sRunUser := ""
 +
sRunPw := ""
 
}
 
}
 
;
 
;
Run, %sRunStr%,,, pidTC2
+
Run, %sRunStr%,,, pidTC2 ; *** single call OK here, no TC bug when opening new instance; also: 2 calls would open 2 new instances!
 
RunAs
 
RunAs
 
}
 
}
 
else
 
else
 
{
 
{
Run, %sRunStr%
+
if (boUseFix_ArchiveFocusNoOpen) and not (boCdToFolderOnly) ; *** separate calls for each TC panel (left/right), workaround for TC bug ("/A")
 +
{
 +
Run, %sTCExe% %sRunStrR% ; *** right side first - on this side "/A" fails using a single command line + existing TC instance (TC 7.22a x86 @ Win7 x64)
 +
; *** second run on existing instance may fail, if TC is called twice in a row too fast!
 +
Sleep, 200 ; *** >= 120 needed for TC 9.50b13 (may vary)
 +
Run, %sTCExe% %sRunStrL%
 +
} else {
 +
Run, %sRunStr%
 +
}
 
}
 
}
 
;
 
;
Line 146: Line 171:
 
global boCdToFolderOnly, iListerTimeOutSecs
 
global boCdToFolderOnly, iListerTimeOutSecs
 
WinWaitNotActive, ahk_class TCmpForm,, %iListerTimeOutSecs% ; wait for starting lister, timeout in seconds, set in hotkey (^#t)
 
WinWaitNotActive, ahk_class TCmpForm,, %iListerTimeOutSecs% ; wait for starting lister, timeout in seconds, set in hotkey (^#t)
IfWinActive, ahk_class TCmpForm ; Lister hasn't started - no file on this panel side?
 
Return
 
 
SetTitleMatchMode, 1
 
SetTitleMatchMode, 1
IfWinActive, Lister
+
IfWinNotActive, ahk_class TLister ; *** Lister hasn't started - no file on this panel side?
 
{
 
{
 +
Return, % ""
 +
} else {
 
WinGetActiveTitle, sWinTitle
 
WinGetActiveTitle, sWinTitle
 
WinClose, %sWinTitle%
 
WinClose, %sWinTitle%
Line 160: Line 185:
 
}
 
}
 
}
 
}
; iNamePos := (InStr(sWinTitle, "[", false, 0) + 1) ; old (fails using [] in FN)
 
 
iNamePos := (InStr(sWinTitle, "[", false, 1) + 1)
 
iNamePos := (InStr(sWinTitle, "[", false, 1) + 1)
 
iNameEnd := (InStr(sWinTitle, "]", false, 0) - 1) ; *** InStr start=0: search in reverse
 
iNameEnd := (InStr(sWinTitle, "]", false, 0) - 1) ; *** InStr start=0: search in reverse
Line 167: Line 191:
 
sReturn := SubStr(sWinTitle, iNamePos, (InStr(sWinTitle, "\", false, 0) + 1) - iNamePos) ; *** InStr start=0: search in reverse
 
sReturn := SubStr(sWinTitle, iNamePos, (InStr(sWinTitle, "\", false, 0) + 1) - iNamePos) ; *** InStr start=0: search in reverse
 
} else { ; folder + file name
 
} else { ; folder + file name
;sReturn := SubStr(sWinTitle, iNamePos, StrLen(sWinTitle) - iNamePos) ; *** 2do: fails on MP3 (Lister opened w/ option Multimedia)
 
 
sReturn := SubStr(sWinTitle, iNamePos, iNameEnd - iNamePos + 1) ; *** _[123abc] 8 - 3 ; ; *** fixed multimedia viewer mode (universal: terminate at last "]")
 
sReturn := SubStr(sWinTitle, iNamePos, iNameEnd - iNamePos + 1) ; *** _[123abc] 8 - 3 ; ; *** fixed multimedia viewer mode (universal: terminate at last "]")
 
}
 
}

Latest revision as of 19:11, 18 January 2020

		; ////////////////////////////////////////////////////////////////////////////
		; // TC_Sync_OpenFolderInSecondTC.ahk  V0.30  (W) StatusQuo 2008 - 2020
		; // http://ghisler.ch/board/viewtopic.php?t=19713
		; // 
		; // open another TC instance
		; // with the folders of the currently selected file in cm_FileSync (Synchronize directories)
		; // via hotkey: Ctrl+Win+T
		; ////////////////////////////////////////////////////////////////////////////

#SingleInstance, Force
Return

#IfWinActive, ahk_class TCmpForm
; F4::
^#t::	; hotkey =  Ctrl+Win+T: Open selected files from SyncFiles in second TC instance (reused by recurring calls)
		; please adjust path here; %COMMANDER_PATH% is not available outside of TC
	sTCExe := "C:\totalcmd\TOTALCMD.EXE"
	boAlwaysOpenNewTask         := 0 ; set to 1 to not re-use TC target window (always open a new one)
	boCdToFolderOnly            := 0 ; set to 0 to have cursor placed on selected files; uses Lister (experimental?)
	iListerTimeOutSecs          := 1 ; if using Lister: timeout after n seconds of not appearing Lister
	boTCSync2nd_RunAsAdmin      := 1 ; set to 1 to start 2nd TC as other user, e.g. administrator
	boUseFix_ArchiveFocusNoOpen := 0 ; fixes a TC bug when using /A /O (present up to TC 9.50b13)
	                                 ; - slower, calls target TC twice (for left/right panel separately)
	                                 ; - set to 1 to use it
	                                 ; - set to 0 if one of the panels is not always refreshing
	; static pidTC2
	;
	LB_GETCARETINDEX := 0x019F
	LB_GETTEXT := 0x0189
	ControlGetFocus, Panel_id
	SendMessage, %LB_GETCARETINDEX%, 0, 0, %Panel_id%
	LB_CursorPosition := ErrorLevel	; *** 0 = line #1 (zero-based)
	LB_CursorPosition_Save := LB_CursorPosition	; *** for debugging only
	VarSetCapacity(LB_String, 1024, 0)
	SendMessage, %LB_GETTEXT%, %LB_CursorPosition%, &LB_String, %Panel_id%
	LB_CursorLine := LB_String
	;
	Loop	; *** find subdirectory	*** only working for VISIBLE lines - after scrolling dir line out of view, LB_GETTEXT fails! (Win2k, TC8.51a)
	{
		If (SubStr(LB_String, StrLen(LB_String)) = "\")
		or (LB_CursorPosition < 0)
			Break
		SendMessage, %LB_GETTEXT%, %LB_CursorPosition%, &LB_String, %Panel_id%
		LB_CursorPosition -= 1
	}
	ControlGetText, sLPath, TEdit2, ahk_class TCmpForm	; *** TC <= 7.04a
	ControlGetText, sRPath, TEdit1, ahk_class TCmpForm	; *** TC <= 7.04a
	boTC75 := 0	; TC <= 7.04a
	if (sLPath . sRPath = "")
	{
		ControlGetText, sLPath, TAltEdit2, ahk_class TCmpForm	; *** TC >= 7.50 rc1
		ControlGetText, sRPath, TAltEdit1, ahk_class TCmpForm	; *** TC >= 7.50 rc1
		if (sLPath . sRPath != "")
			boTC75 := 1	; *** TC >= 7.50 rc1
	}
	if (boTC75)	; *** TC >= 7.50 rc1
	{
		if (SubStr(LB_String, 1, 7) = "DIR EQ ")
			LB_String := SubStr(LB_String, 8)
		if (SubStr(LB_String, 1, 8) = "DIR DEL ")
			LB_String := SubStr(LB_String, 9)
		if (SubStr(LB_String, 1, 11) = "DIR L to R ")
			LB_String := SubStr(LB_String, 12)
		if (SubStr(LB_String, 1, 11) = "DIR R to L ")
			LB_String := SubStr(LB_String, 12)
	}
	;
	LB_SubDir := LB_String
	if (InStr(LB_SubDir, "|") > 0) and (StrLen(LB_SubDir) >= 32)	; *** minimum string lenth: "L L to R F 1 01.02.12 11:22:33 |"
		LB_SubDir := ""	; *** fix: if no subdir exists: LB_SubDir = LB_CursorLine of FIRST file line (also with cursor on a line below the first)
	;
		; *** TC 8.51a / 9.22a:
		; *** LB_CursorLine     =      2 EQ both.zip 1.118 17.01.20 10:30:32 | 17.01.20 10:30:32 1.118 both.zip
		; *** LB_CursorLine     =  L L to R left.zip 1.118 17.01.20 10:30:32 |
		; *** LB_CursorLine     =                                  R R to L  | 17.01.20 10:30:32 1.118 right.zip
		; *** LB_CursorLine     =                                     R DEL  | 17.01.20 10:30:32 1.118 right.zip
	sLDirName := ""	; *** get left path name
	if (not boCdToFolderOnly)
	and (SubStr(LB_CursorLine, 1, 1) != "R")	; and (SubStr(LB_CursorLine, StrLen(LB_CursorLine), 1) != "\")
	{
		Send, {F3}
		sLDirName := GetActiveTCListerPath()
	}
	If (sLDirName = "")
		sLDirName := sLPath . LB_SubDir
		; ---
	sRDirName := ""	; *** get right path name
	if (not boCdToFolderOnly)	; *** do not focus file
	and (SubStr(LB_CursorLine, 1, 1) != "L")	; and (SubStr(LB_CursorLine, StrLen(LB_CursorLine), 1) != "\")
	{
		Send, +{F3}
		sRDirName := GetActiveTCListerPath()
	}
	If (sRDirName = "")
		sRDirName := sRPath . LB_SubDir
		; ---
	If (boAlwaysOpenNewTask)
	or (not WinExist("ahk_pid " . pidTC2))
		pidTC2 := ""
	if not (pidTC2 = "")
	{
		WinActivate, ahk_pid %pidTC2%
		sTCExe = %sTCExe% /O
	}
	;
	sRunStr  := sTCExe
	sRunStrL := ""
	sRunStrR := ""
	if (sLDirName != "")
	{
		sRunStr  = %sRunStr% /A /L="%sLDirName%"
		sRunStrL = /A /L="%sLDirName%"
	}
	if (sRDirName != "")
	{
		sRunStr  = %sRunStr% /A /R="%sRDirName%"
		sRunStrR = /A /R="%sRDirName%"
	}
	if (sRunStr = sTCExe)
		Return
	if (pidTC2 = "")
	{
		if (boTCSync2nd_RunAsAdmin)
		{
				; *** run as admin: also workaround for TC "As Administrator" bug up to TC 7.50 pubbeta 2
			sRunUser := ""
			sRunPw := ""
			InputBox, sRunUser, TC RunAs: Enter Administrator user name, Logon user name (Administrator):,,, 120,,,,, Administrator
			if ErrorLevel
				sRunUser := ""
			if (sRunUser != "")
				InputBox, sRunPw  , TC RunAs: Enter Administrator password,  Logon password for "%sRunUser%":,,, 120
			if ErrorLevel
				sRunUser := ""
			if (sRunUser != "")
				RunAs, %sRunUser%, %sRunPw%
			if ErrorLevel
				sRunUser := ""
			sRunPw := ""
		}
		;
		Run, %sRunStr%,,, pidTC2	; *** single call OK here, no TC bug when opening new instance; also: 2 calls would open 2 new instances!
		RunAs
	}
	else
	{
		if (boUseFix_ArchiveFocusNoOpen) and not (boCdToFolderOnly)	; *** separate calls for each TC panel (left/right), workaround for TC bug ("/A")
		{
			Run, %sTCExe% %sRunStrR%	; *** right side first - on this side "/A" fails using a single command line + existing TC instance (TC 7.22a x86 @ Win7 x64)
				; *** second run on existing instance may fail, if TC is called twice in a row too fast!
			Sleep, 200	; *** >= 120 needed for TC 9.50b13 (may vary)
			Run, %sTCExe% %sRunStrL%
		} else {
			Run, %sRunStr%
		}
	}
	;
	Return

#IfWinActive

; =============
; === TC Lister: grab path/file names of file in active lister window
GetActiveTCListerPath()
{
	global boCdToFolderOnly, iListerTimeOutSecs
	WinWaitNotActive, ahk_class TCmpForm,, %iListerTimeOutSecs%	; wait for starting lister, timeout in seconds, set in hotkey (^#t)
	SetTitleMatchMode, 1
	IfWinNotActive, ahk_class TLister	; *** Lister hasn't started - no file on this panel side?
	{
		Return, % ""
	} else {
		WinGetActiveTitle, sWinTitle
		WinClose, %sWinTitle%
		Loop, 10	; *** for big files: wait until load+close is done
		{
			If !WinExist( sWinTitle )
				Break
			Sleep, 300
		}
	}
	iNamePos := (InStr(sWinTitle, "[", false, 1) + 1)
	iNameEnd := (InStr(sWinTitle, "]", false, 0) - 1)	; *** InStr start=0: search in reverse
	If (boCdToFolderOnly)	; folder only
	{
		sReturn := SubStr(sWinTitle, iNamePos, (InStr(sWinTitle, "\", false, 0) + 1) - iNamePos)	; *** InStr start=0: search in reverse
	} else {	; folder + file name
		sReturn := SubStr(sWinTitle, iNamePos, iNameEnd - iNamePos + 1)	; *** _[123abc] 8 - 3	; 	; *** fixed multimedia viewer mode (universal: terminate at last "]")
	}
	Return, %sReturn%
}
/*

;

Back to AutoHotkey