Related
I would like testing and feedback (I'm hoping this is the correct place for this mods please move/delete as appropriate)
As anyone who alters environment variables frequently knows Visual studio doesn't pick them up automatically.
I found exiting and restarting all instances of explorer.exe gets Visual Studio picking up the latest set of environment variables without a restart.
Unfortunately this means you lose all your open windows.
I have written an AutoHotKey (www.AutoHotKey.com) script to get around this.
; Array must be initialised
Full_Path := Object()
; First Array dimension must be setup
Full_Path[j] := A_LoopField
; Generate a list of HWND's for explorer windows
WinGet, id, list, ahk_class CabinetWClass
; iterate over all HWND's filling in our Full_Path array
Loop, %id%
{
; store hwnd in this_id for current loop
this_id := id%A_Index%
; Get the window information for this_id
WinGetText, pathToStore, ahk_id %this_id%
; strips the address out of the text storing in ActiveAddress
StringSplit, ActiveAddress, pathToStore, `n
; Turn's Path Into Variable
pathToStore = %ActiveAddress1%
; Remove's The Beginning "Address:" Phrase
pathToStore := RegExReplace(pathToStore, "^Address: ", "")
; Remove's Carriage Returns Incase it Exist in pathToStore
StringReplace, pathToStore, pathToStore, `r, , all
; Store the result in the Full_Path array
ifExist, %pathToStore%
Full_Path%A_Index% := pathToStore
}
; We can now kill all instances of explorer.exe at command prompt
Loop, %id%
{
; Store hwnd in id array
this_id := id%A_Index%
; get process id to kill from stored hwnd
WinGet, pidVal, PID, ahk_id %this_id%
; kill the explorer process
Run, taskkill /f /pid %pidVal%
}
; kill explorer shell
RunWait, taskkill /f /im explorer.exe
; restart explorer shell
Run, explorer
; open all windows we had open previously
Loop, %id%
{
; store actual path to open in local variable path To Open
pathToOpen := Full_Path%A_Index%
; Run explorer providing the correct path to open
Run, explorer %pathToOpen%
}
Return
Any advice or improvements you can make would be greatly appreciated.
Hopefully it will be of use to someone else.
Another approach:
; Get fullpath of all opened explorer windows:
If WinExist("ahk_class CabinetWClass") ; explorer
{
list := ""
; https://autohotkey.com/boards/viewtopic.php?p=28751#p28751
for window in ComObjCreate("Shell.Application").Windows
{
explorer_path := ""
try explorer_path := window.Document.Folder.Self.Path
list .= explorer_path ? explorer_path "`n" : ""
}
list := trim(list, "`n")
; MsgBox, "%list%"
}
; We can now restart the Explorer.exe Process:
RunWait, %comspec% /c taskkill /f /im explorer.exe ,,hide
Process, WaitClose, explorer.exe
Run, explorer.exe
; open all explorer windows we had open previously:
If (list != "")
{
Process, wait, explorer.exe
Loop, parse, list, `n
Run %A_LoopField%
}
How do I check if a specific windoww appears in Autoit.
At the moment I am running with Auto it Adobe After Effect,
so far so good.
The problem is that a warning message pops up if the user does not have quick time installed.
Now I want to check if that window appears and is active and then close it.
So far I have this but did not work:
Local $iPID = Run("C:\Program Files\Adobe\Adobe After Effects CC 2015\Support Files\AfterFX.exe", "", #SW_SHOWMAXIMIZED)
WinWait("[CLASS:AfterEffects]", "", 1000)
Sleep(200000)
; if qicktime warning eror appears
If WinExists ("DroverLord - Window Class", "") Then
Send ("{ENTER}")
EndIf
Does this help?
Opt("WinDetectHiddenText", 1) ;0=don't detect, 1=do detect
Opt("WinSearchChildren", 1) ;0=no, 1=search children also
Opt("WinTextMatchMode", 1) ;1=complete, 2=quick
Opt("WinTitleMatchMode", 2) ;1=start, 2=subStr, 3=exact, 4=advanced, -1 to -4=Nocase
#include<Date.au3>
Local $iPID = Run("C:\Program Files\Adobe\Adobe After Effects CC 2015\Support Files\AfterFX.exe", "", #SW_SHOWMAXIMIZED)
If #error Then
ConsoleWrite('ERROR' & #CRLF)
Exit(0)
EndIf
Global $end = False
Do
; if qicktime warning eror appears
If WinExists("DroverLord - Window Class", "") Then
ConsoleWrite('!FOUND ' & _NowTime() & #CRLF)
Send("{ENTER}") ;close?
WinClose("DroverLord - Window Class", "") ; this
WinKill("DroverLord - Window Class", "") ; or this
$end = True
EndIf
Until $end
Here is an some example code of what you are trying to do:
Local $fDiff
Local $sAfterFXPath = "C:\Program Files\Adobe\Adobe After Effects CC 2015\Support Files\AfterFX.exe"
If FileExists($sAfterFXPath) Then
Local $iPID = Run($sAfterFXPath, "", #SW_SHOWMAXIMIZED)
;no need to call WinExists becuase you are waiting for it to exist and be active with WinActivate
Local $hTimer = TimerInit() ; Begin the timer and store the handle in a variable.
Do
$fDiff = TimerDiff($hTimer)
Until WinActive("Title you are looking for") Or $fDiff >= 30000 ;<<<will exit loop when the window is active or after 30 seconds
If WinActive("Title you are looking for") Then
;Closes the window now that it is active
WinClose("Title you are looking for")
Else
MsgBox(0, "", "The window was never active.")
EndIf
Else
MsgBox(0, "", "File path not found. Do something else...")
EndIf
I am automating a software installation in Windows7 using AutoIt.
During the installation, in between if a error window appears. I want to click ENTER.
If the error window not appears then I should NOT do anything. Simply its should go to the next section.
I have tried "WinActive and WinWaitActive" But its waiting for the window to appear. If window not appears its not going to the next screen.
Any idea how to handle this situation?
Do a while loop:
$w = 0
While($w = 0)
If(WinActive("ERROR WINDOW"))Then
Send("{ENTER}")
$w = 1
ElseIf(ControlGetText("YOUR WINDOW", "", "[CLASS:Static; INSTANCE:2]") <> "SOME TEXT") Then
$w = 1
;and something else
EndIf
Sleep(1000)
WEnd
AdlibRegister() is the right choice. From the help file:
"... typically to check for unforeseen errors. For example, you could use adlib in a script which causes an error window to pop up unpredictably."
Each 100 ms (may be adjusted) the function is called to check the appearing of your error dialog:
Global $sErrorWindow = 'ErrorDialogName'
Global $iDelayHowOftenDoTheFunctionCall = 100
AdlibRegister('_isErrorWindowDisplayed', $iDelayHowOftenDoTheFunctionCall)
Func _isErrorWindowDisplayed()
If WinActive($sErrorWindow) <> 0 Then
WinActivate($sErrorWindow) ; just to be sure that the ENTER command is on the correct window/dialog
; either do
Send('{ENTER}')
; or
ControlClick('title', 'text', 'controlID')
EndIf
EndFunc
; do your software installation processing here
; ...
; ...
; don't forget to unregister the function at the end
AdlibUnRegister('_isErrorWindowDisplayed')
I'm having problem using the Navigate Shell command when the path include an # sign.
; this will create 2 folders at the root of your C: drive
myPath1 := "C:\delete_me\"
myPath2 := "C:\delete#me\"
if !FileExist(myPath1)
FileCreateDir, %myPath1%
if !FileExist(myPath2)
FileCreateDir, %myPath2%
; make an Explorer active and press Alt-1 and Alt-2
return
!1::
strWinId := WinExist("A")
TrayTip, %myPath1%, %strWinId%
For pExp in ComObjCreate("Shell.Application").Windows
if (pExp.hwnd = strWinId)
try pExp.Navigate(myPath1)
return
!2::
strWinId := WinExist("A")
TrayTip, %myPath2%, %strWinId%
For pExp in ComObjCreate("Shell.Application").Windows
if (pExp.hwnd = strWinId)
try pExp.Navigate(myPath2)
return
Alt-1 works well. But, with Alt-2, the Navigate command returns "file:///C:/delete#me/ » not found.".
If there is no "/" after the "#" (eg myPath := "C:\delete#me"), it works. But this cannot be a solution because the destination path can be deeper in a subfolder (eg. "C:\delete#me\xyz").
I tried to encode the "#", replacing it with "%23", without success. Found nothing on the web or MSDN about that. Any idea?
[keywords: haskmark, hashtag, number sign or pound]
I have what looks to be a working solution for this, which I've also posted here:
4 options to change the current folder in Windows Explorer - Page 3 - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=5&t=526&p=153676#p153676
;links:
;Explorer Windows Manipulations - Page 5 - Scripts and Functions - AutoHotkey Community
;https://autohotkey.com/board/topic/19039-explorer-windows-manipulations/page-5#entry297581
;Navigate2 Method (IWebBrowser2)
;https://msdn.microsoft.com/en-us/library/aa752134(v=vs.85).aspx
;4 options to change the current folder in Windows Explorer - AutoHotkey Community
;https://autohotkey.com/boards/viewtopic.php?f=5&t=526
;windows - Navigate Shell command not working when the path includes an hash - Stack Overflow
;https://stackoverflow.com/questions/22868546/navigate-shell-command-not-working-when-the-path-includes-an-hash
;an AutoHotkey v1.1 script
;note: will create folder: %A_Desktop%\abc#def\abc#def
;q:: ;explorer - navigate to folder (tested on Windows 7)
WinGet, hWnd, ID, A
WinGetClass, vWinClass, % "ahk_id " hWnd
if !(vWinClass = "CabinetWClass") && !(vWinClass = "ExploreWClass")
return
vDir = %A_Desktop%\abc#def\abc#def
;vDir = %A_Desktop%\abc def\abc def
if !FileExist(vDir)
FileCreateDir, % vDir
DllCall("shell32\SHParseDisplayName", WStr,vDir, Ptr,0, PtrP,vPIDL, UInt,0, Ptr,0)
for oWin in ComObjCreate("Shell.Application").Windows
if (oWin.HWND = hWnd)
{
if !InStr(vDir, "#")
oWin.Navigate(vDir)
else
{
VarSetCapacity(SAFEARRAY, A_PtrSize=8?32:24, 0)
NumPut(1, SAFEARRAY, 0, "UShort")
NumPut(1, SAFEARRAY, 4, "UShort")
NumPut(vPIDL, SAFEARRAY, A_PtrSize=8?16:12, "Ptr")
NumPut(DllCall("shell32\ILGetSize", Ptr,vPIDL, UInt), SAFEARRAY, A_PtrSize=8?24:16, "Int")
oWin.Navigate2(ComObject(0x2011,&SAFEARRAY))
DllCall("shell32\ILFree", Ptr,vPIDL)
}
break
}
return
If you want to open a new window, there's no need for COM or unreliable workarounds: just run the folder.
Run C:\delete#me
If you want to open the path in an existing window which is already active, the simplest and most effective workaround is this:
SendInput {F4}{Esc}{Raw}C:\delete#me`n
So in the context of your script, you could use the following function to work around the # when it is present:
Navigate(pExp, myPath2)
;...
Navigate(Exp, Path)
{
if RegExMatch(Path, "#.*\\")
SendInput {F4}{Esc}{Raw}%Path%`n
else
Exp.Navigate(Path)
}
Unfortunately, there does not seem to be a solution to this. Shell.Application Navigate command fails if the path includes a hash (# as in C:\C#Projects).
Using AutoHotkey, the workaround would be to rely on the "second best" approach as identified by the tests in this thread: http://ahkscript.org/boards/viewtopic.php?f=5&t=526.
run, Explorer.exe
Sleep, 500
strFolder := A_ScriptDir
Send, {F4}{Esc}
Sleep, 500
ControlSetText, Edit1, C:\delete#me, A
ControlSend, Edit1, {Enter}, A
When I saw that Navigate couldn't handle hash, I was shocked,
but sure enough I replicated the error.
I thought I'd try the short form path just in case. It works!
if vDir contains #
Loop, %vDir%, 2, 0 ;(0/1/2=files/both/folders, 0/1=recurse no/yes)
vDir := A_LoopFileShortPath
The following approach doesn't require a visible address bar, or SendInput,
also the previous navigation history is maintained.
In the worst-case scenario of a hash in the short-form path of the dir above the target dir,
a go-between folder is used which is navigated to.
A link is created there, invoked, and deleted.
Below, the workaround code is indented, to separate it from the standard code.
A hotkey of ctrl+q, when an Explorer window is active, launches the script.
-
^q:: ;explorer - navigate to directory (use go-between dir if short-form path of dir above target contains #)
WinGet, hWnd, ID, A
WinGetClass, vWinClass, ahk_id %hWnd%
if vWinClass not in CabinetWClass,ExploreWClass
Return
vDir2 = %A_Desktop%\Go-Between ;go-between dir
vDir3 = C:\delete#me ;target dir
if (SubStr(vDir3, 1-1) = "\")
vDir3 := SubStr(vDir3, 1, -1)
if !InStr(FileExist(vDir3), "D")
Return
vPathLnk := ""
if vDir3 contains #
Loop, %vDir3%, 2, 0 ;(0/1/2=files/both/folders, 0/1=recurse no/yes)
vDir3 := A_LoopFileShortPath
;vDir4 is the short-form path of the dir above the target
;paths of problem target dirs are of the form: *#*\*
;where there is at least one hash with a backslash to its right
SplitPath, vDir3, , vDir4
if vDir4 contains #
{
if !InStr(FileExist(vDir2), "D")
FileCreateDir, %vDir2%
if !InStr(FileExist(vDir2), "D")
{
MsgBox error`, go-between dir not found:`r`n%vDir2%
Return
}
vNameLnk = Go-Between.lnk
vPathLnk = %vDir2%\%vNameLnk%
FileCreateShortcut, %vDir3%, %vPathLnk%
}
for oWin in ComObjCreate("Shell.Application").Windows
if (hWnd = oWin.Hwnd)
{
vDir1 := oWin.Document.Folder.Self.Path
if (vDir1 = vDir3)
break
if vDir3 contains #
{
if !(vDir1 = vDir2)
oWin.Navigate(vDir2)
while !(oWin.ReadyState = 4)
Sleep 10
oItem := oWin.Document.Folder.Items.Item(vNameLnk)
oItem.InvokeVerbEx("open")
break
}
oWin.Navigate(vDir3)
break
}
oWin := ""
if !(vPathLnk = "")
FileRecycle, %vPathLnk% ;send to recycle bin
;if !(vPathLnk = "")
;FileDelete, %vPathLnk% ;delete
Return
I've collected a script from the AutoHotKey forum which lets me open a command prompt at the location I'm open in windows explorer. If the current window is not a explorer window then the prompt opens at the location where the script is present. I would like to change this behavior and make it open from C:\ if the current window is not a explorer window. I've tried to edit the script but its not working as desired.
#ifwinactive, ahk_class CabinetWClass
ControlGetText, address , edit1, ahk_class CabinetWClass
if (address <> "") {
Run, cmd.exe, %address%
}
else {
Run, cmd.exe, "C:"
}
ExitApp
#ifwinactive
The command to run cmd.exe in the c:\ path is
run, cmd.exe, c:\
A full script that would run the cmd window every time would look like this
SetTitleMatchMode, 2
ifwinactive, ahk_class CabinetWClass
ControlGetText, address , edit1, ahk_class CabinetWClass
else
address =
; Exclude specific windows
ifwinactive, My Computer
address =
ifwinactive, My Documents
address =
if (address <> "")
Run, cmd.exe, %address%
else
Run, cmd.exe, C:\
ExitApp
I realize this is an old question, but I was looking into this myself and have a better solution.
Windows has two in-built ways to start cmd at the path of a current explorer window. Shift+RightClick and then click Open Command Window Here (or press w). You can also press alt+d, type cmd, and press enter. So...
LWin & Return::
if WinActive("ahk_class CabinetWClass")
or WinActive("ahk_class ExploreWClass")
{
Send {Shift Down}{AppsKey}{Shift Up}
Sleep 10
Send w{enter}
}
else
{
run, cmd, C:\
}
return
No magically grabbing the address directly from explorer! :)
Couldn't get other answers to work (it has been a few years since they've been written).
I ended up writing this script:
#o::
Send {Alt down}D{Alt up}cmd{enter}
return
Here's a pretty sophisticated script from the AHK forums:
#NoEnv
#SingleInstance Force
#NoTrayIcon
SendMode Input
SetWorkingDir %A_ScriptDir%
SetTitleMatchMode RegEx
#IfWinActive ahk_class ExploreWClass|CabinetWClass|Progman
#c::
WinGetClass WinClass
If ( WinClass = "Progman" )
{
Run %ComSpec% /K cd /D "C:\"
Return
}
If ( InStr( "WIN_7,WIN_VISTA" , A_OSVersion ) )
{
ControlGetText, Path, ToolbarWindow322
RegExMatch(Path, ":\s*(.*)", Path)
Path := Path1
}
Else
{
; Windows XP doesn't know the Edit1 control exists if
; the Address Bar is hidden, so check if it exists and temporarly
; show the Address bar if needed. Temporarly showing the Address bar
; will register the Edit1 control, which contains the path.
ControlGetPos Edit1Pos , , , , Edit1
If ( !Edit1Pos )
{
PostMessage 0x111 , 41477 , 0 , , A ; Show Address Bar
Sleep 100
PostMessage 0x111 , 41477 , 0 , , A ; Hide Address Bar
}
ControlGetText Path , Edit1
}
If ( InStr( Path , ":" ) )
; If( InStr( Path , ":" ) && FileExist(Path) )
Run %ComSpec% /K cd /D "%Path%"
Else
Run %ComSpec% /K cd /D "C:\"
Return
I tweaked the WIN_7 part a little, so that the code is independent of the unreliable Edit1 control, which doesn't always expose the current explorer location or an incorrect one. If ( InStr( Path , ":" ) ) makes sure that there's no custom path like Computer on Windows 7 or My Computer on Windows XP. I also added an alternative condition that additionally checks for the path to exist, if you want to hedge your bets.
Keep it simple. Unless of course you need complexity.
!f1::
run, C:\Windows\System32\cmd.exe
return
!f1 means Alt+F1. For my personal preference. Change it to whatever you like.
Another solution hacked together from here. Works for me on Windows 10, but I admit it's total copy-pasta. Posting in the hopes of saving someone else's eyes from the horror of AHK scripting.
;; Open terminal in current Explorer window folder
#If WinActive("ahk_class CabinetWClass") ; explorer
F4::
WinGetTitle, ActiveTitle, A
If InStr(ActiveTitle, "\") ; If the full path is displayed in the title bar (Folder Options)
Fullpath := ActiveTitle
else
If InStr(ActiveTitle, ":") ; If the title displayed is something like "DriveName (C:)"
{
Fullpath := SubStr(ActiveTitle, -2)
Fullpath := SubStr(Fullpath, 1, -1)
}
else ; If the full path is NOT displayed in the title bar
; https://autohotkey.com/boards/viewtopic.php?p=28751#p28751
for window in ComObjCreate("Shell.Application").Windows
{
try Fullpath := window.Document.Folder.Self.Path
SplitPath, Fullpath, title
If (title = ActiveTitle)
break
}
Run, cmd.exe, %Fullpath%
return
#If