EyesBaby功能实现之软件更新

因这部分代码比较难看,所以最后贴出来:)。自动更新部分纯属本人根据自己思路开发的。现在c/s自动更新网上有比较成熟的例子,可能我的这种做法不是很好(望大虾手下留情)。贴出来只是为了给大家提供一种参考和选择。

 

整个更新程序部分使用到了以下技术:

1.采用Access记录日志更新

2.采用XML记录当前版本配置信息

3.HttpWebRequest下载文件

4.GZipStream解压缩文件包

5.System.Diagnostics.Process操作进程

6.System.IO文件夹/文件复制

7.ProgressBar和BackgroundWorker显示整个更新版本进度

 

奉上CODE:

1.Access操作类:

代码
using  System;
using
 System.Collections.Generic;
using
 System.Text;
using
 System.Data.OleDb;

namespace
 LogHelper.BLL
{
    
/// <summary>

    
///  更新错误日志处理类
    
/// </summary>

    public class  Log
    {
        
private string
 _connStr;

        
public Log(string
 connStr)
        {
            _connStr 
=
 connStr;
        }

        
/// <summary>

        
///  添加一条日志
        
/// </summary>

        
/// <param name="title"></param>
        
/// <param name="content"></param>
        
/// <returns></returns>
        public bool  Add(LogHelper.Model.Log modLog)
        {
            
bool b = false
;
            
if (!string
.IsNullOrEmpty(_connStr))
            {
                OleDbConnection objConnection 
= new
 OleDbConnection(_connStr);
                
try

                {

                    objConnection.Open();
                    
string insertSql = "insert into LogInfo(Title,Content,CreateDate) values('" + modLog.Title + "','" + modLog.Content + "','" + modLog.CreateDate + "')" ;
                    OleDbCommand cmd 
= new
 OleDbCommand(insertSql,objConnection);
                    cmd.ExecuteNonQuery();
                    b
= true
;
                }
                
catch
 (Exception ex)
                { }
                
finally

                {
                    objConnection.Close();
                }

            }
            
return  b;
        }
    }
}

namespace
 LogHelper.Model
{
    
/// <summary>

    
///  UpdateErrorLog模型
    
/// </summary>

    public class  Log
    {
        
string
 _title;

        
public string
 Title
        {
            
get { return
 _title; }
            
set { _title =
 value; }
        }
        
string
 _content;

        
public string
 Content
        {
            
get { return
 _content; }
            
set { _content =
 value; }
        }
        
string
 _createDate;

        
public string
 CreateDate
        {
            
get { return
 _createDate; }
            
set { _createDate =
 value; }
        }

    }
}

 

 

2.XML当前版本配置操作类:

代码
using  System;
using
 System.Collections.Generic;
using
 System.Text;
using
 System.Windows.Forms;

namespace
 EyesBaby
{
    
/// <summary>

    
///  当前版本配置操作类
    
/// </summary>

    public class  CurrentVesionHelper
    {
        
private const string _configName = "CurrentInfo.config"
;

        
private const string _currentVesionKeyName = "currentVesion"
;

        
private const string _updateDateKeyName = "updateDate"
;

        
private const string _programNameKeyName = "programName"
;

        
private const string _installDirKeyName = "installDir"
;

        XMLHandle xml 
= null
;

        
private string
 _currentVesion;

        
private string
 _updateDate;

        
private string
 _installDir;

        
private string
 _programName;

        
/// <summary>

        
///  安装目录
        
/// </summary>

        public string  InstallDir
        {
            
get { return
 _installDir; }
            
set { _installDir =
 value; }
        }

        
/// <summary>

        
///  应用程序名称
        
/// </summary>

        public string  ProgramName
        {
            
get { return
 _programName; }
            
set { _programName =
 value; }
        }

        
/// <summary>

        
///  当前版本
        
/// </summary>

        public string  CurrentVesion
        {
            
get { return
 _currentVesion; }
            
set { _currentVesion =
 value; }
        }

        
/// <summary>

        
///  更新日期
        
/// </summary>

        public string  UpdateDate
        {
            
get { return
 _updateDate; }
            
set { _updateDate =
 value; }
        }

        
public
 CurrentVesionHelper()
        {
            
if (!string
.IsNullOrEmpty(_configName))
            {
                
string filepath = Application.StartupPath +"//"+
 _configName;
                xml 
= new
 XMLHandle();
                xml.Load(filepath);
                _currentVesion 
=
 xml.GetValueByID(_currentVesionKeyName);
                _updateDate 
=
 xml.GetValueByID(_updateDateKeyName);
                _installDir 
=
 xml.GetValueByID(_installDirKeyName);
                _programName 
=
 xml.GetValueByID(_programNameKeyName);
            }
        }

        
/// <summary>

        
///  更新保存
        
/// </summary>

        public void  UpdateVesion()
        {
            xml.SetValueByID(_currentVesionKeyName, _currentVesion);
            xml.SetValueByID(_updateDateKeyName, _updateDate);
            xml.SetValueByID(_installDirKeyName, _installDir);
            xml.SetValueByID(_programNameKeyName, _programName);
        }
    }
}

 

 

