自动更新程序版本DLL问题讨论.如何做到多客户端(100以上)自动更新.利用IE功能下载CAB包.使其更新CAB包功能?

dzq138 2005-04-21 11:16:30
局域网内的应用程序,业务应用都已经写成DLL,但有时需要更新一下DLL版本。
因为程序的客户端很多,一台一台的去更新肯定很费时费力.

设想用一个固定的EXE运行文件下载DLL,再运行业务DLL,SHOW窗体.完成自动更新程序功能.
也就是说,程序只需安装一个空壳EXE,只是负责更新版本与打开第一个窗口.

程序是由多个DLL与一个启动程序组成.
做一个启动客户端.负责更新CAB包中的DLL.

上面的是功能设想要求,
要问的是要解决问题:
一、除了用IE下载DLL之外是否有更好的办法?
二、用IE下载CAB包更新存的如下几个问题需解决:
1)如何自动降低IE的安全级别?当然要先保存原来的安全级别设置,下载完成后,恢复原安全安全级别设置。(见别人写了一下DLL可以达到此目的,但自己想写一下,不知是不是写注册表内容实现的。http://www.hdfdc.gov.cn/download/IESM.dll,里面有一类为IESMLib.Holder 方法有三个为:OpenDoor()降低安全级别 Restore() 恢复安全级别设置 Save())
2)版本比较?如原DLL的版本为1.0.0.1现在的新版本为1.0.0.2是新的才执行更新,否则执行原版本的DLL。()
3)当然要建立一个IIS的HTML文件内容如下:
-----------------------------
<OBJECT ID="clsUserProfile"
CLASSID="CLSID:7286826D-B9A9-4A37-BC6D-1E7EEC76BB92"
CODEBASE="UPDATE.CAB#version=1,0,0,1">
</OBJECT>
-----------------------------
如何调用IE去下载此HTML页?用Microsoft Internet Controls部件?



写得较乱,望给点耐性看完。
欢迎各位兄台解答一下以上问题。或给点更好的自动更新版本主意,
先在此先多谢各位.
...全文
443 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
conan19771130 2005-04-22
  • 打赏
  • 举报
回复
好东西,收藏
dzq138 2005-04-21
  • 打赏
  • 举报
回复

/// <summary>
/// Creates a new temporary folder under the system temp folder
/// and returns its full pathname.
/// </summary>
/// <returns>The full temp path string.</returns>
public static string CreateTemporaryFolder()
{
return Path.Combine( Path.GetTempPath(), Path.GetFileNameWithoutExtension( Path.GetTempFileName() ) );
}

/// <summary>
/// Copies files from the source to destination directories. Directory.Move is not
/// suitable here because the downloader may still have the temporary
/// directory locked.
/// </summary>
/// <param name="sourcePath">The source path.</param>
/// <param name="destinationPath">The destination path.</param>
public static void CopyDirectory( string sourcePath, string destinationPath )
{
CopyDirectory( sourcePath, destinationPath, true );
}

/// <summary>
/// Copies files from the source to destination directories. Directory.Move is not
/// suitable here because the downloader may still have the temporary
/// directory locked.
/// </summary>
/// <param name="sourcePath">The source path.</param>
/// <param name="destinationPath">The destination path.</param>
/// <param name="overwrite">Indicates whether the destination files should be overwritten.</param>
public static void CopyDirectory( string sourcePath, string destinationPath, bool overwrite )
{
CopyDirRecurse( sourcePath, destinationPath, destinationPath, overwrite );
}

/// <summary>
/// Move a file from a folder to a new one.
/// </summary>
/// <param name="existingFileName">The original file name.</param>
/// <param name="newFileName">The new file name.</param>
/// <param name="flags">Flags about how to move the files.</param>
/// <returns>indicates whether the file was moved.</returns>
public static bool MoveFile( string existingFileName, string newFileName, MoveFileFlag flags)
{
return MoveFileEx( existingFileName, newFileName, (int)flags );
}

/// <summary>
/// Deletes a folder. If the folder cannot be deleted at the time this method is called,
/// the deletion operation is delayed until the next system boot.
/// </summary>
/// <param name="folderPath">The directory to be removed</param>
public static void DestroyFolder( string folderPath )
{
try
{
if ( Directory.Exists( folderPath) )
{
Directory.Delete( folderPath, true );
}
}
catch( Exception )
{
// If we couldn't remove the files, postpone it to the next system reboot
if ( Directory.Exists( folderPath) )
{
FileUtility.MoveFile(
folderPath,
null,
MoveFileFlag.DelayUntilReboot );
}
}
}

