I compiled it to an executable, but to open it I have to right-click and press "Run as administrator". I want it to request admin privileges each time I run it, but how to do it?
I can't do this:
Because then it doesn't work when I copy it to a second computer.
Try adding this to the auto-execute section (top of the script):
; If the script is not elevated, relaunch as administrator and kill current instance:
full_command_line := DllCall("GetCommandLine", "str")
if not (A_IsAdmin or RegExMatch(full_command_line, " /restart(?!\S)"))
{
try ; leads to having the script re-launching itself as administrator
{
if A_IsCompiled
Run *RunAs "%A_ScriptFullPath%" /restart
else
Run *RunAs "%A_AhkPath%" /restart "%A_ScriptFullPath%"
}
ExitApp
}
and recompile the script.
For more details read https://autohotkey.com/docs/commands/Run.htm#RunAs.
Here's a much simpler code for this purpose:
#SingleInstance Force
if not A_IsAdmin
Run *RunAs "%A_ScriptFullPath%"
It will run the script as Admin if it's not already running as Admin.
If you don't have #SingleInstance Force on top of your script, it will ask that if you want to replace the running script (not admin) with admin. So to prevent that, add the mentioned line on top of your script.
If you might compile your script in the future, it's better to use this one instead to make it future-proof:
#SingleInstance Force
if !A_IsAdmin
Run, % "*RunAs " (A_IsCompiled ? "" : A_AhkPath " ") Chr(34) A_ScriptFullPath Chr(34)
Chr(34) returns character "
Source: https://www.autohotkey.com/boards/viewtopic.php?t=39647
Related
I can launch an xterm from the command line (or a program, via a system call) like so:
/usr/X11/bin/xterm -fg SkyBlue -bg black -e myscript
That will launch an xterm with blue text and a black background, and run an arbitrary script inside it.
My question: How do I do the equivalent with Terminal.app?
You can open an app by bundle id too, and give other parameters.
If there's an executable script test.sh in the current directory, the following command will open and run it in Terminal.app
open -b com.apple.terminal test.sh
The only down side that I can find is that Terminal doesn't appear to inherit your current environment, so you'll have to arrange another way to pass parameters through to the script that you want to run. I guess building the script on the fly to embed the parameters would be one approach (taking into account the security implications of course...)
Assuming you already have the colors you want in one of your Terminal profiles, here's what I came up with (with some help from Juha's answer and from this Serverfault answer).
Update:
On reflection, I think this echo business is too complicated. It turns out you can use osascript to make an executable AppleScript file with a shebang line:
#!/usr/bin/osascript
on run argv
if length of argv is equal to 0
set command to ""
else
set command to item 1 of argv
end if
if length of argv is greater than 1
set profile to item 2 of argv
runWithProfile(command, profile)
else
runSimple(command)
end if
end run
on runSimple(command)
tell application "Terminal"
activate
set newTab to do script(command)
end tell
return newTab
end runSimple
on runWithProfile(command, profile)
set newTab to runSimple(command)
tell application "Terminal" to set current settings of newTab to (first settings set whose name is profile)
end runWithProfile
Save that as term.scpt, make it executable with chmod +x, and use it the same way as below, e.g. term.scpt "emacs -nw" "Red Sands".
Original answer:
Assuming we save the script below as term.sh...
#!/bin/sh
echo '
on run argv
if length of argv is equal to 0
set command to ""
else
set command to item 1 of argv
end if
if length of argv is greater than 1
set profile to item 2 of argv
runWithProfile(command, profile)
else
runSimple(command)
end if
end run
on runSimple(command)
tell application "Terminal"
activate
set newTab to do script(command)
end tell
return newTab
end runSimple
on runWithProfile(command, profile)
set newTab to runSimple(command)
tell application "Terminal" to set current settings of newTab to (first settings set whose name is profile)
end runWithProfile
' | osascript - "$#" > /dev/null
...it can be invoked as follows:
term.sh
opens a new terminal window, nothing special
term.sh COMMAND
opens a new terminal window, executing the specified command. Commands with arguments can be enclosed in quotes, e.g. term.sh "emacs -nw" to open a new terminal and run (non-windowed) emacs
term.sh COMMAND PROFILE
opens a new terminal window, executing the specified command, and sets it to the specified profile. Profiles with spaces in their names can be enclosed in quotes, e.g. term.sh "emacs -nw" "Red Sands" to open a new terminal and run (non-windowed) emacs with the Red Sands profile.
If you invoke it with a bad command name, it'll still open the window and set the profile, but you'll get bash's error message in the new window.
If you invoke it with a bad profile name, the window will still open and the command will still execute but the window will stick with the default profile and you'll get an error message (to stderr wherever you launched it) along the lines of
525:601: execution error: Terminal got an error: Can’t get settings set 1 whose name = "elvis". Invalid index. (-1719)
The invocation is slightly hacky, and could probably be improved if I took the time to learn getopt (e.g., something like term.sh -p profile -e command would be better and would, for instance, allow you to easily open a new terminal in the specified profile without invoking a command). And I also wouldn't be surprised if there are ways to screw it up with complex quoting. But it works for most purposes.
Almost all (every?) osx program can be launched from command line using:
appName.app/Contents/MacOS/command
For terminal the command is:
/Applications/Utilities/Terminal.app/Contents/MacOS/Terminal
You can use the autocomplete (tab) or ls to find the correct filenames. ".app" is basically a folder.
To change the colors and run a script... I think you cannot do it with shell scripts as Terminal does not accept arguments ("Terminal myScript.sh" does not launch myScript). With iTerm this works.
Workaround is to use applescript (wrapped in a shell script):
#!/bin/sh
osascript -e '
tell application "Terminal"
activate
tell window 1
do script "sleep 5; exit"
set background color to {0, 11111, 11111}
set win_id to id
end tell
set w_ids to (id of every window)
repeat while w_ids contains win_id
delay 1
set w_ids to (id of every window)
end repeat
end tell'
Ok, now it should behave exactly the same as the xterm example. The drawback is the constant polling of the window ids (which is bad programming).
edit: A bit more elegant applescript would use the 'busy' property of Terminal. I will leave the original code as is works for a general program (not just terminal).
tell application "Terminal"
tell window 1
do script "sleep 2"
set background color to {0, 11111, 11111}
repeat while busy
delay 1
end repeat
close
end tell
end tell
Also for perfectly correct program, one should check that whether the terminal is running or not. It affects the number of windows opened. So, this should be run first (again a nasty looking hack, that I will edit later as I find a working solution).
tell application "System Events"
if (count (processes whose name is "Terminal")) is 0 then
tell application "Terminal"
tell window 1
close
end tell
end tell
end if
end tell
br,
Juha
You can also go into terminal GUI, completely configure the options to your heart's content, and export them to a ".terminal" file, and/or group the configurations into a Window Group and export that to a terminal file "myGroup.terminal". Then
open myGroup.terminal
will open the terminal(s) at once, with all your settings and startup commands as configured.
you can launch terminal with the following command, not sure how to specify colors:
open /Applications/Utilities/Terminal.app/
The answer from #david-moles above works but run the terminal and command in ~ rather the current working directory where term was launched. This variation adds a cd command.
#!/usr/bin/env bash
# based on answer by #david-moles in
# https://stackoverflow.com/questions/4404242/programmatically-launch-terminal-app-with-a-specified-command-and-custom-colors
echo "
on run argv
if length of argv is equal to 0
set command to \"\"
else
set command to item 1 of argv
end if
set command to \"cd '"$PWD"' ;\" & command
if length of argv is greater than 1
set profile to item 2 of argv
runWithProfile(command, profile)
else
runSimple(command)
end if
end run
on runSimple(command)
tell application \"Terminal\"
activate
set newTab to do script(command)
end tell
return newTab
end runSimple
on runWithProfile(command, profile)
set newTab to runSimple(command)
tell application \"Terminal\" to set current settings of newTab to (first settings set whose name is profile)
end runWithProfile
" | osascript - "$#" > /dev/null
There may be a way to set PWD this with applescript.
Note: When I use this, I sometimes two Terminal windows, one a shell running in ~ and a second which runs the cd command and command from argv[1]. Seems to happen if Terminal is not already running; perhaps it is opening old state (even tho I had no open terminals when I closed it).
Few years ago a have write following script:
#IfWinActive ahk_class Photoshop
#Wheelup::
Send, {vkDD}
return
#IfWinActive ahk_class Photoshop
#WheelDown::
Send, {vkDB}
return
This script generate input '[' or ']' when I wheel mouse up or down while win-key is pressed. This script worked good, but now, when I have installed photoshop 2020, it's not working. I thought that ahk_class has been changed , but it's not the case. When I removed ifWinActive line, the script sent characters to the notepad, but not sent them to the photoshop. In addition, my other bingings, are not working while Photoshop is active too.
What should I do to solve this problem?
If Photoshop is running with admin privileges, then AHK won't intercept the key presses, and that could very well be the reason behind this problem.
If that is the case, try to run the AHK script as administrator by adding this to the auto-execute section (top of the script):
; If the script is not elevated, relaunch as administrator and kill current instance:
full_command_line := DllCall("GetCommandLine", "str")
if not (A_IsAdmin or RegExMatch(full_command_line, " /restart(?!\S)"))
{
try ; leads to having the script re-launching itself as administrator
{
if A_IsCompiled
Run *RunAs "%A_ScriptFullPath%" /restart
else
Run *RunAs "%A_AhkPath%" /restart "%A_ScriptFullPath%"
}
ExitApp
}
For more details read https://autohotkey.com/docs/commands/Run.htm#RunAs.
I have the following script:
^!c::
Run stop
Return
Stop is configured to run a program via environment variables.
So if I open up cmd and type “stop” and hit enter the program opens as intended, even if I push winkey + R it does the same thing. However if I use the script with ctrl+alt+c. I do not get the same result.
Why is the script doing something different?
How can I change my script to behave the same way as if it was typed into cmd or winkey + R?
Simple:
run, %comspec% /c stop
Or if this doesn't work you could just start a cmd window and send it directly
run, %comspec% /k
WinWait, %comspec%
WinActivate
Send stop{Enter}
/c tells the console window to close after execution, /k lets it stay open
or you could use an COM object and even get the output.
objShell := ComObjCreate("WScript.Shell")
objExec := objShell.Exec(ComSpec " /c stop")
strStdOut := ""
while, !objExec.StdOut.AtEndOfStream
{
strStdOut := objExec.StdOut.ReadAll()
}
Update:
Without the run command at all:
SetTitleMatchMode, 2
send #r
WinWait, TITLE_OF_THE_RUN_WINDOW
WinActivate
send cmd{Enter}
WinWait, cmd.exe
WinActivate
WinGetTitle, title
Send stop{Enter}
WinWait, %title%,,, stop
WinClose,
TITLE_OF_THE_RUN_WINDOW replace this with the title of the window, which opens on Win+r. A windows cmd window has the command in its title while it gets executed. So we save the title of the command window, and wait for it to drop the command ("stop") and close it then.
UPDATE: Cmd window close added to solution 4
I have to run cmd / c from a program, run the start command xx.exe, and I capture the result (there xx.exe?). until everything is right, however, remains open the console with the error popup. how can I close the console with the error?
Usually win32 applications will close the command prompt after execution. If this isn't the case with what you're trying to run, you could:
Run it from Windows "Run" option (Windows button+R) than your program name and path in prompt.
Run it from a batch file, like so:
runMe.bat:
START "" "C:\windows\notepad.exe"
EXIT`
Than just run runMe.bat from wherever. Notice the 'exit' command that closes the command prompt after execution.
Read more about batch files, the start command, and this issue here, and there.
Good luck!
I have a program which requires Administrative privileges that I want to run from a batch file. What command can I run from command line will run my program with administrative privileges? I'm okay with the pop-up window asking for permission. Additionally, the file needs to be able to run from anywhere on a computer so additional files are run from ./src. The problem is that if I right-click and choose "run as administrator" it changes my current directory so ./src no longer works. If I disable UAC on my machine then everything runs fine. Thank you!
Look here: https://superuser.com/a/269750/139371
elevate seems to be working, calling
C:\Utils\bin.x86-64\elevate.exe -k dir
executes dir in the "current directory" where elevate was called.
This is tough, Microsoft provides no utility to do this (mostly because giving a batch file that ability breaks security), except for RunAs, and that requires that the Administrator account be activated.
There IS a JScript program that can do something similar, by using SendKeys to open the Start menu and type cmd[CTL]+[SHIFT]+[ENTER] which will launch a Command-Line shell.
Save the following as as .js file, like StartAdmin.js:
var WshShell = WScript.CreateObject("WScript.Shell");
WshShell.SendKeys("^{esc}cmd^+{ENTER}"); The equivilent of [CTRL]+[ESC] cmd [CTRL]+[SHIFT]+[ENTER]
To run StartAdmin.js from a batch file, you will need the following line:
wscript StartAdmin.js
To launch from a particular directory and launch a batch file, change line 2 in StartAdmin.js to something like:
WshShell.SendKeys("^{esc}cmd /C "cd %userprofile% & batchfile.bat"^+{ENTER}");
/C switch tells it to run the commands, then close the command-line window.
/K would leave the command window open after it exited the batch file.
To help you understand the SendKeys commands:
+=[Shift Key]
^=[Control Key]
{esc}=[Escape Key]
{enter}=[Enter Key]
To learn more about using CMD.EXE, type CMD /? at the command prompt.
This is a very untidy and ugly way to do it, but it's the only way I know how using only the tools that come with Windows.