Equivalent of UNIX `exec` in JScript / Windows Script Host - windows

I've got a .js file that's meant to be executed by Node.js on the command-line. I've got everything set up with npm and such to put the file into the user's path as a "bin". My problem is, because the file ends in .js, running it from the command line is shipping it off to the JScript-based Windows Script Host, instead of node, as expected.
I'm trying to write a JScript wrapper, to sit at myprogram.js, be executed by Windows Script Host, and ship off to Node.js. Unfortunately, it doesn't seem like WScript's Exec command behaves like the UNIX exec command:
var shell = new ActiveXObject("WScript.Shell");
var proc = shell.exec("node .\\Library\\executable.js");
while (proc.Status === 0) {
WScript.Sleep(100);
}
WScript.Echo(proc.Status);
This buffers the program's output, and exposes it via some sort of JScript WshScriptExec object.
I need a script, or a feature, or some other way, to hand the entire terminal over to the command-line script I'm launching. Most usefully, I'd like to replace the JScript process that's executing, with the process for the command that I'm executing (i.e. UNIX-exec-y behaviour.) Is there any way to do this, or some other way to solve my problem?

Avoid the .js suffix completely so you get the same unadorned command name, e.g. executable, on all platforms.
Do so by setting bin in package.json as follows and npm will sort it:
{ "bin" : { "executable" : "./executable.js" } }
Source and further details: https://docs.npmjs.com/files/package.json#bin

Related

Why does a Perl script that is run from PowerShell run in a new console, but a Python script does not?

