One of our users needs to invoke a PowerShell script from a shortcut, as using the command line is probably beyond their abilities. The path of the script contains spaces, and I have been unable to successfully get the script to run from the shortcut. The target of the shortcut is:
powershell.exe -file "C:\Users\xxxxx\xxxx xxxx\Finance - Documents\Secure\xxx (Finance Officer)\Rent\Data File Loader - XXXXX\InvokeDataLoader.ps1"
(I have replaced names of people and the company with x's)
Clicking on the shortcut just briefly opens a cmd window (I think) so I have have been trying to diagnose the problem by running the command in cmd.exe. However when I try to do that I get an error message that it cannot find the path "C:\Users\xxxxx\xxxx" i.e. it is splitting the path on the first space. Enclosing the path with single or double quotes does not change this, and if I try to escape the spaces with backticks I get a message that the path does not exist.
You actually don't need to change the PowerShell script itself to do this. When making the shortcut, simply set the target to:
C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe "C:\Users\xxxxx\xxxx xxxx\Finance - Documents\Secure\xxx (Finance Officer)\Rent\Data File Loader - XXXXX\InvokeDataLoader.ps1"
Related
I am experiencing a rather puzzling error while trying to perform a diff on two files using Visual Studio Code from the command line. I have a text file in the cloud where I save some work related notes. I need to resolve conflicts with other clients editing the file. Usually this only happens during a loss of connection though somehow I find myself having to resolve a lot of them so between this and other uses of diff I will use the usual syntax. It looks something like this:
code --diff "R&D (cloud conflict 2-5-23).txt" "R&D.txt"
My filename happens to have a '&' in it and this command launches the usual 2-way diff in VS Code and reads through the first file name with no problem but doesn't read past the second '&' and the resulting diff tab in VS Code looks something like:
R&D (cloud conflict 2-25-23).txt <-> R
Where the right side "R" doesn't exist. So it would seem '&' needs to be processed literally.
No problem, let's see if backslash \ is an accepted escape parameter...
code --diff "R\&D (cloud conflict 2-5-23).txt" "R\&D.txt"
Nope. Same problem. 🤔 In fact this outputs something even stranger:
Code diff tab:
&D (cloud conflict 2-25-23).txt <-> R
with shell output:
'D.txt' is not recognized as an internal or external command, operable program or batch file.
I also tried the carrot symbol '^' as an escape parameter to a similar effect. I just includes it in the first file and the editor still thinks the second file name is just "R".
The help file for the VS Code command line integration didn't have a lot to say about the --diff parameter other than a short description and I was hoping to get something about processing strings literally or escape characters. Perhaps another parameter that I need or maybe this has more to do with the shell in general.
I find it really strange that it can read the first full file name but breaks at the second '&'. Weirder still that if a supposed escape character is included in the second file name, it will omit that as well. 😵
For now all I can do is rename the file which is a bummer. 🤷♂️ I have VS Code version 1.75.0 on Windows 10 Home latest version/build and I'm using PowerShell version 5.1.19041.2364.
Edit: The issue definitely appears to be PowerShell related as it turns out. I was finally able to run this command successfully in a regular command prompt. (Simply typing "cmd" and Enter into the PowerShell window before running the diff command). Unfortunately, I happen to be running this command as part of PowerShell script. I may have to figure out how to run a CMD command from inside my PowerShell script if that is at all possible. I'm not sure. 🤔 If not, I need to figure out what exactly PowerShell is doing to my command when it reaches the '&' character.
tl;dr
You need a workaround:
cmd /c 'code --diff "R&D (cloud conflict 2-5-23).txt" "R&D.txt"'
Alternatively, using --%, the stop-parsing token:
code --diff "R&D (cloud conflict 2-5-23).txt" --% "R&D.txt"
Note: --% comes with fundamental limitations, notably the inability to reference PowerShell variables - see this answer.
Background information:
The root cause is that code is implemented as a batch file (code.cmd) and that cmd.exe, the interpreter that executes batch file inappropriately parses its list of arguments as if they had been submitted from INSIDE a cmd.exe session.
PowerShell, which - of necessity - has to rebuild the process command line behind the scenes on Windows after having performed argument parsing based on its rules, and - justifiably - places "R&D.txt" as verbatim R&D.txt on the process command line, given that the argument value contains no spaces.
The result is that cmd.exe interprets the unquoted R&D.txt argument on its command line as containing metacharacter &, which is its command-sequencing operator, causing the call to break.
Given that cmd.exe, the legacy Windows shell, is unlikely to receive fixes, the actively maintained PowerShell (Core) 7+ edition could as a courtesy compensate for cmd.exe's inappropriate behavior.
Doing so has been proposed in GitHub issue #15143, but, alas, it looks like these accommodations will not be implemented.
Ex:
cmd /C start C:\Users\Bob Builder\Desktop\New Folder\test.exe
I'm trying to use cmd to start a file but since there are spaces in the path, cmd is throwing an error after Bob.
Error:
"Windows cannot find C:\Users\Bob. Make sure you typed the name
correctly, then try again."
The system cannot find the file C:\Users\Bob.
Its simply failing to accept the spaces. It's driving me crazy because I'm spoiled with C# working out of the box. I don't know much about this, I have been spending way too much time trying to figure this out. Some help would be greatly appreciated.
In order for a path that contains spaces to be recognized as a single path (argument), it must be quoted.
In order for an executable to execute in the current console window, synchronously, with its streams connected to the calling shell, it must be invoked directly, not via start.
Direct invocation from cmd.exe (only "..." quoting supported):
"C:\Users\Bob Builder\Desktop\New Folder\test.exe"
From PowerShell:
& 'C:\Users\Bob Builder\Desktop\New Folder\test.exe'
Note:
PowerShell also supports '...' strings (single-quoted), which are verbatim strings that are preferable to "..." (double-quoted) ones if you do not require expansion of variables (string interpolation) - see the conceptual about_Quoting_Rules help topic.
For syntactic reasons, PowerShell requires the use of &, the call operator to invoke commands that are quoted and/or contain variable references - see this answer for details.
By contrast, use start in cmd.exe / Start-Process in PowerShell (whose built-in alias is also start) to launch an executable in a new window (on Windows), asynchronously, with no (direct) ability to capture the launched executable's output:
From cmd.exe:
start "title" "C:\Users\Bob Builder\Desktop\New Folder\test.exe"
Note:
Specifying "title" - i.e. a self-chosen (console) window title - is required for syntactic reasons in this case: without it, the double-quoted path itself would be interpreted as the window title, and the - implied - executable to launch would be another cmd.exe instance.
Note that if you launch a GUI application this way, the title argument is irrelevant, because no new console window is created.
Conversely, if you launch a console application specified by double-quoted path and therefore must use a title argument, note that "" will result in the new window having no title.
From PowerShell (parameter -FilePath is positionally implied):
Start-Process 'C:\Users\Bob Builder\Desktop\New Folder\test.exe'
Note:
Start-Process does not support specifying a window title, so you may want to call cmd.exe's internal start command for that (or other features not supported by Start-Process, such as specifying the process priority).
To work around quoting problems, invoke cmd.exe's start from PowerShell by passing the entire start command as a single string to cmd /c:
cmd /c 'start "title" "C:\Users\Bob Builder\Desktop\New Folder\test.exe"'
cmd /C start "C:\Users\Bob Builder\Desktop\New Folder\test.exe"
Quotes are your friend. Sometimes even double quotes are too!
Seems like cmd won't work for me. Powershell worked with this script:
$env:Path += ";C:\Users\Bob Builder\Desktop\New Folder\"
test.exe
I think that my question is something too easy that you guys will solve in 1 minute.
I'm trying to run a script that have multiple lines of code. But, when I write the first line and hits SHIFT+ENTER it runs the code. I need to write a new line, instead of running what I've wrote.
Anybody knows what should I do (instead killing myself because I'm too dumb) ?
In powershell console there are a few ways to make a new line
A. Shift + Enter : Use this at any point to make a new line
B. The opening of a string " or ' until the closing of the string " or ' : use this when you have a string that you wish to span many lines
C. A pipe | : Use this if you have output that you would like to pass to another command
D. The Back tick (escape char) ` : use this to separate lines for a new command or splitting a command into other lines
If you are new to powershell, I would suggest using Powershell ISE. If its installed you can go to the powershell console and type ISE or go to start and type Powershell ISE. This will be a good place to run scripts and debug as you can add breakpoints to your scripts.
The easiest and best way to do this would be to create the script inside of the PowerSheell ISE program. You can then reference this script and run it in the console by preceding it with a .\script.ps1.
If needed you can create script on the command line by creating and writing to the file from the console.
Open the PowerShell console
Run the following command to create a file New-Item script.ps1
Run the next command as many times as it takes to populate the file Add-Content script.ps1 "My code line here"
Run the code using the script run command .\script.ps1
Now let it be known that the ISE is a much better tool because it allows for debugging of files and testing them on demand. The only downside is it will cache whatever it uses or creates (such as variables or references). If you aren't getting the expected result trying closing and reopening to clear the cache run it from the console in tandem. One last thing to note is that if you use the ISE and it successfully runs there that doesn't mean it will run in the console. Be sure to test thoroughly.
I got some strange behaviour when executing a powershell script.
When I run my script using the ISE it works just fine.
When I open Powershell.exe and run my script it works just fine.
When I open cmd, and start my script using powershell.exe -noexit
./myscript.ps1, myscript works just fine.
When I double-click myscript however, powershell opens for some milliseconds, I see that it shows some error (red font) and the powershell window closes. I'm unable to track down the error causing this problem since the powershell windows closes to fast.
I even tried one single big try-catch block around my hole script, catching any [Exception] and writing it down to a log file. However: the log file is not generated (catch is not called).
How can I track that issue? What could possibly be causing the trouble?
Please note that my execution-policy is set to unrestricted.
Before trying the suggestion invoke this to see your current settings (if you want restore them later):
cmd /c FType Microsoft.PowerShellScript.1
Then invoke this (note that you will change how your scripts are invoked "from explorer" by this):
cmd /c #"
FType Microsoft.PowerShellScript.1=$PSHOME\powershell.exe -NoExit . "'%1'" %*
"#
Then double-click the script, it should not exit, -NoExit does the trick. See your error messages and solve the problems.
But now all your scripts invoked "from explorer" keep their console opened. You may then
remove -NoExit from the above command and run it again or restore your
original settings.
Some details and one good way to invoke scripts in PS v2 is here.
Unfortunately it is broken in PS v3 - submitted issue.
by default, for security reason when you double clic on a .ps1 file the action is : Edit file, not Run file .
to execute your script : right-click on it and choose run with powershell
I also wasn’t able to run a script by double clicking it although running it manually worked without a problem. I have found out that the problem was in the path. When I ran a script from a path that contained spaces, such as:
C:\Users\john doe\Documents\Sample.ps1
The scipt failed to run. Moving the script to:
C:\Scripts\Sample.ps1
Which has no spaces, solved the problem.
This is most likely an issue with your local Execution Policy.
By default, Powershell is configured to NOT run scripts that are unsigned (even local ones). If you've not signed your scripts, then changing your default double-click 'action' in Windows will have no effect - Powershell will open, read the execution policy, check the script's signature, and finding none, will abort with an error.
In Powershell:
Help about_execution_policies
gives you all the gory details, as well as ways to allow unsigned scripts to run (within reason - you'd probably not want to run remote ones, only ones you've saved onto the system).
EDIT: I see at the tail end of your question that you've set Execution Policy to 'unrestricted' which SHOULD allow the script to run. However, this might be useful info for others running into execution policy issues.
If you would catch the error you will most likely see this
The file cannot be loaded. The file is not
digitally signed. The script will not execute on the system. Please
see "Get-Help about_signing" for more details.
Because you are able to run it from the shell you started yourself, and not with the right mouse button click "Run With PowerShell", I bet you have x64 system. Manually you are starting the one version of PowerShell where execution policy is configured, while with the right click the other version of the PowerShell is started.
Try to start both version x64 and x86 version and check for security policies in each
Get-ExecutionPolicy
I was in exactly the same situation as described in the question : my script worked everywhere except when double-clicking.* When I double-clicked a powershell windows would open but then it will close after a second or so. My execution-policy is also set to unrestricted.
I tried the selected answer concerning FType Microsoft.PowerShellScript.1 but it didn't change anything.
The only solution I found was a work around: create a bat file which start the powershell.
Create a file, copy this and modify the path : powershell.exe -File "C:\Users\user\script\myscript.ps1"
Save it as a .bat
Double-click the bat
I also used .ahk to start my powershell with a shorcut and it didn't work when pointing directly to the powershell. I had to point to the .bat
I have a executable that when double clicked opens in a command line window.
Now there is a input file (i.e named "sphere_15000.inp") in the same directory where the executable apame_win64.exe is located. So we can inter the file name in the command line.
The question is how this can be done from mathematica front end? With the RunThrough command I tried to do it with no avail.
RunThrough["Executable Location", "sphere_15000"]
Do I need to put this file location in my Windows 7 environment path variable? Hope for some suggestion in this regard.
UPDATE
Found a solution to my problem.
First set the Mathematica directory to the folder where the executable is located.
path="C:\Users\FlowCrusher\Desktop\CUSP solver\Apame_build_2011_01_09\solver";
SetDirectory[path];
Then use the following style of input.
Run["\"\"apame_win64.exe\" \"input\"\""]
Here "apame_win64.exe" is the executable one want to run and "input" is the input file for the executable. This solves the problem. But a new item in the wishlist.
Is there a way to hide the console window in the background?
Here is how it looks on my screen.
As Chris suggested if we use minimized console in the Run command we get a minimized window but the program does not execute.
I hope that a solution exists.
BR
Yes, you might put the folder of you executable into the Path variable, or provide the full path name.
However, RunThrough seems to have been superseeded (on Windows) by
Import["!command ","Text"], which will execute command and read the comaand line output into Matheamtica as a string.
E.g.:
Export["testit.txt", "bla", "Text"];
Import["!dir" <> " testit* > dir.log", "Text"];
FilePrint["dir.log"]
--
Otherwise, I also had good results in the past using NETLink (not sure if WScript.shell
still works on Windows7/8 or if one should use something else).
Emulating Run (RunThrough is not really needed I think):
Run2[cmd_String] := Module[{shell},
Switch[$OperatingSystem,
"Windows",
Needs["NETLink`"];
shell = NETLink`CreateCOMObject["WScript.shell"];
shell # run[cmd,0,True],
"Unix",
Run # cmd,
"MacOSX",
Run # cmd ] ];
Can you run your application with input from a basic command window instead of the application console? This might be the form of command you would need:
apame_win64 -input sphere_15000.inp
or simply
apame_win64 sphere_15000.inp
You can probably check the available switches by running apame_win64 -help
A multi-part command can be run from Mathematica, e.g.
Run["type c:\\temp\\test.txt"]
Alternatively, also returning output to the Mathematica session:
ReadList["!type c:\\temp\\test.txt", String]
I landed here wanting to run abaqus command line on windows.
The solutions provided here worked out for me (Windows 7, Mathematica 9):
SetDirectory#path;
Run["start /min abaqus job=" <> fileName <> " interactive ask_delete=OFF >> log.txt"]
(Here the abaqus option ask_delete=OFF overwrites an existing simulation results and the >> redirects all the output to a file)
I think, minimizing the window did not run in your case since the executable throws open that window. In that case, this might be of some help