Inno Setup, spaces and double quote in [Run] - inno-setup

I'm trying to schedule a task on Windows, and unfortunately, it doesn't work!
The task is created but not correctly.
When I look into task's parameters, it says:
PROGRAM: C:\Program
ARGUMENTS: Files(x86)\AppName\executable.exe
This is how I proceed:
[Run]
Filename: "schtasks.exe"; Parameters: "/create /tn TaskName /sc MINUTE /mo 10 /tr ""{app}\{#MyAppExeName}""";
And I don't know why it doesn't work, doubles quotes should fix the "spaces problem"
Any ideas?

This problem is known and is described in this knowledge base article. You will need to enclose the file name between combination of backslash and quotation marks. That article describes:
Cause:
This problem occurs if the path of the scheduled task contains a
space. For example, this problem occurs if you create a schedule for
the following task by using Schtasks.exe:
"c:\foldername containing spaces\task.bat"
Workaround:
To work around this problem, enclose the path portion of the task (not
including arguments or switches) between backslash (\) and quotation
marks (") character combinations, for example \". Enclose the complete
path of the task (including arguments or switches) between quotation
marks as usual when you create a path or command that contains spaces.
For example, the following example task does not run when you schedule
it:
schtasks /create /tn "my task" /tr "c:\foldername containing spaces\script.bat arguments" /sc once /sd 07/29/2003 /st 10:01
However, when you enclose the path of the task between the backslash
and quotation marks character combinations as in the following
example, the scheduled task runs successfully:
schtasks /create /tn "my task" /tr "\"c:\foldername name containing spaces\script.bat\" arguments" /sc once /sd 07/29/2003 /st 10:01
So in your case it could be:
[Run]
Filename: "schtasks.exe"; Parameters: "/create /tn TaskName /sc MINUTE /mo 10 /tr ""\""{app}\{#MyAppExeName}\""";

Late to the party, but as mentioned in this SO answer, you could try to simply add single quotes around your /TR parameter, which would result in
Parameters: "/create /tn TaskName /sc MINUTE /mo 10 /tr '"{app}\{#MyAppExeName}"'";
That might be a bit easier than juggling backslashes.

Related

Schedule task to run hidden in Inno Setup

I have an exe file that I've created using pyinstaller. I am using Inno Setup to create a Windows installer for this executable.
Here's a snippet from my compiler script :
Filename: "schtasks"; \
Parameters: "/Create /F /SC MINUTE /MO 2 /TN ""Discovery"" /TR ""'{app}\Discovery.exe'"""; \
Flags: runhidden runminimized
I'm using schtasks to schedule the execution of my exe file (Discovery.exe). The scheduling works perfectly fine but a command line window still appears when the file runs. This leads me to believe that there's something weird happening with runminimized and runhidden
Discovery.exe is in fact a command line application created using pyinstaller.
How do I ensure that no command line window shows up when this file is supposed to run?
Final working [Run] statement on Inno Setup based on the answer by #Bill_Stewart:
[Run]
Filename: "schtasks"; \
Parameters: "/Create /F /SC MINUTE /MO 5 /TN ""Discovery"" /TR ""'wscript.exe' '{app}\RunHidden.js' '{app}\Discovery.exe' "" "; \
Flags: runhidden runminimized;
Note the usage of quotations due to spaces in my file paths.
The problem is that the runhidden flag in Inno Setup's [Run] section is running the schtasks command, and the schtasks command is scheduling your program (Discovery.exe) to run. When the package installs, the schtasks command runs hidden as requested, but this doesn't mean that the scheduled task you are creating will run Discovery.exe as a hidden process.
If you are running the scheduled task as the current user, the Task Scheduler doesn't have a "run this task hidden" setting. However, you can work around this by creating a short WSH script:
// RunHidden.js
// Runs a program in a hidden window
// Run this script using wscript.exe
var Args = WScript.Arguments;
if ( (Args.Unnamed.Count == 0) || (Args.Named.Item(0) == "/?") ) {
WScript.Echo('Usage: wscript RunHidden.js "command"');
WScript.Quit(0);
}
var FSO = new ActiveXObject("Scripting.FileSystemObject");
var Command = Args.Unnamed.Item(0);
if ( ! FSO.FileExists(Command) ) {
WScript.Echo("File not found - " + Command);
WScript.Quit(2); // ERROR_FILE_NOT_FOUND
}
var WshShell = new ActiveXObject("WScript.Shell");
WshShell.Run('"' + Command + '"',0);
You can distribute the above script with your installation. Schedule wscript.exe as the program to run, the above script and Discovery.exe as parameters, and the scheduled task should run the command without a window.

Signing with full path with spaces to signtool.exe fails with “Sign Tool failed with exit code 0x1” in Inno Script Studio

In Inno Setup, my sign tool is defined as:
cmd /k "C:\Program Files (x86)\Windows Kits\10\bin\10.0.19041.0\x64\signtool.exe" sign /t http://timestamp.comodoca.com /n "My Company" $f
Prepending cmd /k (as suggested at Inno Setup - Signing fails with "Sign Tool failed with exit code 0x1") reveals that there is not actually a problem with the sign tool itself, but rather how Inno Setup is calling it, generating the following message:
'C:\Program' is not recognized as an internal or external command, operable program or batch file.
Clearly, it's chopping off the path to signtool at the first space, even though I put it in quotes. I even tried replacing the quotes with $q to see if that made any difference. (It didn't.) I would think this is improper behavior for the parser to dishonor the quotes, since the instructions clearly say to paste the exact text you'd use on the command line, and the example itself includes quotation marks (https://revolution.screenstepslive.com/s/revolution/m/10695/l/563371-signing-installers-you-create-with-inno-setup).
Everything works beautifully from the command line. For some reason, Inno Setup just isn't properly calling signtool.
ADDED 2020-07-14:
Inno Setup's example, copied from their website:
"C:\Program Files\Microsoft Platform SDK for Windows Server 2003 R2\Bin\signtool.exe" sign /f "C:\MY_CODE_SIGNING.PFX" /t http://timestamp.comodoca.com/authenticode /p MY_PASSWORD $f
My version, used without the cmd /k:
"C:\Program Files (x86)\Windows Kits\10\bin\10.0.19041.0\x64\signtool.exe" sign /t http://timestamp.comodoca.com /n "My Company" $f
As you can see, we use quotes in the same manner. I will check for updates - I probably should have done that first. When I get some time, I'll revert the signtool definition and see if maybe the update fixes it.
Also, I should have been more clear. I am new to Inno Setup and it didn't occur to me to clarify this. I am compiling via Inno Script Studio. It occurs to me that there's some possibility this has to do with a behavior in a specific version of Script Studio and not the compiler itself, but I don't know enough about the inner workings to do any more than speculate.
Having done a bit more tinkering, I'm now fairly certain this must be a bug with Inno Setup. I implemented a work-around as follows:
Open a command window with elevated privileges
Change to a directory I created with no space in the name: cd \bin
Create a 'spaceless' symbolic link to the directory where signtool.exe is located: mklink /d "Windows10SDK" "C:\Program Files (x86)\Windows Kits\10\bin\10.0.19041.0\x64"
Enter new sign tool definition that uses the symbolic link:
C:\bin\Windows10SDK\signtool.exe sign /t http://timestamp.comodoca.com /n "My Company" $f
And that's it! Because there is no longer a space character in the path to signtool.exe, Inno Setup now performs the signing correctly and everything works beautifully.
I'll report this as a bug and update if needed.
I use:
#define SignedDesc "$q" + MSA + "$q"
#define SignedPfx "$qd:\My Certificate\2018\My Certificate.pfx$q"
#define SignedTimeStamp "$qhttp://timestamp.verisign.com/scripts/timestamp.dll$q"
#define SignedPw "$q~~~~~~~$q"
SignTool=SignTool /d {#SignedDesc} /du $q{#AppURL}$q /f {#SignedPfx} /p {#SignedPw} /t {#SignedTimeStamp} /v $f
My sign tool is configured as:
$qC:\Program Files (x86)\Windows Kits\10\bin\10.0.16299.0\x86\Signtool.exe$q sign $p
You have to use $q which is a quote mark.

task scheduler is displaying an error "The specified query is invalid"

I am running Windows 10.
I'm trying to run a backup job (C:\WINDOWS\system32\robocopy.exe) using Task Scheduler. But I was getting issues. To figure out what was going on, I turned on the history log. Unfortunately since doing that, every time I click the History tab I get the following error:
Dialog Title: "Query Error"
Dialog Message: "One or more logs in the query have errors."
The table in the dialog: "Microsoft-Windows-Task-Scheduler/Operational | The specified query is invalid"
"The events displayed are partial results."
Nothing appears in the History pane, so I cannot debug either problem. Does anyone know what is going on?
I am having the exact same error as in
https://www.experts-exchange.com/questions/27676176/Query-Error-In-Microsoft-Task-Scheduler.html
The answer is at
http://www.minasi.com/forum/topic.asp?TOPIC_ID=27906
The answer site (www.minasi.com) is apparently moved and did not retain the answer so cannot try the fix that solved his problem.
Please check if you have single quotes (apostrophes) in the task name. It is known that the apostrophe in the task name breaks task history. To remove them you can try following batch file (it exports task to the xml file, imports it with the new name and removes the old task):
#set "tn=my PC's task"
#if not "%tn%"=="%tn:'=%" echo renaming "%tn%" ==^> "%tn:'=%" && ^
schtasks.exe /query /tn "%tn%" /xml>"%temp%\%tn:\=_%.xml" && ^
schtasks.exe /create /tn "%tn:'=%" /xml "%temp%\%tn:\=_%.xml" && ^
schtasks.exe /delete /tn "%tn%" /f && del /q /f "%temp%\%tn:\=_%.xml"

Quotes around quotes on the Windows command line

So I found this Stack Overflow question which relates to what I would like to do; however, I am having trouble with the directory having spaces within it. I tried looking at several other Stack Overflow questions, but either I misunderstood them, or none have really addressed my problem. I've seen stuff on passing arguments as arrays and using %1 or something to address the special characters, but nothing has worked yet.
I tried entering the following into cmd.exe:
schtasks /Create /SC DAILY /TN PythonTask /TR "python "C:\Users\me\stuff with spaces \pythonprogram.py""
However, the quotes appear to not be taken in the correct order. I would like the command to be input as python "C:\Users\me\stuff with spaces \pythonprogram.py" to cmd.exe everyday.
How can I use quotes around quotes on the Windows command line?
ANSWER FROM BELOW:
Add a backslash \ before the argument which you are putting in quotes. I.e.:
do_some_command_in_windows_shell_with_this_given_string "run "something.exe""
is replaced with:
do_some_command_in_windows_shell_with_this_given_string "run \"something.exe""
Educated guess:
Escape the inner quotes with a backslash.

How to create a triple nested command line string for Shell function in VBA?

I need to create a VBA Macro in Excel.
The task is that when a button is clicked a command will be executed in cmd.
The command to be executed is rfrompcb and it takes the path of a file as argument so there is the first level string which wraps the path up as it contains spaces. As this command is to be executed in cmd there is the second level string, which is the argument for cmd command, i.e. cmd /c "rfrompcb ""file_path""" (I hope I have got this one right). Then since it is to be called by Shell in VBA there is the third level string which wraps the cmd command and serves as the argument for Shell.
My question is: How many double quotation marks should there be? I am quite confused about what the final command line string would look like. Can anyone show me how to construct such string? Or is there another way to do it which involves less string nesting?
Thanks.
You would only need to quote file_path, for example:
shell environ$("COMSPEC") & " /c dir ""c:\program files\"" /b"
environ$("COMSPEC") just returns the full path for cmd.exe.
If the executable path you wish to run does not need to be quoted then to pass it an argument that does need to be quoted:
Shell Environ$("COMSPEC") & " /c rfrompcb ""file path"""
If the exe path does need to be quoted you need to wrap it all in another pair of quotes so it looks like:
cmd.exe /c ""c:\path to\rfrompcb" "file path""
Which can be done:
Shell Environ$("COMSPEC") & " /c """"c:\path to\rfrompcb"" ""file path"""""

Resources