3.HttpWebRequest下载文件

代码
using  System;
using
 System.Collections.Generic;
using
 System.Text;
using
 System.Net;
using
 System.IO;

namespace
 EyesBaby
{
    
/// <summary>

    
///  文件下载类
    
/// </summary>

    public class  DownloadClass
    {
        
public string StrUrl;//文件下载网址

        public string StrFileName;//下载文件保存地址 
        public string strError;//返回结果
        public long lStartPos = 0//返回上次下载字节
        public long lCurrentPos = 0;//返回当前下载字节
        public long lDownloadFile;//返回当前下载文件长度

        
public void  DownloadFile()
        {
            System.IO.FileStream fs;
            
if
 (System.IO.File.Exists(StrFileName))
            {
                fs 
=
 System.IO.File.OpenWrite(StrFileName);
                lStartPos 
=
 fs.Length;
                fs.Seek(lStartPos, System.IO.SeekOrigin.Current);
                
//移动文件流中的当前指针 

            }
            
else

            {
                fs 
= new  System.IO.FileStream(StrFileName, System.IO.FileMode.Create);
                lStartPos 
= 0
;
            }

            
//打开网络连接 

            try
            {
                System.Net.HttpWebRequest request 
=  (System.Net.HttpWebRequest)System.Net.HttpWebRequest.Create(StrUrl);
                
long length =
 request.GetResponse().ContentLength;
                lDownloadFile 
=
 length;
                
if (lStartPos > 0
)
                    request.AddRange((
int)lStartPos); //
设置Range值

                
//向服务器请求,获得服务器回应数据流 

                System.IO.Stream ns =  request.GetResponse().GetResponseStream();

                
byte[] nbytes = new byte[512
];
                
int nReadSize = 0
;
                nReadSize 
= ns.Read(nbytes, 0512
);
                
while (nReadSize > 0
)
                {
                    fs.Write(nbytes, 
0
, nReadSize);
                    nReadSize 
= ns.Read(nbytes, 0512
);
                    lCurrentPos 
=
 fs.Length;
                }

                fs.Close();
                ns.Close();
                strError 
= "下载完成"
;

            }
            
catch
 (Exception ex)
            {
                fs.Close();
                strError 
= "下载过程中出现错误:" +
 ex.ToString();
            }

        }
    } 

}

 

 

4.GZipStream解压缩文件包

代码
using  System;
using
 System.Collections.Generic;
using
 System.Text;
using
 System.IO;
using
 System.IO.Compression;
using
 System.Windows.Forms;
using
 ICSharpCode.SharpZipLib.Zip;

