zoukankan      html  css  js  c++  java
  • 创建可在网页下载安装的ActiveX控件(通过Setup.exe安装)

    为完成网页自动下载并安装控件的功能,需要通过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 CustomInstaller()
            
    {
                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文件。

         当然,这种方法写的东西比较多点,只是提供一种思路,为其他可能的项目准备。

  • 相关阅读:
    分享一个js方法
    微信小程序中如何使用setData修改数组或对象中的某一参数
    微信小程序实现图片上传功能
    微信小程序图片上传放大预览删除代码
    小程序单张图片 和 九宫格图片上传、预览、删除示例
    微信小程序多图上传/朋友圈传图效果【附完整源码】
    shell 和awk性能对比
    超实用的8个Linux命令行性能监测工具
    storm分组模式
    Python程序的执行原理(转)
  • 原文地址:https://www.cnblogs.com/longyi/p/1569518.html
Copyright © 2011-2022 走看看