Flutter进程管理插件process_runner的使用

发布于 1周前 作者 bupafengyu 来自 Flutter

Flutter进程管理插件process_runner的使用

process_runner 是一个用于Dart的包,它利用了 process 包中的 ProcessManager 类来调用外部操作系统进程,并妥善管理 stderr 和 stdout。这确保了你不会丢失任何输出,并可以轻松访问这些输出,而无需等待流完成。与 dart:ioprocess 类似,process_runner 提供了一个丰富的、符合Dart习惯的API来启动OS进程,并且具有轻松获取进程运行结果中的stdout和stderr的优势,同时正确地等待进程及其stderr/stdout流关闭。由于它使用了 process 包,你可以提供一个模拟的 ProcessManager 来测试使用 process_runner 的代码。

除了能够通过 ProcessRunner 单独启动进程外,它还允许创建一个工作进程池(ProcessPool),并管理以设定数量活动的 WorkerJob 运行它们,以及收集它们的stdout、stderr和交错的stdout和stderr输出。

基本使用示例

下面是一个简单的例子,演示如何使用 process_runner 包:

import 'package:process_runner/process_runner.dart';

Future<void> main() async {
  ProcessRunner processRunner = ProcessRunner();
  ProcessRunnerResult result = await processRunner.runProcess(['ls']);

  print('stdout: ${result.stdout}');
  print('stderr: ${result.stderr}');

  // Print interleaved stdout/stderr:
  print('combined: ${result.output}');
}

这段代码将列出当前目录下的文件,并打印出命令的标准输出和标准错误信息。

使用ProcessPool

对于更复杂的需求,比如需要同时运行多个任务,你可以使用 ProcessPool

import 'package:process_runner/process_runner.dart';

Future<void> main() async {
  ProcessPool pool = ProcessPool(numWorkers: 2);
  final List<WorkerJob> jobs = <WorkerJob>[
    WorkerJob(['ls'], name: 'Job 1'),
    WorkerJob(['df'], name: 'Job 2'),
  ];
  await for (final WorkerJob job in pool.startWorkers(jobs)) {
    print('\nFinished job ${job.name}');
  }
}

或者,如果你只想要在所有任务完成后得到结果:

import 'package:process_runner/process_runner.dart';

Future<void> main() async {
  ProcessPool pool = ProcessPool(numWorkers: 2);
  final List<WorkerJob> jobs = <WorkerJob>[
    WorkerJob(['ls'], name: 'Job 1'),
    WorkerJob(['df'], name: 'Job 2'),
  ];
  List<WorkerJob> finishedJobs = await pool.runToCompletion(jobs);
  for (final WorkerJob job in finishedJobs) {
    print("${job.name}: ${job.result.stdout}");
  }
}

以上是 process_runner 包的基本用法。你可以根据自己的需求调整参数,如 numWorkers(并发工作的数量)、workingDirectory(工作目录)等。

安装和运行命令行工具

你还可以安装 process_runner 作为一个有用的命令行工具。可以通过以下命令进行安装:

dart pub global activate process_runner

然后你可以通过如下命令运行它:

dart pub global run process_runner

这些步骤适用于所有支持Dart的平台。当然,你也可以编译这个例子成一个本地可执行文件,并将其移动到你的PATH中的某个目录下:

dart compile exe bin/process_runner.dart -o process_runner
mv process_runner /some/bin/dir/in/your/path

使用说明

该命令行工具的使用方法如下:

process_runner [--help] [--quiet] [--report] [--stdout] [--stderr]
               [--run-in-shell] [--working-directory=<working directory>]
               [--jobs=<num_worker_jobs>] [--command="command" ...]
               [--source=<file|"-" ...]:
