Open SaadArdati opened 4 years ago
If you are running on Windows 10, I wouldn't expect ls
to be available by default.
Do you have anything installed which would provide the ls
and ffmpeg
commands, and are you sure they are findable by Process.run
?
Try referring to the executables with an absolute path.
In particular, the ffmpeg
is running with a new working directory, and the executable path is interpreted as relative to the new working directory, not the original one.
@lrhn I just checked. Windows powershell supports ls
, windows CMD does not.
I changed the command to a cmd compatible one which is cd
, same error
print('process 1');
await Process.run('cd', []).then((result) => print(result.stdout));
print('process 2');
process 2
is never printed.
Tried:
print('process 1');
await Process.run('ping', ['google.com']).then((result) => print(result.stdout));
print('process 2');
This is weird, because it didn't error. It just stopped and did nothing.
CMD:
That is interesting because running the same code on stable 2.8.1:
Dart VM version: 2.8.1 (stable) (Thu Apr 30 09:25:21 2020 +0200) on "windows_x64"
does print the output of ping
.
The cd
probably failed because it's a built-in command in cmd
, not a program you can execute. It has no path, so you can't point to it. To run that, you'd have to do it by executing "cmd" with a "/c" parameter:
print((await Process.run("cmd", ["/c", r"cd \ & dir"])).stdout);
Should i downgrade? Although this means this is a legitamate issue on the dev branch,
Another example:
print('process 2');
await Process.start('ffmpeg',
['-i', '$inputFile', '-f', 'segment', '-segment_time', '300', '-c', 'copy', '${dirname(inputFile)}/%03d.mp3'],
workingDirectory: 'C:/Users/<...>/ffmpeg-windows/bin')
.then((Process process) {
process.stdout.transform(utf8.decoder).listen((data) {
print(data);
});
process.stdin.writeln('Hello, world!');
process.stdin.writeln('Hello, galaxy!');
process.stdin.writeln('Hello, universe!');
}).then((Process process) {
// Get the exit code from the new process.
process.exitCode.then((exitCode) {
print('exit code: $exitCode');
});
});
process 2
CreateProcessW failed 2
'ffmpeg', ['-h']
is the same btw
I tried with the beta version of dart, same problem.
Dart VM version: 2.8.0-20.11.beta (beta) (Mon Apr 20 14:33:01 2020 +0200) on "windows_x64"
Same story with stable
Dart VM version: 2.8.1 (stable) (Thu Apr 30 09:25:21 2020 +0200) on "windows_x64"
I can't reproduce with my Windows 10 machine. Probably something went wrong with your Windows machine.
@zichangg I highly doubt it's my windows. What diagnostic data can I provide? Could it be a permission issue with the dart VM and windows? Something to do with debug mode? The error message should really provide more information.
What diagnostics would you like for me to provide?
I recommend you to try running CreateProcessW locally.
Our Process.run()/start()
will invoke the CreateProcessW
. The environment will be content from Platform.environment
.
If it succeeds, it is likely the arguments or permission is wrongly set on your machine. Otherwise, CreateProcessW
is the one to be investigated.
@zichangg Sorry, I'm not familiar with windows Apis. I don't have a means to make an app that uses CreateProcessW. Is there an existing script I can try to run?
I can reproduce it, but it appears that the problem is that the executable is neither in the path, nor in the current working directory.
The workingDirectory
parameter documentation states that:
Use
workingDirectory
to set the working directory for the process. Note that the change of directory occurs before executing the process on some platforms, which may have impact when using relative paths for the executable and the arguments.
Apparently Windows 10 is not one of the platforms where the change happens prior resolving the executable. If I provide a full path for the executable, then it runs successfully.
import "dart:io";
import "dart:convert";
main() async {
print('process 1');
// Works and does set working directory.
var p = await Process.start(r"cmd", ["/c", "dir"], workingDirectory: r"d:\tools\ffmpeg\bin\");
print('process 2');
await p.stdout.transform(utf8.decoder).forEach(print);
print('process 3');
// Works and does set working directory.
// Does not work, gives the same error.
var q = await Process.start(r"ffmpeg.exe", ["-L"], workingDirectory: r"d:\tools\ffmpeg\bin\");
print('process 4');
await q.stderr.transform(utf8.decoder).forEach(print);
print('process 5');
}
If I add
Directory.current = r"d:\tools\ffmpeg\bin\";
before the Process.start
then it does work.
If I change it to
var q = await Process.start(r"d:\tools\ffmpeg\bin\ffmpeg.exe", ["-L"],
workingDirectory: r"d:\tools\ffmpeg\bin\");
then it also works. If I put d:\tools\ffmpeg\bin\
into my path, it also works.
So, the problem seems to be that the ffmpeg
executable cannot be found in the path or the current working directory.
@lrhn Interesting observations. I tried the following:
Directory.current = File(DependencyManager.ffmpegDir).absolute.path;
await Process.start(
'ffmpeg.exe',
[
'-i',
'${File(inputFile).absolute.path}',
'-f',
'segment',
'-segment_time',
'300',
'-c',
'copy',
'${dirname(inputFile)}/%03d.mp3'
],
workingDirectory: Directory.current.path)
.then((Process process) {
process.stdout.transform(utf8.decoder).listen((data) {
print(data);
});
process.stdin.writeln('Hello, world!');
process.stdin.writeln('Hello, galaxy!');
process.stdin.writeln('Hello, universe!');
}).then((Process process) {
// Get the exit code from the new process.
process.exitCode.then((exitCode) {
print('exit code: $exitCode');
});
});
When I run this, there is no output, no error, and no result (ffmpeg did nothing). Running the ffmpeg command in a powershell runs it properly.
Interestingly, when I add Directory.current to 'ffmpeg.exe', it gives me the Processw 2 error.
I had the same issue. Listening on process.stderr
instead of process.stdout
helped. Not sure why stdout
isn't closed.
@lrhn
process.stderr.transform(utf8.decoder).listen((data) {
print(data);
});
still prints nothing
@lrhn I was missing an await
where I call this method. My bad.
static void segmentFile(String inputFile) async {
print('1');
Directory.current = File(DependencyManager.ffmpegDir).absolute.path;
print('2');
await Process.start(
'ffmpeg.exe',
[
'-i',
'${File(inputFile).absolute.path}',
'-f',
'segment',
'-segment_time',
'300',
'-c',
'copy',
'${dirname(inputFile)}/%03d.mp3'
],
workingDirectory: Directory.current.path)
.then((Process process) {
process.stderr.transform(utf8.decoder).listen((data) {
print('error: $data');
});
process.stdout.transform(utf8.decoder).listen((data) {
print('out: $data');
});
});
print('3');
}
this is my current setup. I tried currentDir before the command name as well as correct the \ to /.
Thing's I've observed:
console output:
1
2
3
.then() after this to get the exit code returns an error. The entire Process object is null after a then() call where the exitcode used to be. Not sure why this happens but i've ommitted it here.
there is no other console output, no error messages, and the command did nothing on the file.
I got it to work!
Directory.current messed up the second File object in the code.
'${File(inputFile).absolute.path}'
. The path here turned into Directory.current + its own absolute path. Resulting in a file not found.
This is the final code
static void segmentFile(String inputFile) async {
print('1');
await Process.start(
'${File(DependencyManager.ffmpegDir).absolute.path}/ffmpeg.exe',
[
'-i',
'${File(inputFile).absolute.path}',
'-f',
'segment',
'-segment_time',
'300',
'-c',
'copy',
'${dirname(inputFile)}/%03d.mp3'
],
).then((Process process) {
process.stderr.transform(utf8.decoder).listen((data) {
print('error: $data');
});
process.stdout.transform(utf8.decoder).listen((data) {
print('out: $data');
});
});
print('2');
}
I would like to note that I still do not have any console output from the command. I'm leaving this issue open so we can resolve that problem
Dart VM version: 2.9.0-7.0.dev (dev) (Thu May 7 09:17:54 2020 +0200) on "windows_x64" Windows 10
Both of these processes fail with
CreateProcessW failed 2
No other messages are provided. Neither the first runs, nor the second. Not even a clue what's going on. I can't get any command to run.