Running programs via shell - windows

I am running Windows 7x64 and Excel 2010x32. I call 32bit dos programs (written in Fortran) via vba using ExecCmd (a Microsoft function that waits for a command prompt process to finish). I send a command line to this function that explicitly contains the program path and the paths of the input file and output file.
This runs fine on my PC and also on a company PC running the same software (OS and Office) and for which I have general access to the C: drive.
On other company PCs, where there is not general access to the C: drive, this does not work - i.e. the dos programs do not produce an output file. On these PCs, I can still run the program at the command prompt manually. It is just that calling this command prompt does not work via Excel VBA.
Now the strange thing is that I can successfully run one of these programs by adding "cmd.exe /c" at the beginning of the command line. That would appear to be running a command prompt within a command prompt (!). The other program (which, incidentally, is quite a bit bigger) does not work at all via vba on these PCs. I need to be able to provide other employees with something that works.
Can anyone shed some light on what is happening here and suggest a work around? I could past some code, but I think the above should be self explanatory.

You're confusing the command shell with the console window. In this context, the distinction is critical.
Console-mode programs (aka "command-line programs") require a console window to provide input and output. When a console-mode program is launched from a GUI program, Windows automatically creates a console window for it (unless instructed otherwise).
The command shell (aka "Command Prompt") is cmd.exe, a console-mode program.
The important point here is that not every console window has an instance of cmd.exe running in it. When a console-mode program is launched from a GUI program, Windows automatically creates a console window but does not automatically create an instance of cmd.exe. If you want to pass a command to cmd.exe you have to do so yourself, or use a run-time library routine that does it for you.
ExecCmd does not do this; it runs the program directly. So passing cmd /c <command> to ExecCmd is not "running a command prompt within a command prompt" at all. Without the cmd /c you aren't running a command shell command, you're just launching an executable.
There are any number of reasons why the command you're passing might need to be given to the command shell. For example:
it might be a built-in command like dir or type which only exists within the command shell;
it might include redirection or pipelining operators, or environment variable substitution;
it might be a script rather than an executable.
There are other cases. If you show us the command line being passed to ExecCmd we may be able to provide more specific advice. (The fact that the same command line is apparently working on some machines is puzzling, but can't be addressed without more information.)

Related

Is there a command in Shell scripting for executing .exe file and running commands automatically inside of it? replacing the user interaction

I have a .sh script file that I'm modifying which runs an .EXE file that opens the Windows command line prompt automatically.
This .exe asks the user for an input (name of the file in the folder workspace that it will read)
I want to automate this step in my shell script so my user doesn't have to interact with this, and run the commands automatically
I read a bit about the expect command but I think that is for Linux only.
Can someone help me, I'm pretty new to Shell scripting and I couldn't find any useful information elsewhere.
I'm assuming that your executable accepts command-line arguments. So, here we go.
You can use the "start" command in Windows Shell. For example:
start C:\path\to\program.exe -argument
If you want to make the script wait until the .exe file finishes running before continuing, you can use the "/wait" command:
start /wait C:\path\to\program.exe -argument
IF all of that doesn't work, please try:
start myprogram.exe /command1 /command2 /command3
Hope it helps,

TeraTerm execution through the Windows command prompt

I have some basic simple two character commands to be executed in TeraTerm.
Is there a way to execute the same TeraTerm commands through a Windows command prompt? This will overcome my dependency to open TeraTerm and then running, commands. I can directly write some .bat file to execute my short commands.
Assuming that your commands are for teraterm, and not for the OS of your device connected via teraterm, you can save your commands into a .ttl file (using notepad or whatever). You can still make it work if the commands are for the OS (using a command line or whatever in the shell of the OS program connected), but you will have to make extra commands to navigate to it.
Using the .ttl file, you can make a .bat file that does two things:
cd C:\Program Files\teraterm
TTPMacro C:\[point to .ttl file]
This won't prevent teraterm from opening, because if you script involves you interfacing with teraterm at all, it'll open unless you add /V after TTPMcro. However, it will be a hands free experience.
You can find out more about deploying the macro here: https://ttssh2.osdn.jp/manual/en/macro/
And a list of all the commands here: https://ttssh2.osdn.jp/manual/en/macro/command/index.html
And if you need special characters for navigation (ctrl+s, etc), the ASCII code table is here: https://ttssh2.osdn.jp/manual/en/macro/appendixes/ascii.html
Hope that helps!
If it's only several basic commands, you can make it without the ttl file by using TTermPro in lieu of TTPMacro.
cd C:\Program Files\teraterm
TTERMPRO /C=1 (connect thru serial com 1)
TTERMPRO etc etc
The syntax for command line using TTERMPRO can be found here: https://ttssh2.osdn.jp/manual/en/commandline/teraterm.html

Difference between calling "start myapp" and "myapp"

In a Windows batch file, or in the Command Prompt, what's the difference between calling start mspaint, for example, and mspaint? They appear to do exactly the same thing.
Another example, where all 4 cases appear to do the same thing. Can you please help me understand what are the subtle differences, if any?
taskmgr
C:\Windows\System32\Taskmgr.exe
start taskmgr
start C:\Windows\System32\Taskmgr.exe
Follow-up: it looks like start opens a separate background command prompt to run the program you write after it (source: https://technet.microsoft.com/en-us/library/cc770297(v=ws.11).aspx). Is this the same as Linux's myApp & format--where you have the & suffix?
Starting a Program
See start /? and call /? for help on all three ways.
Specify a program name
c:\windows\notepad.exe
In a batch file the batch will wait for the program to exit. When
typed the command prompt does not wait for graphical
programs to exit.
If the program is a batch file control is transferred and the rest of the calling batch file is not executed.
Use Start command
start "" c:\windows\notepad.exe
Start starts a program and does not wait. Console programs start in a new window. Using the /b switch forces console programs into the same window, which negates the main purpose of Start.
Start uses the Windows graphical shell - same as typing in WinKey + R (Run dialog). Try
start shell:cache
Also note the first set of quotes, if any, MUST be the window title.
Use Call command
Call is used to start batch files and wait for them to exit and continue the current batch file.
With Reference to Start and just typing a program name.
Help Windows Find Programs and Documents
Programs and documents can be added to the registry so typing their name without their path in the Start - Run dialog box or shortcut enables Windows to find them.
REGEDIT4
;The bolded name below is the name of the document or program, <filename>.<file extension>
[HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\App Paths\IE.txt]
;The # means the path to the file is assigned to the default value for the key.
;The whole path in enclosed in a quotation mark ".
#="\"C:\\Program Files\\Internet Explorer\\IE.txt\""
;Optional Parameters. The semicolon means don't process the line. Remove it if you want to put it in the registry
;Informs the shell that the program accepts URLs.
;"useURL"="1"
;Sets the path that a program will use as its' default directory. This is commented out.
;"Path"="C:\\Program Files\\Microsoft Office\\Office\\"
For a technical discussion.
CMD preprocesses commands and finds the file then calls CreateProcess. Start - Run dialog or the Start command uses ShellExecuteEx which eventually calls CreateProcess.
This is CreateProcess rules - note CMD provides full paths to CreateProcess. https://msdn.microsoft.com/en-us/library/ms682425
1.The directory from which the application loaded.
2.The current directory for the parent process.
3.The 32-bit Windows system directory. Use the GetSystemDirectory function to get the path of this directory.
The 16-bit Windows system directory. There is no function that obtains the path of this directory, but it is searched. The name of this directory is System.
5.The Windows directory. Use the GetWindowsDirectory function to get the path of this directory.
6.The directories that are listed in the PATH environment variable. Note that this function does not search the per-application path specified by the App Paths registry key. To include this per-application path in the search sequence, use the ShellExecute function.
ShellExecuteEx is here https://msdn.microsoft.com/en-us/library/bb759784(v=vs.85).aspx
CMD preprocessing is available on my Skydrive - originally from MS web site but no more. See Windows NT Command Shell Ch 2 https://1drv.ms/f/s!AvqkaKIXzvDieQFjUcKneSZhDjw
you need to call start application when you want the application to launch and return immediately to the command shell for further commands.
(on Linux, closest equivalent of start is the & suffix)
Some commands have the ability to do that without start prefix. That's what you're experiencing.
On the other hand, if you want an application returning immediately to "block" the shell, prefix by cmd /c
Try cmd /c taskmgr for instance, you'll see it blocks the command window until you quit it.
About the question about taskmgr, the 3 possibilities amount to the same result:
taskmgr is in system path: with or without full path the system finds it
taskmgr returns to the command window immediately. In that case, start is redundant.

How to run VBScript from command line without Cscript/Wscript

I am a beginner in VBScript. I googled it & got to know that we can run VBScript from command line by executing below command:
For Example my vbscript name is Converter.vbs & it's present in folder D:\VBS.
I can run it through following methods:
CScript "D:\VBS\Converter.vbs"
OR
WScript "D:\VBS\Converter.vbs"
Now I would like to execute above VBScript without Cscript or Wscript command by simply typing the name of VBscript name i.e. Converter.
I DON'T WANT TO SPECIFY THE FULL PATH OF VBSCRIPT EVERYTIME.
Can anyone please guide me on how to do that ?
I'll break this down in to several distinct parts, as each part can be done individually. (I see the similar answer, but I'm going to give a more detailed explanation here..)
First part, in order to avoid typing "CScript" (or "WScript"), you need to tell Windows how to launch a * .vbs script file. In My Windows 8 (I cannot be sure all these commands work exactly as shown here in older Windows, but the process is the same, even if you have to change the commands slightly), launch a console window (aka "command prompt", or aka [incorrectly] "dos prompt") and type "assoc .vbs". That should result in a response such as:
C:\Windows\System32>assoc .vbs
.vbs=VBSFile
Using that, you then type "ftype VBSFile", which should result in a response of:
C:\Windows\System32>ftype VBSFile
vbsfile="%SystemRoot%\System32\WScript.exe" "%1" %*
-OR-
C:\Windows\System32>ftype VBSFile
vbsfile="%SystemRoot%\System32\CScript.exe" "%1" %*
If these two are already defined as above, your Windows' is already set up to know how to launch a * .vbs file. (BTW, WScript and CScript are the same program, using different names. WScript launches the script as if it were a GUI program, and CScript launches it as if it were a command line program. See other sites and/or documentation for these details and caveats.)
If either of the commands did not respond as above (or similar responses, if the file type reported by assoc and/or the command executed as reported by ftype have different names or locations), you can enter them yourself:
C:\Windows\System32>assoc .vbs=VBSFile
-and/or-
C:\Windows\System32>ftype vbsfile="%SystemRoot%\System32\WScript.exe" "%1" %*
You can also type "help assoc" or "help ftype" for additional information on these commands, which are often handy when you want to automatically run certain programs by simply typing a filename with a specific extension. (Be careful though, as some file extensions are specially set up by Windows or programs you may have installed so they operate correctly. Always check the currently assigned values reported by assoc/ftype and save them in a text file somewhere in case you have to restore them.)
Second part, avoiding typing the file extension when typing the command from the console window.. Understanding how Windows (and the CMD.EXE program) finds commands you type is useful for this (and the next) part. When you type a command, let's use "querty" as an example command, the system will first try to find the command in it's internal list of commands (via settings in the Windows' registry for the system itself, or programmed in in the case of CMD.EXE). Since there is no such command, it will then try to find the command in the current %PATH% environment variable. In older versions of DOS/Windows, CMD.EXE (and/or COMMAND.COM) would automatically add the file extensions ".bat", ".exe", ".com" and possibly ".cmd" to the command name you typed, unless you explicitly typed an extension (such as "querty.bat" to avoid running "querty.exe" by mistake). In more modern Windows, it will try the extensions listed in the %PATHEXT% environment variable. So all you have to do is add .vbs to %PATHEXT%. For example, here's my %PATHEXT%:
C:\Windows\System32>set pathext
PATHEXT=.PLX;.PLW;.PL;.BAT;.CMD;.VBS;.COM;.EXE;.VBE;.JS;.JSE;.WSF;.WSH;.MSC;.PY
Notice that the extensions MUST include the ".", are separated by ";", and that .VBS is listed AFTER .CMD, but BEFORE .COM. This means that if the command processor (CMD.EXE) finds more than one match, it'll use the first one listed. That is, if I have query.cmd, querty.vbs and querty.com, it'll use querty.cmd.
Now, if you want to do this all the time without having to keep setting %PATHEXT%, you'll have to modify the system environment. Typing it in a console window only changes it for that console window session. I'll leave this process as an exercise for the reader. :-P
Third part, getting the script to run without always typing the full path. This part, in relation to the second part, has been around since the days of DOS. Simply make sure the file is in one of the directories (folders, for you Windows' folk!) listed in the %PATH% environment variable. My suggestion is to make your own directory to store various files and programs you create or use often from the console window/command prompt (that is, don't worry about doing this for programs you run from the start menu or any other method.. only the console window. Don't mess with programs that are installed by Windows or an automated installer unless you know what you're doing).
Personally, I always create a "C:\sys\bat" directory for batch files, a "C:\sys\bin" directory for * .exe and * .com files (for example, if you download something like "md5sum", a MD5 checksum utility), a "C:\sys\wsh" directory for VBScripts (and JScripts, named "wsh" because both are executed using the "Windows Scripting Host", or "wsh" program), and so on. I then add these to my system %PATH% variable (Control Panel -> Advanced System Settings -> Advanced tab -> Environment Variables button), so Windows can always find them when I type them.
Combining all three parts will result in configuring your Windows system so that anywhere you can type in a command-line command, you can launch your VBScript by just typing it's base file name. You can do the same for just about any file type/extension; As you probably saw in my %PATHEXT% output, my system is set up to run Perl scripts (.PLX;.PLW;.PL) and Python (.PY) scripts as well. (I also put "C:\sys\bat;C:\sys\scripts;C:\sys\wsh;C:\sys\bin" at the front of my %PATH%, and put various batch files, script files, et cetera, in these directories, so Windows can always find them. This is also handy if you want to "override" some commands: Putting the * .bat files first in the path makes the system find them before the * .exe files, for example, and then the * .bat file can launch the actual program by giving the full path to the actual *. exe file. Check out the various sites on "batch file programming" for details and other examples of the power of the command line.. It isn't dead yet!)
One final note: DO check out some of the other sites for various warnings and caveats. This question posed a script named "converter.vbs", which is dangerously close to the command "convert.exe", which is a Windows program to convert your hard drive from a FAT file system to a NTFS file system.. Something that can clobber your hard drive if you make a typing mistake!
On the other hand, using the above techniques you can insulate yourself from such mistakes, too. Using CONVERT.EXE as an example.. Rename it to something like "REAL_CONVERT.EXE", then create a file like "C:\sys\bat\convert.bat" which contains:
#ECHO OFF
ECHO !DANGER! !DANGER! !DANGER! !DANGER, WILL ROBINSON!
ECHO This command will convert your hard drive to NTFS! DO YOU REALLY WANT TO DO THIS?!
ECHO PRESS CONTROL-C TO ABORT, otherwise..
REM "PAUSE" will pause the batch file with the message "Press any key to continue...",
REM and also allow the user to press CONTROL-C which will prompt the user to abort or
REM continue running the batch file.
PAUSE
ECHO Okay, if you're really determined to do this, type this command:
ECHO. %SystemRoot%\SYSTEM32\REAL_CONVERT.EXE
ECHO to run the real CONVERT.EXE program. Have a nice day!
You can also use CHOICE.EXE in modern Windows to make the user type "y" or "n" if they really want to continue, and so on.. Again, the power of batch (and scripting) files!
Here's some links to some good resources on how to use all this power:
http://ss64.com/
http://www.computerhope.com/batch.htm
http://commandwindows.com/batch.htm
http://www.robvanderwoude.com/batchfiles.php
Most of these sites are geared towards batch files, but most of the information in them applies to running any kind of batch (* .bat) file, command (* .cmd) file, and scripting (* .vbs, * .js, * .pl, * .py, and so on) files.
When entering the script's full file spec or its filename on the command line, the shell will use information accessibly by
assoc | grep -i vbs
.vbs=VBSFile
ftype | grep -i vbs
VBSFile=%SystemRoot%\System32\CScript.exe "%1" %*
to decide which program to run for the script. In my case it's cscript.exe, in yours it will be wscript.exe - that explains why your WScript.Echos result in MsgBoxes.
As
cscript /?
Usage: CScript scriptname.extension [option...] [arguments...]
Options:
//B Batch mode: Suppresses script errors and prompts from displaying
//D Enable Active Debugging
//E:engine Use engine for executing script
//H:CScript Changes the default script host to CScript.exe
//H:WScript Changes the default script host to WScript.exe (default)
//I Interactive mode (default, opposite of //B)
//Job:xxxx Execute a WSF job
//Logo Display logo (default)
//Nologo Prevent logo display: No banner will be shown at execution time
//S Save current command line options for this user
//T:nn Time out in seconds: Maximum time a script is permitted to run
//X Execute script in debugger
//U Use Unicode for redirected I/O from the console
shows, you can use //E and //S to permanently switch your default host to cscript.exe.
If you are so lazy that you don't even want to type the extension, make sure that the PATHEXT environment variable
set | grep -i vbs
PATHEXT=.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.py;.pyw;.tcl;.PSC1
contains .VBS and there is no Converter.cmd (that converts your harddisk into a washing machine) in your path.
Update wrt comment:
If you 'don't want to specify the full path of my vbscript everytime' you may:
put your CONVERTER.VBS in a folder that is included in the PATH environment variable; the shell will then search all pathes - if necessary taking the PATHEXT and the ftype/assoc info into account - for a matching 'executable'.
put a CONVERTER.BAT/.CMD into a path directory that contains a line like cscript p:\ath\to\CONVERTER.VBS
In both cases I would type out the extension to avoid (nasty) surprises.
I am wondering why you cannot put this in a batch file. Example:
cd D:\VBS\
WSCript Converter.vbs
Put the above code in a text file and save the text file with .bat extension. Now you have to simply run this .bat file.
Why don't you just stash the vbscript in a batch/vbscript file hybrid. Name the batch hybrid Converter.bat and you can execute it directly as Converter from the cmd line. Sure you can default ALL scripts to run from Cscript or Wscript, but if you want to execute your vbs as a windows script rather than a console script, this could cause some confusion later on. So just set your code to a batch file and run it directly.
Check the answer -> Here
And here is an example:
Converter.bat
::' VBS/Batch Hybrid
::' --- Batch portion ---------
rem^ &#echo off
rem^ &call :'sub
rem^ &exit /b
:'sub
rem^ &echo begin batch
rem^ &cscript //nologo //e:vbscript "%~f0"
rem^ &echo end batch
rem^ &exit /b
'----- VBS portion -----
Dim tester
tester = "Convert data here"
Msgbox tester
You may follow the following steps:
Open your CMD(Command Prompt)
Type 'D:' and hit Enter. Example: C:\Users\[Your User Name]>D:
Type 'CD VBS' and hit Enter. Example: D:>CD VBS
Type 'Converter.vbs' or 'start Converter.vbs' and hit Enter. Example: D:\VBS>Converter.vbs Or D:\VBS>start Converter.vbs

Difference between running a command from cmd.exe or Windows Run

I'm actually trying to run an application as another user and while it works really nicely in a cmd.exe prompt, it doesn't always work if I go with the Windows Run prompt (it actually depends on what application I'm trying to run).
For example, this works fine both from cmd.exe or from W-Run prompt (using either Windows XP or Windows 7):
runas /user:ME regedit.exe
While this only works in a cmd.exe prompt (it does ask for my password in both cases but it does nothing after that if launched from W-Run on either WinXP or W7):
runas /user:ME services.msc
It's actually kind of inconsistent, with cmd it always works but with Windows Run, it's really unreliable and random.
Any ideas where there is such a difference? To get around the problem, I'm actually using batch files to launch applications as another user and then just type the batch file full path in Windows Run prompt. It does ensure reliability but I still would like to know if I'm doing something wrong.
cmd /k "runas /user:ME ""regedit.exe"" && exit"
The "problem" with runas are
It needs all the command as only one argument, so if you are running something with arguments you have to enclose all the command in quotes, and if the command includes its own quotes, they need to be escaped.
It is designed to call .exe files (well, windows valid executable files).
This two options should handle your program start
runas /user:ME "cmd.exe /c \"start services.msc\""
runas /user:ME "mmc.exe %systemroot%\system32\services.msc"
In the first case, it is using the ability of cmd.exe to find the adecuated executable to run the .msc file. In the second case, it directly calls the adecuated executable to handle the .msc file.
For your batch files, instead of cmd /k .... & exit, you can directly use cmd /c ... that will close the console when the command finishes.

Resources