fromFilepath static method

Future<ProcessInterface> fromFilepath(
  1. String path,
  2. List<String> arguments, {
  3. ProcessInterfaceOptions options = const ProcessInterfaceOptions(),
  4. ProcessInterfaceOutputCallback? onStdout,
  5. ProcessInterfaceOutputCallback? onStderr,
})

Creates a ProcessInterface by starting a process from a file path.

  • path: Absolute or relative path to the executable.
  • arguments: Command line arguments for the invocation.
  • options: Options for the process invocation.
  • onStdout & onStderr: Optional callbacks to listen to output.

Throws ApplicationNotFoundException if the file at path does not exist.

Implementation

static Future<ProcessInterface> fromFilepath(
    String path, List<String> arguments,
    {final ProcessInterfaceOptions options = const ProcessInterfaceOptions(),
    final ProcessInterfaceOutputCallback? onStdout,
    final ProcessInterfaceOutputCallback? onStderr}) async {
  if (!File(path).existsSync()) {
    throw ApplicationNotFoundException(path);
  }
  final Uuid uuid = const Uuid();

  if (options.runAsAdministrator) {
    if (Platform.isWindows) {
      path = "powershell.exe";
      arguments = [
        "-Command",
        """
            \$targetFolder = "${options.workingDirectory}"
            \$command = "$path"
            \$arguments = "${arguments.join(" ")}"

            # Relaunch as administrator
            Start-Process powershell -Verb runAs -wait -ArgumentList @(
                "-NoProfile",
                "-ExecutionPolicy Bypass",
                "-Command `"Set-Location -Path '\$targetFolder'; & '\$command' \$arguments`""
            )

            New-Item -ItemType File -Path "${_validationFile(path, uuid).path}"
            """,
      ];
    }
    else {
      final String? user = Platform.environment['USER'];
      if (user != null && user.isNotEmpty && user != "root") {
        throw Exception("The process needs root access to execute the desired commands. Ensure the permissions are provided.");
      }
    }
  }
  final Process process = await Process.start(path, arguments,
      workingDirectory: options.workingDirectory,
      environment: {"environment_stepflow": "1"}..addAll(options.environment),
      includeParentEnvironment: true,
      mode: ProcessStartMode.normal,
      runInShell: options.runInShell);

  if (onStdout != null) {
    process.stdout.listen((c) => onStdout(c));
  }
  if (onStderr != null) {
    process.stderr.listen((c) => onStderr(c));
  }

  return ProcessInterface._internal(process, uuid, options, path, true);
}