blob: b51006bc7068a95e19eb5aa3d615fed05e13b94f [file] [log] [blame]
// Copyright 2020 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'dart:async';
import 'dart:io';
import 'package:process/process.dart';
final RegExp _whitespace = RegExp(r'\s+');
/// Kill all running processes on windows.
///
/// This is used when we first fail to list devices and need a retry.
Future<bool> killAllRunningProcessesOnWindows(String processName, {ProcessManager? processManager}) async {
processManager ??= LocalProcessManager();
// Avoid endless loop when a process from a different use exists, and fails
// to get killed every try.
int tries = 3;
while (tries > 0) {
tries--;
final pids = runningProcessesOnWindows(processName, processManager: processManager);
if (pids.isEmpty) {
return true;
}
for (String pid in pids) {
processManager.runSync(<String>['taskkill', '/pid', pid, '/f']);
}
// Killed processes don't release resources instantenously.
const Duration delay = Duration(seconds: 1);
await Future<void>.delayed(delay);
}
return false;
}
List<String> runningProcessesOnWindows(String processName, {ProcessManager? processManager}) {
processManager ??= LocalProcessManager();
final ProcessResult result = processManager.runSync(<String>['powershell', 'Get-CimInstance', 'Win32_Process']);
final List<String> pids = <String>[];
if (result.exitCode == 0) {
final String stdoutResult = result.stdout as String;
for (String rawProcess in stdoutResult.split('\n')) {
final String process = rawProcess.trim();
if (!process.contains(processName)) {
continue;
}
final List<String> parts = process.split(_whitespace);
final String processPid = parts[0];
final String currentRunningProcessPid = pid.toString();
// Don't kill current process
if (processPid == currentRunningProcessPid) {
continue;
}
pids.add(processPid);
}
}
return pids;
}