process bug fixed

This commit is contained in:
Toki 2024-12-30 12:42:25 +09:00
parent 46f1faf9ab
commit 5eb8df194f
2 changed files with 116 additions and 93 deletions

View file

@ -45,8 +45,9 @@ class AppDataManager {
Future<int> gitCount() async {
var shell = StringBuffer();
shell.writeln('git rev-list --all HEAD --all --count');
_workspace = '/home/deck/work/dart_framework';
var process = await ProcessExecutor.start(shell, workspace: _workspace);
await process.process.exitCode;
await process.waitForExit();
return dataFutrue(int.parse(process.stdoutArr.last));
}
@ -60,7 +61,7 @@ class AppDataManager {
case SCMType.Git:
shell.writeln('git rev-list --all HEAD --all --count');
var process = await ProcessExecutor.start(shell, workspace: _workspace);
await process.process.exitCode;
await process.waitForExit();
number = int.parse(process.stdoutArr.last);
break;
}
@ -107,7 +108,7 @@ class AppDataManager {
var shell = StringBuffer();
shell.writeln('git rev-parse HEAD');
var process = await ProcessExecutor.start(shell, workspace: _workspace);
await process.process.exitCode;
await process.waitForExit();
var hash = process.stdoutArr.last;
print('#### Git Hash: $hash');
return dataFutrue(hash);

View file

@ -11,29 +11,30 @@ import 'package:dart_framework/utils/system_util.dart';
typedef LogHandler = Function(String, LogType);
class ProcessData {
late Process process;
int? exitCode;
late Process _process;
late File file;
late bool isRunning;
late int exitCode;
Function(ProcessData)? _endListener;
late StringBuffer stdout;
late StringBuffer stderr;
final bool _enableStdout;
final bool _enableStderr;
final Completer _completer = Completer();
LogHandler? _logHandler;
late Converter<List<int>, String> _decoder = utf8.decoder;
bool _completeStdout = false;
bool _completeStderr = false;
bool _completeExitCode = false;
late Converter<List<int>, String> _decoder;
// ignore: no_leading_underscores_for_local_identifiers
ProcessData(this._enableStdout, this._enableStderr, {LogHandler? logHandler}) {
ProcessData(this._enableStdout, this._enableStderr,
{LogHandler? logHandler, Converter<List<int>, String>? decoder}) {
_logHandler = logHandler;
}
Function(ProcessData)? get endListener {
return _endListener;
_decoder = decoder ?? utf8.decoder;
}
bool get isSuccess {
return ProcessExecutor.getSuccess(exitCode);
if (Platform.isWindows) return exitCode == 1;
return exitCode == 0;
}
List<String> get stdoutArr {
@ -56,93 +57,97 @@ class ProcessData {
return list;
}
set decoder(Converter<List<int>, String> value) {
_decoder = value;
Process get process {
return _process;
}
set processValue(Process value) {
process = value;
set process(Process value) {
_process = value;
stdout = StringBuffer();
stderr = StringBuffer();
process.stdout.transform(_decoder).listen((event) {
_process.stdout.transform(_decoder).transform(LineSplitter()).listen(
(event) {
stdout.writeln(event);
if (_enableStdout) {
log(event, LogType.verbose);
}
}, onDone: () {
_completeStdout = true;
_checkComplete();
});
process.stderr.transform(_decoder).listen((event) {
_process.stderr.transform(_decoder).transform(LineSplitter()).listen(
(event) {
stderr.writeln(event);
if (_enableStderr) {
log('[Error] $event', LogType.error);
}
}, onDone: () {
_completeStderr = true;
_checkComplete();
});
isRunning = true;
checkExit();
_checkExitCode();
}
void log(String message, LogType logType) {
if(_logHandler == null) {
if (_logHandler == null) {
print(message);
} else {
_logHandler!(message, logType);
}
}
void addEndListener(Function(ProcessData) listener) {
_endListener = listener;
}
void removeEndListener() {
_endListener = null;
}
void checkExit() async {
exitCode = await process.exitCode;
deleteFile();
isRunning = false;
if (_endListener != null) _endListener!(this);
}
void terminate() {
process.kill();
_process.kill();
_deleteFile();
}
void deleteFile() async {
if (await file.exists()) {
await file.delete();
void _deleteFile() async {
if (file.existsSync()) {
file.deleteSync();
}
}
void dispose() async {
deleteFile();
void _checkExitCode() async {
exitCode = await _process.exitCode;
_completeExitCode = true;
_checkComplete();
}
void _checkComplete() {
if (_completeExitCode && _completeStdout && _completeStderr) {
_completer.complete();
}
}
Future waitForExit() async {
await process.exitCode;
return simpleFuture;
return _completer.future;
}
}
class ProcessExecutor {
static Future<ProcessData> startExe(String exe, List<String> args,
{String? workspace, bool? printStdout, bool? printStderr, LogHandler? logHandler}) async {
{String? workspace,
bool? printStdout,
bool? printStderr,
LogHandler? logHandler}) async {
var arg = '$exe ${args.join(' ')}';
var printStdout_ = printStdout ?? true;
var printStderr_ = printStderr ?? true;
var processData = ProcessData(printStdout_, printStderr_, logHandler: logHandler);
var processData =
ProcessData(printStdout_, printStderr_, logHandler: logHandler);
if (Platform.isMacOS || Platform.isWindows) {
workspace = workspace ?? Directory.systemTemp.path;
if(printStdout_) {
logHandler??('Execute Shell: $arg', LogType.verbose);
if (printStdout_) {
logHandler ?? ('Execute Shell: $arg', LogType.verbose);
}
try {
processData.processValue =
processData.process =
await Process.start(exe, args, workingDirectory: workspace);
} on Exception catch (e) {
logHandler??(e, LogType.error);
logHandler ?? (e, LogType.error);
}
} else {
logHandler??('This platform not support process executor.');
logHandler ?? ('This platform not support process executor.');
}
return dataFutrue(processData);
}
@ -151,40 +156,47 @@ class ProcessExecutor {
{Converter<List<int>, String>? decoder,
String? workspace,
bool? printStdout,
bool? printStderr, LogHandler? logHandler}) async {
bool? printStderr,
LogHandler? logHandler}) async {
var c = Completer<ProcessData>();
try {
var printStdout_ = printStdout ?? true;
var printStderr_ = printStderr ?? true;
var processData = ProcessData(printStdout_, printStderr_, logHandler: logHandler);
if (decoder != null) {
processData.decoder = decoder;
}
var processData = ProcessData(printStdout_, printStderr_,
logHandler: logHandler, decoder: decoder);
if (Platform.isMacOS || Platform.isLinux) {
workspace = workspace ?? Directory.systemTemp.path;
var file = File('$workspace/$tempFileName');
processData.file = file;
if(printStdout_) {
logHandler??('Execute Shell: ${file.path} \n ${shell.toString()}', LogType.verbose);
if (printStdout_) {
logHandler ??
(
'Execute Shell: ${file.path} \n ${shell.toString()}',
LogType.verbose
);
}
if (await file.exists()) {
await file.delete();
if (file.existsSync()) {
file.deleteSync();
}
file.createSync();
file.writeAsStringSync(shell.toString());
file.writeAsStringSync(shell.toString(), flush: true);
try {
var shellExe = Platform.isMacOS ? 'zsh' : 'bash';
processData.processValue = await Process.start(shellExe, [file.path],
workingDirectory: workspace, runInShell: false);
processData.process = await Process.start(shellExe, [file.path],
workingDirectory: workspace);
} on Exception catch (e) {
logHandler??(e, LogType.error);
logHandler ?? (e, LogType.error);
}
} else if (Platform.isWindows) {
workspace = workspace ?? Directory.systemTemp.path;
var file = File('$workspace/$tempFileName');
processData.file = file;
if(printStdout_) {
logHandler??('Execute Shell: ${file.path} \n ${shell.toString()}', LogType.verbose);
if (printStdout_) {
logHandler ??
(
'Execute Shell: ${file.path} \n ${shell.toString()}',
LogType.verbose
);
}
if (await file.exists()) {
await file.delete();
@ -192,31 +204,42 @@ class ProcessExecutor {
file.createSync();
file.writeAsStringSync(shell.toString());
try {
processData.processValue = await Process.start(
'cmd', ['/C', file.path],
processData.process = await Process.start('cmd', ['/C', file.path],
workingDirectory: workspace, runInShell: false);
} on Exception catch (e) {
logHandler??(e, LogType.error);
logHandler ?? (e, LogType.error);
}
} else {
logHandler??('This platform not support process executor.', LogType.error);
logHandler ??
('This platform not support process executor.', LogType.error);
}
c.complete(processData);
await processData.waitForExit();
} on Exception catch (e) {
logHandler??('General Exception in ProcessExecutor.start: $e', LogType.error);
logHandler ??
('General Exception in ProcessExecutor.start: $e', LogType.error);
}
return c.future;
}
static Future<ProcessResult> run(StringBuffer shell,
{String? workspace, bool printStdout = true, LogHandler? logHandler}) async {
{String? workspace,
bool printStdout = true,
LogHandler? logHandler}) async {
var c = Completer<ProcessResult>();
workspace = workspace ?? Directory.systemTemp.path;
var file = File('$workspace/$tempFileName');
if(printStdout) {
logHandler??('---------------------------------------------------', LogType.verbose);
logHandler??('Shell Path: ${file.path} \nExecute Shell: ${shell.toString()}', LogType.verbose);
if (printStdout) {
logHandler ??
(
'---------------------------------------------------',
LogType.verbose
);
logHandler ??
(
'Shell Path: ${file.path} \nExecute Shell: ${shell.toString()}',
LogType.verbose
);
}
ProcessResult? processResult;
if (Platform.isMacOS || Platform.isLinux) {
@ -229,12 +252,15 @@ class ProcessExecutor {
processResult = result;
});
if (printStdout) {
logHandler??(
// ignore: prefer_interpolation_to_compose_strings
'[ProcessExecutor] Exit Code: ${processResult!.exitCode}\nResult: ${processResult!.stdout}\nError: ${processResult!.stderr}', LogType.verbose);
logHandler ??
(
// ignore: prefer_interpolation_to_compose_strings
'[ProcessExecutor] Exit Code: ${processResult!.exitCode}\nResult: ${processResult!.stdout}\nError: ${processResult!.stderr}',
LogType.verbose
);
}
} on Exception catch (e) {
logHandler??(e, LogType.error);
logHandler ?? (e, LogType.error);
} finally {
file.deleteSync();
}
@ -258,7 +284,8 @@ class ProcessExecutor {
file.deleteSync();
c.complete(processResult);
} else {
logHandler??('This platform not support process executor.', LogType.error);
logHandler ??
('This platform not support process executor.', LogType.error);
c.complete(null);
}
return c.future;
@ -271,12 +298,6 @@ class ProcessExecutor {
return 'temp_${DateTime.now().microsecondsSinceEpoch}.bat';
}
}
static bool getSuccess(int exitCode) {
if (Platform.isMacOS || Platform.isLinux) return exitCode == 0;
if (Platform.isWindows) return exitCode == 1;
return false;
}
}
class NetStatData {
@ -395,19 +416,20 @@ Future<List<ProcessInfo>> findProcess(String searchWord,
await removeTempBat();
var c = Completer<List<ProcessInfo>>();
var pList = <ProcessInfo>[];
if(Platform.isWindows) {
if (Platform.isWindows) {
var shell = StringBuffer('tasklist /fo "csv" | findstr $searchWord');
var stdout = runSlient
? await ProcessSilentExecutor.runSlientBat(shell)
: await runGetStdout(shell);
pList = parseProcessStd(stdout);
} else {
var shell = StringBuffer('ps -A | grep \'$searchWord\' | grep -v grep | awk \'{\$2=\$3=""; print \$0}\'');
var shell = StringBuffer(
'ps -A | grep \'$searchWord\' | grep -v grep | awk \'{\$2=\$3=""; print \$0}\'');
var result = await ProcessExecutor.run(shell, printStdout: false);
if(result.exitCode == 0) {
if (result.exitCode == 0) {
var procList = result.stdout.toString().split('\n');
for(var proc in procList) {
if(proc.isNotEmpty) {
for (var proc in procList) {
if (proc.isNotEmpty) {
var info = ProcessInfo();
var index = proc.indexOf(' ');
info.pid = int.parse(proc.substring(0, index));