Initialize push
This commit is contained in:
parent
942ce3048f
commit
49380c4d1c
16 changed files with 1079 additions and 0 deletions
55
.gitignore
vendored
Normal file
55
.gitignore
vendored
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
# Created by https://www.toptal.com/developers/gitignore/api/dart,visualstudiocode
|
||||
# Edit at https://www.toptal.com/developers/gitignore?templates=dart,visualstudiocode
|
||||
|
||||
### Dart ###
|
||||
# See https://www.dartlang.org/guides/libraries/private-files
|
||||
|
||||
# Files and directories created by pub
|
||||
.dart_tool/
|
||||
.packages
|
||||
# If you're building an application, you may want to check-in your pubspec.lock
|
||||
pubspec.lock
|
||||
|
||||
# Directory created by dartdoc
|
||||
# If you don't generate documentation locally you can remove this line.
|
||||
doc/api/
|
||||
|
||||
# dotenv environment variables file
|
||||
.env*
|
||||
|
||||
# Avoid committing generated Javascript files:
|
||||
*.dart.js
|
||||
*.info.json # Produced by the --dump-info flag.
|
||||
*.js # When generated by dart2js. Don't specify *.js if your
|
||||
# project includes source files written in JavaScript.
|
||||
*.js_
|
||||
*.js.deps
|
||||
*.js.map
|
||||
|
||||
.flutter-plugins
|
||||
.flutter-plugins-dependencies
|
||||
|
||||
### Dart Patch ###
|
||||
# dotenv environment variables file
|
||||
.env
|
||||
|
||||
### VisualStudioCode ###
|
||||
.vscode/*
|
||||
!.vscode/settings.json
|
||||
!.vscode/tasks.json
|
||||
!.vscode/launch.json
|
||||
!.vscode/extensions.json
|
||||
!.vscode/*.code-snippets
|
||||
|
||||
# Local History for Visual Studio Code
|
||||
.history/
|
||||
|
||||
# Built Visual Studio Code Extensions
|
||||
*.vsix
|
||||
|
||||
### VisualStudioCode Patch ###
|
||||
# Ignore all local history of files
|
||||
.history
|
||||
.ionide
|
||||
|
||||
# End of https://www.toptal.com/developers/gitignore/api/dart,visualstudiocode
|
||||
3
CHANGELOG.md
Normal file
3
CHANGELOG.md
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
## 1.0.0
|
||||
|
||||
- Initial version.
|
||||
39
README.md
Normal file
39
README.md
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
<!--
|
||||
This README describes the package. If you publish this package to pub.dev,
|
||||
this README's contents appear on the landing page for your package.
|
||||
|
||||
For information about how to write a good package README, see the guide for
|
||||
[writing package pages](https://dart.dev/guides/libraries/writing-package-pages).
|
||||
|
||||
For general information about developing packages, see the Dart guide for
|
||||
[creating packages](https://dart.dev/guides/libraries/create-library-packages)
|
||||
and the Flutter guide for
|
||||
[developing packages and plugins](https://flutter.dev/developing-packages).
|
||||
-->
|
||||
|
||||
TODO: Put a short description of the package here that helps potential users
|
||||
know whether this package might be useful for them.
|
||||
|
||||
## Features
|
||||
|
||||
TODO: List what your package can do. Maybe include images, gifs, or videos.
|
||||
|
||||
## Getting started
|
||||
|
||||
TODO: List prerequisites and provide or point to information on how to
|
||||
start using the package.
|
||||
|
||||
## Usage
|
||||
|
||||
TODO: Include short and useful examples for package users. Add longer examples
|
||||
to `/example` folder.
|
||||
|
||||
```dart
|
||||
const like = 'sample';
|
||||
```
|
||||
|
||||
## Additional information
|
||||
|
||||
TODO: Tell users more about the package: where to find more information, how to
|
||||
contribute to the package, how to file issues, what response they can expect
|
||||
from the package authors, and more.
|
||||
30
analysis_options.yaml
Normal file
30
analysis_options.yaml
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
# This file configures the static analysis results for your project (errors,
|
||||
# warnings, and lints).
|
||||
#
|
||||
# This enables the 'recommended' set of lints from `package:lints`.
|
||||
# This set helps identify many issues that may lead to problems when running
|
||||
# or consuming Dart code, and enforces writing Dart using a single, idiomatic
|
||||
# style and format.
|
||||
#
|
||||
# If you want a smaller set of lints you can change this to specify
|
||||
# 'package:lints/core.yaml'. These are just the most critical lints
|
||||
# (the recommended set includes the core lints).
|
||||
# The core lints are also what is used by pub.dev for scoring packages.
|
||||
|
||||
include: package:lints/recommended.yaml
|
||||
|
||||
# Uncomment the following section to specify additional rules.
|
||||
|
||||
# linter:
|
||||
# rules:
|
||||
# - camel_case_types
|
||||
|
||||
# analyzer:
|
||||
# exclude:
|
||||
# - path/to/excluded/files/**
|
||||
|
||||
# For more information about the core and recommended set of lints, see
|
||||
# https://dart.dev/go/core-lints
|
||||
|
||||
# For additional information about configuring this file, see
|
||||
# https://dart.dev/guides/language/analysis-options
|
||||
6
example/dart_framework_example.dart
Normal file
6
example/dart_framework_example.dart
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
import 'package:dart_framework/dart_framework.dart';
|
||||
|
||||
void main() {
|
||||
var awesome = Awesome();
|
||||
print('awesome: ${awesome.isAwesome}');
|
||||
}
|
||||
120
lib/core/app_data_manager.dart
Normal file
120
lib/core/app_data_manager.dart
Normal file
|
|
@ -0,0 +1,120 @@
|
|||
import 'dart:async';
|
||||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
//import 'package:flutter/services.dart' show rootBundle;
|
||||
|
||||
import 'package:dart_framework/core/process.dart';
|
||||
import 'package:dart_framework/model/app_data.dart';
|
||||
|
||||
enum SCMType { Svn, Git }
|
||||
|
||||
class AppDataManager {
|
||||
AppDataManager._privateConstructor();
|
||||
static final AppDataManager _instance = AppDataManager._privateConstructor();
|
||||
static AppDataManager get to => _instance;
|
||||
|
||||
late SCMType _scm;
|
||||
late String _workspace;
|
||||
late String _relativeAssetPath;
|
||||
|
||||
// Future<AppData> read(String relativeAssetPath) async {
|
||||
// return AppData.fromJson(jsonDecode(
|
||||
// await rootBundle.loadString('$relativeAssetPath/app_data.json')));
|
||||
// }
|
||||
|
||||
Future<AppData> create(
|
||||
SCMType scm, String workspace, String relativeAssetPath) async {
|
||||
_scm = scm;
|
||||
_workspace = workspace;
|
||||
_relativeAssetPath = relativeAssetPath;
|
||||
var c = Completer<AppData>();
|
||||
var appData = AppData();
|
||||
appData.version = await getVersion();
|
||||
appData.buildDate = getBuildTime();
|
||||
if (_scm == SCMType.Git) {
|
||||
appData.gitHash = await getHash();
|
||||
}
|
||||
await createFile(jsonEncode(appData.toJson()));
|
||||
c.complete(appData);
|
||||
return c.future;
|
||||
}
|
||||
|
||||
Future<String> getVersion() async {
|
||||
var c = Completer<String>();
|
||||
var number = 0;
|
||||
var shell = StringBuffer();
|
||||
switch (this._scm) {
|
||||
case SCMType.Svn:
|
||||
break;
|
||||
case SCMType.Git:
|
||||
shell.writeln('git rev-list --all HEAD --all --count');
|
||||
var process =
|
||||
await ProcessExecutor.start(shell, workspace: this._workspace);
|
||||
await process.process.exitCode;
|
||||
number = int.parse(process.stdoutArr.last);
|
||||
break;
|
||||
}
|
||||
|
||||
var version = this.numberToVersion(number);
|
||||
print('#### Version: ' + version);
|
||||
c.complete(version);
|
||||
return c.future;
|
||||
}
|
||||
|
||||
String numberToVersion(int number, {int masterVersion = 0}) {
|
||||
var arr = number.toString().split('');
|
||||
var length = arr.length;
|
||||
var ver = '';
|
||||
var versionList = <int>[];
|
||||
for (int i = 0; i < length; ++i) {
|
||||
if (i != 0 && i % 3 == 0) {
|
||||
versionList.add(int.parse(ver));
|
||||
ver = '';
|
||||
}
|
||||
ver = arr[length - (i + 1)].toString() + ver;
|
||||
}
|
||||
if (ver != '') versionList.add(int.parse(ver));
|
||||
|
||||
ver = '';
|
||||
length = 3;
|
||||
var list = <String>['0', '0', '0'];
|
||||
for (int i = 0; i < length; ++i) {
|
||||
var versionValue = versionList.length <= i ? 0 : versionList[i];
|
||||
var versionStr = i == 2
|
||||
? (versionValue + masterVersion).toString()
|
||||
: versionValue.toString();
|
||||
list[length - (i + 1)] = versionStr;
|
||||
}
|
||||
return list.join('.');
|
||||
}
|
||||
|
||||
Future<String> getHash() async {
|
||||
var c = Completer<String>();
|
||||
var shell = StringBuffer();
|
||||
shell.writeln('git rev-parse HEAD');
|
||||
var process =
|
||||
await ProcessExecutor.start(shell, workspace: this._workspace);
|
||||
await process.process.exitCode;
|
||||
var hash = process.stdoutArr.last;
|
||||
print('#### Git Hash: ' + hash);
|
||||
c.complete(hash);
|
||||
return c.future;
|
||||
}
|
||||
|
||||
String getBuildTime() {
|
||||
var date = DateTime.now().toString();
|
||||
date = date.substring(0, date.lastIndexOf('.'));
|
||||
print('#### Build Date: ' + date);
|
||||
return date;
|
||||
}
|
||||
|
||||
Future createFile(String json) async {
|
||||
var c = Completer();
|
||||
var dir = Directory('$_workspace/$_relativeAssetPath');
|
||||
if (!dir.existsSync()) dir.createSync(recursive: true);
|
||||
var file = File('$_workspace/$_relativeAssetPath/app_data.json');
|
||||
await file.writeAsString(json);
|
||||
c.complete();
|
||||
return c.future;
|
||||
}
|
||||
}
|
||||
520
lib/core/process.dart
Normal file
520
lib/core/process.dart
Normal file
|
|
@ -0,0 +1,520 @@
|
|||
import 'dart:async';
|
||||
import 'dart:io';
|
||||
import 'dart:convert';
|
||||
import 'dart:math';
|
||||
|
||||
class ProcessData {
|
||||
late Process process;
|
||||
late File file;
|
||||
late bool isRunning;
|
||||
late int exitCode;
|
||||
Function(ProcessData)? _endListener;
|
||||
late StringBuffer stdout;
|
||||
late StringBuffer stderr;
|
||||
|
||||
Function(ProcessData)? get endListener {
|
||||
return _endListener;
|
||||
}
|
||||
|
||||
bool get isSuccess {
|
||||
return ProcessExecutor.getSuccess(exitCode);
|
||||
}
|
||||
|
||||
List<String> get stdoutArr {
|
||||
return getBufferToArray(stdout);
|
||||
}
|
||||
|
||||
List<String> get stderrArr {
|
||||
return getBufferToArray(stderr);
|
||||
}
|
||||
|
||||
List<String> getBufferToArray(StringBuffer buffer) {
|
||||
var list = <String>[];
|
||||
var arr = buffer.toString().split('\n');
|
||||
var length = arr.length;
|
||||
for (var i = 0; i < length; ++i) {
|
||||
if (arr[i].isNotEmpty) {
|
||||
list.add(arr[i]);
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
set processValue(Process value) {
|
||||
process = value;
|
||||
stdout = StringBuffer();
|
||||
stderr = StringBuffer();
|
||||
process.stdout.transform(utf8.decoder).listen((event) {
|
||||
stdout.writeln(event);
|
||||
print(event);
|
||||
});
|
||||
process.stderr.transform(utf8.decoder).listen((event) {
|
||||
stderr.writeln(event);
|
||||
print(event);
|
||||
});
|
||||
isRunning = true;
|
||||
checkExit();
|
||||
}
|
||||
|
||||
void addEndListener(Function(ProcessData) listener) {
|
||||
_endListener = listener;
|
||||
}
|
||||
|
||||
void removeEndListener() {
|
||||
_endListener = null;
|
||||
}
|
||||
|
||||
void checkExit() async {
|
||||
exitCode = await this.process.exitCode;
|
||||
print('#### Exit Code: $exitCode');
|
||||
deleteFile();
|
||||
isRunning = false;
|
||||
if (_endListener != null) _endListener!(this);
|
||||
}
|
||||
|
||||
void terminate() {
|
||||
process.kill();
|
||||
}
|
||||
|
||||
void deleteFile() async {
|
||||
if (await file.exists()) {
|
||||
await file.delete();
|
||||
}
|
||||
}
|
||||
|
||||
void dispose() async {
|
||||
deleteFile();
|
||||
}
|
||||
}
|
||||
|
||||
class ProcessExecutor {
|
||||
static Future<ProcessData> startExe(String exe, List<String> args,
|
||||
{String? workspace}) async {
|
||||
var c = Completer<ProcessData>();
|
||||
var arg = '$exe ${args.join(' ')}';
|
||||
var processData = ProcessData();
|
||||
if (Platform.isMacOS || Platform.isWindows) {
|
||||
workspace = workspace ?? Directory.current.path;
|
||||
print('Execute Shell: $arg');
|
||||
try {
|
||||
processData.processValue =
|
||||
await Process.start(exe, args, workingDirectory: workspace);
|
||||
} on Exception catch (e) {
|
||||
print(e);
|
||||
}
|
||||
} else {
|
||||
print('This platform not support process executor.');
|
||||
}
|
||||
c.complete(processData);
|
||||
return c.future;
|
||||
}
|
||||
|
||||
static Future<ProcessData> start(StringBuffer shell,
|
||||
{String? workspace}) async {
|
||||
var c = Completer<ProcessData>();
|
||||
|
||||
try {
|
||||
var processData = ProcessData();
|
||||
var fileName = DateTime.now();
|
||||
if (Platform.isMacOS) {
|
||||
workspace = workspace ?? Directory.current.path;
|
||||
var file =
|
||||
File('$workspace/temp_${fileName.microsecondsSinceEpoch}.sh');
|
||||
processData.file = file;
|
||||
print('Execute Shell: ${file.path} \n ${shell.toString()}');
|
||||
if (await file.exists()) {
|
||||
await file.delete();
|
||||
}
|
||||
file.createSync();
|
||||
file.writeAsStringSync(shell.toString());
|
||||
try {
|
||||
processData.processValue = await Process.start('zsh', [file.path],
|
||||
workingDirectory: workspace, runInShell: false);
|
||||
} on Exception catch (e) {
|
||||
print(e);
|
||||
}
|
||||
} else if (Platform.isWindows) {
|
||||
workspace = workspace ?? Directory.current.path;
|
||||
var file =
|
||||
File('$workspace/temp_${fileName.microsecondsSinceEpoch}.bat');
|
||||
processData.file = file;
|
||||
print('Execute Shell: ${file.path} \n ${shell.toString()}');
|
||||
if (await file.exists()) {
|
||||
await file.delete();
|
||||
}
|
||||
file.createSync();
|
||||
file.writeAsStringSync(shell.toString());
|
||||
try {
|
||||
processData.processValue = await Process.start(
|
||||
'cmd', ['/C', file.path],
|
||||
workingDirectory: workspace, runInShell: false);
|
||||
} on Exception catch (e) {
|
||||
print(e);
|
||||
}
|
||||
} else {
|
||||
print('This platform not support process executor.');
|
||||
}
|
||||
c.complete(processData);
|
||||
} on Exception catch (e) {
|
||||
print('General Exception in ProcessExecutor.start: $e');
|
||||
}
|
||||
return c.future;
|
||||
}
|
||||
|
||||
static Future<ProcessResult> run(StringBuffer shell,
|
||||
{String? workspace, bool printStdout = true}) async {
|
||||
var c = Completer<ProcessResult>();
|
||||
ProcessResult? processResult;
|
||||
if (Platform.isMacOS) {
|
||||
workspace = workspace ?? Directory.current.path;
|
||||
var file = File('$workspace/temp.sh');
|
||||
print('Execute Shell: ${file.path} \n ${shell.toString()}');
|
||||
file.createSync();
|
||||
file.writeAsStringSync(shell.toString());
|
||||
try {
|
||||
await Process.run('zsh', [file.path], workingDirectory: workspace)
|
||||
.then((ProcessResult result) {
|
||||
processResult = result;
|
||||
});
|
||||
if (printStdout) {
|
||||
print(
|
||||
// ignore: prefer_interpolation_to_compose_strings
|
||||
'[ProcessExecutor] Exit Code: ${processResult!.exitCode}, Result: ' +
|
||||
processResult!.stdout);
|
||||
}
|
||||
} on Exception catch (e) {
|
||||
print(e);
|
||||
} finally {
|
||||
file.deleteSync();
|
||||
}
|
||||
c.complete(processResult);
|
||||
} else if (Platform.isWindows) {
|
||||
workspace = workspace ?? Directory.current.path;
|
||||
var file = File('$workspace/temp.bat');
|
||||
print('Execute Bat: ${file.path} \n ${shell.toString()}');
|
||||
file.createSync();
|
||||
file.writeAsStringSync(shell.toString());
|
||||
await Process.run('cmd', ['/C', file.path], workingDirectory: workspace)
|
||||
.then((ProcessResult result) {
|
||||
processResult = result;
|
||||
});
|
||||
if (printStdout) {
|
||||
print(
|
||||
// ignore: prefer_interpolation_to_compose_strings
|
||||
'[ProcessExecutor] Exit Code: ${processResult!.exitCode}, Result: ' +
|
||||
processResult!.stdout);
|
||||
}
|
||||
file.deleteSync();
|
||||
c.complete(processResult);
|
||||
} else {
|
||||
print('This platform not support process executor.');
|
||||
c.complete(null);
|
||||
}
|
||||
return c.future;
|
||||
}
|
||||
|
||||
static bool getSuccess(int exitCode) {
|
||||
if (Platform.isMacOS) return exitCode == 0;
|
||||
if (Platform.isWindows) return exitCode == 1;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
class NetStatData {
|
||||
late String type;
|
||||
late String from;
|
||||
late String to;
|
||||
late String state;
|
||||
late int pid;
|
||||
|
||||
NetStatData(List<String> categories) {
|
||||
var count = 0;
|
||||
var length = categories.length;
|
||||
for (var i = 0; i < length; ++i) {
|
||||
var category = categories[i].replaceAll(' ', '');
|
||||
if (category.isNotEmpty) {
|
||||
switch (count) {
|
||||
case 0:
|
||||
type = category;
|
||||
break;
|
||||
case 1:
|
||||
from = category;
|
||||
break;
|
||||
case 2:
|
||||
to = category;
|
||||
break;
|
||||
case 3:
|
||||
state = category;
|
||||
break;
|
||||
case 4:
|
||||
var value = int.tryParse(category);
|
||||
if (value == null) value = -1;
|
||||
pid = value;
|
||||
break;
|
||||
}
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool _removedBat = false;
|
||||
Future removeTempBat() async {
|
||||
var c = Completer();
|
||||
if (!_removedBat) {
|
||||
_removedBat = true;
|
||||
var reg = RegExp(r'(temp_bat_)([0-9_]+)(.bat)');
|
||||
var list = Directory.current.listSync();
|
||||
for (var item in list) {
|
||||
var match = reg.stringMatch(item.path);
|
||||
if (match != null) {
|
||||
await item.delete();
|
||||
}
|
||||
}
|
||||
await Future.delayed(Duration(milliseconds: 500));
|
||||
}
|
||||
c.complete();
|
||||
return c.future;
|
||||
}
|
||||
|
||||
Future<List<NetStatData>> findNetStat(String searchWord) async {
|
||||
await removeTempBat();
|
||||
var c = Completer<List<NetStatData>>();
|
||||
var shell = StringBuffer('netstat -ano | findstr $searchWord');
|
||||
var stdout = await ProcessSilentExecutor.run(shell);
|
||||
var netList = <NetStatData>[];
|
||||
var returnPattern = RegExp('\n|\r');
|
||||
var list = stdout.split(returnPattern);
|
||||
for (var item in list) {
|
||||
item = item.replaceAll(returnPattern, '');
|
||||
if (item.isNotEmpty) {
|
||||
var categories = item.split(' ');
|
||||
if (categories.length > 0) {
|
||||
netList.add(NetStatData(categories));
|
||||
}
|
||||
}
|
||||
}
|
||||
c.complete(netList);
|
||||
return c.future;
|
||||
}
|
||||
|
||||
Future<List<ProcessInfo>> findProcess(String searchWord) async {
|
||||
await removeTempBat();
|
||||
var c = Completer<List<ProcessInfo>>();
|
||||
var shell = StringBuffer('tasklist /fo "csv" | findstr $searchWord');
|
||||
var stdout = await ProcessSilentExecutor.run(shell);
|
||||
var pList = parseProcessStd(stdout);
|
||||
c.complete(pList);
|
||||
return c.future;
|
||||
}
|
||||
|
||||
List<ProcessInfo> parseProcessStd(String stdout) {
|
||||
var pList = <ProcessInfo>[];
|
||||
var returnPattern = RegExp('\n|\r');
|
||||
var list = stdout.split(returnPattern);
|
||||
for (var item in list) {
|
||||
item = item.replaceAll(returnPattern, '');
|
||||
if (item.isNotEmpty) {
|
||||
var categories = item.split(',');
|
||||
if (categories.length > 4) {
|
||||
pList.add(ProcessInfo(categories));
|
||||
}
|
||||
}
|
||||
}
|
||||
return pList;
|
||||
}
|
||||
|
||||
Future<List<ProcessInfo>> findProcessByPid(int pid) async {
|
||||
// await removeTempBat();
|
||||
var c = Completer<List<ProcessInfo>>();
|
||||
var batch = getTempBat(fixedName: pid.toString());
|
||||
if (!batch.existsSync()) {
|
||||
batch.writeAsStringSync(
|
||||
'tasklist /fi "pid eq ${pid.toString()}" /nh /fo "csv"');
|
||||
}
|
||||
String stdout = await ProcessSilentExecutor.runBat(batch.path);
|
||||
var pList = parseProcessStd(stdout);
|
||||
c.complete(pList);
|
||||
return c.future;
|
||||
}
|
||||
|
||||
class ProcessSilentExecutor {
|
||||
static bool _initialized = false;
|
||||
static Future initialize() async {
|
||||
if (!_initialized) {
|
||||
_initialized = true;
|
||||
//remove before files
|
||||
var regBat = RegExp(r'(silent_bat_)([0-9_]+)(.bat)');
|
||||
var regLog = RegExp(r'(silent_log_)([0-9_]+)(.txt)');
|
||||
var list = Directory.current.listSync();
|
||||
for (var item in list) {
|
||||
var matchBat = regBat.stringMatch(item.path);
|
||||
var matchLog = regLog.stringMatch(item.path);
|
||||
if (matchBat != null || matchLog != null) {
|
||||
item.deleteSync();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static Future<String> run(StringBuffer shell) async {
|
||||
initialize();
|
||||
var c = Completer<String>();
|
||||
var batch =
|
||||
File('${Directory.current.path}/silent_bat_${getRnadomPostfix()}.bat');
|
||||
batch.writeAsStringSync(shell.toString());
|
||||
var result = await runBat(batch.path);
|
||||
await batch.delete();
|
||||
c.complete(result);
|
||||
return c.future;
|
||||
}
|
||||
|
||||
static Future<String> runBat(String batchPath) async {
|
||||
initialize();
|
||||
var c = Completer<String>();
|
||||
var current = Directory.current;
|
||||
String result;
|
||||
var log = File('${current.path}/silent_log_${getRnadomPostfix()}.txt');
|
||||
await Process.run('${current.path}/silentbatch.exe', [batchPath, log.path])
|
||||
.then((resultData) {
|
||||
Process.killPid(resultData.pid);
|
||||
// print('"$batchPath" => exitCode: ${resultData.exitCode}');
|
||||
});
|
||||
try {
|
||||
result = await log.readAsString();
|
||||
} on Exception catch (e) {
|
||||
print(e);
|
||||
result = '';
|
||||
}
|
||||
await log.delete();
|
||||
c.complete(result);
|
||||
return c.future;
|
||||
}
|
||||
}
|
||||
|
||||
String getRnadomPostfix() {
|
||||
return '${DateTime.now().microsecondsSinceEpoch}_${Random().nextInt(100)}';
|
||||
}
|
||||
|
||||
File getTempBat({String? fixedName}) {
|
||||
fixedName ??= getRnadomPostfix();
|
||||
File batch = File('${Directory.current.path}/temp_bat_$fixedName.bat');
|
||||
return batch;
|
||||
}
|
||||
|
||||
class ProcessInfoListener {
|
||||
late ProcessInfo? _process;
|
||||
bool isRunning = false;
|
||||
late Timer? _timer;
|
||||
late int _checkInterval;
|
||||
late Function(ProcessInfoListener, bool)? _connectionListener;
|
||||
set _isRunning(bool value) {
|
||||
if (isRunning != value) {
|
||||
isRunning = value;
|
||||
changedConnection();
|
||||
}
|
||||
}
|
||||
|
||||
ProcessInfoListener(this._process, this._checkInterval) {
|
||||
this.checkLive();
|
||||
}
|
||||
|
||||
void checkLive() async {
|
||||
stopChecker();
|
||||
_isRunning = true;
|
||||
_timer = Timer.periodic(Duration(seconds: _checkInterval), (time) async {
|
||||
var enable = false;
|
||||
if (_process != null) {
|
||||
var list = await findProcessByPid(_process!.pid);
|
||||
if (list.isNotEmpty) {
|
||||
print('process live');
|
||||
enable = true;
|
||||
this._isRunning = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!enable) {
|
||||
_isRunning = false;
|
||||
stopChecker();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void stopChecker() {
|
||||
if (_timer != null) {
|
||||
_timer!.cancel();
|
||||
_timer = null;
|
||||
}
|
||||
}
|
||||
|
||||
void changedConnection() {
|
||||
if (_connectionListener != null) {
|
||||
_connectionListener!(this, isRunning);
|
||||
}
|
||||
}
|
||||
|
||||
Function(ProcessInfoListener, bool)? get endListener {
|
||||
return _connectionListener;
|
||||
}
|
||||
|
||||
void addEndListener(Function(ProcessInfoListener, bool)? listener) {
|
||||
_connectionListener = listener;
|
||||
}
|
||||
|
||||
void removeConnectionListener() {
|
||||
_connectionListener = null;
|
||||
}
|
||||
|
||||
void dispose() {
|
||||
stopChecker();
|
||||
removeConnectionListener();
|
||||
_isRunning = false;
|
||||
_process = null;
|
||||
}
|
||||
|
||||
void terminate() {
|
||||
if (isRunning && _process != null) {
|
||||
Process.killPid(this._process?.pid as int);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class ProcessInfo {
|
||||
late String name;
|
||||
late int pid;
|
||||
late String sessionName;
|
||||
late int session;
|
||||
late String memory;
|
||||
|
||||
ProcessInfo(List<String> categories) {
|
||||
var count = 0;
|
||||
var length = categories.length;
|
||||
for (var i = 0; i < length; ++i) {
|
||||
var category = categories[i].replaceAll('"', '');
|
||||
if (category.isNotEmpty) {
|
||||
switch (count) {
|
||||
case 0:
|
||||
name = category;
|
||||
break;
|
||||
case 1:
|
||||
var value = int.tryParse(category);
|
||||
value ??= -1;
|
||||
pid = value;
|
||||
break;
|
||||
case 2:
|
||||
sessionName = category;
|
||||
break;
|
||||
case 3:
|
||||
var value = int.tryParse(category);
|
||||
value ??= -1;
|
||||
session = value;
|
||||
break;
|
||||
case 4:
|
||||
memory = category;
|
||||
break;
|
||||
}
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
8
lib/dart_framework.dart
Normal file
8
lib/dart_framework.dart
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
/// Support for doing something awesome.
|
||||
///
|
||||
/// More dartdocs go here.
|
||||
library dart_framework;
|
||||
|
||||
export 'src/dart_framework_base.dart';
|
||||
|
||||
// TODO: Export any libraries intended for clients of this package.
|
||||
16
lib/model/app_data.dart
Normal file
16
lib/model/app_data.dart
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
import 'package:json_annotation/json_annotation.dart';
|
||||
|
||||
part 'app_data.g.dart';
|
||||
|
||||
@JsonSerializable()
|
||||
class AppData {
|
||||
AppData();
|
||||
|
||||
late String version;
|
||||
late String gitHash;
|
||||
late String buildDate;
|
||||
|
||||
factory AppData.fromJson(Map<String, dynamic> json) =>
|
||||
_$AppDataFromJson(json);
|
||||
Map<String, dynamic> toJson() => _$AppDataToJson(this);
|
||||
}
|
||||
18
lib/model/app_data.g.dart
Normal file
18
lib/model/app_data.g.dart
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'app_data.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
||||
// **************************************************************************
|
||||
|
||||
AppData _$AppDataFromJson(Map<String, dynamic> json) => AppData()
|
||||
..version = json['version'] as String
|
||||
..gitHash = json['gitHash'] as String
|
||||
..buildDate = json['buildDate'] as String;
|
||||
|
||||
Map<String, dynamic> _$AppDataToJson(AppData instance) => <String, dynamic>{
|
||||
'version': instance.version,
|
||||
'gitHash': instance.gitHash,
|
||||
'buildDate': instance.buildDate,
|
||||
};
|
||||
6
lib/src/dart_framework_base.dart
Normal file
6
lib/src/dart_framework_base.dart
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
// TODO: Put public facing types in this file.
|
||||
|
||||
/// Checks if you are awesome. Spoiler: you are.
|
||||
class Awesome {
|
||||
bool get isAwesome => true;
|
||||
}
|
||||
58
lib/utils/os_startup.dart
Normal file
58
lib/utils/os_startup.dart
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
import 'dart:io';
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:path/path.dart';
|
||||
import 'package:dart_framework/core/process.dart';
|
||||
|
||||
class OSStartup {
|
||||
static final String windowsStartupPath =
|
||||
'\\AppData\\Roaming\\Microsoft\\Windows\\Start Menu\\Programs\\Startup\\';
|
||||
|
||||
static Future<bool> isRegistedStartup(String label) async {
|
||||
var c = Completer<bool>();
|
||||
var exist = false;
|
||||
if (Platform.isMacOS) {
|
||||
} else if (Platform.isWindows) {
|
||||
//For Windows 8, 10
|
||||
var userPath = Platform.environment['UserProfile'];
|
||||
exist = File('$userPath$windowsStartupPath$label').existsSync();
|
||||
} else if (Platform.isLinux) {}
|
||||
c.complete(exist);
|
||||
return c.future;
|
||||
}
|
||||
|
||||
static Future<bool> registStartup(String executableFilePath,
|
||||
{String? label}) async {
|
||||
var c = Completer<bool>();
|
||||
var file = File(executableFilePath);
|
||||
var fileName = basename(file.path);
|
||||
var targetName = label ?? fileName;
|
||||
ProcessResult? result;
|
||||
if (Platform.isMacOS) {
|
||||
} else if (Platform.isWindows) {
|
||||
//For Windows 8, 10
|
||||
var symbolicPath = '%userprofile%$windowsStartupPath$targetName';
|
||||
result = await ProcessExecutor.run(
|
||||
StringBuffer('mklink "$symbolicPath" "$executableFilePath"'));
|
||||
} else if (Platform.isLinux) {}
|
||||
c.complete(result == null ? false : result.exitCode == 0);
|
||||
return c.future;
|
||||
}
|
||||
|
||||
static Future<bool> unregistStartup(String label) async {
|
||||
var c = Completer<bool>();
|
||||
var success = false;
|
||||
if (Platform.isMacOS) {
|
||||
} else if (Platform.isWindows) {
|
||||
//For Windows 8, 10
|
||||
var userPath = Platform.environment['UserProfile'];
|
||||
var file = File('$userPath$windowsStartupPath$label');
|
||||
if (file.existsSync()) {
|
||||
await file.delete();
|
||||
success = true;
|
||||
}
|
||||
} else if (Platform.isLinux) {}
|
||||
c.complete(success);
|
||||
return c.future;
|
||||
}
|
||||
}
|
||||
94
lib/utils/path.dart
Normal file
94
lib/utils/path.dart
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
import 'dart:io';
|
||||
import 'dart:async';
|
||||
import 'package:path/path.dart' as path;
|
||||
|
||||
enum FileType {
|
||||
none, //not exit file
|
||||
file,
|
||||
directory,
|
||||
link
|
||||
}
|
||||
|
||||
class Path {
|
||||
static String? getParent(String path) {
|
||||
path = getNormal(path);
|
||||
var separator = '/';
|
||||
int index = path.lastIndexOf(separator);
|
||||
if (index == -1) {
|
||||
return null;
|
||||
} else {
|
||||
return path.substring(0, index);
|
||||
}
|
||||
}
|
||||
|
||||
static String getName(String path) {
|
||||
path = getNormal(path);
|
||||
var parent = getParent(path);
|
||||
var separator = '/';
|
||||
return path.replaceAll('$parent$separator', '');
|
||||
}
|
||||
|
||||
static String getNormal(String path) {
|
||||
return path.replaceAll('\\', '/');
|
||||
}
|
||||
|
||||
//Remove last slush(/)
|
||||
static String getNormalizePath(String path) {
|
||||
var separator = Platform.isMacOS ? '/' : '\\';
|
||||
if (path.lastIndexOf(separator) == path.length - 1) {
|
||||
path = path.substring(0, path.lastIndexOf(separator));
|
||||
}
|
||||
return path;
|
||||
}
|
||||
|
||||
static FileType getType(String path) {
|
||||
if (Directory(path).existsSync()) return FileType.directory;
|
||||
if (File(path).existsSync()) return FileType.file;
|
||||
return FileType.none;
|
||||
}
|
||||
|
||||
static Future<bool> copy(String startPath, String destPath, bool isDir,
|
||||
{required List<String> ignorePattern,
|
||||
required List<String> ignoredList}) async {
|
||||
var c = Completer<bool>();
|
||||
var result = true;
|
||||
if (ignorePattern != null) {
|
||||
for (var pattern in ignorePattern) {
|
||||
if (startPath.contains(pattern)) {
|
||||
if (ignoredList != null) ignoredList.add(startPath);
|
||||
c.complete(true);
|
||||
return c.future;
|
||||
}
|
||||
}
|
||||
}
|
||||
try {
|
||||
var name = Path.getName(startPath);
|
||||
var destChildPath = path.join(destPath, name);
|
||||
if (isDir) {
|
||||
var startDir = Directory(startPath);
|
||||
var destDir = Directory(destChildPath);
|
||||
if (!startDir.existsSync())
|
||||
throw ArgumentError('Start - $startPath is not exist');
|
||||
if (!destDir.existsSync()) destDir.createSync(recursive: true);
|
||||
var files = startDir.listSync();
|
||||
for (var file in files) {
|
||||
if (file is File)
|
||||
await copy(file.path, destDir.path, false,
|
||||
ignorePattern: ignorePattern, ignoredList: ignoredList);
|
||||
if (file is Directory)
|
||||
await copy(file.path, destDir.path, true,
|
||||
ignorePattern: ignorePattern, ignoredList: ignoredList);
|
||||
}
|
||||
} else {
|
||||
var destDir = Directory(destPath);
|
||||
if (!destDir.existsSync()) destDir.createSync(recursive: true);
|
||||
print('File copy: $startPath --> $destChildPath');
|
||||
await File(startPath).copy(destChildPath);
|
||||
}
|
||||
} on Exception catch (e) {
|
||||
result = false;
|
||||
}
|
||||
c.complete(result);
|
||||
return c.future;
|
||||
}
|
||||
}
|
||||
69
lib/utils/system_util.dart
Normal file
69
lib/utils/system_util.dart
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
import 'dart:async';
|
||||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
|
||||
Map<String, List<String>?> envArguments(List<String> arguments) {
|
||||
var dic = <String, List<String>?>{};
|
||||
var list = <String>[];
|
||||
var length = arguments.length;
|
||||
for (var i = 0; i < length; ++i) {
|
||||
var value = arguments[i];
|
||||
var key = _getKey(value);
|
||||
if (key != null) {
|
||||
var index = i + 1;
|
||||
list.clear();
|
||||
while (index < length) {
|
||||
var arg = arguments[index];
|
||||
if (_getKey(arg) == null) {
|
||||
list.add(arg);
|
||||
index++;
|
||||
} else {
|
||||
i = index - 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
List<String>? arr = List<String>.from(list);
|
||||
if (arr.isEmpty) arr = null;
|
||||
dic[key] = arr;
|
||||
}
|
||||
}
|
||||
return dic;
|
||||
}
|
||||
|
||||
String? _getKey(String value) {
|
||||
String? key;
|
||||
if (value.indexOf('-') == 0) {
|
||||
key = value.substring(1, value.length);
|
||||
}
|
||||
return key;
|
||||
}
|
||||
|
||||
Map<String, dynamic>? getMapFromJson(String jsonStr) {
|
||||
Map<String, dynamic>? map;
|
||||
if (jsonStr.length > 5) {
|
||||
JsonCodec codec = JsonCodec();
|
||||
try {
|
||||
map = codec.decode(jsonStr);
|
||||
} catch (e) {
|
||||
print("Error: $e");
|
||||
}
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
Future<String> getIPAddress(String domain) async {
|
||||
var c = Completer<String>();
|
||||
var ipAddress;
|
||||
var regEx = RegExp(r'(://)([a-zA-Z0-9-.]+)(/|:)');
|
||||
var match = regEx.firstMatch(domain);
|
||||
if (match != null && match.groupCount > 2) {
|
||||
domain = match.group(2)!;
|
||||
var list = await InternetAddress.lookup(domain);
|
||||
for (var address in list) {
|
||||
ipAddress = address.address;
|
||||
break;
|
||||
}
|
||||
}
|
||||
c.complete(ipAddress);
|
||||
return c.future;
|
||||
}
|
||||
21
pubspec.yaml
Normal file
21
pubspec.yaml
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
name: dart_framework
|
||||
description: A starting point for Dart libraries or applications.
|
||||
version: 1.0.0
|
||||
# repository: https://github.com/my_org/my_repo
|
||||
|
||||
environment:
|
||||
sdk: '>=2.19.0-96.0.dev <3.0.0'
|
||||
|
||||
# Add regular dependencies here.
|
||||
dependencies:
|
||||
path: ^1.8.2
|
||||
args: ^2.3.2
|
||||
json_annotation: ^4.8.0
|
||||
archive: ^3.3.5
|
||||
ftpconnect: ^2.0.5
|
||||
|
||||
dev_dependencies:
|
||||
lints: ^2.0.0
|
||||
test: ^1.21.0
|
||||
build_runner: ^2.1.4
|
||||
json_serializable: ^6.0.1
|
||||
16
test/dart_framework_test.dart
Normal file
16
test/dart_framework_test.dart
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
import 'package:dart_framework/dart_framework.dart';
|
||||
import 'package:test/test.dart';
|
||||
|
||||
void main() {
|
||||
group('A group of tests', () {
|
||||
final awesome = Awesome();
|
||||
|
||||
setUp(() {
|
||||
// Additional setup goes here.
|
||||
});
|
||||
|
||||
test('First Test', () {
|
||||
expect(awesome.isAwesome, isTrue);
|
||||
});
|
||||
});
|
||||
}
|
||||
Loading…
Reference in a new issue