源码下载:AutoUpdater.rar (894.81 kb)
项目介绍:
AutoUpdater:主要是更新对话框,下载对话框。dll形式。
AutoUpdaterBuilder:放于网站服务器中,当需要更新的时点击一次,生成新的AutoupdateService.xml文件。
AutoUpdaterDemo:测试客户端主程序例子。
AutoUpdaterTool:更新工具,生成后需要和主程序的生成文件合并文件夹。负责更新后启动主程序,下载更新文件等功能。
更新原理:
对比本地的AutoUpdater.config文件与服务器的AutoupdateService.xml文件内,同一个文件的版本号大小。
一:建立更新服务器
1:重新生成AutoUpdaterBuilder项目。
2:新建一个网站(注意必须是动态网站,含有web.config),然后把【1步】生成的项目放入网站根目录内(pdb文件可删除)。
二:对更新工具设置 服务器地址、设置启动程序名字
1:修改AutoUpdaterTool项目内AutoUpdater.config文件ServerUrl节点,节点值为第二步网站中AutoupdateService.xml文件的网络地址。
如: <ServerUrl>http://localhost:8833/AutoupdateService.xml</ServerUrl>
2:修改AutoUpdaterTool项目内主配置文件【key="MainProgramName"】节点的值,值为:主程序(需要更新的的程序)的可执行文件名
如:<add key="MainProgramName" value="AutoUpdaterDemo.exe"/>
三:修改主程序(AutoUpdaterDemo),每次启动检查更新。
a:在主程序中,首先添加一个新类:
/// <summary>
/// 通过程序名称、版本号和路径检查程序是否已运行
/// </summary>
class ClassCheckProIsRun
{
/// 该函数设置由不同线程产生的窗口的显示状态
/// </summary>
/// <param name="hWnd">窗口句柄</param>
/// <param name="cmdShow">指定窗口如何显示。查看允许值列表,请查阅ShowWlndow函数的说明部分</param>
/// <returns>如果函数原来可见,返回值为非零;如果函数原来被隐藏,返回值为零</returns>
[DllImport("User32.dll")]
private static extern bool ShowWindowAsync(IntPtr hWnd, int cmdShow);
/// <summary>
/// 该函数将创建指定窗口的线程设置到前台,并且激活该窗口。键盘输入转向该窗口,并为用户改各种可视的记号。
/// 系统给创建前台窗口的线程分配的权限稍高于其他线程。
/// </summary>
/// <param name="hWnd">将被激活并被调入前台的窗口句柄</param>
/// <returns>如果窗口设入了前台,返回值为非零;如果窗口未被设入前台,返回值为零</returns>
[DllImport("User32.dll")]
private static extern bool SetForegroundWindow(IntPtr hWnd);
private const int SW_SHOWNOMAL = 1;
private static void HandleRunningInstance(Process instance)
{
ShowWindowAsync(instance.MainWindowHandle, SW_SHOWNOMAL); //show已运行的更新程序
SetForegroundWindow(instance.MainWindowHandle); //窗口置最前
}
/// <summary>
/// 检测进程中程序是否已运行,返回运行状态
/// </summary>
/// <param name="strPath">程序完整路径</param>
/// <returns>运行状态</returns>
public bool checkProcess(string strPath)
{
////获取版本号
string strVersionNumber = Application.ProductVersion;
string strProName = strPath.Substring(strPath.LastIndexOf('\\') + 1, (strPath.LastIndexOf('.') - 1) - strPath.LastIndexOf('\\')); //获取不带扩展名的程序名称
bool isRun = false; //更新程序是否已运行,默认未运行
Process[] processes = Process.GetProcessesByName(strProName); //同程序名的所有进程
foreach (Process p in processes)//判断当前进程中是否已有该程序
{
if (p.MainModule.FileName.ToString() == strPath)//通过程序路径判断,而不能通过程序名判断
{
string strVN = p.MainModule.FileVersionInfo.FileVersion; //获取进程中正在运行的这个程序的版本号,留作判断版本时用
isRun = true; //更新程序已运行
HandleRunningInstance(p); //show已运行的更新程序,并置顶
break;
}
}
return isRun;
}
/// <summary>
/// 按程序名检查进程
/// </summary>
/// <param name="strProName">带扩展名的程序名</param>
/// <returns>是否存在</returns>
public bool checkProcessForProName(string strProName)
{
bool isRun = false; //更新程序是否已运行,默认未运行
Process[] processes = Process.GetProcessesByName(strProName.Substring(0, strProName.LastIndexOf('.'))); //同程序名的所有进程
foreach (Process p in processes)//判断当前进程中是否已有该程序
{
if (p.MainModule.ModuleName == strProName)//通过程序路径判断,而不能通过程序名判断
{
string strVN = p.MainModule.FileVersionInfo.FileVersion; //获取进程中正在运行的这个程序的版本号
isRun = true; //更新程序已运行
break;
}
}
return isRun;
}
}
b:在主程序的 启动窗口程序中(第一个窗口程序) 添加两个变量
/// <summary>
/// 是否已经取消了更新
/// </summary>
public bool IsCancelUpdate { get; set; }
/// <summary>
/// 自动更新程序路径
/// </summary>
private readonly string autoUpdaterPath = AppDomain.CurrentDomain.BaseDirectory + "AutoUpdaterTool.exe";
c:然后在主程序的启动窗口程序中(第一个窗口程序) 的load函数内 添加检查更新代码代码:
/// <summary>
/// 检测更新
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Form1_Load(object sender, EventArgs e)
{
if (!IsCancelUpdate)
{
try
{
IAutoUpdater autoUpdater = new AutoUpdater();
if (autoUpdater.CheckUpdate())
{
if (new lib.ClassCheckProIsRun().checkProcess(autoUpdaterPath))
{
MessageBox.Show(@"更新程序已经运行!");
return;
}
System.Diagnostics.Process.Start(autoUpdaterPath);
Application.Exit();
}
}
catch (Exception exception)
{
MessageBox.Show(exception.Message);
}
}
}
d:修改主程序的winform的main函数,作用是:在主窗口显示前,检验是否用户手动取消更新。
static class Program
{
/// <summary>
/// 应用程序的主入口点。
/// </summary>
[STAThread]
static void Main(string[] args)
{
//新建“启动窗口”对象
var mainForm = new Form1();
//验证是否已经取消更新了
if (args != null && args.Length > 0)
{
mainForm.IsCancelUpdate = Convert.ToBoolean(args[0]);
}
//开始运行
Application.Run(mainForm);
}
}
四:整合更新程序到主程序内。
1:重新生成AutoUpdaterTool项目(pdb文件可以删除)。
2:成新生成主程序项目(本例中的AutoUpdaterDemo,生成后pdb文件可以删除)
3:拷贝【1】生成后的项目到【2】生成后的项目中。OK!可以运行了。
源码与示例下载:
AutoUpdater.rar (894.81 kb)