Parse script output from shell wanted in JScript - command-line

I want to execute a command and parse the output from the shell. I am using JScript inside TestComplete. I already found out that I can run commands using WScript.shell. But I do not know how to parse the output in my JScript. Any hints?
var shell = new ActiveXObject("WScript.shell");
if (shell)
{
shell.run("myCommandIWantToParseOutputfrom.sh");
}

Take a look at the Exec method instead of Run.
var wsh = new ActiveXObject("WScript.Shell");
var cmd = wsh.Exec("cmd /c dir C:\ /on");
while (cmd.Status === 0) {
WScript.Sleep(100);
}
var output = cmd.StdOut.ReadAll();
WScript.Echo(output);

Related

console output using shellexecuteW

I'm using ShellExecuteW from shell32.dll:
int value= ShellExecuteW(0, "open", "C:\test.bat", strParameters, "", 1);
The batch file runs a java app which seems to open but returns an error and quickly the console window closes.
I want to capture the error from the console. I've tried adding the following re-directions at the end of my command in the batch file:
> output.txt
2> output.txt
> output.txt 2>&1
1> output.txt 2>&1
| output.txt
I would expect these common commands to work but none of them result in anything being written in output.txt. What could I be doing wrong here?
I'm using Metatrader5 (MQL5 language) to call shellexecuteW from.
Thankyou for your replies.
First you should put the bat file in Terminal path in "File" folder because of mql5 security policy, Secondly put these codes in your script to use "ShellExecuteW" function correctly.
#import "shell32.dll"
int ShellExecuteW(int hwnd,string operation,string file,string parameters,string directory,int showCmd);
#import
int result;
string strParameters = "";
string filename="test.bat";
string Batfile_path=TerminalInfoString(TERMINAL_COMMONDATA_PATH)+"\\Files\\"+filename;
Print("Batfile_path:",Batfile_path);
result = ShellExecuteW(0, "open", Batfile_path, strParameters, "", 0);
if(result <= 32)Print("Shell Execute for running bat file Failed: ", result);

Run a long Powershell command as parameter when executing a BATCH file [duplicate]

