请教自动升级功能如何实现,十分感谢。

xymsgw 2005-09-13 05:17:35
C/S模式,服务器和客户端都在LAN的,用VB.NET做的WinForm软件,为了更新软件方便,想加个自动升级功能。

思路如下:

事先将最新版的exe文件放在服务器的一个指定目录,用于客户端读取并复制到本地覆盖原旧的exe文件。从而实现软件升级的作用。

问题:

1.客户端如何访问服务器那个指定的目录,如何实现自动将最新的exe文件复制并保存到客户端本地。

听朋友说用Socket可实现,但不知如何应用它,望大哥大姐指点小弟一二。十分感谢。
...全文
444 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
SeeSunSet 2005-09-16
  • 打赏
  • 举报
回复
我这里有现成的.100块卖给你了..呵呵.
greenery 2005-09-16
  • 打赏
  • 举报
回复
核心代码在RUN函数中,ProcessorThread是我们的线程处理类。
我们的处理方法是在更新程序(窗口)启动后,就启动这个线程执行更新。
在该线程执行完毕后,启动指定的进程

public void OnDisposeFinish(object sender, System.EventArgs e)
{
try
{
this.Cursor = Cursors.Default;

labMessage.Text = "更新完成";
bool bRun = true;
if (!m_UpdateThread.LastError)
{
DialogResult dr = MessageBox.Show("更新期间出现错误,是否继续?\r\n详细信息:\r\n" + m_UpdateThread.LastError.Message, "更新错误",
MessageBoxButtons.YesNo, MessageBoxIcon.Warning);
if (dr == DialogResult.No)
{
bRun = false;
}
}

//m_UpdateThread.Dispose();
m_UpdateThread = null;

if (bRun)
{
labMessage.Text = "正在启动主程序";

string sLocalPath = ConfigurationSettings.AppSettings["LocalPath"];
string sFileName = ConfigurationSettings.AppSettings["ExecuteFile"];

// 启动TMS程序
Process tmsProcess = new Process();
tmsProcess.StartInfo.FileName = sFileName;
tmsProcess.StartInfo.WorkingDirectory = sLocalPath;
tmsProcess.StartInfo.WindowStyle = ProcessWindowStyle.Normal;

// 启动进程
tmsProcess.Start();
}
}
catch (Exception ex)
{
CLogInfo.Log(ex);
MessageBox.Show(ex.Message, "更新错误",
MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
Close();
}

相关配置文件:app.config
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="ServerPath" value="E:\yehaoen\angsen\TMS\Program\TMS\MainWindow\bin\Debug" />
<add key="LocalPath" value="d:\tms\mainprogram" />
<add key="ExecuteFile" value="d:\tms\mainprogram\MainWindow.exe" />
</appSettings>
</configuration>

注:这份代码有些调用基类的事件处理函数,请各位自己注释掉。如有更好(更简单)的处理方法,或解决该版本不能删除文件的问题的,希望大家可以讨论。
greenery 2005-09-16
  • 打赏
  • 举报
回复
这是我们的自动更新程序的处理代码,供大家参考。
如果发现有什么BUG,请在CSDN留言通知一下。
using System;
using System.Collections;
using System.Threading;
using System.IO;
using System.Configuration;
using System.Diagnostics;

using Components.General;

namespace AutoUpdate
{
/// <summary>
/// UpdateThread 的摘要说明。
/// </summary>
/// <author>Greenery</author>
/// <date>2005-08-06</date>
/// <version>1.0.0.3</version>
/// <summary>
/// Log编号:1
/// 更新复制子目录时,目标路径因为缺少'\'导致目录不正确的问题。
/// </summary>
/// <summary>
/// Log编号:2
/// 更新算法
/// 为了更准确的显示更新进度和提高更新速度,不复制一样的文件,所以更新算法
/// 算法说明:
/// 先使用 PreProcessDircrtory() 函数将需要处理的文件列表,文件总大小
/// 然后使用 for 循环逐个处理每个文件对,
/// 如果目标文件不存在或
/// 比较源文件与目标文件的大小和最后修改时间 LastWriteTime 大于1秒,
/// 将更新改文件
/// 存在问题:
/// 现在仍然不能解决服务器如果删除了文件,客户端不会将服务器删除的文件同步删除
/// </summary>
public class UpdateThread : ProcessorThread
{
/// <summary>
/// 服务器元文件列表,存放 FileInfo 对象
/// </summary>
private ArrayList m_SourceFiles = new ArrayList();

/// <summary>
/// 目标文件名,存放 FileInfo 对象
/// </summary>
private ArrayList m_DestFiles = new ArrayList();

/// <summary>
/// 总文件大小
/// </summary>
private long m_lTotalFileSize = 0;

public UpdateThread()
{
}
public UpdateThread(string sName)
: base(sName)
{
}

public override void Run()
{
try
{

string sServerPath = ConfigurationSettings.AppSettings["ServerPath"];
string sLocalPath = ConfigurationSettings.AppSettings["LocalPath"];

if (sServerPath == null)
{
sServerPath = ".";
}

if (sLocalPath == null)
{
sLocalPath = @"d:\tms\MainProgram";
}

// 准备要算处理的文件
// 发出开始消息
setMessageEvent("准备更新文件");

PreProcessDircrtory(sServerPath, sLocalPath);
Debug.Assert(m_SourceFiles.Count == m_DestFiles.Count);


if (m_SourceFiles.Count == 0)
{
m_LastError = new ExecuteResult(false, -1, "无法连接到服务器,请检查网络连接");
}
else
{

// 开始处理
setStartDisposeEvent(m_lTotalFileSize);


long lPlan = 0;

// 比较文件时间差的变量
TimeSpan timeSpan;

// 是否需要复制该文件
bool bCopyFile;

// 源文件对象
FileInfo sourceFile;

// 目标文件对象
FileInfo destFile;

// 目标目录对象
DirectoryInfo dir;

// 目标目录对象的缓存
Hashtable dirCache = new Hashtable();

for(int i = 0; i < m_SourceFiles.Count; i++)
{
//System.Threading.Thread.Sleep(100);

sourceFile = (FileInfo)m_SourceFiles[i];
destFile = (FileInfo)m_DestFiles[i];

// 检查目标文件是否存在
if (destFile.Exists)
{
// 检查文件是否较新
timeSpan = sourceFile.LastWriteTime - destFile.LastWriteTime;
bCopyFile = (destFile.Length != sourceFile.Length) ||
(timeSpan.Duration().TotalSeconds > 1);

// 检查只读属性
if ((destFile.Attributes & FileAttributes.ReadOnly) > 0)
{
// 去除只读属性
Debug.WriteLine(".. remove file attributes ReadOnly: " + destFile.FullName);
destFile.Attributes &= ~FileAttributes.ReadOnly;
}
}
else
{
// 文件不存在,需要复制
bCopyFile = true;
}

// 需要更新
if (bCopyFile)
{
// 复制文件
Debug.WriteLine("Copy file : " + sourceFile.FullName);
Debug.WriteLine(" to: " + destFile.FullName);

// 从缓冲器中获取目录对象,如果已经在缓冲器的目录,那么就已经存在
if (!dirCache.Contains(destFile.DirectoryName))
{
// 检查目录是否存在
dir = new DirectoryInfo(destFile.DirectoryName);
if (!dir.Exists)
{
// 创建目录
Debug.WriteLine("Create directory : " + dir.FullName);
dir.Create();
}
Debug.WriteLine(".. add directory to hash table: " + dir.FullName);
dirCache.Add(destFile.DirectoryName, dir);
}
sourceFile.CopyTo(destFile.FullName, true);
}
else
{
Debug.WriteLine("-- jump Copy file : " + sourceFile.FullName);
}

lPlan += sourceFile.Length;

// 更新进度
setDisposeEvent(lPlan);
}
m_LastError = new ExecuteResult(true);
}
}
catch (Exception ex)
{
m_LastError = new ExecuteResult(ex);
CLogInfo.Log(ex);
}
finally
{
setDisposeFinishEvent();
GC.Collect();
}
}

private void PreProcessDircrtory(string sourPath, string destPath)
{
DirectoryInfo dSource = new DirectoryInfo(sourPath);
DirectoryInfo dDestPath = new DirectoryInfo(destPath);

if (!dSource.Exists)
{
// m_LastError.Message = "无法连接到服务器,请检查网络连接";
return;
}

foreach (FileInfo file in dSource.GetFiles())
{
// 记录总处理文件大小
m_lTotalFileSize += file.Length;

// 记录源文件
m_SourceFiles.Add(file);

// 记录目标文件
m_DestFiles.Add(new FileInfo(Path.Combine(destPath,file.Name)));
}

foreach (DirectoryInfo dir in dSource.GetDirectories())
{
PreProcessDircrtory(dir.FullName, Path.Combine(destPath, dir.Name));
}
}
}
}
xymsgw 2005-09-15
  • 打赏
  • 举报
回复
现余下一点问题,如何把服务器最新的exe文件整到客户端机子中,我不知用vb.net中哪个命令或函数。请指教。
3tzjq 2005-09-14
  • 打赏
  • 举报
回复
http://community.csdn.net/Expert/topic/4252/4252819.xml?temp=8.614749E-02
pupo 2005-09-14
  • 打赏
  • 举报
回复
用web service或者remoting来提供版本检测服务就可以了
ranzige 2005-09-14
  • 打赏
  • 举报
回复
自动更新程序(vb.net,winform结合web服务),包含源代码。

http://blog.csdn.net/Qqwwee_Com/archive/2005/09/05/471968.aspx

===============================
CSDN小助手 是一款脱离浏览器也可以使用csdn论坛的
软件!
界面: http://qqwwee.com/
下载: http://qqwwee.com/csdn.rar 包含源代码
yuetoby 2005-09-13
  • 打赏
  • 举报
回复
注意比较的时候不要比较文件创建时间,否则会无限更新的
如果选用复制文件的方法 可以直接问我 MSN:yuetoby@hotmail.com
wisecloud 2005-09-13
  • 打赏
  • 举报
回复
使用微软的 Updater Application Block可以很专业得解决这个问题!
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnpag2/html/updaterv2.asp
wtk13 2005-09-13
  • 打赏
  • 举报
回复
把文件用WEB发布,把远程文件和本地文件时间进行对比,然后下载。
家鸣 2005-09-13
  • 打赏
  • 举报
回复
建议使用webservice实现..这样不需要了解太多的网络细节,容易穿透防火墙.
xymsgw 2005-09-13
  • 打赏
  • 举报
回复
原理我也明白,就是不知如何用vb.net来实现。用什么方法,函数等。还望哪位耐心的朋友写点指导性的代码,十分感谢楼上回贴的朋友。
xymsgw 2005-09-13
  • 打赏
  • 举报
回复
to greenery:我要的就是您的那种哟,我就是不知如何通过比较服务器中的文件,能发一下原代码学习一下吗,小弟感激不尽哟。
yuetoby 2005-09-13
  • 打赏
  • 举报
回复
自动更新一般用的是IIS,如果在局域网环境可以使用INI文件来控制版本。
在服务器端安装新版本程序,在客户端程序运行时先比较本地和服务器的INI文件
如果版本不相同,用File和Directory类扫描程序目录(递归)
将每一个文件都复制到客户端来。
greenery 2005-09-13
  • 打赏
  • 举报
回复
haha,我们系统的自动更新方法比较简单。
使用环境:局域网,win2000,C/S系统
客户端通过的自动更新程序通过比较服务器的\\server\mySoftware文件(递归处理子目录), 将新的复制过来,哈哈。使用File类的操作, 整个更新比较简单,但只能用于局域网的更新。
水如烟 2005-09-13
  • 打赏
  • 举报
回复
你到微软的网站看看,那里有篇文章作了介绍.网址现在我不便查.如果你查不到,晚上我再给.

16,554

社区成员

发帖
与我相关
我的任务
社区描述
VB技术相关讨论,主要为经典vb,即VB6.0
社区管理员
  • VB.NET
  • 水哥阿乐
  • 无·法
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