程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> .NET實例教程 >> 創建可在網頁下載安裝的ActiveX控件(通過Setup.exe安裝)

創建可在網頁下載安裝的ActiveX控件(通過Setup.exe安裝)

編輯:.NET實例教程

為完成網頁自動下載並安裝控件的功能,需要通過C#創建一個ActiveX控件,然後將該控件置於安裝程序中,在打開網頁的時候下載、安裝並注冊該ActiveX控件。本文是采用VS2005創建的,VS2003創建過程與之相似。

    首先,創建一個類庫,為其命名為CreateActiveXEmail:

    刪除掉默認生成的類Class1.cs,創建一個接口ActiveXEmailInterface:

 



using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;

namespace CreateActiveXEmail
...{
    [Guid("CB5BDC81-93C1-11CF-8F20-00805F2CD064"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    public interface ActiveXEmailInterface
    ...{
        void GetInterfacceSafyOptions(int riid, out int pdwSupportedOptions, out int pdwEnabledOptions);
        void SetInterfaceSafetyOptions(int riid, int dwOptionsSetMask, int dwEnabledOptions);
    }
}

    其中GUID可以通過【工具】-【創建GUID】來產生。

    實現該接口的目的就是提高程序的安全性,以便客戶端IE在不更改設置的情況下可以預行該ActiveX控件。

    然後,用你需要實現某些功能的類來繼承上面的接口。

 



using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace CreateActiveXEmail
    [Guid("060d1308-f34e-4c9f-8962-0abafe385d33"), ComVisible(true)]
    public class ActiveXEmail : ActiveXEmailInterface
    ...{
        public void GetInterfacceSafyOptions(int riid, out int pdwSupportedOptions, out int pdwEnabledOptions)
        ...{
            pdwSupportedOptions = 1;
            pdwEnabledOptions = 2;
        }

        public void SetInterfaceSafetyOptions(int riid, int dwOptionsSetMask, int dwEnabledOptions)
        ...{
        }

        public ActiveXEmail()
        ...{
        }
}

 

    注意,上面代碼中的類屬性“ComVisible(true)”,是必須添加的。

    在上面的類中,僅僅是現實了接口的兩個方法,至於其他需要的方法,自行添加即可。另外,需要對項目屬性進行一點修改:

    注意,類屬性中的“ComVisible(true)”和上圖中的【為 COM Interop 注冊】缺一不可!只有這樣才能生成tlb文件。

    這樣,一個可用的ActiveX控件就已經生成。在本機你可以隨意調用其中的任何方法,但問題是,當客戶端機器需要遠程調用時,必須在能在客戶端機器上注冊該ActiveX控件才行。所以,還必須進行下面的步驟:將該ActiveX打包,在安裝後在目標機器進行注冊。

    創建一個安裝包:

    然後右鍵單擊項目,點擊【添加】-【項目輸出】,在【主輸出】中選擇上面創建的工程“CreateActiveXEmail”。然後,打開安裝工程的【屬性】頁面,對項目的【安裝URL】項進行設置:

注意,上圖的【安裝URL】項中,必須使用絕對路徑。另外,上圖中的“DllFolder”是一個已發布網站“http://172.16.11.136/TestingAX”下的一個目錄,這意味著,當在客戶端訪問頁面時,如果客戶端未安裝當前ActiveX控件,則從路徑http://172.16.11.136/TestingAX/DllFolder”來下載。

    最後,在頁面中按如下方法調用即可:

 



<object classid="clsid:060d1308-f34e-4c9f-8962-0abafe385d33"
               codebase="DllFolder/setup.exe#version=1,0,0,0"></object>

 

 

另外,還可以采用其他方法,即上面的類庫屬性不選擇【為 COM Interop 注冊】,安裝工程屬性不為【安裝URL】指定路徑,類中也不添加“ComVisible(true)”屬性,而是創建一個安裝類:

 



using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Configuration.Install;
using System.Reflection;
using System.IO;
using Microsoft.Win32;
using System.Diagnostics;

namespace CreateActiveXEmail
...{
    [RunInstaller(true)]
    public partial class CustomInstaller : Installer
    ...{
        private string regCommandFile = string.Empty;
        private string unRegCommandFile = string.Empty;

        public CustomI        ...{
            InitializeComponent();
        }

        protected override void OnAfterInstall(System.Collections.IDictionary savedState)
        ...{
            base.OnAfterInstall(savedState);

            try
            ...{
                //get the path of the Regasm.exe
                string regasmPath = string.Empty;

                //get the path of the current executing assembly
                string currentAsmDLLFilePath = Assembly.GetExecutingAssembly().Location;
                string currentAsmPath = currentAsmDLLFilePath.Substring(0, currentAsmDLLFilePath.LastIndexOf(''\'') + 1);

                string currentRegasmPath = string.Format("{0}{1}", currentAsmPath, "RegAsm.exe");
                if (!File.Exists(currentRegasmPath))
                ...{
                    try
                    ...{
                        RegistryKey frmReg = Registry.LocalMachine.OpenSubKey(@"SOFTWAREMicrosoft.NetFramework");
                        if (frmReg == null)
                        ...{
                            //the .Net framework do not exist in the local Machine
                            return;
                        }

                        string frameworkVersion = Environment.Version.ToString();
                        frameworkVersion = frameworkVersion.Substring(0, frameworkVersion.LastIndexOf(''.''));

                        regasmPath = string.Format(@"{0}v{1}{2}", frmReg.GetValue("InstallRoot").ToString(), frameworkVersion, "RegAsm.exe");

                        if (!File.Exists(regasmPath))
                        ...{
                            //the Regasm.exe do not exist in the local Machine
                            return;
                        }
                    }
                    catch (System.ArgumentException ex)
                    ...{
                        throw new System.ArgumentException(ex.Message);
                    }
                }
                else
                ...{
                    regasmPath = currentRegasmPath;
                }

                //create the registration command line
                string regCommand = string.Format("{0} "{1}" /{2} /{3}", regasmPath, currentAsmDLLFilePath, "tlb", "codebase");                
                
                try
                ...{
                    regCommandFile = string.Format("{0}{1}", currentAsmPath, "Regasm.bat");
                    if (File.Exists(regCommandFile))
                    ...{
                        File.Delete(regCommandFile);
                    }

                    using (StreamWriter swReg = File.CreateText(regCommandFile))
                    ...{
                        swReg.Write(regCommand);
                        swReg.Flush();
                    }
                }
                catch (UnauthorizedAccessException uaex)
                ...{
                    throw new UnauthorizedAccessException(uaex.Message);
                }
                catch (DirectoryNotFoundException dnex)
                ...{
                    throw new DirectoryNotFoundException(dnex.Message);
                }
                catch (IOException ioex)
                ...{
                    throw new IOException(ioex.Message);
                }

                //create the unregistration command file
                string unRegCommand = string.Format("{0} "{1}" /{2 regasmPath, currentAsmDLLFilePath, "u");

                try
                ...{
                    unRegCommandFile = string.Format("{0}{1}", currentAsmPath, "UnRegasm.bat");
                    if (File.Exists(unRegCommandFile))
                    ...{
                        File.Delete(unRegCommandFile);
                    }

                    using (StreamWriter swReg = File.CreateText(unRegCommandFile))
                    ...{
                        swReg.Write(unRegCommand);
                        swReg.Flush();
                    }
                }
                catch (UnauthorizedAccessException uaex)
                ...{
                    throw new UnauthorizedAccessException(uaex.Message);
                }
                catch (DirectoryNotFoundException dnex)
                ...{
                    throw new DirectoryNotFoundException(dnex.Message);
                }
                catch (IOException ioex)
                ...{
                    throw new IOException(ioex.Message);
                }

                //register for the COM Interop
                Process.Start(regCommandFile);
            }
            catch (Exception ex)
            ...{
                throw new Exception(ex.Message);
            }
        }

        public override void Uninstall(System.Collections.IDictionary savedState)
        ...{
            try
            ...{
                Process.Start(unRegCommandFile);
            }
            catch (Exception ex)
            ...{
                throw new Exception(ex.Message);
            }

            base.Uninstall(savedState);
        }
    }
}

 

    因為沒有了“ComVisible(true)”和【為 COM Interop 注冊】,工程也就無法生成tlb文件,沒有tlb文件也就意味著注冊失敗,dll文件或ActiveX控件在客戶端無法使用。上面的類就是通過代碼的方式將dll文件在客戶端注冊,生成tlb文件。

     當然,這種方法寫的東西比較多點,只是提供一種思路,為其他可能的項目准備。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved