forked from yanw/App_win_iot_V2.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
245 lines
9.3 KiB
245 lines
9.3 KiB
using System;
|
|
using System.Collections.Generic;
|
|
using System.Diagnostics;
|
|
using System.IO;
|
|
using System.IO.Compression;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
using System.Windows;
|
|
|
|
namespace ConUpdate.ViewModel
|
|
{
|
|
class ProgressViewModel : ViewModelBase
|
|
{
|
|
private double currentProgress = 0;
|
|
public double CurrentProgress
|
|
{
|
|
get { return currentProgress; }
|
|
set
|
|
{
|
|
currentProgress = value;
|
|
Val = Math.Round(((value / _maxLength) * 100), 2);
|
|
Message = value + "/" + _maxLength;
|
|
}
|
|
}
|
|
private LogHelper log = new LogHelper();
|
|
private double _maxLength;
|
|
private string containerName = "IOTContainer.exe";
|
|
#region 组件
|
|
|
|
private double val = 0.00;
|
|
public double Val
|
|
{
|
|
get { return val; }
|
|
set
|
|
{
|
|
val = value;
|
|
OnPropertyChanged("Val");
|
|
}
|
|
}
|
|
|
|
private string title = string.Empty;
|
|
public string Title
|
|
{
|
|
get { return title; }
|
|
set
|
|
{
|
|
title = value;
|
|
OnPropertyChanged("Title");
|
|
}
|
|
}
|
|
|
|
private int maxValue = 100;
|
|
public int MaxValue
|
|
{
|
|
get { return maxValue; }
|
|
set
|
|
{
|
|
maxValue = value;
|
|
OnPropertyChanged("MaxValue");
|
|
}
|
|
}
|
|
|
|
private string message = string.Empty;
|
|
public string Message
|
|
{
|
|
get { return message; }
|
|
set
|
|
{
|
|
message = value;
|
|
OnPropertyChanged("Message");
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
|
|
public ProgressViewModel(string filePath)
|
|
{
|
|
Task.Run(() =>
|
|
{
|
|
UpdateContainer(filePath);
|
|
});
|
|
}
|
|
#region 方法
|
|
/// <summary>
|
|
/// 更新容器
|
|
/// </summary>
|
|
/// <param name="filePath"></param>
|
|
public void UpdateContainer(string filePath)
|
|
{
|
|
try
|
|
{
|
|
log.WriteInfoFile($"关闭容器{containerName}中...");
|
|
CloseContainer();
|
|
log.WriteInfoFile($"加载压缩文件{filePath}...");
|
|
Title = "加载新版文件...请稍等...";
|
|
var basePath = AppDomain.CurrentDomain.BaseDirectory;
|
|
var tempDir = Path.Combine(basePath, "updateTempFolder");
|
|
if (Directory.Exists(tempDir))
|
|
{
|
|
Directory.Delete(tempDir, true);
|
|
}
|
|
ZipFile.ExtractToDirectory(filePath, tempDir);
|
|
log.WriteInfoFile($"解压文件{filePath}...");
|
|
Title = "正在更新版本...";
|
|
GetFilesCount(tempDir, ref _maxLength);
|
|
CopyDireToDire(tempDir, basePath);
|
|
Directory.Delete(tempDir, true);
|
|
//File.Delete(filePath);
|
|
Title = "更新已完成...";
|
|
log.WriteInfoFile($"更新容器成功!...");
|
|
OpenContainer();
|
|
Environment.Exit(0);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Title = "更新失败...";
|
|
log.WriteInfoFile("容器更新失败:" + ex.Message);
|
|
OpenContainer();
|
|
Environment.Exit(0);
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// 将一个文件夹下的所有东西复制到另一个文件夹 (可备份文件夹)
|
|
/// </summary>
|
|
/// <param name="sourceDire">源文件夹全名</param>
|
|
/// <param name="destDire">目标文件夹全名</param>
|
|
/// <param name="backupsDire">备份文件夹全名</param>
|
|
public void CopyDireToDire(string sourceDire, string destDire, string backupsDire = null)
|
|
{
|
|
if (Directory.Exists(sourceDire) && Directory.Exists(destDire))
|
|
{
|
|
DirectoryInfo sourceDireInfo = new DirectoryInfo(sourceDire);
|
|
FileInfo[] fileInfos = sourceDireInfo.GetFiles();
|
|
foreach (FileInfo fInfo in fileInfos)
|
|
{
|
|
CurrentProgress += 1;
|
|
string sourceFile = fInfo.FullName;
|
|
string destFile = sourceFile.Replace(sourceDire, destDire);
|
|
if (backupsDire != null && File.Exists(destFile))
|
|
{
|
|
Directory.CreateDirectory(backupsDire);
|
|
string backFile = destFile.Replace(destDire, backupsDire);
|
|
File.Copy(destFile, backFile, true);
|
|
}
|
|
File.Copy(sourceFile, destFile, true);
|
|
}
|
|
DirectoryInfo[] direInfos = sourceDireInfo.GetDirectories();
|
|
foreach (DirectoryInfo dInfo in direInfos)
|
|
{
|
|
string sourceDire2 = dInfo.FullName;
|
|
string destDire2 = sourceDire2.Replace(sourceDire, destDire);
|
|
string backupsDire2 = null;
|
|
if (backupsDire != null)
|
|
{
|
|
backupsDire2 = sourceDire2.Replace(sourceDire, backupsDire);
|
|
}
|
|
Directory.CreateDirectory(destDire2);
|
|
CopyDireToDire(sourceDire2, destDire2, backupsDire2);
|
|
}
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// 获取文件总数
|
|
/// </summary>
|
|
/// <param name="dir"></param>
|
|
/// <param name="count"></param>
|
|
public void GetFilesCount(string dir, ref double count)
|
|
{
|
|
count += new DirectoryInfo(dir).GetFiles().Length;
|
|
var dirs = new DirectoryInfo(dir).GetDirectories();
|
|
foreach (var item in dirs)
|
|
{
|
|
GetFilesCount(item.FullName, ref count);
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// 开启容器
|
|
/// </summary>
|
|
public void OpenContainer()
|
|
{
|
|
App app = ((App)Application.Current);
|
|
//if (killexe)
|
|
{
|
|
System.Security.Principal.WindowsIdentity identity = System.Security.Principal.WindowsIdentity.GetCurrent();
|
|
//创建Windows用户主题
|
|
System.Windows.Forms.Application.EnableVisualStyles();
|
|
System.Security.Principal.WindowsPrincipal principal = new System.Security.Principal.WindowsPrincipal(identity);
|
|
//判断当前登录用户是否为管理员
|
|
if (!principal.IsInRole(System.Security.Principal.WindowsBuiltInRole.Administrator))
|
|
{
|
|
//创建启动对象
|
|
System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo();
|
|
//设置运行文件
|
|
startInfo.WorkingDirectory = AppDomain.CurrentDomain.BaseDirectory.Replace("\\", "/");//设置应用程序在其所在目录
|
|
startInfo.FileName = startInfo.WorkingDirectory + "/"+ containerName; //设置启动参数
|
|
startInfo.Arguments = app.info + "&true";
|
|
log.WriteInfoFile("发送" + startInfo.FileName);
|
|
//设置启动动作,确保以管理员身份运行
|
|
startInfo.Verb = "runas";
|
|
//如果不是管理员,则启动UAC
|
|
Process.Start(startInfo);
|
|
//退出
|
|
System.Windows.Forms.Application.Exit();
|
|
}
|
|
else
|
|
{
|
|
System.Diagnostics.Process p = new System.Diagnostics.Process();
|
|
p.StartInfo.WorkingDirectory = AppDomain.CurrentDomain.BaseDirectory.Replace("\\", "/");//设置应用程序在其所在目录
|
|
p.StartInfo.FileName = p.StartInfo.WorkingDirectory + "/"+ containerName;
|
|
p.StartInfo.Arguments = app.info + "&true";
|
|
log.WriteInfoFile("管理员发送" + p.StartInfo.FileName);
|
|
p.StartInfo.UseShellExecute = false; //是否使用操作系统shell启动
|
|
p.StartInfo.RedirectStandardInput = true;//接受来自调用程序的输入信息
|
|
p.StartInfo.RedirectStandardOutput = true;//由调用程序获取输出信息
|
|
p.StartInfo.RedirectStandardError = true;//重定向标准错误输出
|
|
p.StartInfo.CreateNoWindow = false;//不显示程序窗口
|
|
p.Start();//启动程序
|
|
}
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// 关闭容器
|
|
/// </summary>
|
|
public void CloseContainer()
|
|
{
|
|
try
|
|
{
|
|
Process[] pro = Process.GetProcesses();
|
|
var process = pro.FirstOrDefault(p => string.Equals(p.ProcessName, containerName.Substring(0, containerName.IndexOf(".")), StringComparison.OrdinalIgnoreCase));
|
|
if(process != null)
|
|
{
|
|
process.Kill();
|
|
log.WriteInfoFile("关闭容器...");
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
log.WriteInfoFile("关闭容器失败:" + ex.ToString());
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
}
|
|
}
|
|
|