diff --git a/.idea/.idea.WinformGeneralDeveloperFrame/.idea/workspace.xml b/.idea/.idea.WinformGeneralDeveloperFrame/.idea/workspace.xml
index a585f86..74b880e 100644
--- a/.idea/.idea.WinformGeneralDeveloperFrame/.idea/workspace.xml
+++ b/.idea/.idea.WinformGeneralDeveloperFrame/.idea/workspace.xml
@@ -3,9 +3,23 @@
WinformGeneralDeveloperFrame.Start/Start.csproj
WinformGeneralPrimordialForm/PrimordialForm.csproj
+ Update/Update.csproj
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -66,6 +80,24 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -77,6 +109,9 @@
1637673594984
+
+
+
diff --git a/.vs/WinformGeneralDeveloperFrame/v17/.suo b/.vs/WinformGeneralDeveloperFrame/v17/.suo
index ee77f42..b928a27 100644
Binary files a/.vs/WinformGeneralDeveloperFrame/v17/.suo and b/.vs/WinformGeneralDeveloperFrame/v17/.suo differ
diff --git a/.vs/WinformGeneralDeveloperFrame/v17/fileList.bin b/.vs/WinformGeneralDeveloperFrame/v17/fileList.bin
index 43ef3fa..95cf36e 100644
Binary files a/.vs/WinformGeneralDeveloperFrame/v17/fileList.bin and b/.vs/WinformGeneralDeveloperFrame/v17/fileList.bin differ
diff --git a/Update.Core/Downloader.cs b/Update.Core/Downloader.cs
new file mode 100644
index 0000000..205a63a
--- /dev/null
+++ b/Update.Core/Downloader.cs
@@ -0,0 +1,385 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Net;
+using System.ComponentModel;
+using System.Xml.Serialization;
+using System.IO;
+using System.Threading;
+using System.Collections.Specialized;
+
+namespace Updater.Core
+{
+ ///
+ /// 下载错误事件数据
+ ///
+ public class DownloadErrorEventArgs : EventArgs
+ {
+ public Exception Error { get; set; }
+
+ public Manifest Manifest { get; set; }
+ }
+
+ ///
+ /// 下载进度事件数据
+ ///
+ public class DownloadProgressEventArgs : ProgressChangedEventArgs
+ {
+ public DownloadProgressEventArgs(int progressPercentage, object userState)
+ : base(progressPercentage, userState)
+ { }
+
+ ///
+ /// 当前下载的文件名
+ ///
+ public string FileName { get; set; }
+
+ ///
+ /// 获取收到的字节数。
+ ///
+ public long BytesReceived { get; set; }
+ ///
+ /// 获取 System.Net.WebClient 数据下载操作中的字节总数。
+ ///
+ public long TotalBytesToReceive { get; set; }
+ }
+
+ ///
+ /// 下载完成事件数据
+ ///
+ public class DownloadCompleteEventArgs : AsyncCompletedEventArgs
+ {
+ public DownloadCompleteEventArgs(Exception error, bool cancelled, object userState)
+ : base(error, cancelled, userState)
+ {
+ }
+
+ public Manifest Manifest { get; set; }
+ }
+
+ ///
+ /// 服务器文件下载类
+ ///
+ public class DownloadClass : Component
+ {
+ #region 变量定义
+ private WebClient webClient = new WebClient();
+ private Manifest manifest;
+ private int fileCount = 0;
+ private bool cancel = false;
+ private string tempPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "temp");
+
+ private HybridDictionary userStateToLifetime = new HybridDictionary();
+ private object defaultTaskId = new object();
+ private delegate void WorkerEventHandler(AsyncOperation asyncOp);
+ private System.ComponentModel.Container components = null;
+ private SendOrPostCallback onProgressReportDelegate;
+ private SendOrPostCallback onCompletedDelegate;
+ private AsyncOperation current;
+ #endregion
+
+ #region 事件
+ ///
+ /// 下载进度
+ ///
+ public event EventHandler DownloadProgressChanged;
+
+ ///
+ /// 下载完成事件
+ ///
+ public event EventHandler DownloadCompleted;
+
+ ///
+ /// 下载错误触发的事件
+ ///
+ public event EventHandler DownloadError;
+ #endregion
+
+ #region 构造及析构
+ public DownloadClass(IContainer container)
+ {
+ container.Add(this);
+ InitializeComponent();
+ InitializeDelegates();
+ }
+
+ public DownloadClass()
+ {
+ InitializeComponent();
+ InitializeDelegates();
+ }
+
+ ///
+ /// 初始化代理
+ ///
+ protected virtual void InitializeDelegates()
+ {
+ onProgressReportDelegate = new SendOrPostCallback(ReportProgress);
+ onCompletedDelegate = new SendOrPostCallback(DoDownloadCompleted);
+ }
+
+ private void InitializeComponent()
+ {
+ components = new System.ComponentModel.Container();
+ }
+
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing)
+ {
+ if (components != null)
+ {
+ components.Dispose();
+ }
+ }
+ base.Dispose(disposing);
+ }
+ #endregion
+
+ ///
+ /// 触发下载进度事件
+ ///
+ ///
+ protected virtual void OnDownloadProgressChanged(DownloadProgressEventArgs e)
+ {
+ if (DownloadProgressChanged != null)
+ {
+ DownloadProgressChanged(this, e);
+ }
+ }
+
+ ///
+ /// 触发下载完成事件
+ ///
+ ///
+ protected virtual void OnDownloadCompleted(DownloadCompleteEventArgs e)
+ {
+ if (DownloadCompleted != null)
+ {
+ DownloadCompleted(this, e);
+ }
+ }
+
+ ///
+ /// 触发下载错误事件
+ ///
+ ///
+ protected virtual void OnDownloadError(DownloadErrorEventArgs e)
+ {
+ if (DownloadError != null)
+ {
+ DownloadError(this, e);
+ }
+ }
+
+ ///
+ /// 下载文字保存的临时目录
+ ///
+ public string TempPath
+ {
+ get
+ {
+ return tempPath;
+ }
+ set
+ {
+ tempPath = value;
+ }
+ }
+
+ ///
+ /// 同步下载
+ ///
+ /// 文件下载清单
+ public void Download(Manifest manifest)
+ {
+ Init(manifest);
+ foreach (var file in manifest.ManifestFiles.Files)
+ {
+ string serverFileName = Path.Combine(manifest.ManifestFiles.BaseUrl, file.Source);
+ string clientFileName = Path.Combine(tempPath, file.Source);
+ Uri uri = new Uri(serverFileName);
+ if (!Directory.Exists(Path.GetDirectoryName(clientFileName)))
+ {
+ Directory.CreateDirectory(Path.GetDirectoryName(clientFileName));
+ }
+ webClient.DownloadFile(uri, clientFileName);
+ }
+ }
+
+ ///
+ /// 异步下载
+ ///
+ /// 文件下载清单
+ public void DownloadAsync(Manifest manifest)
+ {
+ Init(manifest);
+ DownloadAsync(manifest, defaultTaskId);
+ }
+
+ ///
+ /// 异步下载并指定任务Id
+ ///
+ /// 文件下载清单
+ /// 任务Id
+ public void DownloadAsync(Manifest manifest, object taskId)
+ {
+ AsyncOperation asyncOp = AsyncOperationManager.CreateOperation(taskId);
+ lock (userStateToLifetime.SyncRoot)
+ {
+ if (userStateToLifetime.Contains(taskId))
+ {
+ throw new ArgumentException("参数taskId必须是唯一的", "taskId");
+ }
+ userStateToLifetime[taskId] = asyncOp;
+ }
+ WorkerEventHandler workerDelegate = new WorkerEventHandler(DownloadWorker);
+ workerDelegate.BeginInvoke(asyncOp, null, null);
+ }
+
+ private void Init(Manifest manifest)
+ {
+ this.manifest = manifest;
+ webClient.BaseAddress = manifest.ManifestFiles.BaseUrl;
+ webClient.Credentials = CredentialCache.DefaultCredentials;
+ webClient.Encoding = Encoding.UTF8;
+ }
+
+ ///
+ /// 异步下载方法
+ ///
+ ///
+ private void DownloadWorker(AsyncOperation asyncOp)
+ {
+ current = asyncOp;
+ if (!TaskCanceled(asyncOp.UserSuppliedState))
+ {
+ try
+ {
+ webClient.DownloadFileCompleted += new AsyncCompletedEventHandler(webClient_DownloadFileCompleted);
+ webClient.DownloadProgressChanged += new DownloadProgressChangedEventHandler(webClient_DownloadProgressChanged);
+ foreach (var file in manifest.ManifestFiles.Files)
+ {
+ string serverFileName = Path.Combine(manifest.ManifestFiles.BaseUrl, file.Source);
+ string clientFileName = Path.Combine(tempPath, file.Source);
+ Uri uri = new Uri(serverFileName);
+ if (!Directory.Exists(Path.GetDirectoryName(clientFileName)))
+ {
+ Directory.CreateDirectory(Path.GetDirectoryName(clientFileName));
+ }
+ while (webClient.IsBusy)
+ {
+ //阻塞异步下载
+ }
+ if (!cancel)
+ {
+ webClient.DownloadFileAsync(uri, clientFileName, file.Source);
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ DownloadErrorEventArgs e = new DownloadErrorEventArgs();
+ e.Error = ex;
+ e.Manifest = manifest;
+ OnDownloadError(e);
+ }
+ }
+ }
+
+ ///
+ /// 异步完成方法
+ ///
+ /// 异常数据
+ /// 是否取消
+ ///
+ private void CompletionMethod(Exception exception, bool canceled, AsyncOperation asyncOp)
+ {
+ if (!canceled)
+ {
+ lock (userStateToLifetime.SyncRoot)
+ {
+ userStateToLifetime.Remove(asyncOp.UserSuppliedState);
+ }
+ }
+
+ DownloadCompleteEventArgs e = new DownloadCompleteEventArgs(exception, canceled, asyncOp.UserSuppliedState);
+ e.Manifest = manifest;
+ asyncOp.PostOperationCompleted(onCompletedDelegate, e);
+ current = null;
+ }
+
+ ///
+ /// 异步下载进度事件(仅对于单个文件)
+ ///
+ void webClient_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
+ {
+ DownloadProgressEventArgs args = new DownloadProgressEventArgs(e.ProgressPercentage, e.UserState);
+ args.BytesReceived = e.BytesReceived;
+ args.FileName = e.UserState.ToString();
+ args.TotalBytesToReceive = e.TotalBytesToReceive;
+ if (current != null)
+ {
+ current.Post(onProgressReportDelegate, args);
+ }
+ }
+
+ ///
+ /// 异步下载完成事件(仅对于单个文件)
+ ///
+ ///
+ ///
+ void webClient_DownloadFileCompleted(object sender, AsyncCompletedEventArgs e)
+ {
+ fileCount++;
+ if (fileCount == manifest.ManifestFiles.Files.Length)
+ {
+ this.CompletionMethod(e.Error, TaskCanceled(current.UserSuppliedState), current);
+ }
+ }
+
+ ///
+ /// 取消异步下载
+ ///
+ public void CancelAsync()
+ {
+ CancelAsync(defaultTaskId);
+ }
+
+ ///
+ /// 取消异步下载
+ ///
+ public void CancelAsync(object taskId)
+ {
+ webClient.CancelAsync();
+ cancel = true;
+ current = null;
+ AsyncOperation asyncOp = userStateToLifetime[taskId] as AsyncOperation;
+ if (asyncOp != null)
+ {
+ lock (userStateToLifetime.SyncRoot)
+ {
+ userStateToLifetime.Remove(taskId);
+ }
+ }
+ }
+
+ private bool TaskCanceled(object taskId)
+ {
+ return cancel || (userStateToLifetime[taskId] == null);
+ }
+
+ private void DoDownloadCompleted(object operationState)
+ {
+ DownloadCompleteEventArgs e = operationState as DownloadCompleteEventArgs;
+ OnDownloadCompleted(e);
+ }
+
+ private void ReportProgress(object state)
+ {
+ DownloadProgressEventArgs e = state as DownloadProgressEventArgs;
+ OnDownloadProgressChanged(e);
+ }
+ }
+
+}
diff --git a/Update.Core/FileCopyClass.cs b/Update.Core/FileCopyClass.cs
new file mode 100644
index 0000000..ef209e1
--- /dev/null
+++ b/Update.Core/FileCopyClass.cs
@@ -0,0 +1,411 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.ComponentModel;
+using System.Threading;
+using System.Collections.Specialized;
+using System.Collections;
+using System.IO;
+
+namespace Updater.Core
+{
+ ///
+ /// 文件复制进度报告事件参数
+ ///
+ public class FileCopyProgressChangedEventArgs : ProgressChangedEventArgs
+ {
+ public FileCopyProgressChangedEventArgs(int progressPercentage, object userState)
+ : base(progressPercentage, userState)
+ {
+ }
+
+ ///
+ /// 当前复制的字节数
+ ///
+ public double BytesToCopy { get; set; }
+
+ ///
+ /// 当前复制操作中的字节总数
+ ///
+ public double TotalBytesToCopy { get; set; }
+
+ ///
+ /// 当前复制的源文件名
+ ///
+ public string SourceFileName { get; set; }
+
+ ///
+ /// 当前复制的目标文件名
+ ///
+ public string TargetFileName { get; set; }
+
+ public Manifest Manifest { get; set; }
+ }
+
+ ///
+ /// 文件复制完成事件参数
+ ///
+ public class FileCopyCompletedEventArgs : AsyncCompletedEventArgs
+ {
+ public FileCopyCompletedEventArgs(Exception error, bool cancelled, object userState)
+ : base(error, cancelled, userState)
+ {
+ }
+
+ public Manifest Manifest { get; set; }
+ }
+
+ ///
+ /// 文件复制错误事件参数
+ ///
+ public class FileCopyErrorEventArgs : EventArgs
+ {
+ public Exception Error { get; set; }
+
+ public Manifest Manifest { get; set; }
+ }
+
+ ///
+ /// 文件复制组件类
+ ///
+ public class FileCopyClass : Component
+ {
+ #region 变量定义
+ private object defaultTaskId = new object();
+ private int writeFileLength = 1024 * 64;
+
+ private delegate void WorkerEventHandler(Manifest manifest, string sourcePath, AsyncOperation asyncOp);
+
+ private SendOrPostCallback onProgressReportDelegate;
+ private SendOrPostCallback onCompletedDelegate;
+
+ private HybridDictionary userStateToLifetime = new HybridDictionary();
+
+ private System.ComponentModel.Container components = null;
+ #endregion
+
+ #region 事件
+
+ ///
+ /// 文件复制进度事件
+ ///
+ public event EventHandler FileCopyProgressChanged;
+
+ ///
+ /// 文件复制完成事件
+ ///
+ public event EventHandler FileCopyCompleted;
+
+ ///
+ /// 文件复制错误事件
+ ///
+ public event EventHandler FileCopyError;
+
+ #endregion
+
+ #region 构造及析构
+
+ public FileCopyClass(IContainer container)
+ {
+ container.Add(this);
+ InitializeComponent();
+ InitializeDelegates();
+ }
+
+ public FileCopyClass()
+ {
+ InitializeComponent();
+ InitializeDelegates();
+ }
+
+ protected virtual void InitializeDelegates()
+ {
+ onProgressReportDelegate = new SendOrPostCallback(ReportProgress);
+ onCompletedDelegate = new SendOrPostCallback(CopyCompleted);
+ }
+
+ private void InitializeComponent()
+ {
+ components = new System.ComponentModel.Container();
+ }
+
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing)
+ {
+ if (components != null)
+ {
+ components.Dispose();
+ }
+ }
+ base.Dispose(disposing);
+ }
+
+ #endregion
+
+ #region 实现
+
+ public int WriteFileLength
+ {
+ set
+ {
+ writeFileLength = value;
+ }
+ }
+
+ public void Copy(Manifest manifest, string sourcePath)
+ {
+ string[] sourceFiles = null;
+ string[] targetFiles = null;
+ GetFiles(manifest, sourcePath, out sourceFiles, out targetFiles);
+ for (int i = 0; i < sourceFiles.Length; i++)
+ {
+ if (!Directory.Exists(Path.GetDirectoryName(targetFiles[i])))
+ {
+ Directory.CreateDirectory(Path.GetDirectoryName(targetFiles[i]));
+ }
+ File.Copy(sourceFiles[i], targetFiles[i], true);
+ }
+ }
+
+ public void CopyAsync(Manifest manifest, string sourcePath)
+ {
+ CopyAsync(manifest, sourcePath, defaultTaskId);
+ }
+
+ public void CopyAsync(Manifest manifest, string sourcePath, object taskId)
+ {
+ AsyncOperation asyncOp = AsyncOperationManager.CreateOperation(taskId);
+ lock (userStateToLifetime.SyncRoot)
+ {
+ if (userStateToLifetime.Contains(taskId))
+ {
+ throw new ArgumentException("参数taskId必须是唯一的", "taskId");
+ }
+ userStateToLifetime[taskId] = asyncOp;
+ }
+
+ WorkerEventHandler workerDelegate = new WorkerEventHandler(FileCopyWorker);
+ workerDelegate.BeginInvoke(manifest, sourcePath, asyncOp, null, null);
+ }
+
+ private bool TaskCanceled(object taskId)
+ {
+ return (userStateToLifetime[taskId] == null);
+ }
+
+ public void CancelAsync()
+ {
+ CancelAsync(defaultTaskId);
+ }
+
+ public void CancelAsync(object taskId)
+ {
+ AsyncOperation asyncOp = userStateToLifetime[taskId] as AsyncOperation;
+ if (asyncOp != null)
+ {
+ lock (userStateToLifetime.SyncRoot)
+ {
+ userStateToLifetime.Remove(taskId);
+ }
+ }
+ }
+
+ private void FileCopyWorker(Manifest manifest, string sourcePath, AsyncOperation asyncOp)
+ {
+ Exception exception = null;
+ FileCopyProgressChangedEventArgs e = null;
+ Stream rStream = null;
+ Stream wStream = null;
+ double writeBytes = 0;
+ string[] sourceFiles = null;
+ string[] targetFiles = null;
+ GetFiles(manifest, sourcePath, out sourceFiles, out targetFiles);
+
+ if (!TaskCanceled(asyncOp.UserSuppliedState))
+ {
+ try
+ {
+ double totalBytes = GetFileLength(sourceFiles);
+ byte[] buffer = new byte[writeFileLength];
+ int len = 0;
+ int offset = 0;
+ for (int i = 0; i < sourceFiles.Length; i++)
+ {
+ try
+ {
+ if (!Directory.Exists(Path.GetDirectoryName(targetFiles[i])))
+ {
+ Directory.CreateDirectory(Path.GetDirectoryName(targetFiles[i]));
+ }
+
+ rStream = new FileStream(sourceFiles[i], FileMode.Open, FileAccess.Read, FileShare.None);
+ wStream = new FileStream(targetFiles[i], FileMode.Create, FileAccess.Write, FileShare.None);
+ while ((len = rStream.Read(buffer, offset, writeFileLength)) > 0)
+ {
+ wStream.Write(buffer, offset, len);
+ writeBytes += len;
+ e = new FileCopyProgressChangedEventArgs((int)(writeBytes / totalBytes * 100), asyncOp.UserSuppliedState);
+ e.SourceFileName = sourceFiles[i];
+ e.TargetFileName = targetFiles[i];
+ e.TotalBytesToCopy = totalBytes;
+ e.BytesToCopy = len;
+ e.Manifest = manifest;
+ asyncOp.Post(this.onProgressReportDelegate, e);
+ Thread.Sleep(1);
+ }
+ }
+ finally
+ {
+ DisposeStream(wStream);
+ DisposeStream(rStream);
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ exception = ex;
+ OnFileCopyError(new FileCopyErrorEventArgs() { Error = ex, Manifest = manifest });
+ }
+ }
+
+ this.CompletionMethod(manifest, exception, TaskCanceled(asyncOp.UserSuppliedState), asyncOp);
+
+ //如果文件是压缩文件,则解压这些文件
+ ZipFiles(e.Manifest);
+ }
+
+ private void GetFiles(Manifest manifest, string sourcePath, out string[] sourceFiles, out string[] targetFiles)
+ {
+ sourceFiles = new string[manifest.ManifestFiles.Files.Length];
+ targetFiles = new string[manifest.ManifestFiles.Files.Length];
+ string path = Path.GetFullPath(manifest.MyApplication.Location);
+ for (int i = 0; i < manifest.ManifestFiles.Files.Length; i++)
+ {
+ sourceFiles[i] = Path.Combine(sourcePath, manifest.ManifestFiles.Files[i].Source);
+ targetFiles[i] = Path.Combine(path, manifest.ManifestFiles.Files[i].Source);
+ }
+ }
+
+ private void DisposeStream(Stream stream)
+ {
+ if (stream != null)
+ {
+ stream.Flush();
+ stream.Close();
+ stream.Dispose();
+ }
+ }
+
+ private double GetFileLength(string[] sourceFiles)
+ {
+ double bytes = 0;
+ foreach (var file in sourceFiles)
+ {
+ FileInfo fileInfo = new FileInfo(file);
+ bytes += fileInfo.Length;
+ }
+ return bytes;
+ }
+
+ private void CopyCompleted(object operationState)
+ {
+ FileCopyCompletedEventArgs e = operationState as FileCopyCompletedEventArgs;
+
+ OnFileCopyCompleted(e);
+ }
+
+ private void ReportProgress(object state)
+ {
+ FileCopyProgressChangedEventArgs e = state as FileCopyProgressChangedEventArgs;
+
+ OnProgressChanged(e);
+ }
+
+ protected void OnFileCopyCompleted(FileCopyCompletedEventArgs e)
+ {
+ if (FileCopyCompleted != null)
+ {
+ FileCopyCompleted(this, e);
+ }
+ }
+
+ ///
+ /// 如果文件是压缩文件,则解压这些文件
+ ///
+ ///
+ private void ZipFiles(Manifest manifest)
+ {
+ if (manifest != null)
+ {
+ string path = Path.GetFullPath(manifest.MyApplication.Location);
+ foreach (ManifestFile file in manifest.ManifestFiles.Files)
+ {
+ bool unzip = false;
+ bool.TryParse(file.Unzip, out unzip);
+
+ if (file.Source.EndsWith(".zip", StringComparison.OrdinalIgnoreCase) && unzip)
+ {
+ string zipFile = Path.Combine(path, file.Source);
+ try
+ {
+ ZipUtility.UnZipFiles(zipFile, path, null, true);
+ }
+ catch (Exception ex)
+ {
+ WriteLine(ex.ToString());
+ }
+ }
+ }
+ }
+ }
+
+ public static void WriteLine(string message)
+ {
+ string temp = DateTime.Now.ToString("[yyyy-MM-dd HH:mm:ss] ") + message + "\r\n\r\n";
+ string fileName = DateTime.Now.ToString("yyyyMMdd") + ".log";
+ try
+ {
+ File.AppendAllText(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, fileName), temp, Encoding.GetEncoding("GB2312"));
+ }
+ catch
+ {
+ }
+ }
+
+ protected void OnProgressChanged(FileCopyProgressChangedEventArgs e)
+ {
+ if (FileCopyProgressChanged != null)
+ {
+ FileCopyProgressChanged(this, e);
+ }
+ }
+
+ protected void OnFileCopyError(FileCopyErrorEventArgs e)
+ {
+ if (FileCopyError != null)
+ {
+ FileCopyError(this, e);
+ }
+ }
+
+ private void CompletionMethod(Manifest manifest, Exception exception, bool canceled, AsyncOperation asyncOp)
+ {
+ if (!canceled)
+ {
+ lock (userStateToLifetime.SyncRoot)
+ {
+ userStateToLifetime.Remove(asyncOp.UserSuppliedState);
+ }
+ }
+
+ FileCopyCompletedEventArgs e = new FileCopyCompletedEventArgs(exception, canceled, asyncOp.UserSuppliedState);
+ e.Manifest = manifest;
+ asyncOp.PostOperationCompleted(onCompletedDelegate, e);
+ }
+
+ #endregion
+
+ }
+
+}
diff --git a/Update.Core/GZip.cs b/Update.Core/GZip.cs
new file mode 100644
index 0000000..0ef55db
--- /dev/null
+++ b/Update.Core/GZip.cs
@@ -0,0 +1,655 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.IO;
+using System.Collections;
+using System.IO.Compression;
+
+namespace Updater.Core
+{
+ ///
+ /// 压缩文件类
+ ///
+ public class GZip
+ {
+ #region MyRegion
+ /*
+ //Compress三个参数分别是“要压缩的目标目录”,“保存压缩文件的目录”,压缩文件名
+ GZip.Compress(@"E:\much\", @"E:\much\", "ziptest");
+
+ //Decompress三个参数分别是"压缩包所在目录","要解压到的目录",“压缩包名”
+ //如果压缩包所在目录不存在则解压不会成功
+ GZip.Decompress(@"E:\much\zip\", @"E:\much\zip\", "ziptest");
+ */
+ #endregion
+
+ ///
+ /// Compress
+ ///
+ /// The location of the files to include in the zip file, all files including files in subfolders will be included.
+ /// Folder to write the zip file into
+ /// Name of the zip file to write
+ public static GZipResult Compress(string lpSourceFolder, string lpDestFolder, string zipFileName)
+ {
+ return Compress(lpSourceFolder, "*.*", SearchOption.AllDirectories, lpDestFolder, zipFileName, true);
+ }
+
+ ///
+ /// Compress
+ ///
+ /// The location of the files to include in the zip file
+ /// Search pattern (ie "*.*" or "*.txt" or "*.gif") to idendify what files in lpSourceFolder to include in the zip file
+ /// Only files in lpSourceFolder or include files in subfolders also
+ /// Folder to write the zip file into
+ /// Name of the zip file to write
+ /// Boolean, true deleted the intermediate temp file, false leaves the temp file in lpDestFolder (for debugging)
+ public static GZipResult Compress(string lpSourceFolder, string searchPattern, SearchOption searchOption, string lpDestFolder, string zipFileName, bool deleteTempFile)
+ {
+ DirectoryInfo di = new DirectoryInfo(lpSourceFolder);
+ FileInfo[] files = di.GetFiles("*.*", searchOption);
+ return Compress(files, lpSourceFolder, lpDestFolder, zipFileName, deleteTempFile);
+ }
+
+ ///
+ /// Compress
+ ///
+ /// Array of FileInfo objects to be included in the zip file
+ /// Base folder to use when creating relative paths for the files
+ /// stored in the zip file. For example, if lpBaseFolder is 'C:\zipTest\Files\', and there is a file
+ /// 'C:\zipTest\Files\folder1\sample.txt' in the 'files' array, the relative path for sample.txt
+ /// will be 'folder1/sample.txt'
+ /// Folder to write the zip file into
+ /// Name of the zip file to write
+ public static GZipResult Compress(FileInfo[] files, string lpBaseFolder, string lpDestFolder, string zipFileName)
+ {
+ return Compress(files, lpBaseFolder, lpDestFolder, zipFileName, true);
+ }
+
+ ///
+ /// Compress
+ ///
+ /// Array of FileInfo objects to be included in the zip file
+ /// Base folder to use when creating relative paths for the files
+ /// stored in the zip file. For example, if lpBaseFolder is 'C:\zipTest\Files\', and there is a file
+ /// 'C:\zipTest\Files\folder1\sample.txt' in the 'files' array, the relative path for sample.txt
+ /// will be 'folder1/sample.txt'
+ /// Folder to write the zip file into
+ /// Name of the zip file to write
+ /// Boolean, true deleted the intermediate temp file, false leaves the temp file in lpDestFolder (for debugging)
+ public static GZipResult Compress(FileInfo[] files, string lpBaseFolder, string lpDestFolder, string zipFileName, bool deleteTempFile)
+ {
+ GZipResult result = new GZipResult();
+
+ try
+ {
+ if (!lpDestFolder.EndsWith("\\"))
+ {
+ lpDestFolder += "\\";
+ }
+
+ string lpTempFile = lpDestFolder + zipFileName + ".tmp";
+ string lpZipFile = lpDestFolder + zipFileName;
+
+ result.TempFile = lpTempFile;
+ result.ZipFile = lpZipFile;
+
+ if (files != null && files.Length > 0)
+ {
+ CreateTempFile(files, lpBaseFolder, lpTempFile, result);
+
+ if (result.FileCount > 0)
+ {
+ CreateZipFile(lpTempFile, lpZipFile, result);
+ }
+
+ // delete the temp file
+ if (deleteTempFile)
+ {
+ File.Delete(lpTempFile);
+ result.TempFileDeleted = true;
+ }
+ }
+ }
+ catch //(Exception ex4)
+ {
+ result.Errors = true;
+ }
+ return result;
+ }
+
+ private static void CreateZipFile(string lpSourceFile, string lpZipFile, GZipResult result)
+ {
+ byte[] buffer;
+ int count = 0;
+ FileStream fsOut = null;
+ FileStream fsIn = null;
+ GZipStream gzip = null;
+
+ // compress the file into the zip file
+ try
+ {
+ fsOut = new FileStream(lpZipFile, FileMode.Create, FileAccess.Write, FileShare.None);
+ gzip = new GZipStream(fsOut, CompressionMode.Compress, true);
+
+ fsIn = new FileStream(lpSourceFile, FileMode.Open, FileAccess.Read, FileShare.Read);
+ buffer = new byte[fsIn.Length];
+ count = fsIn.Read(buffer, 0, buffer.Length);
+ fsIn.Close();
+ fsIn = null;
+
+ // compress to the zip file
+ gzip.Write(buffer, 0, buffer.Length);
+
+ result.ZipFileSize = fsOut.Length;
+ result.CompressionPercent = GetCompressionPercent(result.TempFileSize, result.ZipFileSize);
+ }
+ catch //(Exception ex1)
+ {
+ result.Errors = true;
+ }
+ finally
+ {
+ if (gzip != null)
+ {
+ gzip.Close();
+ gzip = null;
+ }
+ if (fsOut != null)
+ {
+ fsOut.Close();
+ fsOut = null;
+ }
+ if (fsIn != null)
+ {
+ fsIn.Close();
+ fsIn = null;
+ }
+ }
+ }
+
+ private static void CreateTempFile(FileInfo[] files, string lpBaseFolder, string lpTempFile, GZipResult result)
+ {
+ byte[] buffer;
+ int count = 0;
+ byte[] header;
+ string fileHeader = null;
+ string fileModDate = null;
+ string lpFolder = null;
+ int fileIndex = 0;
+ string lpSourceFile = null;
+ string vpSourceFile = null;
+ GZipFileInfo gzf = null;
+ FileStream fsOut = null;
+ FileStream fsIn = null;
+
+ if (files != null && files.Length > 0)
+ {
+ try
+ {
+ result.Files = new GZipFileInfo[files.Length];
+
+ // open the temp file for writing
+ fsOut = new FileStream(lpTempFile, FileMode.Create, FileAccess.Write, FileShare.None);
+
+ foreach (FileInfo fi in files)
+ {
+ lpFolder = fi.DirectoryName + "\\";
+ try
+ {
+ gzf = new GZipFileInfo();
+ gzf.Index = fileIndex;
+
+ // read the source file, get its virtual path within the source folder
+ lpSourceFile = fi.FullName;
+ gzf.LocalPath = lpSourceFile;
+ vpSourceFile = lpSourceFile.Replace(lpBaseFolder, string.Empty);
+ vpSourceFile = vpSourceFile.Replace("\\", "/");
+ gzf.RelativePath = vpSourceFile;
+
+ fsIn = new FileStream(lpSourceFile, FileMode.Open, FileAccess.Read, FileShare.Read);
+ buffer = new byte[fsIn.Length];
+ count = fsIn.Read(buffer, 0, buffer.Length);
+ fsIn.Close();
+ fsIn = null;
+
+ fileModDate = fi.LastWriteTimeUtc.ToString();
+ gzf.ModifiedDate = fi.LastWriteTimeUtc;
+ gzf.Length = buffer.Length;
+
+ fileHeader = fileIndex.ToString() + "," + vpSourceFile + "," + fileModDate + "," + buffer.Length.ToString() + "\n";
+ header = Encoding.Default.GetBytes(fileHeader);
+
+ fsOut.Write(header, 0, header.Length);
+ fsOut.Write(buffer, 0, buffer.Length);
+ fsOut.WriteByte(10); // linefeed
+
+ gzf.AddedToTempFile = true;
+
+ // update the result object
+ result.Files[fileIndex] = gzf;
+
+ // increment the fileIndex
+ fileIndex++;
+ }
+ catch //(Exception ex1)
+ {
+ result.Errors = true;
+ }
+ finally
+ {
+ if (fsIn != null)
+ {
+ fsIn.Close();
+ fsIn = null;
+ }
+ }
+ if (fsOut != null)
+ {
+ result.TempFileSize = fsOut.Length;
+ }
+ }
+ }
+ catch //(Exception ex2)
+ {
+ result.Errors = true;
+ }
+ finally
+ {
+ if (fsOut != null)
+ {
+ fsOut.Close();
+ fsOut = null;
+ }
+ }
+ }
+
+ result.FileCount = fileIndex;
+ }
+
+ public static GZipResult Decompress(string lpSourceFolder, string lpDestFolder, string zipFileName)
+ {
+ return Decompress(lpSourceFolder, lpDestFolder, zipFileName, true, true, null, null, 4096);
+ }
+
+ public static GZipResult Decompress(string lpSourceFolder, string lpDestFolder, string zipFileName, bool writeFiles, string addExtension)
+ {
+ return Decompress(lpSourceFolder, lpDestFolder, zipFileName, true, writeFiles, addExtension, null, 4096);
+ }
+
+ public static GZipResult Decompress(string lpSrcFolder, string lpDestFolder, string zipFileName,
+ bool deleteTempFile, bool writeFiles, string addExtension, Hashtable htFiles, int bufferSize)
+ {
+ GZipResult result = new GZipResult();
+
+ if (!lpDestFolder.EndsWith("\\"))
+ {
+ lpDestFolder += "\\";
+ }
+
+ string lpTempFile = lpSrcFolder + zipFileName + ".tmp";
+ string lpZipFile = lpSrcFolder + zipFileName;
+
+ result.TempFile = lpTempFile;
+ result.ZipFile = lpZipFile;
+
+ string line = null;
+ string lpFilePath = null;
+ string lpFolder = null;
+ GZipFileInfo gzf = null;
+ FileStream fsTemp = null;
+ ArrayList gzfs = new ArrayList();
+ bool write = false;
+
+ if (string.IsNullOrEmpty(addExtension))
+ {
+ addExtension = string.Empty;
+ }
+ else if (!addExtension.StartsWith("."))
+ {
+ addExtension = "." + addExtension;
+ }
+
+ // extract the files from the temp file
+ try
+ {
+ fsTemp = UnzipToTempFile(lpZipFile, lpTempFile, result);
+ if (fsTemp != null)
+ {
+ while (fsTemp.Position != fsTemp.Length)
+ {
+ line = null;
+ while (string.IsNullOrEmpty(line) && fsTemp.Position != fsTemp.Length)
+ {
+ line = ReadLine(fsTemp);
+ }
+
+ if (!string.IsNullOrEmpty(line))
+ {
+ gzf = new GZipFileInfo();
+ if (gzf.ParseFileInfo(line) && gzf.Length > 0)
+ {
+ gzfs.Add(gzf);
+ lpFilePath = lpDestFolder + gzf.RelativePath;
+ lpFolder = GetFolder(lpFilePath);
+ gzf.LocalPath = lpFilePath;
+
+ write = false;
+ if (htFiles == null || htFiles.ContainsKey(gzf.RelativePath))
+ {
+ gzf.RestoreRequested = true;
+ write = writeFiles;
+ }
+
+ if (write)
+ {
+ // make sure the folder exists
+ if (!Directory.Exists(lpFolder))
+ {
+ Directory.CreateDirectory(lpFolder);
+ }
+
+ // read from fsTemp and write out the file
+ gzf.Restored = WriteFile(fsTemp, gzf.Length, lpFilePath + addExtension, bufferSize);
+ }
+ else
+ {
+ // need to advance fsTemp
+ fsTemp.Position += gzf.Length;
+ }
+ }
+ }
+ }
+ }
+ }
+ catch //(Exception ex3)
+ {
+ result.Errors = true;
+ }
+ finally
+ {
+ if (fsTemp != null)
+ {
+ fsTemp.Close();
+ fsTemp = null;
+ }
+ }
+
+ // delete the temp file
+ try
+ {
+ if (deleteTempFile)
+ {
+ File.Delete(lpTempFile);
+ result.TempFileDeleted = true;
+ }
+ }
+ catch //(Exception ex4)
+ {
+ result.Errors = true;
+ }
+
+ result.FileCount = gzfs.Count;
+ result.Files = new GZipFileInfo[gzfs.Count];
+ gzfs.CopyTo(result.Files);
+ return result;
+ }
+
+ private static string ReadLine(FileStream fs)
+ {
+ string line = string.Empty;
+
+ const int bufferSize = 4096;
+ byte[] buffer = new byte[bufferSize];
+ byte b = 0;
+ byte lf = 10;
+ int i = 0;
+
+ while (b != lf)
+ {
+ b = (byte)fs.ReadByte();
+ buffer[i] = b;
+ i++;
+ }
+
+ line = System.Text.Encoding.Default.GetString(buffer, 0, i - 1);
+
+ return line;
+ }
+
+ private static bool WriteFile(FileStream fs, int fileLength, string lpFile, int bufferSize)
+ {
+ bool success = false;
+ FileStream fsFile = null;
+
+ if (bufferSize == 0 || fileLength < bufferSize)
+ {
+ bufferSize = fileLength;
+ }
+
+ int count = 0;
+ int remaining = fileLength;
+ int readSize = 0;
+
+ try
+ {
+ byte[] buffer = new byte[bufferSize];
+ fsFile = new FileStream(lpFile, FileMode.Create, FileAccess.Write, FileShare.None);
+
+ while (remaining > 0)
+ {
+ if (remaining > bufferSize)
+ {
+ readSize = bufferSize;
+ }
+ else
+ {
+ readSize = remaining;
+ }
+
+ count = fs.Read(buffer, 0, readSize);
+ remaining -= count;
+
+ if (count == 0)
+ {
+ break;
+ }
+
+ fsFile.Write(buffer, 0, count);
+ fsFile.Flush();
+
+ }
+ fsFile.Flush();
+ fsFile.Close();
+ fsFile = null;
+
+ success = true;
+ }
+ catch //(Exception ex2)
+ {
+ success = false;
+ }
+ finally
+ {
+ if (fsFile != null)
+ {
+ fsFile.Flush();
+ fsFile.Close();
+ fsFile = null;
+ }
+ }
+ return success;
+ }
+
+ private static string GetFolder(string lpFilePath)
+ {
+ string lpFolder = lpFilePath;
+ int index = lpFolder.LastIndexOf("\\");
+ if (index != -1)
+ {
+ lpFolder = lpFolder.Substring(0, index + 1);
+ }
+ return lpFolder;
+ }
+ private static FileStream UnzipToTempFile(string lpZipFile, string lpTempFile, GZipResult result)
+ {
+ FileStream fsIn = null;
+ GZipStream gzip = null;
+ FileStream fsOut = null;
+ FileStream fsTemp = null;
+
+ const int bufferSize = 4096;
+ byte[] buffer = new byte[bufferSize];
+ int count = 0;
+
+ try
+ {
+ fsIn = new FileStream(lpZipFile, FileMode.Open, FileAccess.Read, FileShare.Read);
+ result.ZipFileSize = fsIn.Length;
+
+ fsOut = new FileStream(lpTempFile, FileMode.Create, FileAccess.Write, FileShare.None);
+ gzip = new GZipStream(fsIn, CompressionMode.Decompress, true);
+ while (true)
+ {
+ count = gzip.Read(buffer, 0, bufferSize);
+ if (count != 0)
+ {
+ fsOut.Write(buffer, 0, count);
+ }
+ if (count != bufferSize)
+ {
+ break;
+ }
+ }
+ }
+ catch (Exception ex1)
+ {
+ result.Errors = true;
+ }
+ finally
+ {
+ if (gzip != null)
+ {
+ gzip.Close();
+ gzip = null;
+ }
+ if (fsOut != null)
+ {
+ fsOut.Close();
+ fsOut = null;
+ }
+ if (fsIn != null)
+ {
+ fsIn.Close();
+ fsIn = null;
+ }
+ }
+
+ fsTemp = new FileStream(lpTempFile, FileMode.Open, FileAccess.Read, FileShare.None);
+ if (fsTemp != null)
+ {
+ result.TempFileSize = fsTemp.Length;
+ }
+ return fsTemp;
+ }
+
+ private static int GetCompressionPercent(long tempLen, long zipLen)
+ {
+ double tmp = (double)tempLen;
+ double zip = (double)zipLen;
+ double hundred = 100;
+
+ double ratio = (tmp - zip) / tmp;
+ double pcnt = ratio * hundred;
+
+ return (int)pcnt;
+ }
+ }
+
+ ///
+ /// 要压缩的文件信息
+ ///
+ public class GZipFileInfo
+ {
+ ///
+ /// 文件索引
+ ///
+ public int Index = 0;
+ ///
+ /// 文件相对路径,'/'
+ ///
+ public string RelativePath = null;
+ public DateTime ModifiedDate;
+ ///
+ /// 文件内容长度
+ ///
+ public int Length = 0;
+ public bool AddedToTempFile = false;
+ public bool RestoreRequested = false;
+ public bool Restored = false;
+ ///
+ /// 文件绝对路径,'\'
+ ///
+ public string LocalPath = null;
+ public string Folder = null;
+
+ public bool ParseFileInfo(string fileInfo)
+ {
+ bool success = false;
+ try
+ {
+ if (!string.IsNullOrEmpty(fileInfo))
+ {
+ // get the file information
+ string[] info = fileInfo.Split(',');
+ if (info != null && info.Length == 4)
+ {
+ this.Index = Convert.ToInt32(info[0]);
+ this.RelativePath = info[1].Replace("/", "\\");
+ this.ModifiedDate = Convert.ToDateTime(info[2]);
+ this.Length = Convert.ToInt32(info[3]);
+ success = true;
+ }
+ }
+ }
+ catch
+ {
+ success = false;
+ }
+ return success;
+ }
+ }
+
+ ///
+ /// 文件压缩后的压缩包类
+ ///
+ public class GZipResult
+ {
+ ///
+ /// 压缩包中包含的所有文件,包括子目录下的文件
+ ///
+ public GZipFileInfo[] Files = null;
+ ///
+ /// 要压缩的文件数
+ ///
+ public int FileCount = 0;
+ public long TempFileSize = 0;
+ public long ZipFileSize = 0;
+ ///
+ /// 压缩百分比
+ ///
+ public int CompressionPercent = 0;
+ ///
+ /// 临时文件
+ ///
+ public string TempFile = null;
+ ///
+ /// 压缩文件
+ ///
+ public string ZipFile = null;
+ ///
+ /// 是否删除临时文件
+ ///
+ public bool TempFileDeleted = false;
+ public bool Errors = false;
+ }
+}
diff --git a/Update.Core/Model.cs b/Update.Core/Model.cs
new file mode 100644
index 0000000..e2ae797
--- /dev/null
+++ b/Update.Core/Model.cs
@@ -0,0 +1,184 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Xml;
+using System.IO;
+using System.Xml.Serialization;
+
+namespace Updater.Core
+{
+ ///
+ /// 文件清单对象
+ ///
+ [XmlRoot("manifest")]
+ public class Manifest
+ {
+ [XmlElement("version")]
+ public string Version { get; set; }
+
+ [XmlElement("description")]
+ public string Description { get; set; }
+
+ [XmlElement("fileBytes")]
+ public long FileBytes { get; set; }
+
+ [XmlElement("myapplication")]
+ public MyApplication MyApplication { get; set; }
+
+ [XmlElement("files")]
+ public ManifestFiles ManifestFiles { get; set; }
+ }
+
+ ///
+ /// 更新的文件列表
+ ///
+ public class ManifestFiles
+ {
+ [XmlElement("file")]
+ public ManifestFile[] Files { get; set; }
+
+ [XmlAttribute("base")]
+ public string BaseUrl { get; set; }
+ }
+
+ ///
+ /// 更新的单个文件对象
+ ///
+ public class ManifestFile
+ {
+ [XmlAttribute("source")]
+ public string Source
+ {
+ get;
+ set;
+ }
+
+ [XmlAttribute("hash")]
+ public string Hash
+ {
+ get;
+ set;
+ }
+
+ [XmlAttribute("unzip")]
+ public string Unzip
+ {
+ get;
+ set;
+ }
+ }
+
+ ///
+ /// 更新的程序对象
+ ///
+ public class MyApplication
+ {
+ [XmlAttribute("applicationId")]
+ public string ApplicationId { get; set; }
+
+ [XmlElement("location")]
+ public string Location { get; set; }
+
+ [XmlElement("entryPoint")]
+ public EntryPoint EntryPoint { get; set; }
+ }
+
+ ///
+ /// 程序启动对象
+ ///
+ public class EntryPoint
+ {
+ [XmlAttribute("file")]
+ public string File { get; set; }
+
+ [XmlAttribute("parameters")]
+ public string Parameters { get; set; }
+ }
+
+ ///
+ /// 客户端配置文件对象
+ ///
+ public class UpdaterConfigurationView
+ {
+ private static XmlDocument document = new XmlDocument();
+ private static readonly string xmlFileName = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "updateconfiguration.config");
+
+ static UpdaterConfigurationView()
+ {
+ document.Load(xmlFileName);
+ }
+
+ ///
+ /// 刷新配置文件信息
+ ///
+ public void Refresh()
+ {
+ document.RemoveAll();
+ document.Load(xmlFileName);
+ }
+
+ ///
+ /// 程序版本
+ ///
+ public string Version
+ {
+ get
+ {
+ return document.SelectSingleNode("applicationUpdater").Attributes["version"].Value;
+ }
+ set
+ {
+ document.SelectSingleNode("applicationUpdater").Attributes["version"].Value = value;
+ document.Save(xmlFileName);
+ }
+ }
+
+ ///
+ /// 应用程序唯一标识
+ ///
+ public string ApplicationId
+ {
+ get
+ {
+ return document.SelectSingleNode("applicationUpdater").Attributes["applicationId"].Value;
+ }
+ set
+ {
+ document.SelectSingleNode("applicationUpdater").Attributes["applicationId"].Value = value;
+ document.Save(xmlFileName);
+ }
+ }
+
+ ///
+ /// 远程更新文件的清单路径
+ ///
+ public string ManifestUri
+ {
+ get
+ {
+ return document.SelectSingleNode("applicationUpdater").Attributes["manifestUri"].Value;
+ }
+ set
+ {
+ document.SelectSingleNode("applicationUpdater").Attributes["manifestUri"].Value = value;
+ document.Save(xmlFileName);
+ }
+ }
+
+ ///
+ /// 程序名称
+ ///
+ public string Title
+ {
+ get
+ {
+ return document.SelectSingleNode("applicationUpdater").Attributes["title"].Value;
+ }
+ set
+ {
+ document.SelectSingleNode("applicationUpdater").Attributes["title"].Value = value;
+ document.Save(xmlFileName);
+ }
+ }
+ }
+}
diff --git a/Update.Core/Properties/AssemblyInfo.cs b/Update.Core/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..c92652b
--- /dev/null
+++ b/Update.Core/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// 有关程序集的一般信息由以下
+// 控制。更改这些特性值可修改
+// 与程序集关联的信息。
+[assembly: AssemblyTitle("Update.Core")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("Update.Core")]
+[assembly: AssemblyCopyright("Copyright © 2022")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// 将 ComVisible 设置为 false 会使此程序集中的类型
+//对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型
+//请将此类型的 ComVisible 特性设置为 true。
+[assembly: ComVisible(false)]
+
+// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
+[assembly: Guid("4903d5f5-ff01-426d-b5bb-aadf7c4232fa")]
+
+// 程序集的版本信息由下列四个值组成:
+//
+// 主版本
+// 次版本
+// 生成号
+// 修订号
+//
+//可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值
+//通过使用 "*",如下所示:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/Update.Core/Update.Core.csproj b/Update.Core/Update.Core.csproj
new file mode 100644
index 0000000..56e18a1
--- /dev/null
+++ b/Update.Core/Update.Core.csproj
@@ -0,0 +1,59 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {4903D5F5-FF01-426D-B5BB-AADF7C4232FA}
+ Library
+ Properties
+ Update.Core
+ Update.Core
+ v4.8
+ 512
+ true
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+ ..\packages\SharpZipLib.1.3.3\lib\net45\ICSharpCode.SharpZipLib.dll
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Update.Core/UpdateClass.cs b/Update.Core/UpdateClass.cs
new file mode 100644
index 0000000..1ad6a2d
--- /dev/null
+++ b/Update.Core/UpdateClass.cs
@@ -0,0 +1,386 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Net;
+using System.IO;
+using System.Xml.Serialization;
+using System.Xml;
+using System.ComponentModel;
+
+namespace Updater.Core
+{
+ ///
+ /// 程序更新事件参数
+ ///
+ public class ManifestEventArgs : EventArgs
+ {
+ public Manifest Manifest { get; set; }
+ }
+
+ ///
+ /// 激活安装开始事件参数
+ ///
+ public class ActivationStartedEventArgs : EventArgs
+ {
+ public Manifest Manifest { get; set; }
+
+ public bool Cancel { get; set; }
+ }
+
+ ///
+ /// 安装完成事件参数
+ ///
+ public class ActivationCompletedEventArgs : AsyncCompletedEventArgs
+ {
+ public ActivationCompletedEventArgs(Exception error, bool cancelled, object userState)
+ : base(error, cancelled, userState)
+ {
+ }
+
+ public Manifest Manifest { get; set; }
+ }
+
+ ///
+ /// 程序自动更新操作类,封装了文件下载、文件复制、文件解压等操作
+ ///
+ public class UpdateClass
+ {
+ #region 变量属性
+ private DownloadClass downloader = new DownloadClass();
+ private FileCopyClass fileCopyer = new FileCopyClass();
+ private UpdaterConfigurationView updateCfgView = new UpdaterConfigurationView();
+ private string backupFilePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "backup");
+
+ ///
+ /// 封装的文件下载操作类
+ ///
+ public DownloadClass Downloader
+ {
+ get
+ {
+ return downloader;
+ }
+ }
+
+ ///
+ /// 封装的文件复制操作类
+ ///
+ public FileCopyClass FileCopyer
+ {
+ get
+ {
+ return fileCopyer;
+ }
+ }
+ #endregion
+
+ #region 事件
+
+ ///
+ /// 下载进度
+ ///
+ public event EventHandler DownloadProgressChanged;
+
+ ///
+ /// 下载完成事件
+ ///
+ public event EventHandler DownloadCompleted;
+
+ ///
+ /// 下载错误触发的事件
+ ///
+ public event EventHandler DownloadError;
+
+ public event EventHandler ActivationInitializing;
+
+ public event EventHandler ActivationCompleted;
+
+ public event EventHandler ActivationStarted;
+
+ public event EventHandler ActivationProgressChanged;
+
+ public event EventHandler ActivationError;
+
+ #endregion
+
+ #region 下载更新实现
+
+ public UpdateClass()
+ {
+ downloader.DownloadCompleted += new EventHandler(downloader_DownloadCompleted);
+ downloader.DownloadError += new EventHandler(downloader_DownloadError);
+ downloader.DownloadProgressChanged += new EventHandler(downloader_DownloadProgressChanged);
+ fileCopyer.FileCopyError += new EventHandler(fileCopyer_FileCopyError);
+ fileCopyer.FileCopyCompleted += new EventHandler(fileCopyer_FileCopyCompleted);
+ fileCopyer.FileCopyProgressChanged += new EventHandler(fileCopyer_FileCopyProgressChanged);
+ }
+
+ ///
+ /// 是否有最新的版本
+ ///
+ public bool HasNewVersion
+ {
+ get
+ {
+ var m = CheckForUpdates();
+ return m.Length > 0;
+ }
+ }
+
+ ///
+ /// 检查更新,返回更新清单列表
+ ///
+ ///
+ public Manifest[] CheckForUpdates()
+ {
+ updateCfgView.Refresh();
+
+ Uri uri = new Uri(updateCfgView.ManifestUri);
+ string doc = DownLoadFile(uri);
+ XmlSerializer xser = new XmlSerializer(typeof(Manifest));
+ var manifest = xser.Deserialize(new XmlTextReader(doc, XmlNodeType.Document, null)) as Manifest;
+ if (manifest == null ||
+ manifest.Version == updateCfgView.Version ||
+ manifest.MyApplication.ApplicationId != updateCfgView.ApplicationId)
+ {
+ return new Manifest[0];
+ }
+ return new Manifest[] { manifest };
+ }
+
+ ///
+ /// 用于远程下载文件清单
+ ///
+ /// 文件清单网络路径
+ ///
+ private string DownLoadFile(Uri uri)
+ {
+ WebRequest request = WebRequest.Create(uri);
+ request.Credentials = CredentialCache.DefaultCredentials;
+ string response = String.Empty;
+ using (WebResponse res = request.GetResponse())
+ {
+ using (StreamReader reader = new StreamReader(res.GetResponseStream(), true))
+ {
+ response = reader.ReadToEnd();
+ }
+ }
+ return response;
+ }
+
+ ///
+ /// 同步下载文件清单中的文件
+ ///
+ /// 下载文件清单
+ public void Download(Manifest[] manifests)
+ {
+ foreach (var m in manifests)
+ {
+ downloader.Download(m);
+ }
+ }
+
+ ///
+ /// 异步下载文件清单中的文件
+ ///
+ /// 下载文件清单
+ public void DownloadAsync(Manifest[] manifests)
+ {
+ foreach (var m in manifests)
+ {
+ downloader.DownloadAsync(m);
+ }
+ }
+
+ ///
+ /// 下载完毕后执行的启动操作
+ ///
+ ///
+ public void Activate(Manifest[] manifests)
+ {
+ foreach (var m in manifests)
+ {
+ OnActivationInitializing(new ManifestEventArgs() { Manifest = m });
+ Backup(m);
+ ActivationStartedEventArgs e = new ActivationStartedEventArgs() { Manifest = m };
+ OnActivationStarted(e);
+ if (e.Cancel)
+ {
+ Clear();
+ break;
+ }
+ else
+ {
+ fileCopyer.CopyAsync(m, downloader.TempPath);
+ }
+ }
+ }
+
+ ///
+ /// 备份操作
+ ///
+ /// 文件清单
+ private void Backup(Manifest manifest)
+ {
+ try
+ {
+ string sourcePath = Path.GetFullPath(manifest.MyApplication.Location);
+ string s_filename = string.Empty;
+ string t_filename = string.Empty;
+ if (!Directory.Exists(backupFilePath))
+ {
+ Directory.CreateDirectory(backupFilePath);
+ }
+ foreach (var file in manifest.ManifestFiles.Files)
+ {
+ t_filename = Path.Combine(backupFilePath, file.Source);
+ s_filename = Path.Combine(sourcePath, file.Source);
+ if (File.Exists(s_filename))
+ {
+ File.Copy(s_filename, t_filename, true);
+ }
+ }
+ }
+ catch
+ {
+ }
+ }
+
+ ///
+ /// 回滚文件下载内容
+ ///
+ ///
+ public void Rollback(Manifest manifest)
+ {
+ try
+ {
+ string filename = string.Empty;
+ foreach (var file in manifest.ManifestFiles.Files)
+ {
+ filename = Path.Combine(backupFilePath, file.Source);
+ File.Copy(filename, Path.Combine(Path.GetFullPath(manifest.MyApplication.Location), file.Source));
+ }
+ Directory.Delete(backupFilePath, true);
+ }
+ catch
+ {
+ }
+ }
+
+ ///
+ /// 清除临时文件
+ ///
+ private void Clear()
+ {
+ try
+ {
+ Directory.Delete(backupFilePath, true);
+ Directory.Delete(downloader.TempPath, true);
+ }
+ catch
+ { }
+ }
+
+ #endregion
+
+ #region 事件处理
+
+ private void fileCopyer_FileCopyError(object sender, FileCopyErrorEventArgs e)
+ {
+ OnActivationError(e);
+ }
+
+ private void fileCopyer_FileCopyProgressChanged(object sender, FileCopyProgressChangedEventArgs e)
+ {
+ if (ActivationProgressChanged != null)
+ {
+ ActivationProgressChanged(sender, e);
+ }
+ }
+
+ private void fileCopyer_FileCopyCompleted(object sender, FileCopyCompletedEventArgs e)
+ {
+ Clear();
+ try
+ {
+ updateCfgView.Version = e.Manifest.Version;
+ }
+ catch
+ { }
+
+ if (ActivationCompleted != null)
+ {
+ ActivationCompletedEventArgs evt = new ActivationCompletedEventArgs(e.Error, e.Cancelled, e.UserState);
+ evt.Manifest = e.Manifest;
+ OnActivationCompleted(evt);
+ }
+ }
+
+ private void downloader_DownloadProgressChanged(object sender, DownloadProgressEventArgs e)
+ {
+ if (DownloadProgressChanged != null)
+ {
+ DownloadProgressChanged(sender, e);
+ }
+ }
+
+ private void downloader_DownloadError(object sender, DownloadErrorEventArgs e)
+ {
+ if (DownloadError != null)
+ {
+ DownloadError(sender, e);
+ }
+ }
+
+ private void downloader_DownloadCompleted(object sender, DownloadCompleteEventArgs e)
+ {
+ if (DownloadCompleted != null)
+ {
+ DownloadCompleted(sender, e);
+ }
+ }
+
+ private void OnActivationInitializing(ManifestEventArgs e)
+ {
+ if (ActivationInitializing != null)
+ {
+ ActivationInitializing(this, e);
+ }
+ }
+
+ private void OnActivationStarted(ActivationStartedEventArgs e)
+ {
+ if (ActivationStarted != null)
+ {
+ ActivationStarted(this, e);
+ }
+ }
+
+ private void OnActivationCompleted(ActivationCompletedEventArgs e)
+ {
+ if (ActivationCompleted != null)
+ {
+ ActivationCompleted(this, e);
+ }
+ }
+
+ private void OnActivationError(FileCopyErrorEventArgs e)
+ {
+ if (ActivationError != null)
+ {
+ ActivationError(this, e);
+ }
+ }
+
+ private void OnActivationProgressChanged(FileCopyProgressChangedEventArgs e)
+ {
+ if (ActivationProgressChanged != null)
+ {
+ ActivationProgressChanged(this, e);
+ }
+ }
+
+ #endregion
+
+ }
+}
diff --git a/Update.Core/ZipUtility.cs b/Update.Core/ZipUtility.cs
new file mode 100644
index 0000000..9a4d837
--- /dev/null
+++ b/Update.Core/ZipUtility.cs
@@ -0,0 +1,153 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Collections;
+using ICSharpCode.SharpZipLib.Zip;
+using System.IO;
+
+namespace Updater.Core
+{
+ public static class ZipUtility
+ {
+ ///
+ /// 压缩文件中的文件,可设置密码
+ ///
+ /// 输入的文件夹
+ /// 输出的压缩文件全名
+ /// 压缩密码
+ public static void ZipFiles(string inputFolderPath, string outputPathAndFile, string password)
+ {
+ ArrayList ar = GenerateFileList(inputFolderPath);
+ int TrimLength = (Directory.GetParent(inputFolderPath)).ToString().Length;
+ // find number of chars to remove // from orginal file path
+ TrimLength += 1; //remove '\'
+ FileStream ostream;
+ byte[] obuffer;
+ string outPath = inputFolderPath + @"\" + outputPathAndFile;
+ ZipOutputStream oZipStream = new ZipOutputStream(File.Create(outPath));
+ if (!string.IsNullOrEmpty(password))
+ {
+ oZipStream.Password = password;
+ }
+ oZipStream.SetLevel(9); // 设置最大压缩率
+
+ ZipEntry oZipEntry;
+ foreach (string Fil in ar)
+ {
+ oZipEntry = new ZipEntry(Fil.Remove(0, TrimLength));
+ oZipStream.PutNextEntry(oZipEntry);
+
+ if (!Fil.EndsWith(@"/")) // 如果文件以 '/' 结束,则是目录
+ {
+ ostream = File.OpenRead(Fil);
+ obuffer = new byte[ostream.Length];
+ ostream.Read(obuffer, 0, obuffer.Length);
+ oZipStream.Write(obuffer, 0, obuffer.Length);
+ }
+ }
+ oZipStream.Finish();
+ oZipStream.Close();
+ }
+
+ ///
+ /// 根据文件夹生成文件列表
+ ///
+ ///
+ ///
+ private static ArrayList GenerateFileList(string Dir)
+ {
+ ArrayList fils = new ArrayList();
+ bool Empty = true;
+ foreach (string file in Directory.GetFiles(Dir))
+ {
+ fils.Add(file);
+ Empty = false;
+ }
+
+ if (Empty)
+ {
+ //加入完全为空的目录
+ if (Directory.GetDirectories(Dir).Length == 0)
+ {
+ fils.Add(Dir + @"/");
+ }
+ }
+
+ foreach (string dirs in Directory.GetDirectories(Dir)) // 递归目录
+ {
+ foreach (object obj in GenerateFileList(dirs))
+ {
+ fils.Add(obj);
+ }
+ }
+ return fils;
+ }
+
+ ///
+ /// 解压文件到指定的目录,可设置密码、删除原文件等
+ ///
+ /// 压缩文件全名
+ /// 解压输出文件目录
+ /// 解压密码
+ /// 是否删除原文件(压缩文件)
+ public static void UnZipFiles(string zipPathAndFile, string outputFolder, string password, bool deleteZipFile)
+ {
+ using (ZipInputStream s = new ZipInputStream(File.OpenRead(zipPathAndFile)))
+ {
+ if (password != null && password != String.Empty)
+ {
+ s.Password = password;
+ }
+
+ ZipEntry theEntry;
+ string tmpEntry = String.Empty;
+ while ((theEntry = s.GetNextEntry()) != null)
+ {
+ #region 遍历每个Entry对象进行解压处理
+ string directoryName = outputFolder;
+ string fileName = Path.GetFileName(theEntry.Name);
+ if (directoryName != "")
+ {
+ Directory.CreateDirectory(directoryName);
+ }
+
+ if (fileName != String.Empty)
+ {
+ if (theEntry.Name.IndexOf(".ini") < 0)
+ {
+ string fullPath = directoryName + "\\" + theEntry.Name;
+ fullPath = fullPath.Replace("\\ ", "\\");
+ string fullDirPath = Path.GetDirectoryName(fullPath);
+ if (!Directory.Exists(fullDirPath)) Directory.CreateDirectory(fullDirPath);
+ using (FileStream streamWriter = File.Create(fullPath))
+ {
+ #region 写入文件流
+ int size = 2048;
+ byte[] data = new byte[2048];
+ while (true)
+ {
+ size = s.Read(data, 0, data.Length);
+ if (size > 0)
+ {
+ streamWriter.Write(data, 0, size);
+ }
+ else
+ {
+ break;
+ }
+ }
+ #endregion
+ }
+ }
+ }
+ #endregion
+ }
+ }
+
+ if (deleteZipFile)
+ {
+ File.Delete(zipPathAndFile);
+ }
+ }
+ }
+}
diff --git a/Update.Core/packages.config b/Update.Core/packages.config
new file mode 100644
index 0000000..b99f329
--- /dev/null
+++ b/Update.Core/packages.config
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/Update/App.config b/Update/App.config
new file mode 100644
index 0000000..193aecc
--- /dev/null
+++ b/Update/App.config
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Update/Class1.cs b/Update/Class1.cs
deleted file mode 100644
index ae0723d..0000000
--- a/Update/Class1.cs
+++ /dev/null
@@ -1,12 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace Update
-{
- public class Class1
- {
- }
-}
diff --git a/Update/Form1.Designer.cs b/Update/Form1.Designer.cs
new file mode 100644
index 0000000..2aa0859
--- /dev/null
+++ b/Update/Form1.Designer.cs
@@ -0,0 +1,118 @@
+namespace Update
+{
+ partial class Form1
+ {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Windows Form Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent()
+ {
+ this.progressBarControl1 = new DevExpress.XtraEditors.ProgressBarControl();
+ this.lab_percent = new DevExpress.XtraEditors.LabelControl();
+ this.lab_filename = new System.Windows.Forms.Label();
+ this.lab_fileinfo = new System.Windows.Forms.Label();
+ this.lblUpdateLog = new System.Windows.Forms.Label();
+ ((System.ComponentModel.ISupportInitialize)(this.progressBarControl1.Properties)).BeginInit();
+ this.SuspendLayout();
+ //
+ // progressBarControl1
+ //
+ this.progressBarControl1.Location = new System.Drawing.Point(25, 63);
+ this.progressBarControl1.Name = "progressBarControl1";
+ this.progressBarControl1.Properties.Step = 1;
+ this.progressBarControl1.Size = new System.Drawing.Size(438, 35);
+ this.progressBarControl1.TabIndex = 0;
+ //
+ // lab_percent
+ //
+ this.lab_percent.Location = new System.Drawing.Point(469, 74);
+ this.lab_percent.Name = "lab_percent";
+ this.lab_percent.Size = new System.Drawing.Size(18, 15);
+ this.lab_percent.TabIndex = 1;
+ this.lab_percent.Text = "0%";
+ //
+ // lab_filename
+ //
+ this.lab_filename.BackColor = System.Drawing.Color.Transparent;
+ this.lab_filename.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
+ this.lab_filename.ForeColor = System.Drawing.SystemColors.ActiveCaptionText;
+ this.lab_filename.Location = new System.Drawing.Point(31, 31);
+ this.lab_filename.Name = "lab_filename";
+ this.lab_filename.Size = new System.Drawing.Size(410, 19);
+ this.lab_filename.TabIndex = 3;
+ this.lab_filename.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
+ //
+ // lab_fileinfo
+ //
+ this.lab_fileinfo.BackColor = System.Drawing.Color.Transparent;
+ this.lab_fileinfo.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
+ this.lab_fileinfo.ForeColor = System.Drawing.SystemColors.ActiveCaptionText;
+ this.lab_fileinfo.Location = new System.Drawing.Point(23, 114);
+ this.lab_fileinfo.Name = "lab_fileinfo";
+ this.lab_fileinfo.Size = new System.Drawing.Size(410, 19);
+ this.lab_fileinfo.TabIndex = 4;
+ this.lab_fileinfo.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
+ //
+ // lblUpdateLog
+ //
+ this.lblUpdateLog.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
+ this.lblUpdateLog.ForeColor = System.Drawing.SystemColors.ActiveCaptionText;
+ this.lblUpdateLog.Location = new System.Drawing.Point(23, 133);
+ this.lblUpdateLog.Name = "lblUpdateLog";
+ this.lblUpdateLog.Size = new System.Drawing.Size(440, 85);
+ this.lblUpdateLog.TabIndex = 6;
+ this.lblUpdateLog.Text = "更新说明:(无)";
+ //
+ // Form1
+ //
+ this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.ClientSize = new System.Drawing.Size(515, 233);
+ this.Controls.Add(this.lblUpdateLog);
+ this.Controls.Add(this.lab_fileinfo);
+ this.Controls.Add(this.lab_filename);
+ this.Controls.Add(this.lab_percent);
+ this.Controls.Add(this.progressBarControl1);
+ this.MaximizeBox = false;
+ this.MinimizeBox = false;
+ this.Name = "Form1";
+ this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
+ this.Text = "版本更新";
+ this.Load += new System.EventHandler(this.Form1_Load);
+ ((System.ComponentModel.ISupportInitialize)(this.progressBarControl1.Properties)).EndInit();
+ this.ResumeLayout(false);
+ this.PerformLayout();
+
+ }
+
+ #endregion
+
+ private DevExpress.XtraEditors.ProgressBarControl progressBarControl1;
+ private DevExpress.XtraEditors.LabelControl lab_percent;
+ private System.Windows.Forms.Label lab_filename;
+ private System.Windows.Forms.Label lab_fileinfo;
+ private System.Windows.Forms.Label lblUpdateLog;
+ }
+}
+
diff --git a/Update/Form1.cs b/Update/Form1.cs
new file mode 100644
index 0000000..871a447
--- /dev/null
+++ b/Update/Form1.cs
@@ -0,0 +1,336 @@
+using DevExpress.XtraEditors;
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Data;
+using System.Diagnostics;
+using System.Drawing;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Windows.Forms;
+using Updater.Core;
+
+namespace Update
+{
+ public partial class Form1 : DevExpress.XtraEditors.XtraForm
+ {
+ //主程序传入的参数,系统标示 是否需要重新启动主程序
+ private string[] args;
+ //表示主程序打开时传入的参数
+ private readonly static string OPEN_FLAG = "121";
+ private bool isComplete = true;
+
+ private UpdateClass updater;
+ private List mList = new List();
+ private int mLen = 0;
+ public Form1()
+ {
+ InitializeComponent();
+ }
+
+ private void simpleButton1_Click(object sender, EventArgs e)
+ {
+
+ }
+
+ private void simpleButton1_Click_1(object sender, EventArgs e)
+ {
+ for (int i = 0; i <= 100; i++)
+ {
+
+ System.Threading.Thread.Sleep(10);
+ //progressBarControl1.PerformStep();
+ progressBarControl1.Position = i;
+ lab_percent.Text = i + "%";
+ //progressBarControl1.EditValue = i + 1;
+ //处理当前消息队列中的所有windows消息,不然进度条会不同步
+ System.Windows.Forms.Application.DoEvents();
+ }
+ }
+
+ private void Form1_Load(object sender, EventArgs e)
+ {
+ try
+ {
+ updater = new UpdateClass();
+ updater.ActivationCompleted += new EventHandler(ActivationCompleted);
+ updater.ActivationError += new EventHandler(ActivationError);
+ updater.ActivationInitializing += new EventHandler(ActivationInitializing);
+ updater.ActivationProgressChanged += new EventHandler(ActivationProgressChanged);
+ updater.ActivationStarted += new EventHandler(ActivationStarted);
+ updater.DownloadCompleted += new EventHandler(DownloadCompleted);
+ updater.DownloadError += new EventHandler(DownloadError);
+ updater.DownloadProgressChanged += new EventHandler(DownloadProgressChanged);
+
+ InitUpdater();
+ }
+ catch (Exception ex)
+ {
+ Log.Write("更新错误:" + ex.Message);
+ XtraMessageBox.Show("更新错误", "系统提示");
+ }
+ }
+ void ActivationCompleted(object sender, ActivationCompletedEventArgs e)
+ {
+ //安装完成
+ isComplete = true;
+ lab_filename.Text = "安装完成";
+ lab_percent.Text = "100%";
+ if (progressBarControl1.Position != 100)
+ {
+ progressBarControl1.Position = 100;
+ }
+ if (e.Error != null)
+ {
+ lab_filename.Text += ",但出现错误";
+ lab_filename.Update();
+ }
+ else
+ {
+ lab_filename.Update();
+ System.Threading.Thread.Sleep(3000);
+ string filename = GetFileName(e.Manifest.MyApplication.Location, e.Manifest.MyApplication.EntryPoint.File);
+ Startup(filename, e.Manifest.MyApplication.EntryPoint.Parameters);
+ //if (args != null && args.Length > 0)
+ {
+ Exit();
+ }
+ }
+ }
+ private string GetFileName(string location, string file)
+ {
+ return Path.Combine(Path.GetFullPath(location), file);
+ }
+
+ void ActivationError(object sender, FileCopyErrorEventArgs e)
+ {
+ Log.Write("安装过程中出现错误,错误描述:" + e.Error.Message + System.Environment.NewLine + "Version:" + e.Manifest.Version);
+ XtraMessageBox.Show(this, "安装错误:" + e.Error.Message, "系统提示");
+ lab_filename.Text = "系统正在回滚";
+ updater.Rollback(e.Manifest);
+ }
+ void ActivationInitializing(object sender, ManifestEventArgs e)
+ {
+ lab_filename.Text = "正在初始化安装,请稍后......";
+ lab_filename.Update();
+ lab_percent.Text = "0%";
+ lab_percent.Update();
+ lab_fileinfo.Text = "";
+ lab_fileinfo.Update();
+ //progressBar1.Value = 0;
+ }
+ void ActivationProgressChanged(object sender, FileCopyProgressChangedEventArgs e)
+ {
+ progressBarControl1.Position = e.ProgressPercentage;
+ lab_percent.Text = e.ProgressPercentage.ToString() + "%";
+ lab_percent.Update();
+ lab_fileinfo.Text = string.Format("字节数:{0}/{1}", e.BytesToCopy, e.TotalBytesToCopy);
+ lab_fileinfo.Update();
+ lab_filename.Text = "正在安装:" + e.SourceFileName;
+ lab_filename.Update();
+ }
+
+ void ActivationStarted(object sender, ActivationStartedEventArgs e)
+ {
+ lab_filename.Text = "开始安装,请稍后......";
+ lab_filename.Update();
+ e.Cancel = CheckActivation();
+ if (e.Cancel)
+ {
+ lab_filename.Text = "安装已被取消";
+ isComplete = true;
+ }
+ }
+ private bool CheckActivation()
+ {
+ bool cancel = false;
+ //检查主程序(进程名称)是否打开,如果打开则提示
+ string[] processName = { "Client", "Server" };
+ foreach (string name in processName)
+ {
+ System.Diagnostics.Process[] processes = System.Diagnostics.Process.GetProcessesByName(name);
+ if (processes != null && processes.Length != 0)
+ {
+ if (XtraMessageBox.Show(string.Format("进程{0}正在运行中,请关闭后重试。", name), "系统提示",
+ MessageBoxButtons.RetryCancel, MessageBoxIcon.Information) == System.Windows.Forms.DialogResult.Cancel)
+ {
+ cancel = true;
+ break;
+ }
+ else
+ {
+ return CheckActivation();
+ }
+ }
+ }
+ return cancel;
+ }
+
+ ///
+ /// 文件下载完毕执行的操作
+ ///
+ void DownloadCompleted(object sender, DownloadCompleteEventArgs e)
+ {
+ mList.Add(e.Manifest);
+ if (mList.Count == mLen)
+ {
+ updater.Activate(mList.ToArray());
+ mList.Clear();
+ }
+ }
+ void DownloadError(object sender, DownloadErrorEventArgs e)
+ {
+ Log.Write("下载过程中出现错误,错误描述:" + e.Error.Message + System.Environment.NewLine + "Version:" + e.Manifest.Version);
+ XtraMessageBox.Show("下载出错:" + e.Error.Message, "系统提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
+ }
+
+ void DownloadProgressChanged(object sender, DownloadProgressEventArgs e)
+ {
+ progressBarControl1.Position = e.ProgressPercentage;
+ lab_percent.Text = e.ProgressPercentage.ToString() + "%";
+ lab_percent.Update();
+ lab_fileinfo.Text = string.Format("字节数:{0}/{1}", e.BytesReceived, e.TotalBytesToReceive);
+ lab_fileinfo.Update();
+ lab_filename.Text = "正在下载文件:" + e.FileName;
+ lab_filename.Update();
+ }
+ private void InitUpdater()
+ {
+ //从配置文件动态设置更新标题
+ UpdaterConfigurationView updateCfgView = new UpdaterConfigurationView();
+
+ var manifests = updater.CheckForUpdates();
+ mLen = manifests.Length;
+ if (updater.HasNewVersion)
+ {
+ //显示本次更新内容
+ string updateDescription = manifests[0].Description;
+ this.lblUpdateLog.Text = string.Format("更新说明:{0}", updateDescription);
+
+ if (args != null && args.Length > 0)
+ {
+ #region 关闭主程序
+ try
+ {
+ string entryPoint = manifests[0].MyApplication.EntryPoint.File;
+ KillProcessDos(entryPoint);
+ }
+ catch (Exception ex)
+ {
+ Log.Write(ex.ToString());
+
+ }
+ #endregion
+ }
+ isComplete = false;
+ updater.DownloadAsync(manifests);
+ }
+ else
+ {
+ lab_filename.Text = "";
+ XtraMessageBox.Show("您当前的版本已经是最新,不需要更新。", "系统提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
+ Exit();
+ }
+ }
+ ///
+ /// 使用DOS关闭进程
+ ///
+ /// 进程名称
+ private void KillProcessDos(string processName)
+ {
+ RunCmd("taskkill /im " + processName + " /f ");
+ }
+ ///
+ /// 系统退出
+ ///
+ private void Exit()
+ {
+ this.Close();
+ Environment.Exit(0);
+ }
+ ///
+ /// 带参数启动指定的应用程序
+ ///
+ /// 入口的应用程序
+ /// 程序启动参数
+ private void Startup(string entryPoint, string parameters)
+ {
+ try
+ {
+ // if (args != null && args.Length > 0)
+ {
+ // if (args[0] == OPEN_FLAG)
+ {
+ //关闭主程序
+ ExeCommand("taskkill /im " + Path.GetFileName(entryPoint) + " /f ");
+ //启动主程序
+ System.Threading.Thread.Sleep(1000);
+ System.Diagnostics.Process.Start(entryPoint, parameters);
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ Log.Write(ex);
+ }
+ }
+
+ ///
+ /// DOS命令运行函数
+ ///
+ ///
+ private void ExeCommand(string commandText)
+ {
+ Process p = new Process();
+ p.StartInfo.FileName = "cmd.exe";
+ p.StartInfo.UseShellExecute = false;
+ p.StartInfo.RedirectStandardInput = true;
+ p.StartInfo.RedirectStandardOutput = true;
+ p.StartInfo.RedirectStandardError = true;
+ p.StartInfo.CreateNoWindow = true;
+ try
+ {
+ p.Start();
+ p.StandardInput.WriteLine(commandText);
+ p.StandardInput.WriteLine("exit");
+ //p.StandardOutput.ReadToEnd();
+ }
+ catch
+ {
+
+ }
+ }
+ ///
+ /// 运行DOS命令
+ /// DOS关闭进程命令(ntsd -c q -p PID )PID为进程的ID
+ ///
+ ///
+ ///
+ private void RunCmd(string command)
+ {
+ //實例一個Process類,啟動一個獨立進程
+ System.Diagnostics.Process p = new System.Diagnostics.Process();
+
+ //Process類有一個StartInfo屬性,這個是ProcessStartInfo類,包括了一些屬性和方法,下面我們用到了他的幾個屬性:
+ p.StartInfo.FileName = "cmd.exe"; //設定程序名
+ p.StartInfo.Arguments = "/c " + command; //設定程式執行參數
+ p.StartInfo.UseShellExecute = false; //關閉Shell的使用
+ p.StartInfo.RedirectStandardInput = true; //重定向標準輸入
+ p.StartInfo.RedirectStandardOutput = true; //重定向標準輸出
+ p.StartInfo.RedirectStandardError = true; //重定向錯誤輸出
+ p.StartInfo.CreateNoWindow = true; //設置不顯示窗口
+ p.Start(); //啟動
+
+ //p.StandardInput.WriteLine(command); //也可以用這種方式輸入要執行的命令
+ //p.StandardInput.WriteLine("exit"); //不過要記得加上Exit要不然下一行程式執行的時候會當機
+ p.StandardOutput.ReadToEnd(); //從輸出流取得命令執行結果
+
+ while (!p.HasExited)
+ {
+ p.WaitForExit(1000);
+ }
+ }
+
+ }
+}
diff --git a/Update/Form1.resx b/Update/Form1.resx
new file mode 100644
index 0000000..1af7de1
--- /dev/null
+++ b/Update/Form1.resx
@@ -0,0 +1,120 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
\ No newline at end of file
diff --git a/Update/Program.cs b/Update/Program.cs
new file mode 100644
index 0000000..5c257e6
--- /dev/null
+++ b/Update/Program.cs
@@ -0,0 +1,22 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+
+namespace Update
+{
+ internal static class Program
+ {
+ ///
+ /// 应用程序的主入口点。
+ ///
+ [STAThread]
+ static void Main()
+ {
+ Application.EnableVisualStyles();
+ Application.SetCompatibleTextRenderingDefault(false);
+ Application.Run(new Form1());
+ }
+ }
+}
diff --git a/Update/Properties/AssemblyInfo.cs b/Update/Properties/AssemblyInfo.cs
index d6b98b8..9f31f9e 100644
--- a/Update/Properties/AssemblyInfo.cs
+++ b/Update/Properties/AssemblyInfo.cs
@@ -10,7 +10,7 @@ using System.Runtime.InteropServices;
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Update")]
-[assembly: AssemblyCopyright("Copyright © 2021")]
+[assembly: AssemblyCopyright("Copyright © 2022")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
@@ -20,7 +20,7 @@ using System.Runtime.InteropServices;
[assembly: ComVisible(false)]
// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
-[assembly: Guid("295218b6-0c7e-4d1b-ad85-ab0636a83323")]
+[assembly: Guid("40fb5be4-89be-4717-9378-e85de86d56dd")]
// 程序集的版本信息由下列四个值组成:
//
diff --git a/Update/Properties/Resources.Designer.cs b/Update/Properties/Resources.Designer.cs
new file mode 100644
index 0000000..4ec49c4
--- /dev/null
+++ b/Update/Properties/Resources.Designer.cs
@@ -0,0 +1,71 @@
+//------------------------------------------------------------------------------
+//
+// 此代码由工具生成。
+// 运行时版本: 4.0.30319.42000
+//
+// 对此文件的更改可能导致不正确的行为,如果
+// 重新生成代码,则所做更改将丢失。
+//
+//------------------------------------------------------------------------------
+
+namespace Update.Properties
+{
+
+
+ ///
+ /// 强类型资源类,用于查找本地化字符串等。
+ ///
+ // 此类是由 StronglyTypedResourceBuilder
+ // 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。
+ // 若要添加或删除成员,请编辑 .ResX 文件,然后重新运行 ResGen
+ // (以 /str 作为命令选项),或重新生成 VS 项目。
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ internal class Resources
+ {
+
+ private static global::System.Resources.ResourceManager resourceMan;
+
+ private static global::System.Globalization.CultureInfo resourceCulture;
+
+ [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+ internal Resources()
+ {
+ }
+
+ ///
+ /// 返回此类使用的缓存 ResourceManager 实例。
+ ///
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Resources.ResourceManager ResourceManager
+ {
+ get
+ {
+ if ((resourceMan == null))
+ {
+ global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Update.Properties.Resources", typeof(Resources).Assembly);
+ resourceMan = temp;
+ }
+ return resourceMan;
+ }
+ }
+
+ ///
+ /// 重写当前线程的 CurrentUICulture 属性,对
+ /// 使用此强类型资源类的所有资源查找执行重写。
+ ///
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Globalization.CultureInfo Culture
+ {
+ get
+ {
+ return resourceCulture;
+ }
+ set
+ {
+ resourceCulture = value;
+ }
+ }
+ }
+}
diff --git a/Update/Properties/Resources.resx b/Update/Properties/Resources.resx
new file mode 100644
index 0000000..af7dbeb
--- /dev/null
+++ b/Update/Properties/Resources.resx
@@ -0,0 +1,117 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
\ No newline at end of file
diff --git a/Update/Properties/Settings.Designer.cs b/Update/Properties/Settings.Designer.cs
new file mode 100644
index 0000000..37ea7c8
--- /dev/null
+++ b/Update/Properties/Settings.Designer.cs
@@ -0,0 +1,30 @@
+//------------------------------------------------------------------------------
+//
+// This code was generated by a tool.
+// Runtime Version:4.0.30319.42000
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+namespace Update.Properties
+{
+
+
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")]
+ internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase
+ {
+
+ private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
+
+ public static Settings Default
+ {
+ get
+ {
+ return defaultInstance;
+ }
+ }
+ }
+}
diff --git a/Update/Properties/Settings.settings b/Update/Properties/Settings.settings
new file mode 100644
index 0000000..3964565
--- /dev/null
+++ b/Update/Properties/Settings.settings
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/Update/Update.csproj b/Update/Update.csproj
index 596dbb4..1697a69 100644
--- a/Update/Update.csproj
+++ b/Update/Update.csproj
@@ -1,19 +1,20 @@
-
+
Debug
AnyCPU
- 295218b6-0c7e-4d1b-ad85-ab0636a83323
- Library
- Properties
+ {40FB5BE4-89BE-4717-9378-E85DE86D56DD}
+ WinExe
Update
Update
v4.8
512
+ true
true
+ AnyCPU
true
full
false
@@ -23,6 +24,7 @@
4
+ AnyCPU
pdbonly
true
bin\Release\
@@ -31,24 +33,70 @@
4
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+ False
+ ..\..\..\..\..\Program Files (x86)\DevExpress 19.2\Components\Bin\Framework\DevExpress.Data.v19.2.dll
+
+
+
+ False
+ ..\..\..\..\..\Program Files (x86)\DevExpress 19.2\Components\Bin\Framework\DevExpress.XtraEditors.v19.2.dll
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+ Form
+
+
+ Form1.cs
+
+
+
+
+ Form1.cs
+
+
+ ResXFileCodeGenerator
+ Resources.Designer.cs
+ Designer
+
+
+ True
+ Resources.resx
+
+
+ SettingsSingleFileGenerator
+ Settings.Designer.cs
+
+
+ True
+ Settings.settings
+ True
+
+
+ Always
+
+
+
+
+
+
+
+ {4903D5F5-FF01-426D-B5BB-AADF7C4232FA}
+ Update.Core
+
-
+
\ No newline at end of file
diff --git a/Update/UpdateLog.cs b/Update/UpdateLog.cs
new file mode 100644
index 0000000..9902cd9
--- /dev/null
+++ b/Update/UpdateLog.cs
@@ -0,0 +1,50 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.IO;
+
+namespace Update
+{
+ ///
+ /// 记录操作过程的信息
+ ///
+ public class Log
+ {
+ public static void Write(string msg)
+ {
+ Write(msg, true);
+ }
+
+ public static void Write(string msg, bool isAppend)
+ {
+ try
+ {
+ string filename = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "update.txt");
+ if (!Directory.Exists(Path.GetDirectoryName(filename)))
+ {
+ Directory.CreateDirectory(Path.GetDirectoryName(filename));
+ }
+ using (FileStream stream = new FileStream(filename, isAppend ? FileMode.Append : FileMode.Create, FileAccess.Write, FileShare.None))
+ {
+ StreamWriter writer = new StreamWriter(stream);
+ writer.WriteLine(msg);
+ writer.Close();
+ stream.Close();
+ }
+ }
+ catch
+ {
+ }
+ }
+
+ public static void Write(Exception ex)
+ {
+ string msg = DateTime.Now + System.Environment.NewLine
+ + ex.Message + System.Environment.NewLine
+ + ex.Source + System.Environment.NewLine
+ + ex.StackTrace + System.Environment.NewLine
+ + ex.TargetSite.Name;
+ Write(msg);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Update/updateconfiguration.config b/Update/updateconfiguration.config
new file mode 100644
index 0000000..7ed1f8e
--- /dev/null
+++ b/Update/updateconfiguration.config
@@ -0,0 +1,6 @@
+
+
+
diff --git a/WinformGeneralDeveloperFrame.Commons/GetDataTableUtils.cs b/WinformGeneralDeveloperFrame.Commons/GetDataTableUtils.cs
index a0fe7cb..e269842 100644
--- a/WinformGeneralDeveloperFrame.Commons/GetDataTableUtils.cs
+++ b/WinformGeneralDeveloperFrame.Commons/GetDataTableUtils.cs
@@ -17,8 +17,8 @@ namespace WinformGeneralDeveloperFrame.Commons
public static DataTable SqlTable(string name)
{
- string connstring = EncodeHelper.AES_Decrypt(ConfigurationManager.ConnectionStrings["DB"].ConnectionString);
- // string connstring=ConfigurationManager.ConnectionStrings["DB"].ConnectionString;
+ //string connstring = EncodeHelper.AES_Decrypt(ConfigurationManager.ConnectionStrings["DB"].ConnectionString);
+ string connstring=ConfigurationManager.ConnectionStrings["DB"].ConnectionString;
string sql = "";
string url = "";
DataTable dt1 = new DataTable();
diff --git a/WinformGeneralDeveloperFrame.Start/App.config b/WinformGeneralDeveloperFrame.Start/App.config
index 567b1aa..b43d7d0 100644
--- a/WinformGeneralDeveloperFrame.Start/App.config
+++ b/WinformGeneralDeveloperFrame.Start/App.config
@@ -51,7 +51,7 @@
-
+
diff --git a/WinformGeneralDeveloperFrame.Start/Start.csproj b/WinformGeneralDeveloperFrame.Start/Start.csproj
index ab2e360..719b5b9 100644
--- a/WinformGeneralDeveloperFrame.Start/Start.csproj
+++ b/WinformGeneralDeveloperFrame.Start/Start.csproj
@@ -76,6 +76,14 @@
+
+ {4903d5f5-ff01-426d-b5bb-aadf7c4232fa}
+ Update.Core
+
+
+ {40fb5be4-89be-4717-9378-e85de86d56dd}
+ Update
+
{6f2b061d-6116-45a4-9649-49ae4981c496}
Commons
diff --git a/WinformGeneralDeveloperFrame.sln b/WinformGeneralDeveloperFrame.sln
index 158a207..41f1a3f 100644
--- a/WinformGeneralDeveloperFrame.sln
+++ b/WinformGeneralDeveloperFrame.sln
@@ -15,12 +15,14 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PrimordialForm", "WinformGe
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Entity", "Entity\Entity.csproj", "{524A09B1-52EE-49C6-ACD2-CEC2AEB8D2F6}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Update", "Update\Update.csproj", "{295218B6-0C7E-4D1B-AD85-AB0636A83323}"
-EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CodeGeneration", "CodeGeneration\CodeGeneration.csproj", "{D7D32522-8FA4-4B12-ADB1-72A74F0B3964}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Business", "Business\Business.csproj", "{3A1FD334-A7FD-4815-A745-ACC07A7C367F}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Update.Core", "Update.Core\Update.Core.csproj", "{4903D5F5-FF01-426D-B5BB-AADF7C4232FA}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Update", "Update\Update.csproj", "{40FB5BE4-89BE-4717-9378-E85DE86D56DD}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -51,10 +53,6 @@ Global
{524A09B1-52EE-49C6-ACD2-CEC2AEB8D2F6}.Debug|Any CPU.Build.0 = Debug|Any CPU
{524A09B1-52EE-49C6-ACD2-CEC2AEB8D2F6}.Release|Any CPU.ActiveCfg = Release|Any CPU
{524A09B1-52EE-49C6-ACD2-CEC2AEB8D2F6}.Release|Any CPU.Build.0 = Release|Any CPU
- {295218B6-0C7E-4D1B-AD85-AB0636A83323}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {295218B6-0C7E-4D1B-AD85-AB0636A83323}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {295218B6-0C7E-4D1B-AD85-AB0636A83323}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {295218B6-0C7E-4D1B-AD85-AB0636A83323}.Release|Any CPU.Build.0 = Release|Any CPU
{D7D32522-8FA4-4B12-ADB1-72A74F0B3964}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D7D32522-8FA4-4B12-ADB1-72A74F0B3964}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D7D32522-8FA4-4B12-ADB1-72A74F0B3964}.Release|Any CPU.ActiveCfg = Release|Any CPU
@@ -63,6 +61,14 @@ Global
{3A1FD334-A7FD-4815-A745-ACC07A7C367F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3A1FD334-A7FD-4815-A745-ACC07A7C367F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3A1FD334-A7FD-4815-A745-ACC07A7C367F}.Release|Any CPU.Build.0 = Release|Any CPU
+ {4903D5F5-FF01-426D-B5BB-AADF7C4232FA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {4903D5F5-FF01-426D-B5BB-AADF7C4232FA}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {4903D5F5-FF01-426D-B5BB-AADF7C4232FA}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {4903D5F5-FF01-426D-B5BB-AADF7C4232FA}.Release|Any CPU.Build.0 = Release|Any CPU
+ {40FB5BE4-89BE-4717-9378-E85DE86D56DD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {40FB5BE4-89BE-4717-9378-E85DE86D56DD}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {40FB5BE4-89BE-4717-9378-E85DE86D56DD}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {40FB5BE4-89BE-4717-9378-E85DE86D56DD}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/WinformGeneralDeveloperFrame.sln.DotSettings.user b/WinformGeneralDeveloperFrame.sln.DotSettings.user
new file mode 100644
index 0000000..6f84b54
--- /dev/null
+++ b/WinformGeneralDeveloperFrame.sln.DotSettings.user
@@ -0,0 +1,2 @@
+
+ True
\ No newline at end of file
diff --git a/WinformGeneralDeveloperFrame/DB.cs b/WinformGeneralDeveloperFrame/DB.cs
index 9d0ac89..a3d4744 100644
--- a/WinformGeneralDeveloperFrame/DB.cs
+++ b/WinformGeneralDeveloperFrame/DB.cs
@@ -13,7 +13,8 @@ namespace WinformGeneralDeveloperFrame
public partial class DB : DbContext
{
public DB()
- : base(EncodeHelper.AES_Decrypt(ConfigurationManager.ConnectionStrings["DB"].ConnectionString))
+ :base("DB")
+ //: base(EncodeHelper.AES_Decrypt(ConfigurationManager.ConnectionStrings["DB"].ConnectionString))
{
}
diff --git a/WinformGeneralDeveloperFrame/DB/MESDB.cs b/WinformGeneralDeveloperFrame/DB/MESDB.cs
index 85a732f..e1903f3 100644
--- a/WinformGeneralDeveloperFrame/DB/MESDB.cs
+++ b/WinformGeneralDeveloperFrame/DB/MESDB.cs
@@ -11,8 +11,8 @@ namespace MES
public partial class MESDB : DbContext
{
public MESDB()
- //: base("name=DB")
- : base(EncodeHelper.AES_Decrypt(ConfigurationManager.ConnectionStrings["DB"].ConnectionString))
+ : base("name=DB")
+ //: base(EncodeHelper.AES_Decrypt(ConfigurationManager.ConnectionStrings["DB"].ConnectionString))
{
}
public virtual DbSet stockDataInfo { get; set; }
diff --git a/WinformGeneralDeveloperFrame/DevexpressForm.csproj b/WinformGeneralDeveloperFrame/DevexpressForm.csproj
index 92d254b..4df135b 100644
--- a/WinformGeneralDeveloperFrame/DevexpressForm.csproj
+++ b/WinformGeneralDeveloperFrame/DevexpressForm.csproj
@@ -742,6 +742,14 @@
+
+ {4903D5F5-FF01-426D-B5BB-AADF7C4232FA}
+ Update.Core
+
+
+ {40FB5BE4-89BE-4717-9378-E85DE86D56DD}
+ Update
+
{6f2b061d-6116-45a4-9649-49ae4981c496}
Commons
diff --git a/WinformGeneralDeveloperFrame/LoginView.cs b/WinformGeneralDeveloperFrame/LoginView.cs
index f413cd3..c8e5c43 100644
--- a/WinformGeneralDeveloperFrame/LoginView.cs
+++ b/WinformGeneralDeveloperFrame/LoginView.cs
@@ -10,11 +10,18 @@ using System.Text;
using System.Windows.Forms;
using MES.Entity;
using WinformGeneralDeveloperFrame.Commons;
+using Updater.Core;
+using System.Diagnostics;
+using System.IO;
+using DevExpress.Utils;
+using DevExpress.XtraEditors;
+using Update;
namespace Login
{
public partial class LoginView : DevExpress.XtraEditors.XtraForm
{
+ private BackgroundWorker updateWorker;
public bool bLogin = false; //判断用户是否登录
public LoginView()
{
@@ -45,8 +52,32 @@ namespace Login
private void LoginView_Load(object sender, EventArgs e)
{
+ updateWorker = new BackgroundWorker();
+ updateWorker.DoWork += new DoWorkEventHandler(updateWorker_DoWork);
+ updateWorker.RunWorkerAsync();
+
+ }
+ private void updateWorker_DoWork(object sender, DoWorkEventArgs e)
+ {
+ try
+ {
+ UpdateClass update = new UpdateClass();
+ bool newVersion = update.HasNewVersion;
+ if (newVersion)
+ {
+ //if (MessageUtil.ShowYesNoAndTips(Portal.gc.DicLag["Version"].Where(p => p.Name == Portal.gc.Language).First().Value) == DialogResult.Yes)
+ {
+ //Thread.Sleep(1500);
+ Process.Start(Path.Combine(Application.StartupPath, "Update.exe"), "121");
+ Application.Exit();
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ XtraMessageBox.Show(ex.Message);
+ }
}
-
private void User_MouseEnter(object sender, EventArgs e)
{
skinPanel2.BackColor = Color.FromArgb(69, 159, 176);