-h, --help                 Print help for process_runner.
-q, --quiet                Silences the stderr and stdout output of the commands. This is a shorthand for "--no-stdout --no-stderr".
-r, --report               Print progress on the jobs to stderr while running.
    --[no-]stdout          Prints the stdout output of the commands to stdout in the order they complete. Will not interleave lines from separate processes. Has no effect if --quiet is specified.
                           (defaults to on)
    --[no-]stderr          Prints the stderr output of the commands to stderr in the order they complete. Will not interleave lines from separate processes. Has no effect if --quiet is specified
                           (defaults to on)
    --run-in-shell         Run the commands in a subshell.
    --[no-]fail-ok         If set, allows continuing execution of the remaining commands even if one fails to execute. If not set, ("--no-fail-ok") then process will just exit with a non-zero code at completion if there were any jobs that failed.
-j, --jobs                 Specify the number of worker jobs to run simultaneously. Defaults to the number of processor cores on the machine.
    --working-directory    Specify the working directory to run in.
                           (defaults to ".")
-c, --command              Specify a command to add to the commands to be run. Commands specified with this option run before those specified with --source. Be sure to quote arguments to --command properly on the command line.
-s, --source               Specify the name of a file to read commands from, one per line, as they would appear on the command line, with spaces escaped or quoted. Specify "--source -" to read from stdin. More than one --source argument may be specified, and they will be concatenated in the order specified. The stdin ("--source -") argument may only be specified once.

希望这些信息能帮助你在Flutter项目中更好地管理和操作外部进程。如果有更多问题或需要进一步的帮助,请随时提问!


更多关于Flutter进程管理插件process_runner的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter进程管理插件process_runner的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是如何在Flutter项目中使用process_runner插件来进行进程管理的示例代码。process_runner插件允许你在Flutter应用中启动和管理外部进程。

1. 添加依赖

首先,你需要在pubspec.yaml文件中添加process_runner依赖:

dependencies:
  flutter:
    sdk: flutter
  process_runner: ^x.y.z  # 请将x.y.z替换为当前最新版本号

然后运行flutter pub get来安装依赖。

2. 导入包

在你的Dart文件中导入process_runner包:

import 'package:process_runner/process_runner.dart';

3. 使用ProcessRunner

以下是一个简单的示例,展示如何使用ProcessRunner来启动一个外部进程(例如,列出当前目录的文件),并获取其输出。

import 'package:flutter/material.dart';
import 'package:process_runner/process_runner.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  String _output = '';

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Process Runner Example'),
        ),
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              Text('Process Output:'),
              Text(_output, style: TextStyle(fontSize: 16)),
              SizedBox(height: 20),
              ElevatedButton(
                onPressed: _runProcess,
                child: Text('Run Process'),
              ),
            ],
          ),
        ),
      ),
    );
  }

  Future<void> _runProcess() async {
    final ProcessRunner processRunner = ProcessRunner();
    final ProcessResult result = await processRunner.run('ls', ['-l']); // 在Windows上可以使用 'dir'

    setState(() {
      _output = result.stdout;
    });
  }
}

注意事项

  1. 跨平台兼容性ls命令在Unix/Linux/macOS系统上有效,而在Windows系统上应使用dir命令。
  2. 错误处理:在实际应用中,你应该添加错误处理逻辑来处理可能的异常情况,例如进程启动失败或执行过程中发生错误。
  3. 环境变量:如果需要设置环境变量,可以使用ProcessOptions类来配置。

高级用法

如果你需要更复杂的进程管理,例如传递环境变量或重定向标准输入/输出流,可以使用ProcessOptions类:

final ProcessOptions options = ProcessOptions(
  command: 'your_command',
  arguments: ['arg1', 'arg2'],
  environment: {'VAR_NAME': 'value'},
  workingDirectory: '/path/to/working/directory',
  includeParentEnvironment: true,
  stdinEncoding: Encoding.getByName('utf-8'),
  stdoutEncoding: Encoding.getByName('utf-8'),
  stderrEncoding: Encoding.getByName('utf-8'),
);

final ProcessResult result = await processRunner.start(options);

通过这种方式,你可以更灵活地控制外部进程的启动和行为。

希望这些示例代码能够帮助你在Flutter项目中有效地使用process_runner插件进行进程管理。

回到顶部