dart:io Process - How to run 'CMD start' on Windows? - flutter

On Linux we are able to open url's using a simple io.Process call:
io.Process.run("xdg-open", [ url, ])
But trying to do the equivalent thing on windows
io.Process.run("start", [url]);
It fails with:
The system cannot find the file specified.
I'm guessing we need the path of cmd.exe, which is located at %ComSpec%. Tried doing a 'echo %ComSpec%, but getting the same error. Also tried hard-coding the path, but no success.
Here is our complete function:
ProcessResult result;
try {
if(Platform.isLinux){
result = await io.Process.run("xdg-open", [ url, ]);
}
else if(Platform.isWindows){
result = await io.Process.run("start", [url]);
}
} on ProcessException catch (e){
Log.e(e?.message);
};
return result?.exitCode == 0;
[Edit] Updated title to be more accurate

The title of your question doesn't match your code; that isn't trying to run cmd.exe, it's trying to run an executable called start. The reason it doesn't work is that start isn't an executable, it's a command built into cmd.exe's interpreter. (Try running where start at a command prompt; compare with where cmd.)
If you want to run a cmd.exe command like start, you need to pass runInShell: true to Process.run. However, keep in mind that if you do you may need to be careful about special characters in your arguments.
(The answer to the question in your title is: Process.run('cmd', [...]);. But since what you want to do is run a command in the shell it's easier to use runInShell: true than to invoke cmd with /c and your command as a string.)

Work example for Windows -
Future<io.ProcessResult> processRun() {
var result = io.Process.run(
'C:\\Program Files (x86)\\1cv8\\common\\1cestart.exe', [],
runInShell: true);
result.then((value) {
print(value.exitCode);
});
return result;
}

Related

VSCode Extension executes local python (bash) code and append to output channel

In my VS Code extension, I'd like to invoke a python file and append standard output to VSCode's output channel. I'm aware that I can create an output channel via vscode.window.createOutputChannel("..."); and I'm also aware I can execute such python (or for this matter, any local bash) script via these APIs: https://nodejs.org/api/child_process.html. Would it be possible to append standard out information to this output channel in real-time (i.e., as the script runs)?
What I currently have is the following:
export function execute(cmd: string, callback: any, logging?: vscode.OutputChannel) {
const spwanedProcess = spawn(cmd, [], {shell: true, detached: true});
console.log(`spawned pid ${spwanedProcess.pid} with command ${cmd}`);
spwanedProcess.stdout.on('data', (data: any) => {
console.log(data);
logging?.appendLine("stdout:" + data);
});
spwanedProcess.stderr.on('data', (data: any) => {
console.error(`spawned pid ${spwanedProcess.pid} pushed something to stderr`);
logging?.appendLine(data);
});
spwanedProcess.on('exit', function(code: any) {
if (code !== 0) {
console.log('Failed: ' + code);
}
else {
console.log(`pid ${spwanedProcess.pid} finished`);
}
callback();
});
}
where callback() is something to be executed after the execution is done. I got this structure from here https://stackoverflow.com/a/32872753/14264786.
However, when I run a simple python code that sleeps for 3 seconds and prints something and does this again, the standard out information is still not displayed on the logging in real-time. Instead, they are outputted together after the script finishes.
Any idea on what's a potential solution?
After some more digging, I found out that one solution is to use python -u to invoke the python script to unbuffer the python output

How to pass GitHub action event hook from a javascript to a bash file?

I want to create a GitHub action that is simple and only run a bash-script file, see previous
question: How to execute a bash-script from a java script
With this javascript action, I want to pass values to the bash-script from the JSON payload given by GitHub.
Can this be done with something as simple as an exec command?
...
exec.exec(`export FILEPATH=${filepath}`)
...
I wanted to do something like this, but found there to be much more code needed that I originally expected. So while this is not simple, it does work and will block the action script while the bash script runs:
const core = require('#actions/core');
function run() {
try {
// This is just a thin wrapper around bash, and runs a file called "script.sh"
//
// TODO: Change this to run your script instead
//
const script = require('path').resolve(__dirname, 'script.sh');
var child = require('child_process').execFile(script);
child.stdout.on('data', (data) => {
console.log(data.toString());
});
child.on('close', (code) => {
console.log(`child process exited with code ${code}`);
process.exit(code);
});
}
catch (error) {
core.setFailed(error.message);
}
}
run()
Much of the complication is handling output and error conditions.
You can see my debugger-action repo for an example.

How can I extend the window reuse code paths in vscode and Azure Data Studio?

I am working in the microsoft/azuredatastudio github repo, which is largely forked from vscode. I am trying to extend our command line processing to handle the window reuse parameter such that if we pass a server connection along with -r that we will open the specified connection. Our current command line processing service is loaded by src\vs\workbench\electron-browser\workbench.ts in Workbench.initServices.
Is there any platform-provided service that is visible to both electron-main and workbench\electron-browser that I could modify or leverage to be informed of the app being reused with new command line arguments?
I've found that the LaunchService defined in src\vs\code\electron-main\launch.ts appears to be responsible for capturing the arguments and opening or reusing the window, but it's not clear how I would marshal a notification from the LaunchService over to our services that are loaded by workbench.
2/12/2019 update:
It looks like I need to add an equivalent of this function in src\vs\code\electron-main\windows.ts
private doOpenFilesInExistingWindow(configuration: IOpenConfiguration, window: ICodeWindow, filesToOpen: IPath[], filesToCreate: IPath[], filesToDiff: IPath[], filesToWait: IPathsToWaitFor): ICodeWindow {
window.focus(); // make sure window has focus
window.ready().then(readyWindow => {
const termProgram = configuration.userEnv ? configuration.userEnv['TERM_PROGRAM'] : void 0;
readyWindow.send('vscode:openFiles', { filesToOpen, filesToCreate, filesToDiff, filesToWait, termProgram });
});
return window;
}
which has a new message like 'ads:openconnection' . Now to find out how to handle the message.
I ended up using ipcRenderer service and adding an ipc call to the launch service in main.
// {{SQL CARBON EDIT}}
// give the first used window a chance to process the other command line arguments
if (args['reuse-window'] && usedWindows.length > 0 && usedWindows[0])
{
let window = usedWindows[0];
usedWindows[0].ready().then(() => window.send('ads:processCommandLine', args));
}
// {{SQL CARBON EDIT}}

Jenkins Powershell write to console

I have a jenkins job that calls a powershell file. When I use it from a freestyle project it shows the powershell execution in the console output. Having switched it to a pipeline job I no longer see the output.
Currently my pipeline looks like this:
pipeline
{
stages
{
stage ('Deploy To Dev')
{
steps
{
powershell '"%WORKSPACE%\\SpearsLoad\\Scripts\\CIDeployToDev.Ps1"'
}
}
}
}
but I get no logging of the powershell steps.
Following the documentation I tried changing the stage to:
pipeline
{
stages
{
stage ('Deploy To Dev')
{
steps
{
node('Deploy the SSIS load')
{
//Deploy the SSIS load
def msg = powershell(returnStdout: true, script: '"%WORKSPACE%\\SpearsLoad\\Scripts\\CIDeployToDev.Ps1"')
println msg
}
}
}
}
}
but that gives:
Expected a step # line 123, column 6. def msg =
powershell(returnStdout: true, script:
'"%WORKSPACE%\SpearsLoad\Scripts\CIDeployToDev.Ps1"')
I feel like I am missing something quite fundamental. What am I doing wrong ?
You need to wrap your pipeline execution into script section, because you're trying to use scripted syntax in declarative pipeline:
script {
//Deploy the SSIS load
def msg = powershell(returnStdout: true, script: '"%WORKSPACE%\\SpearsLoad\\Scripts\\CIDeployToDev.Ps1"')
println msg
}
For anyone who comes here looking for answers, I need to point out that there were actually 3 separate problems with the code:
The lack of a script section as per the accepted answer.
The powershell was not actually running due to not calling it correctly
The powershell was not running due to spaces in the %WORKSPACE% variable
in the end, I went with:
script {
def msg = powershell(returnStdout: true, script: " & './SpearsLoad\\Scripts\\CIDeployToDev.Ps1'")
println msg
}
which actually works!
I use
Write-Host "My message"
in powershell. This will show up in the log.

Nothing happens using spawn gulp task to execute commands into subfolder

Yesterday, I've been sent to a reference to use process_child.spawn for my need. I'd like gulp executing commands for me, to avoid typing commands concerning my dependency when I need to compile my main project.
I got something that seems ok, any error into logs, but nothing happened, the way my commands wouldn't been executed.
Any one with feedback about my code ? I got another task like this one to compile the dependency.
var spawn = require("child_process").spawn;
gulp.task("my-dependency-install", function(done) {
spawn("ft", ["install"], {
cwd: "node_modules/app/my-dependency/"
})
.on("error", function (err) {
throw err
})
.on("close", done);
});
Thanks
Here is the way I've fixed it :
var spawn = require("child_process").spawn;
spawn("ft.cmd", ["install"], {
cwd: "node_modules/app/my-dependency/"
})
.on("error", function (err) {
throw err
});
Anyone is able to explain why I had to add .cmd ? It's because of windows OS, isn'it ?