Is there a way to write an autohotkey within an autohotkey? For instance, I have an autohotkey that opens some websites in tabs at work for me & I have an autohotkey that when typed puts in my username & password for some of those sites. Is there a way to put the password autohotkey (actd(at symbol)) inside the IE tabs autohotkey? I did some searching, & it doesn't look like {#} can be sent, so I wasn't sure if there was another way to do it.
Your AutoHotKey script can #Include other scripts, assuming they are not #Persistent. You could loop through your list of tabs, and then call one or more other scripts.
As far as sending the # sign, you should be able to use the Send command without problems. If you do encounter a strange problem, then you can try using the SendRaw command or use the syntax: Send {raw}#
If this doesn't answer your question, please paste some code of what you are trying to get working.
What you can do is write two separate scripts. One does not have an autohotkey assigned, but gets called by the initial script. In your case, you have said that you already have a tabopening hotkey, so I will use a VERY rudimentary example of both scripts, but demonstrate how to send the # symbol and call another script from within a hotkey.
The two scripts I would use are:
tabOpener.ahk, and
passwordEntry.ahk
And they would appear as follows:
tabOpener.ahk
#NoEnv ; Recommended for performance and compatibility with future AutoHotkey releases.
SendMode Input ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir% ; Ensures a consistent starting directory.
; hotkey is set as WinowsKey+t and checks if FireFox exists, if so, it makes it active, if not, it starts FireFox
~#t::
IfWinExist, ahk_class MozillaWindowClass
{ WinActivate
Send ^t
} else run firefox
;Upon opening a new tab in FireFox, the address bar has already got focus,
;so send the web address (You can use COM functions for this, and are highly
;recommended, but out of the scope of this example)
Send, hotmail.com{Enter}
;Waits until page is loaded. Again COM functions are available as they can tell
;when a page is finished loading, but that is a more involved example.
Sleep 5000
;Calls the password entry script.
Run passwordEntry.ahk
return
passwordEntry.ahk
#NoEnv ; Recommended for performance and compatibility with future AutoHotkey releases.
SendMode Input ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir% ; Ensures a consistent starting directory.
;When using send, adding the {Raw} tag will literally interpret every
;character in the remainder of a string. For instance ^ will send ^
;instead of a Control keypress.
Send {Raw}Username#domain.tld
Send {Tab} {Raw}Password
Hopefully that helps. This example showed the use of the {Raw} tag for sending special characters (http://www.autohotkey.com/docs/commands/Send.htm), in addition to calling a separate script from within one's existing hotkey using Run / Runwait (http://www.autohotkey.com/docs/commands/Run.htm).
;~ Alt+1 to send username (email format) and password
!1::Send, myUsername#mydomain.com{tab}myPassword{enter}
depending on you web browser you could use COM objects to handle this very easily. You would find the user id password fields and then for example:
url := "http://yourwebsite.com"
wb := ComObjCreate("InternetExplorer.Application") ; create broswer object
wb.navigate(url)
wb.visible := true ; sets the browser as visible, defaults as not
While (wb.busy || wb.readyState <> 4)
Sleep 100<br>
wb.document.all.username.value := "yourname#wherever.com"
wb.document.all.password.value := "Pa$$word15"
wb.document.all.btnLogin.click()
this however depends on if you are using IE to access your site or not. Look at COM objects in the docs a bit to get a feel for it, and you will learn some really basic things about the DOM, here: Basic DOM MSDN. where I set the "username" & "password" and "btnLogin" control ids in our javascript, would need to be discovered by looking at your page. you should also check out out this tutorial: AHK Basic COM/JavaScript Tutorial
Related
I want define a custom hotkey to rename a selected file in File Explorer. So my new hotkey should behave exactly like the F2 key does by default. That is, when I press the hotkeys, the file name should be editable, allowing me to type a new name. However, I can't use the F2 key to cause windows to do this.
The reason is that I'm using the default hotkeys for something else. I am often running an application (unrelated to AutoHotKey) where the buttons in the UI are triggered using keyhooking for all of the F keys. The only suggestions that I can find on this are to have my custom hotkey use 'send' to raise the default key codes that would be associated with the action. This won't work, because I am using those hotkeys for something else. What I need is a solution that causes a file to be renameable without sending the F2 keycode.
^+!R::
Send {F2} ;This won't work for me
return
Actually the original hotkey can be used, just add $ before the hotkey that you don't want to be fired by the send command. Also using app-specific hotkeys a good idea to minimize possible conflicts.
Try this:
#If winActive("ahk_exe Explorer.EXE")
^+!R::
send {F2}
return
$F2::
send {down}
return
In case you have an application which scans the F2 key globally and unconditionally, and you cannot redefine it, there is not much you can do from within AHK. So ideally you should get rid of that application, and use e.g. AHK for same functionality, or find some workaround.
In this particular case the easiest workaround is alternative way to rename the file:
^+!R::
send {AppsKey}
sleep 100
send {m}
return
Did anyone try to fix the way Labview interferes with normal Alt-Tab behaviour using Autohotkey?
Alt-Tab inside Labview puts all non-labview windows to the end of the list.
So if you have just alt-tabbed to labview window from your browser it takes
(2 × number_of_currently_open_labview_projects -1)
keystrokes to get back.
Great idea. I find that functionality annoying and there doesn't appear to be an easy fix anywhere on the web. Here's my script. Two quick notes:
I had a lot of trouble re-mapping Alt-Tab. If that's critical you can try starting here for help.
To my knowledge it's not possible to get rid of the "screen flicker" because Windows requires some delay between keystrokes.
Note: to adapt this code for various Windows - look up the "ahk_class" using the Window Spy tool included in the AutoHotkey installer .
Code
#NoEnv ; Recommended for performance and compatibility with future
AutoHotkey releases.
#Warn ; Enable warnings to assist with detecting common errors.
SendMode Input ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir% ; Ensures a consistent starting directory.
#NoTrayIcon
#SingleInstance force
SetTitleMatchMode 2 ;partial search mode
#IfWinActive vi
#q:: ;there were issues mapping to Alt+Tab
CountOfVIs := -1
WinGet, id, list,ahk_class LVDChild,, Program Manager
Loop, %id%
{
CountOfVIs := CountOfVIs +1
}
msgbox, # of VIs open: %CountOfVIs% ;when I remove this it doesn't work - must be an AHK thing
Send {Alt down}
Loop,%CountOfVIs%
{
Send {tab}
Sleep,50 ;if this is too low it doesn't work
}
Send {Alt up}
I've recently found an article related to this problem, but unfortunately it is in Russian.
It references the following blog with a python script (+autohotkey mapping) that seems to be solving the problem without the "screen flicker".
In Matlab I can start external .exe files that sometime have a pop up that requires an enter key pressed. For example:
system('C:\Program Files (x86)\WinZip\WINZIP32.EXE')
will start Winzip, and then in order to use it you need to pass the "buy now" pop up window by pressing enter.
Now my problem is not with winzip, I only gave it as an example (i use winrar anyway :).
How can I programmatically press an enter key in Matlab in such cases ? (I use win 7)
Can an event listener be used to solve that?
EDIT: The java.awt.Robot class indeed works on explorer, but not on any software that has a pop up window with an OK button that needs to be pressed. I don't know why it doesn't work for that. I gave the winzip example because I assume everybody has winzip/winrar installed in their machine. The actual software I have is different and irrelevant for the question.
There is a way using Java from Matlab, specifically the java.awt.Robot class. See here.
Apparently there are two types of programs, regarding the way they work when called from Matlab with system('...'):
For some programs, Matlab waits until the program has finished before running the next statement. This happens for example with WinRAR (at least in my Windows 7 machine).
For other programs this doesn't happen, and Matlab proceeds with the next statement right after the external program has been started. An example of this type is explorer (the standard Windows file explorer).
Now, it is possible to return execution to Matlab immediately even for type 1 programs: just add & at the end of the string passed to system. This is standard in Linux Bash shell, and it also works in Windows, as discussed here.
So, you would proceed as follows:
robot = java.awt.Robot;
command = '"C:\Program Files (x86)\WinRAR\WinRAR"'; %// external program; full path
system([command ' &']); %// note: ' &' at the end
pause(5) %// allow some time for the external program to start
robot.keyPress (java.awt.event.KeyEvent.VK_ENTER); %// press "enter" key
robot.keyRelease (java.awt.event.KeyEvent.VK_ENTER); %// release "enter" key
If your applications are only on Windows platform, you can try using .net objects.
The SendWait method of the SendKeys objects allows to send virtually any key, or key combination, to the application which has the focus, including the "modifier" keys like Alt, Shift, Ctrl etc ...
The first thing to do is to import the .net library, then the full syntax to send the ENTER key would be:
NET.addAssembly('System.Windows.Forms');
System.Windows.Forms.SendKeys.SendWait('{ENTER}'); %// send the key "ENTER"
If you only do it once the full syntax is OK. If you plan to make extensive use of the command, you can help yourself with an anonymous helper function.
A little example with notepad
%% // import the .NET assembly and define helper function
NET.addAssembly('System.Windows.Forms');
sendkey = #(strkey) System.Windows.Forms.SendKeys.SendWait(strkey) ;
%% // prepare a few things to send to the notepad
str1 = 'Hello World' ;
str2 = 'OMG ... my notepad is alive' ;
file2save = [pwd '\SelfSaveTest.txt'] ;
if exist(file2save,'file')==2 ; delete(file2save) ; end %// this is just in case you run the test multiple times.
%% // go for it
%// write a few things, save the file then close it.
system('notepad &') ; %// Start notepad, without matlab waiting for the return value
sendkey(str1) %// send a full string to the notepad
sendkey('{ENTER}'); %// send the {ENTER} key
sendkey(str2) %// send another full string to the notepad
sendkey('{! 3}'); %// note how you can REPEAT a key send instruction
sendkey('%(FA)'); %// Send key combination to open the "save as..." dialog
pause(1) %// little pause to make sure your hard drive is ready before continuing
sendkey(file2save); %// Send the name (full path) of the file to save to the dialog
sendkey('{ENTER}'); %// validate
pause(3) %// just wait a bit so you can see you file is now saved (check the titlebar of the notepad)
sendkey('%(FX)'); %// Bye bye ... close the Notepad
As explained in the Microsoft documentation the SendKeys class may have some timing issues sometimes so if you want to do complex manipulations (like Tab multiple times to change the button you actually want to press), you may have to introduce a pause in your Matlab calls to SendKeys.
Try without first, but don't forget you are managing a process from another without any synchronization between them, so timing all that can require a bit of trial and error before you get it right, at least for complex sequences (simple one should be straightforward).
In my case above for example I am running all my data from an external hard drive with an ECO function which puts it into standby, so when I called the "save as..." dialog, it takes time for it to display because the HDD has to wake up. If I didn't introduce the pause(1), sometimes the file path would be imcomplete (the first part of the path was send before the dialog had the focus).
Also, do not forget the & character when you execute the external program. All credit to Luis Mendo for highlighting it. (I tend to forget how important it is because I use it by default. I only omit it if I have to specifically wait for a return value from the program, otherwise I let it run on its own)
The special characters have a special code. Here are a few:
Shift +
Control (Ctrl) ^
Alt %
Tab {TAB}
Backspace {BACKSPACE}, {BS}, or {BKSP}
Validation {ENTER} or ~ (a tilde)
Ins Or Insert {INSERT} or {INS}
Delete {DELETE} or {DEL}
Text Navigation {HOME} {END} {PGDN} {PGUP}
Arrow Keys {UP} {RIGHT} {DOWN} {LEFT}
Escape {ESC}
Function Keys {F1} ... {F16}
Print Screen {PRTSC}
Break {BREAK}
The full list from Microsoft can be found here
There is a small javascript utility that simulates keystrokes like this on the Windows javascript interpreter.
Just create a js file with following code:
var WshShell = WScript.CreateObject("WScript.Shell");
WshShell.SendKeys(WScript.Arguments(0));
then call it from Matlab after the necessary timeout like this:
system('c:\my\js\file\script.js {Enter}');
Can't test here now, but I think this should work...
If you need to run a console-only program in a context that permits full DOS redirection, you can create a file called, say, CR.txt containing a carriage return and use the '<' notation to pipe the value into the program.
This only works if you can provide all the keyboard input can be recorded in the file. It fails dismally if the input has to vary based on responses.
An alternative is to duplicate the input (and possibly output) stream(s) for the program and then pipe data into and out of the program. This is more robust and can permit dynamic responses to the data, but will also likely require substantial effort to implement a robot user to the application.
Rog-O-Matic is an example of a large application completely controlled by a program that monitors screen output and simulates keyboard input to play an early (1980s) ASCII graphic adventure game.
The other responses will be required for GUI-based applications.
Python package pywinauto can wait any dialog and click buttons automatically. But it's capable for native and some .NET applications only. You may have problems with pressing WPF button (maybe QT button is clickable - not checked), but in such case code like app.DialogTitle.wait('ready').set_focus(); app.DialogTitle.type_keys('{ENTER}') may help. Your case is quite simple and probably some tricks with pywinauto are enough. Is your "app with popup" 64-bit or 32-bit?
wait and wait_not functions have timeout parameter. But if you need precisely listener with potentially infinite loop awaiting popups, good direction is global Windows hooks (pyHook can listen mouse and keybd events, but cannot listen dialog opening). I'll try to find my prototype that can detect new windows. It uses UI Automation API event handlers... and... ops... it requires IronPython. I still don't know how to set UI Automation handler with COM interface from standard CPython.
EDIT (2019, January): new module win32hooks was implemented in pywinauto a while ago. Example of usage is here: examples/hook_and_listen.py.
am using AHK to publish boilerplate e-mail body texts in our company. Our employees use various webmail, and other mail so managing templates is impossible. So comes AHK. We have created scripts to publish this with the details of the boilerplate within the body of the script, but it is difficult to delegate revision management when the script itself needs to be edited each time as the boilerplate text changes. Is there a way to send the contents of a Text file, i.e. "bp..pins.txt" as a keyboard input verses placing all the boilerplate text within the script?
Btw: We use Dropbox to sync scripts across users computers.
One way to do that is to simply use the command FileRead
FileSelectFile, path
::doit:: ; hotstring type "doit" to activate
FileRead, FileContent, %path%
Sendinput %FileContent%
return
Hope it helps
Do realize that SendInput has limitations. If you send enough text, it will buffer in the keyboard buffer and show up on the screen much slower than expected. It won't take more than a paragraph for the SendInput to end up being slower than a manual cut and paste.
I recommend reading the file into the clipboard and pasting it instead:
FileSelectFile, path
::doit:: ; hotstring type "doit" to activate
FileRead, FileContent, %path%
Clipboard := FileContent
SendInput ^v
return
I'm testing AutoHotkeys as a way to block user's usage of Ctrl, Alt and Windows Key while an application is running. To do this, I compiled the code:
LAlt::return
RAlt::return
LControl::return
RControl::return
RWin::Return
LWin::Return
into an .exe using the compiler that comes with AutoHotkeys.
My problem is that normally when I close the .exe file (either by code using TerminateProcess(,) or manually) the keys are not released immediately. The Windows Key, for example, may take something like 10 seconds to be finely "unlocked" and become able to be used again, and for me this is unacceptable.
So I got two questions:
Is there a way to fix this problem? How can I make the keys to be released as soon as the .exe is closed?
Would there be any improvement if I tryed to get the same functionality by code? Or if I create the hooks by myself I would get the same problem I'm having with AutoHotkeys?
Thanks,
Momergil
AutoHotkey has a built-in command ExitApp for terminating your scripts.
This example makes Esc your termination hotkey:
Esc::ExitApp
It seems like the delay you are experiencing might be related to how long it's taking the process to close.
You could try making the hotkeys conditional with the #If command*
(i.e. they are only blocked when Flag = 1).
Then you can have the script quickly change the context just before ExitApp by using OnExit. The OnExit subroutine is called when the script exits by any means (except when it is killed by something like "End Task"). You can call a subroutine with a hotkey by using the GoSub command.
Flag := 1
OnExit, myExit
Esc::GoSub, myExit
#If Flag
LAlt::return
LCtrl::return
x::return
#If
myExit:
Flag := 0
Exitapp
* The #If command requires Autohotkey_L.
The other option that will be more verbose, but work for AHK basic, is the hotkey command.
Another option is to have AutoHotkey run the target application, and upon application exit, AutoHotkey exits as well. Here's an example with Notepad. When the user closes Notepad, the script gracefully exits.
RunWait, Notepad.exe
ExitApp ; Run after Notepad.exe closes
LAlt::return
RAlt::return
LControl::return
RControl::return
RWin::Return
LWin::Return
I would use winactive to disable these keys. In this example the modyfier keys are disabled for "Evernote". As soon as you switch to another program the keys are restored and when you switch back to Evernote the modifier keys are disabled again.
SetTitleMatchMode, 2 ; Find the string Evernote anywhere in the windows title
#ifWinActive Evernote
LAlt::return
RAlt::return
LControl::return
RControl::return
RWin::Return
LWin::Return
#ifWinActive