WinForm应用程序中实现自动更新功能

编写人:左丘文

2015-4-20

近来在给一客户实施ECM系统,但他们使用功能并不是我们ECM制造版提供的标准功能,他们要求对系统作一些定制功能,为了避免因程序的bug而带来频繁让用户更新程序的不良影响,就想给ECM增加一个winform自动更新功能,今天在这里,我想与大家一起分享代码,在此做个小结,以供参考。有兴趣的同学,可以一同探讨与学习一下,否则就略过吧。

 

1、 首先我们在这里先分析一下其它程序猿的一些基本情况:

相信有许多程序猿都喜欢用Winform做开发吧?!因为Winform相对Webform而言,优点是,功能更强大,编程更方便.但是它的缺点,就是软件的安装及维护是相当麻烦地,要实现软件更新,需要到客户端一台一台地升级。

长期以来,广大程序猿为到底是使用Client/Server,还是使用Browser/Server结构争论不休,在这些争论当中,C/S结构的程序可维护性差,布置困难,升级不方便,维护成本高就是一个相当重要的因素。有很多企业用户就是因为这个原因而放弃使用C/S。然而当一个应用必须要使用C/S结构才能很好的实现其功能的时候,我们该如何解决客户端的部署与自动升级问题?部署很简单,只要点击安装程序即可,难的在于每当有新版本发布时,能够实现自动升级。现在好了,我们的目标很简单,我们希望开发一个与具体应用无关的能够复用的自动升级系统。下面我为大家提供了一套可复用的用C#实现在线升级。这里分为本地在线升级,也可以利用webservice 在线通过互联网与软件开商的服务器在线升级。

2、 实现软件自动在线升级的原理

1)         写三个程序,一个是主程序;两个是升级程序;所有升级任务都由升级程序完成

原本只需要一个升级程序,但在这里,由于我们另外还涉及到了,在线与软件供应商服务器更新功能,因此我们这里用到了一个主程序两个升级程序。

2)         很多人实行的原理是将现有版本与最新版本作比较,发现最新的则提示用户是否升级,当然也有人用其它属性比较的,例如:文件大小或者更新日期。我们这里主要利用FileUtil的两个属性SHA1File与MD5File来判断,与服务器之间是否存在版本差异,存在就更新。

3)         我们的程序,刚开始初始版本是我一同事利用了三天时间,大致写了一个框架出来,我是在他的基础上,对其进行了完善,如增加了对文件流的压缩与解压缩功能,方便进行网络的传输,增加了通过webservices的在线更新功能。并将程序做到通用功能,并嵌套到了我们的ECM系统中。

3、 软件更新操作界面:

1)   启动我们的主程序ECM

2)   系统会从数据库中检查是否有新版本,点点【否】会直接进入系统,点【是】系统会进入到更新介面:

先择需要更新的内容,点击更新,系统会自动更新相关程序。

3)   与软件供应商服务器在线更新介面:

操作类似于在线本地更新一样。

具体就需要各位好好的自已去调试了。

4、 更新程序的代码:

1)   我们的更新程序是以文件流的形式存放在数据库中,因此我们首先需要为系统数据库增加相关的表,用于存储更新文件。

--建立相关表

SET ANSI_NULLS ON

GO

SET QUOTED_IDENTIFIER ON

GO

SET ANSI_PADDING ON

GO

CREATE TABLE [dbo].[SysUpdate](

[ID] [,) NOT NULL,

[FileName] [varchar]() NULL,

[FileVersion] [varchar]() NULL,

[FilePath] [varchar]() NULL,

[FileData] [varbinary](max) NULL,

[FileSize] [varchar]() NULL,

[FileDate] [varchar]() NULL,

[FileType] [varchar]() NULL,

[FilesHash] [varchar](max) NULL,

[FilesMD5] [varchar](max) NULL,

[UpdateBit] [bit] NULL,

[RegBit] [bit] NULL

) ON [PRIMARY]

GO

SET ANSI_PADDING OFF

--建立插入SP

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
create procedure [dbo].[Insert_UpdateFile] @filename varchar(),@fileversion varchar(),@filepath varchar(),@filesize varchar(),@filedate varchar(),@filetype varchar(),@fileshash varchar(),@filesmd5 varchar(),@file varbinary(Max)
,,@fileshash,@filesmd5,@file

2)   整体程序框架图如下:

3)   上传功能代码:

;
            dgvList.AutoGenerateColumns = , newColumn);
            dgvList.Columns.Insert(, newColumn1);
            dgvList.Columns.Insert(, newColumn2);
            ].DefaultView;
            ].Frozen = ].Frozen = ].Frozen = ].Frozen = ].HeaderText = ].Width = ;
            dgvList.Columns[].HeaderText = ].Width = ;
            dgvList.Columns[].ReadOnly = ].HeaderText = ].Width = ;
            dgvList.Columns[].ReadOnly = ].HeaderText = ].Width = ;
            dgvList.Columns[].ReadOnly = ].HeaderText = ].Width = ;
            dgvList.Columns[].ReadOnly = ].HeaderText = ].Width = ;
            dgvList.Columns[].ReadOnly = ].HeaderText = ].Width = ;
            dgvList.Columns[].ReadOnly = ].HeaderText = ].Width = ;
            dgvList.Columns[].ReadOnly = ].HeaderText = ].Width = ;
            dgvList.Columns[].ReadOnly = ].HeaderText = ].Width = ;
            dgvList.Columns[].ReadOnly = ].HeaderText = ].Width = ;
           ].HeaderText = ].Width = ;
             ? Convert.ToString(b, ) : ));
            }
            ].DataPropertyName = ].DataPropertyName = ].DataPropertyName = ].DataPropertyName = ].DataPropertyName = ].DataPropertyName = ].DataPropertyName = ].DataPropertyName = ].DataPropertyName = ].DataPropertyName = ].DataPropertyName = ].DataPropertyName = ].DefaultView;
            ;
            openFileDialog1.RestoreDirectory = , streamLength);        )
                    {
                        MessageBox.Show(, e.RowIndex].Value.ToString();
            txtFilePath.Text = dgvList[, e.RowIndex].Value.ToString();
            chkUpdateBit.Checked = Convert.ToBoolean(dgvList[, e.RowIndex].Value);
            chkRegBit.Checked = Convert.ToBoolean(dgvList[, e.RowIndex].Value);
        }
 
        )
            {
                MessageBox.Show()
            {
                MessageBox.Show(; i < ;
            }
        }
 
 
        ;
            dgvList.AutoGenerateColumns = , newColumn);
            dgvList.Columns.Insert(, newColumn1);
            dgvList.Columns.Insert(, newColumn2);
            ].DefaultView;
            ].Frozen = ].Frozen = ].Frozen = ].Frozen = ].HeaderText = ].Width = ;
            dgvList.Columns[].HeaderText = ].Width = ;
            dgvList.Columns[].ReadOnly = ].HeaderText = ].Width = ;
            dgvList.Columns[].ReadOnly = ].HeaderText = ].Width = ;
            dgvList.Columns[].ReadOnly = ].HeaderText = ].Width = ;
            dgvList.Columns[].ReadOnly = ].HeaderText = ].Width = ;
            dgvList.Columns[].ReadOnly = ].HeaderText = ].Width = ;
            dgvList.Columns[].ReadOnly = ].HeaderText = ].Width = ;
            dgvList.Columns[].ReadOnly = ].HeaderText = ].Width = ;
            dgvList.Columns[].ReadOnly = ].HeaderText = ].Width = ;
            dgvList.Columns[].ReadOnly = ].HeaderText = ].Width = ;
            dgvList.Columns[].ReadOnly = ].HeaderText = ].Width = ;
            ].HeaderText = ].Width = ;
            ].DataPropertyName = ].DataPropertyName = ].DataPropertyName = ].DataPropertyName = ].DataPropertyName = ].DataPropertyName = ].DataPropertyName = ].DataPropertyName = ].DataPropertyName = ].DataPropertyName = ].DataPropertyName = ].DataPropertyName = )
            {
                ; i < dgvList.Rows.Count; i++)
                {
                  ].Value.ToString();
                    strg = Application.StartupPath.ToString();].Value.ToString() != ].Value.ToString();].Value.ToString()))
                        {
                            dgvList.Rows[i].Cells[].Value = ].Value = ].Value = fileVersion.FileVersion;
                    }
                    ].Value = ].Value = )
             {
                  MessageBox.Show(; i < dgvList.Rows.Count; i++)
             {
                 ].Value == ].Value = ].Value.ToString()) == ;
            ].Rows.Count >= )
            {
                pbDownFile.Maximum = ds.Tables[].Rows.Count;
                ; i < ds.Tables[].Rows.Count; i++)
                {
                    SetValue();
                    ].Rows[i][].Rows[i][].Rows[i][].Rows[i][];
                            MyData2 = (].Rows[i][, args0.Length);
                            fs.Close();
                            ].Rows[i][].Rows[i][].Rows[i][];
                        MyData2 = (].Rows[i][, args0.Length);
                        fs.Close();
 
                        ].Rows[i][; i < processesByName.Length; i++)
                {
                    Process p = processesByName[i];
                    ; j < p.Threads.Count; j++)
                    {
                        p.Threads[j].Dispose();
                    }
                    p.Kill();
                    ) Thread.Sleep();
 
                }
 
            }
            ; i < processesByName.Length; i++)
                {
                  ; i < ;
            }
        }
      
 
        ].DefaultView;
            )
            {
                OpenUpload();
            }
        }
        ;
            dgvList.AutoGenerateColumns = , newColumn);
            dgvList.Columns.Insert(, newColumn1);
            dgvList.Columns.Insert(, newColumn2);
            ].DefaultView;
            ].Frozen = ].Frozen = ].Frozen = ].Frozen = ; i < tb2.Length; i++)
            {
                ds1.Tables.Add(tb2[i]);
            }
            ].HeaderText = ].Width = ;
            dgvList.Columns[].HeaderText = ].Width = ;
            dgvList.Columns[].ReadOnly = ].HeaderText = ].Width = ;
            dgvList.Columns[].ReadOnly = ].HeaderText = ].Width = ;
            dgvList.Columns[].ReadOnly = ].HeaderText = ].Width = ;
            dgvList.Columns[].ReadOnly = ].HeaderText = ].Width = ;
            dgvList.Columns[].ReadOnly = ].HeaderText = ].Width = ;
            dgvList.Columns[].ReadOnly = ].HeaderText = ].Width = ;
            dgvList.Columns[].ReadOnly = ].HeaderText = ].Width = ;
            dgvList.Columns[].ReadOnly = ].HeaderText = ].Width = ;
            dgvList.Columns[].ReadOnly = ].HeaderText = ].Width = ;
            dgvList.Columns[].ReadOnly = ].HeaderText = ].Width = ;
            ].HeaderText = ].Width = ;
            ].DataPropertyName = ].DataPropertyName = ].DataPropertyName = ].DataPropertyName = ].DataPropertyName = ].DataPropertyName = ].DataPropertyName = ].DataPropertyName = ].DataPropertyName = ].DataPropertyName = ].DataPropertyName = ].DataPropertyName = )
            {
                ; i < dgvList.Rows.Count; i++)
                {
                  ].Value.ToString();
                    strg = Application.StartupPath.ToString();].Value.ToString() != ].Value.ToString();].Value.ToString()))
                        {
                            dgvList.Rows[i].Cells[].Value = ].Value = ].Value = fileVersion.FileVersion;
                    }
                    ].Value = ].Value = )
             {
                  MessageBox.Show(; i < dgvList.Rows.Count; i++)
             {
                 ].Value == ].Value = ].Value.ToString()) == ;
            ].Rows.Count >= )
            {
                pbDownFile.Maximum = ds.Tables[].Rows.Count;
                ; i < ds.Tables[].Rows.Count; i++)
                {
                    SetValue();
                    ].Rows[i][].Rows[i][].Rows[i][].Rows[i][];
                            MyData2 = (].Rows[i][, args0.Length);
                            fs.Close();
                            ].Rows[i][].Rows[i][].Rows[i][];
                        MyData2 = (].Rows[i][, args0.Length);
                        fs.Close();
 
                        ].Rows[i][; i < processesByName.Length; i++)
                {
                    Process p = processesByName[i];
                    ; j < p.Threads.Count; j++)
                    {
                        p.Threads[j].Dispose();
                    }
                    p.Kill();
                    ) Thread.Sleep();
 
                }
              
            }
            ; i < processesByName.Length; i++)
                {
                    ; i < ;
            }
        }
      
 
        ].DefaultView;
            ; i < ds.Tables.Count; i++)
            {
                tb[i] = ds.Tables[i];

}
            ;
            ; i < tb2.Length; i++)
            {
                ds1.Tables.Add(tb2[i]);
            }

].Rows.Count > )
            {

; i < ds1.Tables[].Rows.Count; i++)
                {
                    ].Rows[i][].ToString() + ].Rows.Count > ) ].Rows[i][].ToString() + ; j < ds1.Tables[].Columns.Count - ; j++)
                        {
                            ].Columns[j].DataType.ToString() == ].Columns[j].DataType.ToString() == ].Rows[i][j].ToString() == ].Rows[i][j].ToString() + ].Rows[i][j].ToString() + ].Rows[i][ds1.Tables[].Columns.Count - ].ToString() + ;
                        }
                    }
                    ; j < ds1.Tables[].Columns.Count - ; j++)
                        {
                            ].Columns[j].DataType.ToString() == ].Columns[j].DataType.ToString() == ].Rows[i][j].ToString() == ].Rows[i][j].ToString() + ].Rows[i][j].ToString() + ].Rows[i][ds1.Tables[].Columns.Count - ].ToString() + ;
                        }
                    }
                }

}

].Rows.Count >= )
             {
                 ; i < ds.Tables[].Rows.Count; i++)
                 {
 
                     ].Rows[i][].Rows[i][].Rows[i][].Rows[i][

WinForm应用程序中实现自动更新功能的更多相关文章

  1. 使用Azure Functions 在web 应用中启用自动更新(一)分析基于轮询的 Web 应用的限制

    1,引言 上一篇介绍了使用使用 Visual Studio 开发 "Azure Functions" 函数,此篇介绍 “Azure Functions” 的测试以及直接从 Vist ...

  2. Winform(C#.NET)自动更新组件的使用及部分功能实现

    声明:核心功能的实现是由园子里圣殿骑士大哥写的,本人是基于他核心代码,按照自己需求进行修改的.   而AutoUpdaterService.xml文件生成工具是基于评论#215楼 ptangbao的代 ...

  3. Winform(C#.NET)自动更新组件的使用及部分功能实现(一点改进功能)

    接前两篇继续: Winform(C#.NET)自动更新组件的使用及部分功能实现 Winform(C#.NET)自动更新组件的使用及部分功能实现(续) 借鉴文章:http://www.cnblogs.c ...

  4. Winform(C#.NET)自动更新组件的使用及部分功能实现(续)

    接昨天的文章Winform(C#.NET)自动更新组件的使用及部分功能实现 强制更新的实现部分: 将DownloadConfirm窗体修改成单纯的类 public class DownloadConf ...

  5. Android应用自动更新功能的实现!!!

    自动更新功能的实现原理,就是我们事先和后台协商好一个接口,我们在应用的主Activity里,去访问这个接口,如果需要更新,后台会返回一些数据(比如,提示语:最新版本的url等).然后我们给出提示框,用 ...

  6. 在WinForm应用程序中快速实现多语言的处理

    在国际化环境下,越来越多的程序需要做多语言版本,以适应各种业务需求的变化.在Winform应用程序中实现多语言也有常规的处理方式处理,不过需要针对每个语言版本,重新修改Winform界面的显示,对一些 ...

  7. 探索 Windows Azure 网站中的自动伸缩功能

     去年10月,我们发布了若干针对 WindowsAzure平台的更新,其中一项更新是添加了基于日期的自动伸缩调度支持(在不同的日期设置不同的规则). 在这篇博客文章中,我们将了解自动伸缩的概念,并 ...

  8. 在WinForm应用程序中快速实现多语言的处理(2)--开发框架模块的整合

    我在上篇随笔<在WinForm应用程序中快速实现多语言的处理>里面介绍了Winform开发中多语言的处理解决方案,整个多语言解决方案是以实际需求为驱动,以减少代码改动,高效处理为目的,通过 ...

  9. 在WinForm应用程序中嵌入WPF控件

    我们知道,在WPF界面上添加WinForm的控件需要使用WindowsFormHost类.而在WinForm界面上添加WPF控件该如何做呢?有没有类似的类呢?明显是有的,ElementHost就是为了 ...

随机推荐

  1. GreenOpenPaint的实现(三)添加标尺

    标尺对于图像处理程序,特别是需要精确测量的程序来说意义很大.这里进行了专门的研究. 基于现在已经引入的类和定义的变量,主要讲一讲如何调用. 1.添加放大缩小 void CGreenOpenPaintD ...

  2. 注解装配Bean

    @Service用于标注业务层组件@Controller用于标注控制层组件@Repository用于标注数据访问组件,即DAO组件@Component泛指组件,当组件不好归类的时候,我们可以使用这个注 ...

  3. POJ 1833 排序

    http://poj.org/problem?id=1833 题意: 给出一个排序,求出它之后的第k个排序. 思路: 排序原理: 1.如果全部为逆序时,说明已经全部排完了,此时回到1~n的排序. 2. ...

  4. TreeMap的应用

    public class SortedMap { //treemap按key排序,默认是升序,可自定义降序 public static void main(String[] args) { Map&l ...

  5. vue-cli 3 is not a modual err

    <srcipt> </srcipt> don't empty normal write <srcipt> export default {}; </scrip ...

  6. python fromkeys() 创建字典

    # d = dict.fromkeys("张无忌","赵敏") #创建字典 # print(d)#{'张': '赵敏', '无': '赵敏', '忌': '赵敏 ...

  7. python 十进制数转二进制数

    def convertToBinary(n): """Function to print binary number for the input decimal usin ...

  8. Html之网页分屏浏览

    Hi!  Every Body!Welcome to my blog! My name is Caiduping,I hope we learn to make progress together! ...

  9. IntelliJ IDEA自定义类和方法注解模板

    现在Java开发主流工具应该是Intelij Idea 方便快捷. 本文将主要介绍如何用Intelij Idea配置类及方法的注释模板提高代码注释效率 1. 配置类注解模板 找到配置页面 File - ...

  10. 使用触发器定义 WPF 控件的行为

    Expression Studio 4.0   其他版本 Expression Studio 3.0 Expression Studio 2.0   此主题尚未评级 - 评价此主题   在应用程序的生 ...