namespace
 EyesBaby
{

    
public class
 clsZip
    {
        
public void CompressFile(string sourceFile, string
 destinationFile)
        {
            
// make sure the source file is there

            if (File.Exists(sourceFile) == false )
                
throw new
 FileNotFoundException();

            
// Create the streams and byte arrays needed

            byte[] buffer = null ;
            FileStream sourceStream 
= null
;
            FileStream destinationStream 
= null
;
            GZipStream compressedStream 
= null
;

            
try

            {
                
// Read the bytes from the source file into a byte array
                sourceStream = new  FileStream(sourceFile, FileMode.Open, FileAccess.Read, FileShare.Read);

                
// Read the source stream values into the buffer

                buffer = new byte [sourceStream.Length];
                
int checkCounter = sourceStream.Read(buffer, 0
, buffer.Length);

                
if (checkCounter !=
 buffer.Length)
                {
                    
throw new
 ApplicationException();
                }

                
// Open the FileStream to write to

                destinationStream = new  FileStream(destinationFile, FileMode.OpenOrCreate, FileAccess.Write);

                
// Create a compression stream pointing to the destiantion stream

                compressedStream = new GZipStream(destinationStream, CompressionMode.Compress, true );

                
// Now write the compressed data to the destination file

                compressedStream.Write(buffer, 0 , buffer.Length);
            }
            
catch
 (ApplicationException ex)
            {
                MessageBox.Show(ex.Message, 
"压缩文件时发生错误:"
, MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            
finally

            {
                
// Make sure we allways close all streams
                if (sourceStream != null )
                    sourceStream.Close();

                
if (compressedStream != null
)
                    compressedStream.Close();

                
if (destinationStream != null
)
                    destinationStream.Close();
            }
        }

        
public void DecompressFile(string sourceFile, string
 destinationFile)
        {
            
// make sure the source file is there

            if (File.Exists(sourceFile) == false )
                
throw new
 FileNotFoundException();

            
// Create the streams and byte arrays needed

            FileStream sourceStream = null ;
            FileStream destinationStream 
= null
;
            GZipStream decompressedStream 
= null
;
            
byte[] quartetBuffer = null
;

            
try

            {
                
// Read in the compressed source stream
                sourceStream = new  FileStream(sourceFile, FileMode.Open);

                
// Create a compression stream pointing to the destiantion stream

                decompressedStream = new GZipStream(sourceStream, CompressionMode.Decompress, true );

                
// Read the footer to determine the length of the destiantion file

                quartetBuffer = new byte[4 ];
                
int position = (int)sourceStream.Length - 4
;
                sourceStream.Position 
=
 position;
                sourceStream.Read(quartetBuffer, 
04
);
                sourceStream.Position 
= 0
;
                
int checkLength = BitConverter.ToInt32(quartetBuffer, 0
);

                
byte[] buffer = new byte[checkLength + 100
];

                
int offset = 0
;
                
int total = 0
;

                
// Read the compressed data into the buffer

                while (true )
                {
                    
int bytesRead = decompressedStream.Read(buffer, offset, 100
);

                    
if (bytesRead == 0
)
                        
break
;

                    offset 
+=
 bytesRead;
                    total 
+=
 bytesRead;
                }

                
// Now write everything to the destination file

                destinationStream = new  FileStream(destinationFile, FileMode.Create);
                destinationStream.Write(buffer, 
0
, total);

                
// and flush everyhting to clean out the buffer

                destinationStream.Flush();
            }
            
catch
 (ApplicationException ex)
            {
                MessageBox.Show(ex.Message, 
"解压文件时发生错误:"
, MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            
finally

            {
                
// Make sure we allways close all streams
                if (sourceStream != null )
                    sourceStream.Close();

                
if (decompressedStream != null
)
                    decompressedStream.Close();

                
if (destinationStream != null
)
                    destinationStream.Close();
            }

        }

        
/// <summary>

        
///  功能:解压zip格式的文件。
        
/// </summary>

        
/// <param name="zipFilePath">压缩文件路径</param>
        
/// <param name="unZipDir">解压文件存放路径,为空时默认与压缩文件同一级目录下,跟压缩文件同名的文件夹</param>
        
/// <param name="err">出错信息</param>
        
/// <returns>解压是否成功</returns>
        public bool UnZipFile(string zipFilePath, string unZipDir, out string  err)
        {
            err 
= ""
;
            
if (zipFilePath == string
.Empty)
            {
                err 
= "压缩文件不能为空!"
;
                
return false
;
            }
            
if (!
File.Exists(zipFilePath))
            {
                err 
= "压缩文件不存在!"
;
                
return false
;
            }
            
//解压文件夹为空时默认与压缩文件同一级目录下,跟压缩文件同名的文件夹

            if (unZipDir == string .Empty)
                unZipDir 
=
 zipFilePath.Replace(Path.GetFileName(zipFilePath), Path.GetFileNameWithoutExtension(zipFilePath));
            
if (!unZipDir.EndsWith("//"
))
                unZipDir 
+= "//"
;
            
if (!
Directory.Exists(unZipDir))
                Directory.CreateDirectory(unZipDir);

            
try

            {
                
using (ZipInputStream s = new  ZipInputStream(File.OpenRead(zipFilePath)))
                {

                    ZipEntry theEntry;
                    
while ((theEntry = s.GetNextEntry()) != null
)
                    {
                        
string directoryName =
 Path.GetDirectoryName(theEntry.Name);
                        
string fileName =
 Path.GetFileName(theEntry.Name);
                        
if (directoryName.Length > 0
)
                        {
                            Directory.CreateDirectory(unZipDir 
+
 directoryName);
                        }
                        
if (!directoryName.EndsWith("//"
))
                            directoryName 
+= "//"
;
                        
if (fileName !=
 String.Empty)
                        {
                            
using (FileStream streamWriter = File.Create(unZipDir +
 theEntry.Name))
                            {

                                
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 ;
                                    }
                                }
                            }
                        }
                    }
//while

                }
            }
            
catch
 (Exception ex)
            {
                err 
=
 ex.Message;
                
return false
;
            }
            
return true
;
        }
//


    }


}

 

 

5.System.Diagnostics.Process操作进程

 

                 // 关闭程序
                    System.Diagnostics.Process[] ps =  System.Diagnostics.Process.GetProcessesByName(programName);
                    
foreach (System.Diagnostics.Process p in
 ps)
                    {
                        p.Kill();
                    }
           // 重启程序

                    System.Diagnostics.Process.Start(startpath);

 

  

6.System.IO文件夹/文件复制

 

代码
using  System;
using
 System.Collections.Generic;
using
 System.Text;
using
 System.IO;

namespace
 EyesBaby
{
    
public class
 CopyFolder
    { 
          
private   static   int   total   =   0
;  
          
private   int   FileNumber   =   0;     //文件夹文件总数  

   
          
///   <summary>
  
          
///
   复制文件夹  
          
///   </summary>
  
          
///   <param   name="sourceDirName">源文件夹</param>
  
          
///   <param   name="destDirName">目标文件夹</param>  

          //复制文件夹  
        public void CopyDirectory(string sourceDirName, string  destDirName)
        {
            
if (!
Directory.Exists(destDirName))
            {
                Directory.CreateDirectory(destDirName);
                File.SetAttributes(destDirName, File.GetAttributes(sourceDirName));
                
//File.SetAttributes(destDirName,FileAttributes.Normal);  

            }

            
if (destDirName[destDirName.Length - 1!=
 Path.DirectorySeparatorChar)
                destDirName 
= destDirName +
 Path.DirectorySeparatorChar;

            
string[] files =
 Directory.GetFiles(sourceDirName);
            
foreach (string file in
 files)
            {
                File.Copy(file, destDirName 
+ Path.GetFileName(file), true
);
                File.SetAttributes(destDirName 
+
 Path.GetFileName(file), FileAttributes.Normal);
                total
++
;
            }
            
string[] dirs =
 Directory.GetDirectories(sourceDirName);
            
foreach (string dir in
 dirs)
            {
                CopyDirectory(dir, destDirName 
+
 Path.GetFileName(dir));
            }
        }
     
        
public   static   int
   GetFilesCount(System.IO.DirectoryInfo   dirInfo)    
        {
              
int   totalFile   =   0
;    
              totalFile   
+=
   dirInfo.GetFiles().Length;    
              
foreach   (System.IO.DirectoryInfo   subdir   in
   dirInfo.GetDirectories())    
              {    
                  totalFile   
+=
   GetFilesCount(subdir);    
              }    
              
return
   totalFile;    
        }
    }
}

 

 

7.ProgressBar和BackgroundWorker显示整个更新版本进度

 

代码
        // 启动执行
        bkgWorker.RunWorkerAsync();


        
/// <summary>

        
///  设置加载时间值
        
/// </summary>

        
/// <param name="text"></param>
        
/// <param name="value"></param>
        private void SetValue(string text, int  value)
        {
            
// 更新进度

            for (int i = 1; i <= value; i++ )
            {
                bkgWorker.ReportProgress(
1
, text);
                System.Threading.Thread.Sleep(
10
);
            }
        }

        
/// <summary>

        
///  执行工作
        
/// </summary>

        
/// <param name="sender"></param>
        
/// <param name="e"></param>
        private void backgroundWorker1_DoWork(object  sender, DoWorkEventArgs e)
        {
            
// 调用更新

            CallUpdate();
        }

        
/// <summary>

        
///  操作进程
         
/// </summary>

        
/// <param name="sender"></param>
        
/// <param name="e"></param>
        private void backgroundWorker1_ProgressChanged(object  sender, ProgressChangedEventArgs e)
        {
            lblMsg.Text 
=
 e.UserState.ToString();
            prgUpdate.Value 
+=
 e.ProgressPercentage;
        }

        
/// <summary>

        
///  调用更新
         
/// </summary>

        private void  CallUpdate()
        {
            LogHelper.Model.Log modLog 
= new
 LogHelper.Model.Log();

            
// 判断是否有新版本

             AutoUpdate autoUpdate = new  AutoUpdate();
            CurrentVesionHelper currentVesion 
= new
 CurrentVesionHelper();

            
string updatexmlpath = System.Configuration.ConfigurationSettings.AppSettings["updateXmlPath"
];
            UpdateXmlHelper updateXml 
= new
 UpdateXmlHelper(updatexmlpath);
            
string oldVesion =
 currentVesion.CurrentVesion;
            
string newVesion =
 updateXml.Vesion;
            
string newDownURL =
 updateXml.DownURL;
            
bool b =
 autoUpdate.IsNewVesion(newVesion, oldVesion);
            
            
if
 (b)
            {
                
                
string filename = newDownURL.Substring(newDownURL.LastIndexOf('/'+ 1
);
                
string savePath = Application.StartupPath + "/update/" +
 filename;
                SetValue(
"正在下载新版本……"10
);
                
if
 (autoUpdate.DownNewEdition(newDownURL, savePath))
                {
                    
string installDir = currentVesion.InstallDir =
 Application.StartupPath;
                    
string programName =
 currentVesion.ProgramName;
                   
                    
string error = string
.Empty;
                    
string zipfilepath =
 savePath;
                    
string unzipdir = Application.StartupPath + "//update//" + DateTime.Now.ToString("yyyy-MM-dd"+ "//"
;
                    SetValue(
"正在解压文件包……"20
);
                    
// 解压文件包

                      clsZip zip = new  clsZip();
                    zip.UnZipFile(zipfilepath, unzipdir, 
out
 error);
                    SetValue(
"正在关闭程序……"10
);
                    
// 关闭程序

                      System.Diagnostics.Process[] ps =  System.Diagnostics.Process.GetProcessesByName(programName);
                    
foreach (System.Diagnostics.Process p in
 ps)
                    {
                        p.Kill();
                    }
                    SetValue(
"正在覆盖原安装程序……"20
);
                    
#region 覆盖原安装程序

                       
// 休息1秒
                       System.Threading.Thread.Sleep(1000 );
                    
string installPath = installDir + "//" +
 programName;
                    
//
if (System.IO.Directory.Exists(installPath))
                    
//
{
                    
//    //
 先删除原安装路径
                       
//
    System.IO.DirectoryInfo dir = new System.IO.DirectoryInfo(installPath);
                    
//
     dir.Delete(true);
                    
//    //
System.IO.Directory.Delete(installPath, true);
                    
//}

                    //// 休息3秒
                       // System.Threading.Thread.Sleep(5000);
                    
// 再将新版本复制到原安装目录

                       CopyFolder copy = new  CopyFolder();
                    copy.CopyDirectory(unzipdir, installDir);
                    
//System.IO.Directory.Move(unzipdir, installDir);


                    
#endregion
                    
string exepath = "EyesBaby.exe" ;
                    
// 休息3秒

                       System.Threading.Thread.Sleep(3000 );
                    
string startpath = installPath + "//" +
 exepath;
                    SetValue(
"记录新版本……"20
);

                    
// 记录新版本到CurrentInfo.config

                    currentVesion.CurrentVesion =  newVesion;
                    currentVesion.UpdateDate 
=
 DateTime.Now.ToShortDateString();
                    currentVesion.UpdateVesion();

                    modLog.Content 
= "更新成功--新版本号:" +
 newVesion;
                    
//MessageBox.Show("更新成功!");

                    SetValue("重启程序……"20 );
                    
// 重启程序

                      System.Diagnostics.Process.Start(startpath);

                }
                
else

                {
                    modLog.Content 
= "下载最新版本失败" ;
                    MessageBox.Show(
"下载最新版本失败!"
);
                }
            }
            
else

                modLog.Content 
= "没有发现新版本" ;
            modLog.Title 
= "调用更新服务"
;
            modLog.CreateDate 
= DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss"
);
            bllLog.Add(modLog);
        }

 

 

部分代码也是从网上东拼西凑找出来的,现已丢失源文路径。深感抱歉!

 

 

 下载地址:http://eyesbaby.codeplex.com/

我的第一款实用工具-眼保程序(EyesBaby)

EyesBaby1.0使用帮助文档

EyesBaby功能实现之窗口拖拽与缩放功能

EyesBaby功能实现之图片控件上添加字符 

EyesBaby功能实现之Windows前景色调节器

EyesBaby功能实现之软件更新

 

 欢迎加入EyesBaby再次开发小组

 EyesBaby需求反馈小组

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值