using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Net;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using UpgradePackageUploadTool.Services;
using UpgradePackageUploadTool.Settings;
using Vinno.IUS.Common.Network.Leaf;
using Vinno.IUS.Common.Network.Tcp;
using Vinno.IUS.Common.Network.Transfer;
using Vinno.vCloud.Common.Storage.Download;
using Vinno.vCloud.Protocol.Infrastructures;
using Vinno.vCloud.Protocol.Initializers;
using Vinno.vCloud.Protocol.Messages;
using Vinno.vCloud.Protocol.Messages.Upgrade;
namespace UpgradePackageUploadTool
{
public class UltrasoundMachineUpgrader
{
private ClientLeaf _leaf;
private readonly string _url;
///
/// The constructor of the UltrasoundMachineUpgrader.
///
/// The server url.
public UltrasoundMachineUpgrader(string url)
{
_url = url;
TerminalTagsInitializer.Initialize();
SystemInitializer.Initialize();
}
///
/// Get Ultrasound Machine Latest Package Info
///
/// Package Type
/// Ultrasound Machine Package Info
public GeneralPackInfo GetUltrasoundMachineLatestPackageInfo(string uniquedCode)
{
try
{
CreateLeaf();
using (var queryLatestPackageRequest = MessagePool.GetMessage())
{
queryLatestPackageRequest.UniquedCode = uniquedCode;
var message = _leaf.Send(queryLatestPackageRequest);
if (message == null)
{
return null;
}
var result = GetPackageResult.Convert(message);
if (result != null)
{
var createUserName = result.CreateUserName;
var description = result.Description;
var fileName = result.FileName;
var fileSize = result.FileSize;
var fileToken = result.FileToken;
var updateTime = result.UpdateTime;
var version = result.Version;
return new GeneralPackInfo(createUserName, description, fileName, fileToken, fileSize, result.PackageType, updateTime, version, result.UniquedCode);
}
}
return null;
}
finally
{
CloseLeaf();
}
}
///
/// Download the Latest Package of Ultrasound Machine from Storage Server Async.
///
/// File Token
/// The Path to place the package
/// Download Progress
/// Cancel Token Source
public void DownloadUltrasoundMachineLatestPackage(string fileToken, string packagePath, Action progress = null, CancellationTokenSource cancelTokenSource = null)
{
DownloadHelper.GetFile(fileToken, packagePath, progress, cancelTokenSource, true);
}
///
/// Create a leaf to connect to the server.
///
private void CreateLeaf()
{
if (_leaf != null)
{
_leaf.Close();
}
_leaf = new ClientLeaf(new LeafIdContext(), LeafMode.Dual, new TcpCreator(_url), "Terminal upgrade:");
if (!_leaf.Online)
{
_leaf.Close();
}
else
{
_leaf.RegisterSetAccountDataMessageFunc(SetAccountDataToMessage);
}
}
private void CloseLeaf()
{
_leaf?.Close();
}
private Message SetAccountDataToMessage(Message message)
{
if (message is ClientRequestMessage clientRequestMessage)
{
clientRequestMessage.AccountData = GetAccountDataMessage() as ClientAccountMessage;
return clientRequestMessage;
}
return message;
}
private Message GetAccountDataMessage()
{
var accountData = MessagePool.GetMessage();
accountData.AccountId = "TerminalUpgradeId";
accountData.AccountName = "TerminalUpgrade";
accountData.Source = LoginSource.UltrasoundMachine;
return accountData;
}
}
///
/// MainWindow.xaml 的交互逻辑
///
public partial class MainWindow : Window
{
private vCloudService _vCloudService;
private bool _isConnected;
private int _startTickCount;
private UltrasoundMachineUpgrader _ultrasoundMachineUpgrader;
private PackageType _packageType;
private Version _newVersion;
private Version _oldVersion;
private WingServerService _wingServerService;
private void ConnectStatusChanged()
{
if (_isConnected)
{
ConnectOrDisconnectServer_Button.Content = "断开连接";
ServerIP_Text.IsEnabled = false;
ServerPort_Text.IsEnabled = false;
Account_Text.IsEnabled = false;
Password_PasswordBox.IsEnabled = false;
WingServer_Text.IsEnabled = false;
_ultrasoundMachineUpgrader = new UltrasoundMachineUpgrader($"{ServerIP_Text.Text}:{ServerPort_Text.Text}");
}
else
{
ConnectOrDisconnectServer_Button.Content = "连接";
ServerIP_Text.IsEnabled = true;
ServerPort_Text.IsEnabled = true;
Account_Text.IsEnabled = true;
Password_PasswordBox.IsEnabled = true;
WingServer_Text.IsEnabled = true;
}
}
public MainWindow()
{
InitializeComponent();
LoadConfig();
_isConnected = false;
_vCloudService = new vCloudService();
_vCloudService.UploadProgressChanged += OnUploadProgressChanged;
}
protected override void OnClosing(CancelEventArgs e)
{
_vCloudService.UploadProgressChanged -= OnUploadProgressChanged;
base.OnClosing(e);
}
private void OnUploadProgressChanged(object sender, int e)
{
Dispatcher.Invoke(() =>
{
Waiting.ProgressTextBlock.Text = $"{e}%";
});
}
private void LoadConfig()
{
ServerIP_Text.Text = SettingConfig.Instance.ServerIP;
ServerPort_Text.Text = SettingConfig.Instance.ServerPort.ToString();
Account_Text.Text = SettingConfig.Instance.Account;
Password_PasswordBox.Password = SettingConfig.Instance.Password;
WingServer_Text.Text = SettingConfig.Instance.WingServer;
}
private void ServerIPText_TextChanged(object sender, TextChangedEventArgs e)
{
SettingConfig.Instance.ServerIP = ServerIP_Text.Text;
SettingConfig.Instance.Save();
}
private void ServerPortText_TextChanged(object sender, TextChangedEventArgs e)
{
if (int.TryParse(ServerPort_Text.Text, out int port))
{
SettingConfig.Instance.ServerPort = port;
SettingConfig.Instance.Save();
}
}
private void Account_Text_TextChanged(object sender, TextChangedEventArgs e)
{
SettingConfig.Instance.Account = Account_Text.Text;
SettingConfig.Instance.Save();
}
private void Password_PasswordBox_PasswordChanged(object sender, RoutedEventArgs e)
{
SettingConfig.Instance.Password = Password_PasswordBox.Password;
SettingConfig.Instance.Save();
}
private void OnOpenFile(object sender, RoutedEventArgs e)
{
OpenFileDialog openFileDialog = new OpenFileDialog
{
Multiselect = false,
Title = "请选择上传的安装包",
Filter = "安卓安装包|*.apk"
};
if (openFileDialog.ShowDialog() ?? false)
{
var filepath = openFileDialog.FileName;
FilePath_Text.Text = filepath;
}
}
private async void OnUploadPackage(object sender, RoutedEventArgs e)
{
ButtonIsEnabledChange(false);
try
{
if (_isConnected)
{
if (!UploadInfoCheck())
{
ButtonIsEnabledChange(true);
return;
}
_startTickCount = Environment.TickCount;
Waiting.StartWaiting();
try
{
var fileName = $"{FileName_Text.Text}_{Version_Text.Text}.apk";
var packInfo = await _wingServerService.UploadPackageAsync(FilePath_Text.Text, Version_Text.Text, fileName, Description_Text.Text, FileName_Text.Text);
if (packInfo != null)
{
ShowPackInfo(packInfo);
var endTickCount = Environment.TickCount;
var elapsedTime = Math.Round((endTickCount - _startTickCount) / 1000d, 2);
MessageBox.Show($"Upload Package Successful! Elapsed Time is {elapsedTime} s.");
}
else
{
ShowInfo_DataGrid.Visibility = Visibility.Collapsed;
MessageBox.Show("Upload Package Failed!");
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
else
{
MessageBox.Show("Please Login First!");
}
}
catch (Exception ex)
{
MessageBox.Show($"Upload Package Failed! Fail Message: {ex.Message}");
}
Waiting.StopWaiting();
ButtonIsEnabledChange(true);
}
private void ShowPackInfo(GeneralPackInfo packInfo)
{
List packInfos = new List { packInfo };
ShowInfo_DataGrid.ItemsSource = packInfos;
ShowInfo_DataGrid.Visibility = Visibility.Visible;
}
private void ButtonIsEnabledChange(bool isEnabled)
{
UploadPackage_Button.IsEnabled = isEnabled;
ConnectOrDisconnectServer_Button.IsEnabled = isEnabled;
OpenFile_Button.IsEnabled = isEnabled;
Download_Button.IsEnabled = isEnabled;
}
private bool UploadInfoCheck()
{
if (string.IsNullOrEmpty(FilePath_Text.Text))
{
MessageBox.Show($"The package path is empty,please choose the package.");
return false;
}
if (string.IsNullOrEmpty(Version_Text.Text))
{
MessageBox.Show($"The version of package is empty, please input the version of package!");
return false;
}
if (!Version.TryParse(Version_Text.Text, out _newVersion))
{
MessageBox.Show("Invalid version format!");
return false;
}
if (_oldVersion != null && _newVersion < _oldVersion)
{
MessageBox.Show("Please make sure the new version is greater than the current one!");
return false;
}
if (string.IsNullOrEmpty(FileName_Text.Text))
{
MessageBox.Show($"The package name is empty,please input the package name");
return false;
}
return true;
}
private async void OnConnectOrDisconnectServer(object sender, RoutedEventArgs e)
{
Waiting.StartWaiting();
_oldVersion = null;
ConnectOrDisconnectServer_Button.IsEnabled = false;
try
{
if (!_isConnected)
{
if (!ValidateInput())
{
return;
}
_wingServerService = new WingServerService(SettingConfig.Instance.WingServer);
var result = await _wingServerService.LoginAsync(SettingConfig.Instance.Account, SettingConfig.Instance.Password);
if (!result.Success)
{
_isConnected = false;
ConnectStatusChanged();
MessageBox.Show(result.ErrMessage);
}
else
{
_isConnected = true;
ConnectStatusChanged();
}
}
else
{
var result = await _wingServerService.LoginOutAsync();
if (result.Success)
{
_isConnected = false;
ConnectStatusChanged();
ShowInfo_DataGrid.Visibility = Visibility.Collapsed;
}
else
{
_isConnected = true;
ConnectStatusChanged();
MessageBox.Show("Loginout Failed.");
}
}
}
catch (Exception ex)
{
MessageBox.Show($"Operation Fail:{ex.Message}");
}
finally
{
Waiting.StopWaiting();
ConnectOrDisconnectServer_Button.IsEnabled = true;
}
}
private bool ValidateInput()
{
//if (!ValidateServerAddress(ServerIP_Text.Text))
//{
// MessageBox.Show("Invalid server address");
// return false;
//}
//if (!IsPort(ServerPort_Text.Text))
//{
// MessageBox.Show("Invalid port");
// return false;
//}
if (string.IsNullOrEmpty(WingServer_Text.Text))
{
MessageBox.Show("Server Url is empty!");
return false;
}
if (string.IsNullOrEmpty(Account_Text.Text))
{
MessageBox.Show("Account is empty!");
return false;
}
if (string.IsNullOrEmpty(Password_PasswordBox.Password))
{
MessageBox.Show("Password is empty!");
return false;
}
return true;
}
private bool IsPort(string port)
{
if (int.TryParse(port, out int portnumber))
{
if (portnumber > 0 && portnumber < 65535)
{
return true;
}
return false;
}
return false;
}
private bool ValidateServerAddress(string serverip)
{
if (string.IsNullOrEmpty(serverip))
{
return false;
}
if (IPAddress.TryParse(serverip, out IPAddress ip))
{
return true;
}
else
{
try
{
ip = Dns.GetHostAddresses(serverip).Where(x => x.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork).First();
if (ip != null)
{
return true;
}
else
{
return false;
}
}
catch
{
return false;
}
}
}
private async void OnDownloadPackage(object sender, RoutedEventArgs e)
{
if (string.IsNullOrEmpty(FileName_Text.Text))
{
return;
}
if (!_isConnected)
{
MessageBox.Show("Please Login First!");
return;
}
ButtonIsEnabledChange(false);
try
{
var package = await _wingServerService.GetPackageInfoAsync(FileName_Text.Text);
if (package != null)
{
var localPatch = $"D://{package.FileName}";
_ultrasoundMachineUpgrader.DownloadUltrasoundMachineLatestPackage($"1!U${package.FileToken}", localPatch);
MessageBox.Show($"Download success, path:{localPatch}");
}
else
{
MessageBox.Show($"Package does not exist!");
}
}
catch (Exception ex)
{
MessageBox.Show($"Download Fail:{ex.Message}");
}
finally
{
ButtonIsEnabledChange(true);
}
}
private async void ComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
_oldVersion = null;
SettingConfig.Instance.PackageType = _packageType;
SettingConfig.Instance.Save();
ShowInfo_DataGrid.ItemsSource = null;
if (_vCloudService != null && _isConnected)
{
try
{
Waiting.StartWaiting();
var packInfo = await _vCloudService.GetLatestPackageAsync(FileName_Text.Text);
if (packInfo != null)
{
_oldVersion = new Version(packInfo.Version);
ShowPackInfo(packInfo);
}
}
finally
{
Waiting.StopWaiting();
}
}
}
private async void OnGetLatestPackage(object sender, RoutedEventArgs e)
{
try
{
if (string.IsNullOrEmpty(FileName_Text.Text))
{
return;
}
if (_isConnected)
{
var package = await _wingServerService.GetPackageInfoAsync(FileName_Text.Text);
if (package != null)
{
_oldVersion = new Version(package.Version);
ShowPackInfo(package);
}
else
{
MessageBox.Show($"Package does not exist!");
}
}
else
{
MessageBox.Show("Please Login First!");
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
private void WingServer_Text_TextChanged(object sender, TextChangedEventArgs e)
{
SettingConfig.Instance.WingServer = WingServer_Text.Text;
SettingConfig.Instance.Save();
}
}
}