move logic to Core project and create UI project with UI lol #1

Merged
sheptikhinv merged 7 commits from unstable into master 2025-09-15 03:47:40 +05:00
6 changed files with 192 additions and 43 deletions
Showing only changes of commit 243224a720 - Show all commits

View file

@ -7,6 +7,10 @@
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
</PropertyGroup> </PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\MetaforceInstaller.Core\MetaforceInstaller.Core.csproj" />
</ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="AdvancedSharpAdbClient" Version="3.4.14" /> <PackageReference Include="AdvancedSharpAdbClient" Version="3.4.14" />
</ItemGroup> </ItemGroup>

View file

@ -5,7 +5,7 @@ namespace MetaforceInstaller.Cli;
static class Program static class Program
{ {
static void Main(string[] args) static async Task Main(string[] args)
{ {
try try
{ {
@ -22,32 +22,29 @@ static class Program
var adbService = new AdbService(); var adbService = new AdbService();
adbService.InstallApk(installationRequest.ApkPath); // Подписка на события прогресса
adbService.CopyFile(installationRequest.ZipPath, installationRequest.OutputPath); adbService.ProgressChanged += OnProgressChanged;
adbService.StatusChanged += OnStatusChanged;
// var adbPath = ExtractAdbFiles(); // Получение информации об устройстве
// var deviceInfo = adbService.GetDeviceInfo();
// var server = new AdbServer(); Console.WriteLine($"Найдено устройство: {deviceInfo.SerialNumber}");
// var result = server.StartServer(adbPath, restartServerIfNewer: false); Console.WriteLine($"Состояние: {deviceInfo.State}");
// Console.WriteLine($"ADB сервер запущен: {result}"); Console.WriteLine($"Модель: {deviceInfo.Model} - {deviceInfo.Name}");
// Console.WriteLine();
// adbClient = new AdbClient();
// // Создание объекта для отслеживания прогресса
// var devices = adbClient.GetDevices(); var progress = new Progress<MetaforceInstaller.Core.Models.ProgressInfo>(OnProgressReport);
//
// if (!devices.Any()) // Установка APK
// { await adbService.InstallApkAsync(installationRequest.ApkPath, progress);
// Console.WriteLine("Устройства не найдены. Подключите Android-устройство и включите отладку по USB."); Console.WriteLine();
// return;
// } // Копирование файла
// await adbService.CopyFileAsync(installationRequest.ZipPath, installationRequest.OutputPath, progress);
// deviceData = devices.FirstOrDefault(); Console.WriteLine();
// Console.WriteLine($"Найдено устройство: {deviceData.Serial}");
// Console.WriteLine($"Состояние: {deviceData.State}"); Console.WriteLine("Операция завершена успешно!");
// Console.WriteLine($"Имя устройства: {deviceData.Name} - {deviceData.Model}");
//
// InstallApk(installationRequest.ApkPath);
// CopyFileToDevice(installationRequest.ZipPath, installationRequest.OutputPath);
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -55,6 +52,29 @@ static class Program
} }
} }
private static void OnProgressChanged(object? sender, MetaforceInstaller.Core.Models.ProgressInfo e)
{
DrawProgressBar(e.PercentageComplete, e.BytesTransferred, e.TotalBytes);
}
private static void OnStatusChanged(object? sender, string e)
{
Console.WriteLine(e);
}
private static void OnProgressReport(MetaforceInstaller.Core.Models.ProgressInfo progressInfo)
{
if (progressInfo.TotalBytes > 0)
{
DrawProgressBar(progressInfo.PercentageComplete, progressInfo.BytesTransferred, progressInfo.TotalBytes);
}
else
{
// Для случаев без информации о байтах (например, установка APK)
DrawProgressBar(progressInfo.PercentageComplete, 0, 100);
}
}
static void ShowUsage() static void ShowUsage()
{ {
Console.WriteLine("Использование:"); Console.WriteLine("Использование:");
@ -82,7 +102,12 @@ static class Program
var filledLength = (int)(barLength * progress / 100.0); var filledLength = (int)(barLength * progress / 100.0);
var bar = "[" + new string('█', filledLength) + new string('░', barLength - filledLength) + "]"; var bar = "[" + new string('█', filledLength) + new string('░', barLength - filledLength) + "]";
var bytesText = $" {FormatBytes(receivedBytes)} / {FormatBytes(totalBytes)}";
string bytesText = "";
if (totalBytes > 0)
{
bytesText = $" {FormatBytes(receivedBytes)} / {FormatBytes(totalBytes)}";
}
Console.Write($"\r{bar} {progress}%{bytesText}"); Console.Write($"\r{bar} {progress}%{bytesText}");
} }

View file

@ -1,10 +1,18 @@
using MetaforceInstaller.Core.Models; using MetaforceInstaller.Core.Models;
using MetaforceInstaller.Core.Models;
namespace MetaforceInstaller.Core.Intefaces; namespace MetaforceInstaller.Core.Intefaces;
public interface IAdbService public interface IAdbService
{ {
public void InstallApk(string apkPath); event EventHandler<ProgressInfo>? ProgressChanged;
public void CopyFile(string localPath, string remotePath); event EventHandler<string>? StatusChanged;
public DeviceInfo GetDeviceInfo();
Task InstallApkAsync(string apkPath, IProgress<ProgressInfo>? progress = null, CancellationToken cancellationToken = default);
Task CopyFileAsync(string localPath, string remotePath, IProgress<ProgressInfo>? progress = null, CancellationToken cancellationToken = default);
DeviceInfo GetDeviceInfo();
// Синхронные версии для обратной совместимости
void InstallApk(string apkPath);
void CopyFile(string localPath, string remotePath);
} }

View file

@ -12,8 +12,14 @@
<EmbeddedResource Include="adb\AdbWinUsbApi.dll" /> <EmbeddedResource Include="adb\AdbWinUsbApi.dll" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="8.0.0" />
<PackageReference Include="AdvancedSharpAdbClient" Version="3.4.14" />
</ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="AdvancedSharpAdbClient" Version="3.4.14" /> <PackageReference Include="AdvancedSharpAdbClient" Version="3.4.14" />
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="8.0.3" />
</ItemGroup> </ItemGroup>
</Project> </Project>

View file

@ -0,0 +1,19 @@
namespace MetaforceInstaller.Core.Models;
public class ProgressInfo
{
public int PercentageComplete { get; set; }
public long BytesTransferred { get; set; }
public long TotalBytes { get; set; }
public string? Message { get; set; }
public string? CurrentFile { get; set; }
public ProgressType Type { get; set; }
}
public enum ProgressType
{
Installation,
FileCopy,
Extraction,
General
}

View file

@ -1,33 +1,42 @@
using System.Reflection; using System.Reflection;
using AdvancedSharpAdbClient; using AdvancedSharpAdbClient;
using AdvancedSharpAdbClient.DeviceCommands; using AdvancedSharpAdbClient.DeviceCommands;
using AdvancedSharpAdbClient.Logs;
using AdvancedSharpAdbClient.Models; using AdvancedSharpAdbClient.Models;
using MetaforceInstaller.Core.Intefaces; using MetaforceInstaller.Core.Intefaces;
using MetaforceInstaller.Core.Models; using MetaforceInstaller.Core.Models;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
namespace MetaforceInstaller.Core.Services; namespace MetaforceInstaller.Core.Services;
public class AdbService : IAdbService public class AdbService : IAdbService
{ {
private ILogger<AdbService> _logger; private readonly ILogger<AdbService> _logger;
private readonly AdbClient _adbClient; private readonly AdbClient _adbClient;
private DeviceData _deviceData; private DeviceData _deviceData;
public AdbService() public event EventHandler<ProgressInfo>? ProgressChanged;
public event EventHandler<string>? StatusChanged;
public AdbService(ILogger<AdbService>? logger = null)
{ {
_logger = logger ?? new NullLogger<AdbService>();
var adbPath = GetAdbPath(); var adbPath = GetAdbPath();
var server = new AdbServer(); var server = new AdbServer();
var serverStatus = server.StartServer(adbPath, restartServerIfNewer: false); var serverStatus = server.StartServer(adbPath, restartServerIfNewer: false);
_adbClient = new AdbClient(); _adbClient = new AdbClient();
var devices = _adbClient.GetDevices(); var devices = _adbClient.GetDevices();
foreach (var device in devices)
{
Console.WriteLine(device.Model);
}
_deviceData = devices.FirstOrDefault(); _deviceData = devices.FirstOrDefault();
} }
private void ExtractResource(string resourceName, string outputPath) private void ExtractResource(string resourceName, string outputPath)
{ {
_logger.LogInformation($"Extracting resource: {resourceName} to {outputPath}"); _logger.LogInformation($"Extracting resource: {resourceName} to {outputPath}");
using var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName); using var stream = Assembly.GetAssembly(typeof(AdbService)).GetManifestResourceStream(resourceName);
using var fileStream = File.Create(outputPath); using var fileStream = File.Create(outputPath);
stream.CopyTo(fileStream); stream.CopyTo(fileStream);
_logger.LogInformation($"Resource extracted: {resourceName} to {outputPath}"); _logger.LogInformation($"Resource extracted: {resourceName} to {outputPath}");
@ -41,14 +50,30 @@ public class AdbService : IAdbService
var adbPath = Path.Combine(tempDir, "adb.exe"); var adbPath = Path.Combine(tempDir, "adb.exe");
if (File.Exists(adbPath)) return adbPath; if (File.Exists(adbPath)) return adbPath;
ExtractResource("MetaforceInstaller.Cli.adb.adb.exe", adbPath); ExtractResource("MetaforceInstaller.Core.adb.adb.exe", adbPath);
ExtractResource("MetaforceInstaller.Cli.adb.AdbWinApi.dll", Path.Combine(tempDir, "AdbWinApi.dll")); ExtractResource("MetaforceInstaller.Core.adb.AdbWinApi.dll", Path.Combine(tempDir, "AdbWinApi.dll"));
ExtractResource("MetaforceInstaller.Cli.adb.AdbWinUsbApi.dll", Path.Combine(tempDir, "AdbWinUsbApi.dll")); ExtractResource("MetaforceInstaller.Core.adb.AdbWinUsbApi.dll", Path.Combine(tempDir, "AdbWinUsbApi.dll"));
return adbPath; return adbPath;
} }
private void OnProgressChanged(ProgressInfo progressInfo)
{
ProgressChanged?.Invoke(this, progressInfo);
}
private void OnStatusChanged(string status)
{
StatusChanged?.Invoke(this, status);
}
public void InstallApk(string apkPath) public void InstallApk(string apkPath)
{
InstallApkAsync(apkPath).Wait();
}
public async Task InstallApkAsync(string apkPath, IProgress<ProgressInfo>? progress = null,
CancellationToken cancellationToken = default)
{ {
try try
{ {
@ -58,11 +83,37 @@ public class AdbService : IAdbService
return; return;
} }
OnStatusChanged("Начинаем установку APK...");
_logger.LogInformation($"Installing APK: {apkPath}"); _logger.LogInformation($"Installing APK: {apkPath}");
var packageManager = new PackageManager(_adbClient, _deviceData); progress?.Report(new ProgressInfo
packageManager.InstallPackage(apkPath, o => { }); {
PercentageComplete = 0,
Message = "Подготовка к установке APK...",
Type = ProgressType.Installation,
CurrentFile = Path.GetFileName(apkPath)
});
var packageManager = new PackageManager(_adbClient, _deviceData);
await Task.Run(() =>
{
packageManager.InstallPackage(apkPath, installProgress =>
{
var progressInfo = new ProgressInfo
{
PercentageComplete = (int)installProgress.UploadProgress,
Message = $"Установка APK: {installProgress.UploadProgress:F1}%",
Type = ProgressType.Installation,
CurrentFile = Path.GetFileName(apkPath)
};
progress?.Report(progressInfo);
OnProgressChanged(progressInfo);
});
}, cancellationToken);
OnStatusChanged("APK успешно установлен!");
_logger.LogInformation("APK successfully installed!"); _logger.LogInformation("APK successfully installed!");
} }
catch (Exception ex) catch (Exception ex)
@ -73,6 +124,12 @@ public class AdbService : IAdbService
} }
public void CopyFile(string localPath, string remotePath) public void CopyFile(string localPath, string remotePath)
{
CopyFileAsync(localPath, remotePath).Wait();
}
public async Task CopyFileAsync(string localPath, string remotePath, IProgress<ProgressInfo>? progress = null,
CancellationToken cancellationToken = default)
{ {
try try
{ {
@ -82,14 +139,44 @@ public class AdbService : IAdbService
return; return;
} }
OnStatusChanged("Начинаем копирование файла...");
_logger.LogInformation($"Copying file: {localPath} to {remotePath}"); _logger.LogInformation($"Copying file: {localPath} to {remotePath}");
using var fileStream = File.OpenRead(localPath); var fileInfo = new FileInfo(localPath);
var syncService = new SyncService(_adbClient, _deviceData);
syncService.Push(fileStream, remotePath, UnixFileStatus.DefaultFileMode, DateTime.Now, progress?.Report(new ProgressInfo
new Action<SyncProgressChangedEventArgs>(progress => { })); {
PercentageComplete = 0,
Message = "Подготовка к копированию файла...",
Type = ProgressType.FileCopy,
CurrentFile = Path.GetFileName(localPath),
TotalBytes = fileInfo.Length
});
await Task.Run(() =>
{
using var fileStream = File.OpenRead(localPath);
var syncService = new SyncService(_adbClient, _deviceData);
syncService.Push(fileStream, remotePath, UnixFileStatus.DefaultFileMode, DateTime.Now,
copyProgress =>
{
var progressInfo = new ProgressInfo
{
PercentageComplete = (int)copyProgress.ProgressPercentage,
BytesTransferred = copyProgress.ReceivedBytesSize,
TotalBytes = copyProgress.TotalBytesToReceive,
Message = $"Копирование: {copyProgress.ProgressPercentage:F1}%",
Type = ProgressType.FileCopy,
CurrentFile = Path.GetFileName(localPath)
};
progress?.Report(progressInfo);
OnProgressChanged(progressInfo);
});
}, cancellationToken);
OnStatusChanged("Файл успешно скопирован!");
_logger.LogInformation("File successfully copied!"); _logger.LogInformation("File successfully copied!");
} }
catch (Exception ex) catch (Exception ex)