This question already has answers here:
Convert a small PS script into a long line in a .BATch file
(3 answers)
Closed 4 years ago.
I want to run the following Powershell command by executing a .bat file:
Add-Type -TypeDefinition #'
using System.Runtime.InteropServices;
[Guid("5CDF2C82-841E-4546-9722-0CF74078229A"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
interface IAudioEndpointVolume
{
// f(), g(), ... are unused COM method slots. Define these if you care
int f(); int g(); int h(); int i();
int SetMasterVolumeLevelScalar(float fLevel, System.Guid pguidEventContext);
int j();
int GetMasterVolumeLevelScalar(out float pfLevel);
int k(); int l(); int m(); int n();
int SetMute([MarshalAs(UnmanagedType.Bool)] bool bMute, System.Guid pguidEventContext);
int GetMute(out bool pbMute);
}
[Guid("D666063F-1587-4E43-81F1-B948E807363F"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
interface IMMDevice
{
int Activate(ref System.Guid id, int clsCtx, int activationParams, out IAudioEndpointVolume aev);
}
[Guid("A95664D2-9614-4F35-A746-DE8DB63617E6"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
interface IMMDeviceEnumerator
{
int f(); // Unused
int GetDefaultAudioEndpoint(int dataFlow, int role, out IMMDevice endpoint);
}
[ComImport, Guid("BCDE0395-E52F-467C-8E3D-C4579291692E")] class MMDeviceEnumeratorComObject { }
public class Audio
{
static IAudioEndpointVolume Vol()
{
var enumerator = new MMDeviceEnumeratorComObject() as IMMDeviceEnumerator;
IMMDevice dev = null;
Marshal.ThrowExceptionForHR(enumerator.GetDefaultAudioEndpoint(/*eRender*/ 0, /*eMultimedia*/ 1, out dev));
IAudioEndpointVolume epv = null;
var epvid = typeof(IAudioEndpointVolume).GUID;
Marshal.ThrowExceptionForHR(dev.Activate(ref epvid, /*CLSCTX_ALL*/ 23, 0, out epv));
return epv;
}
public static float Volume
{
get { float v = -1; Marshal.ThrowExceptionForHR(Vol().GetMasterVolumeLevelScalar(out v)); return v; }
set { Marshal.ThrowExceptionForHR(Vol().SetMasterVolumeLevelScalar(value, System.Guid.Empty)); }
}
public static bool Mute
{
get { bool mute; Marshal.ThrowExceptionForHR(Vol().GetMute(out mute)); return mute; }
set { Marshal.ThrowExceptionForHR(Vol().SetMute(value, System.Guid.Empty)); }
}
}
'#
[audio]::Volume = 1
The problem with cmd command prompt is that it interprets a new line of code as execute this command.
However, when I enter everything into a PowerShell command line, it does not do so.
Is there any possibility to run this whole PowerShell script by executing a batch script?
I have already tried powershell -command "and the whole script", but that did not work either... cmd keeps thinking a new line means to execute it.
Try this if you want to execute your PS1 File:
powershell.exe -executionpolicy bypass -file "YOUR_FILE_NAME.ps1"
If you want to do everythin in one batch File do this:
powershell.exe
"Your Command"
You just need to put your command into the next line.
First of all, if you have a long PowerShell command, the maximum limit of characters per cmd command line can be easily reached (I believe it is ~8191 characters?).
Furthermore, it is quite uncommon to execute such big PowerShell commands directly in the cmd command line. Usually you should put it inside a file ending with .ps1, and then you execute it using the following command:
powershell.exe -executionpolicy bypass -file script.ps1
In case you really need to run the PowerShell command as you mentioned, you must first modify it a little bit. Take as example the following PS script:
function Say-Hello
{
[CmdletBinding()]
Param
(
[string] $name
)
Process
{
# Let's say hello!
$str = "Hello " + $name
Write-Output $str
}
}
Say-Hello "Jason"
The trick is to replace all \r\n line endings with \n, using a text editor (like Notepad++ for instance):
HOWEVER, you must first add some ; at the end of many of your PowerShell commands, because that is the only way you can tell PowerShell that a new PowerShell command is being issued. Otherwise, PowerShell may take 2 lines of your code and execute them as a single one, since they look all concatenated after you removed the newlines.
Then remove all line comments from your code, and escape all double quotes (or alternatively, just replace them with single quotes):
function Say-Hello
{
[CmdletBinding()]
Param
(
[string] $name
)
Process
{
$str = 'Hello ' + $name;
Write-Output $str
}
}
Say-Hello 'Jason'
Now you are ready to copy it from your text editor tool (Notepad++ in my case) and paste it to your command line like this:
powershell.exe -executionpolicy bypass -command "function Say-Hello { [CmdletBinding()] Param ([string] $name) Process { $str = 'Hello ' + $name; Write-Output $str }} Say-Hello 'Jason'"
And the expected output for that is:
Hello Jason

Issue while executing powershell script through System.Diagnostics.Process or System.Management.Automation.Runspaces

Need your help in solving this following issue.
We have a powershell script like:
invoke-command -ScriptBlock { [cmdletbinding()]
param(
[parameter(mandatory=$True)]
[string] $ticktfilepath
)
$ticketdetails=get-content $ticktfilepath |%{if ( $_ -like '"AB*' ) {$_}}|%{echo "$($_.Split(',')[7].Split('"')[1])=$($_.Split(',')[3].Split(':')[0].Split(' ')[$_.Split(',')[3].Split(':')[0].Split(' ').length-1])=$($_.Split(',')[0].Split('"')[1]);"}
write-output $ticketdetails } -ArgumentList 'D:\file.csv'
This script reads a csv file and for those lines in the csv with “AB…” at the start, does some string parsing. The csv file passed has rows with the “AB…” and hence result are returned. This runs perfectly when executing through powershell console or ISE.
But as per our requirement, where we trying to execute the same script through:
1. System.Diagnostics.Process with process start info having file name as powershell.exe and the argument at the above script. It fails for –like. i.e at |%{if ( $_ -like '"AB*' ). It is always false for the condition even though it is expected to be true.
N.B. other powershell script works perfectly with this approach
2. Exactly Similar issue when executed through System.Management.Automation.Runspaces
So looks like some constraint using the “–like” operator.
We even with the System.Diagnostics.Process approach tried writing the script line by line leveraging the Process.StandardInput.WriteLine(line) but then powershell hangs.
Any pointer to address this will be highly appreciated.
While using System.Diagnostics.Process, I used something like:
ProcessStartInfo processStartInfo = new ProcessStartInfo();
processStartInfo.UseShellExecute = false;
processStartInfo.RedirectStandardError = true;
processStartInfo.RedirectStandardOutput = true;
processStartInfo.FileName = "powershell.exe";
processStartInfo.Arguments = <ScriptContent>;
Process powerShellProc = new Process();
powerShellProc.StartInfo = processStartInfo;
powerShellProc.Start();
string successMessage = powerShellProc.StandardOutput.ReadToEndAsync().Result;
string errorMessage = powerShellProc.StandardError.ReadToEndAsync().Result;
powerShellProc.WaitForExit();
where,
ScriptContent- is the above powershell script.
Instead of like, even tried with startswith but then also the same result. But with powershell console or iSE, it works perfectly.
It's probably too late to answer :)
You shouldn't call powerShellProc.StandardOutput.ReadToEndAsync().Result before process actually finished. You can use Invoke-Executable function from How to capture process output asynchronously in powershell?
The following order is working
$outTask = $oProcess.StandardOutput.ReadToEndAsync();
$errTask = $oProcess.StandardError.ReadToEndAsync();
$bRet=$oProcess.WaitForExit($TimeoutMilliseconds)
$outText = $outTask.Result;
$errText = $errTask.Result;

Console log in MongoDB Shell

I want to write functions into MongoDB Shell like this:
var last = function(collection) { db[collection].find().sort({_id: -1}).limit(1).toArray(); }
But there is one problem. When I call last() function, it will make no output. How to fix it?
You need to use either use the JavaScript print() function or the mongo specific printjson() function which returns formatted JSON to actually log to output the result from the find method, for example:
var last = function(collection) {
var doc = db.getCollection(collection).find().sort({_id: -1}).limit(1).toArray();
printjson(doc);
};
last("test");

How to pass argument to gulp?

I am using gulp and gulp-shell packages for a php Laravel application, I just need to know if this is possible to pass argument from cmd to gulpfile.js ? this is my file:
gulp.task('default', shell.task([
'echo user',
]));
Question:
Is it possible to pass an argument from command-line when running gulp and then inside the gulpfile print it out instead of user?
var command_line_args = require('yargs').argv
Not sure if this is of any use to you or others but I did this manually by passing the arguments explicitly through a custom function. It's not super elegant but it gets the job done.
var appendWithCommandLineArguments = function(cmd, arguments) {
var to_append = _.chain(command_line_args)
.pick(arguments)
.reduce(function(string, val, prop){
return string+"--"+prop+"="+val+" ";
}, " ")
.value();
return cmd + to_append
}
gulp.task('taskmailer', shell.task([
appendWithCommandLineArguments('node automate/build/mail/taskMailer.js', ["email", "template"])
]))