/// <summary>
/// Deletes a file. If the file cannot be deleted at the time this method is called,
/// the deletion operation is delayed until the next system boot.
/// </summary>
/// <param name="filePath">The file to be removed</param>
public static void DestroyFile( string filePath )
{
try
{
if ( File.Exists( filePath ) )
{
File.Delete( filePath );
}
}
catch
{
if ( File.Exists( filePath ) )
{
FileUtility.MoveFile(
filePath,
null,
MoveFileFlag.DelayUntilReboot );
}
}
}


/// <summary>
/// Returns the path to the newer version of the .NET Framework installed on the system.
/// </summary>
/// <returns>A string containig the full path to the newer .Net Framework location</returns>
public static string GetLatestDotNetFrameworkPath()
{
Version latestVersion = null;
string fwkPath = Path.GetFullPath( Path.Combine( Environment.SystemDirectory, @"..\Microsoft.NET\Framework" ) );
foreach(string path in Directory.GetDirectories( fwkPath, "v*" ) )
{
string candidateVersion = Path.GetFileName( path ).TrimStart( 'v' );
try
{
Version curVersion = new Version( candidateVersion );
if ( latestVersion == null || ( latestVersion != null && latestVersion < curVersion ) )
{
latestVersion = curVersion;
}
}
catch {}
}

return Path.Combine( fwkPath, "v" + latestVersion.ToString() );
}
dzq138 2005-04-21
  • 打赏
  • 举报
回复
//============================================================================================================
// Microsoft Updater Application Block for .NET
// http://msdn.microsoft.com/library/en-us/dnbda/html/updater.asp
//
// FileUtility.cs
//
// Contains the implementation of the FileUtility helper class.
//
// For more information see the Updater Application Block Implementation Overview.
//
//============================================================================================================
// Copyright ?Microsoft Corporation. All rights reserved.
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY
// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT
// LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
// FITNESS FOR A PARTICULAR PURPOSE.
//============================================================================================================

using System;
using System.IO;
using System.Runtime.InteropServices;

