Code
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Net;
using System.Text;
using System.Threading;
using System.Xml;
using ICSharpCode.SharpZipLib;
using ICSharpCode.SharpZipLib.Zip;
namespace NUpdate
{
class NUpdate
{
object controllerLock = new object();
bool isStarted = false;
/// <summary>
/// Updates this instance.
/// </summary>
public void Update(string url)
{
try
{
string logPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, Properties.Settings.Default.LogPath);
if (File.Exists(logPath))
{
File.Delete(logPath);
}
}
catch
{
}
string version = null;
string downloadUrl = null;
XmlNodeList exeNodeList = null;
try
{
using (XmlTextReader updateInfoReader = new XmlTextReader(url))
{
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(updateInfoReader);
version = xmlDoc.SelectSingleNode(@"/NUpdate/Version").InnerText;
downloadUrl = xmlDoc.SelectSingleNode(@"/NUpdate/DownloadUrl").InnerText;
exeNodeList = xmlDoc.SelectNodes(@"//Run/Item");
}
if (Properties.Settings.Default.InstalledVersion != version)
{
string downloadFile = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, Path.GetFileName(downloadUrl));
string updatePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, Path.GetFileNameWithoutExtension(downloadFile));
string executablePath = AppDomain.CurrentDomain.BaseDirectory;
string backupPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "backup");
LogOperation("New version in XML info detected.");
LogOperation("Downloaded files from " + downloadUrl + " to " + Properties.Settings.Default.LocalPath);
#region download files
// Downloading the latest MSI
using (WebClient webClient = new WebClient())
{
webClient.DownloadFile(downloadUrl, downloadFile);
}
#endregion
LogOperation("unzip " + downloadFile);
#region unrar
try
{
unzip(downloadFile, updatePath);
}
catch (Exception ex)
{
LogException(ex);
}
finally
{
File.Delete(downloadFile);
}
#endregion
LogOperation("Stop Main exec " + Properties.Settings.Default.Main);
#region stop main exe
try
{
WaitToStop(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, Properties.Settings.Default.Main));
}
catch (Exception ex)
{
LogException(new NUpdateException("Failing to initiate STOP process.", ex));
}
#endregion
LogOperation("Starting to Update files.");
#region copy files
if (Directory.Exists(updatePath))
{
try
{
moveDirectoryFiles(updatePath, executablePath, backupPath);
Directory.Delete(backupPath, true);
}
catch (Exception ex)
{
LogOperation(ex.Message);
}
finally
{
Directory.Delete(updatePath, true);
}
}
#endregion
Properties.Settings.Default.InstalledVersion = version;
Properties.Settings.Default.Save();
LogOperation("Updated current installed version as " + version);
}
}
catch (Exception ex)
{
LogException(ex);
}
#region starting the processes (if not already started)
try
{
if (exeNodeList != null && isStarted)
{
foreach (XmlNode node in exeNodeList)
{
try
{
if (!string.IsNullOrEmpty(node.InnerText))
{
int wait = 0;
int.TryParse(node.Attributes["wait"].Value, out wait);
string arguments = node.Attributes["arguments"].Value;
StartAndWaitProcess(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, node.InnerText), arguments, wait);
}
}
catch (Exception ex)
{
LogException(ex);
}
}
}
}
catch (Exception ex)
{
LogException(ex);
}
try
{
if (!IsRuning(Properties.Settings.Default.Main) && isStarted)
{
try
{
if (!string.IsNullOrEmpty(Properties.Settings.Default.InstalledVersion.ToString()))
{
LogOperation("start " + Properties.Settings.Default.Main);
StartProcess(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, Properties.Settings.Default.Main), null);
}
}
catch (Exception ex)
{
LogException(new NUpdateException("Failing to initiate START process.", ex));
}
}
}
catch (Exception ex)
{
LogException(ex);
}
#endregion
}
/// <summary>
/// Starts the and wait process.
/// </summary>
/// <param name="execPath">The exec logPath.</param>
/// <param name="execArgs">The exec args.</param>
void StartAndWaitProcess(string execPath, string execArgs)
{
ProcessStartInfo startInfo = new ProcessStartInfo(execPath);
startInfo.WorkingDirectory = Path.GetDirectoryName(execPath);
if (!string.IsNullOrEmpty(execArgs))
{
startInfo.Arguments = execArgs;
}
Process process = Process.Start(startInfo);
process.WaitForExit();
}
void StartAndWaitProcess(string execPath, string execArgs, int waitMilliseconds)
{
ProcessStartInfo startInfo = new ProcessStartInfo(execPath);
startInfo.WorkingDirectory = Path.GetDirectoryName(execPath);
if (!string.IsNullOrEmpty(execArgs))
{
startInfo.Arguments = execArgs;
}
Process process = Process.Start(startInfo);
process.WaitForExit(waitMilliseconds);
}
/// <summary>
/// Starts the process.
/// </summary>
/// <param name="execPath">The exec logPath.</param>
/// <param name="execArgs">The exec args.</param>
void StartProcess(string execPath, string execArgs)
{
Process process = null;
if (File.Exists(execPath))
{
try
{
ProcessStartInfo startInfo = new ProcessStartInfo(execPath);
startInfo.CreateNoWindow = false;
startInfo.UseShellExecute = false;
startInfo.RedirectStandardInput = true;
startInfo.RedirectStandardOutput = true;
startInfo.RedirectStandardError = true;
startInfo.WindowStyle = ProcessWindowStyle.Normal;
startInfo.WorkingDirectory = AppDomain.CurrentDomain.BaseDirectory;
startInfo.LoadUserProfile = true;
if (!string.IsNullOrEmpty(execArgs))
{
startInfo.Arguments = execArgs;
}
process = Process.Start(startInfo);
}
catch (Exception ex)
{
LogException(ex);
}
}
}
/// <summary>
/// Waits to stop.
/// </summary>
/// <param name="exeName">Name of the exe.</param>
void WaitToStop(string exeName)
{
foreach (Process process in Process.GetProcessesByName(Path.GetFileNameWithoutExtension(exeName)))
{
isStarted = true;
process.Kill();
process.WaitForExit();
}
}
/// <summary>
/// Determines whether the specified exe name is runing.
/// </summary>
/// <param name="exeName">Name of the exe.</param>
/// <returns>
/// <c>true</c> if the specified exe name is runing; otherwise, <c>false</c>.
/// </returns>
bool IsRuning(string exeName)
{
foreach (Process process in Process.GetProcessesByName(Path.GetFileNameWithoutExtension(exeName)))
{
return true;
}
return false;
}
/// <summary>
/// Logs the exception.
/// </summary>
/// <param name="ex">The ex.</param>
void LogException(Exception ex)
{
Console.WriteLine(ex.Message);
// logging the exception if something is going wrong.
File.AppendAllText(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, Properties.Settings.Default.LogPath),
Environment.NewLine + DateTime.Now.ToString() +
Environment.NewLine + ex.ToString());
}
/// <summary>
/// Logs the operation.
/// </summary>
/// <param name="message">The message.</param>
void LogOperation(string message)
{
Console.WriteLine(message);
File.AppendAllText(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, Properties.Settings.Default.LogPath),
Environment.NewLine + DateTime.Now.ToString() +
Environment.NewLine + message);
}
/// <summary>
/// Moves the directory files.
/// </summary>
/// <param name="sourcePath">The source logPath.</param>
/// <param name="destPath">The dest logPath.</param>
/// <param name="backupPath">The backup logPath.</param>
void moveDirectoryFiles(string sourcePath, string destPath, string backupPath)
{
if (!sourcePath.EndsWith(Path.DirectorySeparatorChar.ToString()))
{
sourcePath = sourcePath + Path.DirectorySeparatorChar;
}
if (!destPath.EndsWith(Path.DirectorySeparatorChar.ToString()))
{
destPath = destPath + Path.DirectorySeparatorChar;
}
if (!backupPath.EndsWith(Path.DirectorySeparatorChar.ToString()))
{
backupPath = backupPath + Path.DirectorySeparatorChar;
}
if (!Directory.Exists(backupPath))
{
Directory.CreateDirectory(backupPath);
}
try
{
// 文件
foreach (string fileInfo in Directory.GetFiles(sourcePath))
{
try
{
string fileName = Path.GetFileName(fileInfo);
string sourceFile = Path.Combine(sourcePath, fileName);
string destFile = Path.Combine(destPath, fileName);
if (File.Exists(destFile))
{
File.Copy(destFile, Path.Combine(backupPath, fileName));
File.Delete(destFile);
}
File.Move(sourceFile, destFile);
}
catch { };
}
foreach (string dir in Directory.GetDirectories(sourcePath))
{
try
{
string dirName = Path.GetFileName(dir);
if (!Directory.Exists(Path.Combine(destPath, dirName)))
{
Directory.CreateDirectory(Path.Combine(destPath, dirName));
}
if (!Directory.Exists(backupPath + dirName))
{
Directory.CreateDirectory(Path.Combine(backupPath, dirName));
}
moveDirectoryFiles(Path.Combine(sourcePath, dirName), Path.Combine(destPath, dirName), Path.Combine(backupPath, dirName));
}
catch { };
}
}
catch (Exception ex)
{
throw ex;
}
}
/// <summary>
/// unzip: Open the zip file specified by stZipPath, into the stDestPath Directory
/// </summary>
void unzip(string stZipPath, string stDestPath)
{
using (ZipInputStream s = new ZipInputStream(File.OpenRead(stZipPath)))
{
ZipEntry theEntry;
while ((theEntry = s.GetNextEntry()) != null)
{
string fileName = Path.Combine(stDestPath, Path.GetDirectoryName(theEntry.Name));
fileName = Path.Combine(fileName, Path.GetFileName(theEntry.Name));
//create directory for file (if necessary)
Directory.CreateDirectory(Path.GetDirectoryName(fileName));
if (!theEntry.IsDirectory)
{
FileStream streamWriter = File.Create(fileName);
int size = 2048;
byte[] data = new byte[2048];
try
{
while (true)
{
size = s.Read(data, 0, data.Length);
if (size > 0)
{
streamWriter.Write(data, 0, size);
}
else
{
break;
}
}
}
catch { }
streamWriter.Close();
}
else
{
}
}
s.Close();
}
}
}
}
Code
namespace NUpdate
{
class Program
{
static void Main(string[] args)
{
if (args.Length > 0)
{
NUpdate nUpdate = new NUpdate();
nUpdate.Update(args[0]);
}
}
}
}
Code
private void UpdateApp()
{
do
{
try
{
App.Loger.Debug("啟動自動更新");
string updateExec = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, Properties.Settings.Default.Updater);
if (System.IO.File.Exists(updateExec) && !Common.IsRuning(Properties.Settings.Default.Updater))
{
ProcessStartInfo startInfo = new ProcessStartInfo(updateExec);
startInfo.Arguments = Properties.Settings.Default.UpdateUrl;
startInfo.CreateNoWindow = true;
startInfo.WindowStyle = ProcessWindowStyle.Hidden;
Process.Start(startInfo);
}
DateTime lastPing = DateTime.Now;
while (!exit && DateTime.Now.Subtract(lastPing).TotalSeconds < Properties.Settings.Default.PingFrequency)
{
System.Threading.Thread.Sleep(1000);
}
App.Loger.Debug("停止自動更新");
}
catch (Exception ex)
{
App.Loger.Error("更新程式錯誤", ex);
System.Threading.Thread.Sleep(1000 * 60 * 60);
}
}
while (!exit);
}