局域网内的应用程序,业务应用都已经写成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部件?写得较乱,望给点耐性看完。
欢迎各位兄台解答一下以上问题。或给点更好的自动更新版本主意,
先在此先多谢各位.

解决方案 »

  1.   

    建议参考Update Application Block...比较傻瓜了。
      

  2.   

    微软的Updater Application Block正是解决这个问题的
      

  3.   

    Reflector.exe            参考一下这个东东的更新
      

  4.   

    有点意思:
    用了这么久的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    存放应用程序的升级文件和相关设置,该目录下有若干个目录,这些目录都对应一个应用程序的升级,每一个应用程序的升级文件分别保存在相应的目录下。
      

  5.   

    //============================================================================================================
    // 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  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  if there is not already one; returns corrected path.
            /// </summary>
            /// <param name="path">The path that may be missing a terminal slash .</param>
            /// <returns>The corrected path with terminal slash .</returns>
            public static string AppendTerminalForwardSlash( string path )
            {
                if( path.IndexOf( Path.AltDirectorySeparatorChar, path.Length - 1 ) == -1 )
                {
                    return path + Path.AltDirectorySeparatorChar;
                }
                else
                {
                    return path;
                }
            }
      

  6.   


            /// <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() );
            }