For both file associations, .py and .pl, I have a pair of ftype and assoc so that I can run Perl and Python scripts without explicitely specifying the path to their respective interpreter executable, like so:
C:\users\rene> .\abc.pl
C:\users\rene> .\xyz.py
When I do the "same" in a PowerShell console, executing the Perl Script opens another console in which it executes, yet the Python script executes in the same console.
Because the Perl Script runs in another console, I am faced with two problems: 1) I cannot redirect STDOUT of the script and 2) the console closes when the script is done, thus I cannot see its output.
I have no idea why the Python script behaves differently from the Perl script and I wonder what I need to change in order for the Perl script to run in the same console when executed in PowerShell.
Assuming that the .pl filename extension is associated with a file type that uses a console application to perform the Open verb on that file type (run ($fileTypeName = cmd /c assoc .pl) to learn the file-type name, then cmd /c ftype $fileTypeName to see its definition):
In order for PowerShell to run files with a given filename extension in the current console window, synchronously (assuming they're associated with a console application), that extension must be listed in the system-defined $env:PATHEXT environment variable, which is surprising.[1]
You can add .pl to $env:PATHEXT as follows:
For the current session only:
$env:PATHEXT += ';.pl'
Persistently:
Must be run from an elevated session (run as admin), and requires starting a new session to take effect:
[Environment]::SetEnvironmentVariable('PATHEXT',
([Environment]::GetEnvironmentVariable('PATHEXT', 'Machine') + ';.pl'),
'Machine'
)
Note: It is possible - though rare and not advisable - for a persistent user-level definition of this environment variable to shadow the machine-level (all-users) definition. If that is true for your user account, replace 'Machine' with 'User' above.
[1] As you state, the purpose of the $env:PATHEXT environment variable is to list filename extensions that are implicitly executable, so that, with .pl present in the variable, excecuting .\abc.pl can be shortened to .\abc. This aspect is conceptually separate from the file-type associations that allow defining what executable to pass non-executables with given filename extensions to on direct invocation, and it is arguably a bug that PowerShell couples these two aspects; it would make more sense for PowerShell to always run console-based executables in the current window, synchronously.

Launch .exe from MATLAB m.file, path issues

I want to Launch and .exe file from an m-file in MATLAB. The .exe does not Launch when i try. In restPath, the path of the .exe included. I am coding in a Windows Environment using the command line. My idea was to pass the command to run the .exe to the command line.
command = restPath;
[status,cmdout] = system(command,'-echo');
The error message is; Error file .cfg not found...
Do you have any suggestions?
Best regards
Edit: The .exe is now launched in 2 iterations. 1. cd to file, 2. Launch
addpath(restPath);
command = horzcat('cd ',restPath);
[status,cmdout] = dos(command,'-echo');
execute = 'abc.exe';
[statusExe,cmdoutExe] = system(execute,'-echo');
The main issue that I see here is that you are using two separate commands for the cd and the execution. Once the cd command executes, the command line context is thrown away and you start with a new one when you execute the system command (so the cd has no effect).
I would suggest either concatenating the two commands into one using the '&' notation like the following:
[status,cmdout] = dos([command ' & ' execute],'-echo');
or you could change your Matlab workspace first using a standard cd command in your mscript and then execute the system command.
currentPath = pwd;
cd(restPath);
execute = 'abc.exe';
[statusExe,cmdoutExe] = system(execute,'-echo');
cd(currentPath);
It is also possible that the exe you are calling is expecting an additional input to point to the .cfg file (although this may not be an issue if you have that in the same directory as the exe and it expects it to be there).

prevent Windows .bat file from quiting

I have a very simple Windows .BAT file:
set PATH=c:\xxx;%PATH%
call foo.pl
set VAR=true
I thought "call" will start a new batch process, without affecting the current one. However, the batch file exited immediately after the foo.pl finished executing. The set VAR=true has never been called.
Is there a way to fix it?
foo.pl is not a batch file, it is a Perl script.
So you need to use
path c:\xxx;%PATH%
"Path to\Folder With\perl.exe" "foo.pl"
rem Additional batch code executed after Perl script execution finished.
In other words you have to run the console application perl.exe best with full path, or with just perl.exe if program files folder of Perl is not the same on all computers on which this batch file is used and hopefully PATH contains also the directory containing perl.exe.
If you specify on a command line or in a batch file just foo.pl, Windows looks in Windows registry which application is associated with .pl for action Open. If there is such a file association, Windows runs this application in a separate process like when using command start.
So using call foo.pl is like using start foo.pl.
PATH is not only an environment variable, but also an interal command written for changing the value of environment variable PATH at any time within a batch file. This is the reason why I removed set from first line. It is better to use internal command path for modifying environment variable PATH.

running a perl script from a windows scheduled task

I have awstats installed on windows 2008 server.
I schedule the Updatestats.bat file to run every day, the task runs fine without error, but the script is not being executed or is throwing an error that I cannot see.
-- If I run the bat file directly from command line then it works fine. --
I have tried various alternatives to the windows scheduler, such as "nncron" and "Freebyte Task Scheduler", nncron had the same issue, but the freebyte app worked, but sadly it does not run as a service so is of no use.
here is the contents of the bat file, all lines look like this.
c:\strawberry\perl\bin\perl.exe D:\AWStats\wwwroot\cgi-bin\awstats.pl config=earlsmere.co.uk -update
anyone got any ideas ?
Your unattended environment is obviously different from you command line. Check if the following are set:
Script's working directory, if it reads anything from it or uses relative paths.
PERL*_LIB environment variables if your script uses any modules.
PATH environment variable, if your script calls any external scripts/binaries.
User that is running scheduled tasks have sufficient rights for everything you want to do.
As a quick workaround you can set them directly in script using chdir function, lib module, and $ENV{PATH} entry.
You also can try to capture standard output and error with following redirections before you start doing anything else:
open(STDOUT, '>>', '/full/path/to/out.log') || die "Error stdout: $!";
open(STDERR, '>>', '/full/path/to/err.log') || die "Error stderr: $!";
Note that you really should use full paths there in case you indeed have working directory set wrong. And make sure target directory/file is writable for anyone.
Looks like the output gets lost in space...
I suggest redirecting the output of the command to a file, like this:
c:\strawberry\perl\bin\perl.exe D:\AWStats\wwwroot\cgi-bin\awstats.pl config=earlsmere.co.uk -update > c:\my_log.txt 2>&1
(courtesy of Anders Lindahl: Redirect stdout and stderr to a single file in DOS)

Any way to interpret a command without running cmd.exe?

I am looking for a way to run an executable or a script without getting cmd.exe to do it for me. Currently I'm launching a process using cmd.exe /C <command>, which I need to do the following things for me:
Look for the executable file in the current directory and PATH
Interpret PATHEXT to permit extension-less script commands
Interpret file associations to, e.g., run the python interpreter when I tell it to run blah.py.
I don't need to be able to run any of the "built-in" commands, like "dir".
Is it possible to avoid using cmd.exe without essentially re-implementing all of the above functionality? There must be some sort of shell API to do the above things, right?
ShellExecute should do exactly what you want - you can use it to launch an executable or a file (which is then opened with the standard application),
http://msdn.microsoft.com/en-us/library/bb762153%28v=vs.85%29.aspx
Take a look at System.Diagnostics.Process.Start( appName, args) .
http://msdn.microsoft.com/en-us/library/system.diagnostics.process.start.aspx and about the shell, have you looked it: http://msdn.microsoft.com/en-us/library/bb773177(v=vs.85).aspx ?

Resources