namespace Microsoft.ApplicationBlocks.Updater.Utilities
{
/// <summary>
/// Indicates how to proceed with the move file operation.
/// </summary>
[Flags]
public enum MoveFileFlag : int
{
/// <summary>
/// Perform a default move funtion.
/// </summary>
None = 0x00000000,
/// <summary>
/// If the target file exists, the move function will replace it.
/// </summary>
ReplaceExisting = 0x00000001,
/// <summary>
/// If the file is to be moved to a different volume,
/// the function simulates the move by using the CopyFile and DeleteFile functions.
/// </summary>
CopyAllowed = 0x00000002,
/// <summary>
/// The system does not move the file until the operating system is restarted.
/// The system moves the file immediately after AUTOCHK is executed, but before
/// creating any paging files. Consequently, this parameter enables the function
/// to delete paging files from previous startups.
/// </summary>
DelayUntilReboot = 0x00000004,
/// <summary>
/// The function does not return until the file has actually been moved on the disk.
/// </summary>
WriteThrough = 0x00000008,
/// <summary>
/// Reserved for future use.
/// </summary>
CreateHardLink = 0x00000010,
/// <summary>
/// The function fails if the source file is a link source, but the file cannot be tracked after the move. This situation can occur if the destination is a volume formatted with the FAT file system.
/// </summary>
FailIfNotTrackable = 0x00000020,
}

/// <summary>
/// Provides certain utilities used by configuration processors, such as correcting file paths.
/// </summary>
public sealed class FileUtility
{
#region Constructor

/// <summary>
/// Default constructor.
/// </summary>
private FileUtility()
{
}

#endregion

#region Public members

/// <summary>
/// Returns whether the path is a UNC path.
/// </summary>
/// <param name="path">The path string.</param>
/// <returns><c>true</c> if the path is a UNC path.</returns>
public static bool IsUncPath( string path )
{
// FIRST, check if this is a URL or a UNC path; do this by attempting to construct uri object from it
Uri url = new Uri( path );

if( url.IsUnc )
{
// it is a unc path, return true
return true;
}
else
{
return false;
}
}

/// <summary>
/// Takes a UNC or URL path, determines which it is (NOT hardened against bad strings, assumes one or the other is present)
/// and returns the path with correct trailing slash: backslash for UNC or
/// slash mark for URL.
/// </summary>
/// <param name="path">The URL or UNC string.</param>
/// <returns>Path with correct terminal slash.</returns>
public static string AppendSlashUrlOrUnc( string path )
{
if( IsUncPath( path ) )
{
// it is a unc path, so decorate the end with a back-slash (to correct misconfigurations, defend against trivial errors)
return AppendTerminalBackslash( path );
}
else
{
// assume URL here
return AppendTerminalForwardSlash( path );
}
}

/// <summary>
/// If not present appends terminal backslash to paths.
/// </summary>
/// <param name="path">A path string; for example, "C:\AppUpdaterClient".</param>
/// <returns>A path string with trailing backslash; for example, "C:\AppUpdaterClient\".</returns>
public static string AppendTerminalBackslash( string path )
{
if( path.IndexOf( Path.DirectorySeparatorChar, path.Length - 1 ) == -1 )
{
return path + Path.DirectorySeparatorChar;
}
else
{
return path;
}
}

/// <summary>
/// Appends a terminal slash mark if there is not already one; returns corrected path.
/// </summary>
/// <param name="path">The path that may be missing a terminal slash mark.</param>
/// <returns>The corrected path with terminal slash mark.</returns>
public static string AppendTerminalForwardSlash( string path )
{
if( path.IndexOf( Path.AltDirectorySeparatorChar, path.Length - 1 ) == -1 )
{
return path + Path.AltDirectorySeparatorChar;
}
else
{
return path;
}
}
dzq138 2005-04-21
  • 打赏
  • 举报
回复
有点意思:
用了这么久的C#,现在才知道Update Application Block,实在不好意思见人.


---------------------
更新判断方式与v1.0的区别
v2.0不再使用版本号来区分更新是否可用,而是采用manifest ID+application ID来判断,对于每一个新的更新,即使是同一个应用程序,必须更新manifest ID。同时要注意,一个应用程序的application ID一旦确定就不能随意改变,因为客户端的配置文件中,已经写入了确定了的application ID,不能改变,当然你可以尝试通过更新客户端的配置文件来改变application ID。

更新检查 调用过程
1. 客户端新建一个ApplicationUpdaterManager实例,ApplicationUpdaterManager将负责整个升级过程控制
2. 调用ApplicationUpdaterManager的CheckForUpdates()方法
3. CheckForUpdates()内部调用CheckForUpdates(Uri Location)方法,其中的Location是服务器端Manifest文件的url路径,可通过UpdaterConfigurationView.DefaultManifestUriLocation获得。
4. CheckForUpdates(Uri Location)中有两个处理过程,一个是处理上一次更新过程中未完成的更新,一个是从服务器段下载最新的manifest文件,并判断是否要进行更新。
5. CheckForPendingUpdates()是专门用来处理未完成的更新的,该函数通过调用RegistryManager.Tasks属性获得未完成的任务列表。让我们来看看Tasks属性的实现
private Hashtable Tasks
{
get
{
if ( !loaded )
{
Load();
loaded = true;
}
return registry;
}
} 如果Tasks没有初始化过,则会调用Load()方法,该方法枚举每一个在AppRoot/registry中的文件,并将这些文件的句柄传给LoadTask()方法,最后会把每一个保存在registry目录下的未完成任务读入Tasks,这样就可以把这些任务传给ApplicationUpdaterManager.OnPendingUpdatesDetected()事件进行处理。
6. 下载和获得Manifest文件则是通过ManifestManager.GetManifests()方法完成的。

客户端目录用途
AppRoot/registry 存放未完成的task信息文件(xml格式)
AppRoot/applications 存放应用程序的升级文件和相关设置,该目录下有若干个目录,这些目录都对应一个应用程序的升级,每一个应用程序的升级文件分别保存在相应的目录下。
koenemy 2005-04-21
  • 打赏
  • 举报
回复
Reflector.exe 参考一下这个东东的更新
fanruinet 2005-04-21
  • 打赏
  • 举报
回复
微软的Updater Application Block正是解决这个问题的
timiil 2005-04-21
  • 打赏
  • 举报
回复
建议参考Update Application Block...比较傻瓜了。

110,619

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • AIGC Browser
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

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