惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

博客园_首页
博客园 - 【当耐特】
博客园 - 叶小钗
阮一峰的网络日志
阮一峰的网络日志
WordPress大学
WordPress大学
D
Docker
T
The Blog of Author Tim Ferriss
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
Microsoft Azure Blog
Microsoft Azure Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
月光博客
月光博客
M
MIT News - Artificial intelligence
H
Hackread – Cybersecurity News, Data Breaches, AI and More
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
云风的 BLOG
云风的 BLOG
F
Fortinet All Blogs
罗磊的独立博客
小众软件
小众软件
A
About on SuperTechFans
MyScale Blog
MyScale Blog
D
DataBreaches.Net
The GitHub Blog
The GitHub Blog
C
Check Point Blog
L
LangChain Blog

博客园 - 彷徨......

轻巧地,我走了 Unable to load print control in ReportingService reporting service报表设计时候页面宽度高度的设置 -转 Beginning SQL Server 2005 Reporting Services Sharepoint Server与Reporting Services整合配置 -转 T61装win2003后的驱动安装 一篇绝好的讲sql server索引的文章,值得收藏 使用Div自动换行一事 一个检查SPN的小工具 Create many user to ducumentum contentserver "Personalize" property is invalid in moss2010 - 彷徨...... 这个破备案制度 可恶的小偷 How to overwrite the method in Javascript SEO工具大全-转 使用metablog迁移博客园的文章 - 彷徨...... - 博客园 dsa XmlDocument的Load方法报“hexadecimal value .., is an invalid character” - 彷徨...... 出来了没有呢?
转:HowTo: Deploy .NET ActiveX Control
彷徨...... · 2010-07-21 · via 博客园 - 彷徨......

From ; http://nikolkos.blogspot.com/2009/08/howto-deploy-net-activex-control.html

这篇技术文章居然国内访问不了,转之分享。

You have developed an ActiveX Control with your favorite .NET language, and you think it's time to deploy it. The most common way is to pack the control to a CAB file and use Internet Explorer for installation (via "Internet Component Download" service). If you are VB6 programmer the first problem you'll face: Visual Studio does not have "Package & Deployment Wizard".

There are some nice posts in the web describing how you can accomplish this. But not everything work as expected (Vista issues, update troubles and etc.) Hereby I'll try to summarize all info I have found and use at the moment... Let's do that step by step.


  1. Create an ActiveX Control: MyControl.dll
    Create a class library project, add a class, implement the control's logic within the class. Mark the class with attributes: ProgId, Guid, ComVisible.
    Assume that the library has 1.0.0.0 file and assembly versions.
  2. Create an installation package: MyControl.msi
    You can use Visual Studio Setup project to create Windows Installation package (MSI) of your ActiveX Control.

    - Add primary output from the class library project.
    - Set for the DLL a Register option to vsdrpCOM.
    - Add a registry key to HKCR:
    "CLSID\{XXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}\InstalledVersion" with default string value: 1,0,0,0. Replace XXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX with a GUID of your class in the control (see GuidAttribute you mark the class with). This key is used by Internet Component Download service to detect version of installed ActiveX control.
    - Build the project.

    More info:
    - Deployment Changes in Visual Basic .NET
    - How to: Create or Add a Setup Project
    - Visual Studio Setup - series of articles by Phil Wilson
    - Be aware of the Visual Studio 2008 bug for 64bit target platform

  3. Create a bootstrapper: setup.exe
    To ensure that your control will install and run successfully, you must first ensure that all components upon which it is dependent (.NET Framework, third-party components and etc.) are already installed on a target machine. In other words, we need a bootstrapper.

    Create a text file named "bootstrapper.proj".



    <Project ToolsVersion="3.5" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    <PropertyGroup>
    <SDKBootstrapperPath>$(registry:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\GenericBootstrapper\3.5@Path)</SDKBootstrapperPath>
    </PropertyGroup> <ItemGroup>
    <BootstrapperFile Include="Microsoft.Net.Framework.3.5">
    <ProductName>Microsoft .NET Framework 3.5</ProductName>
    </BootstrapperFile>
    <BootstrapperFile Include="Microsoft.Windows.Installer.3.1">
    <ProductName>Windows Installer 3.1</ProductName>
    </BootstrapperFile>
    </ItemGroup>

    <Target Name="Bootstrapper">
    <GenerateBootstrapper
    ApplicationFile="run.exe"
    ApplicationName="MyControl"
    BootstrapperItems="@(BootstrapperFile)"
    OutputPath="$(TargetDir)"
    ComponentsLocation="HomeSite"
    ComponentsUrl=""
    CopyComponents="false"
    Culture="en"
    Path="$(SDKBootstrapperPath) "/>
    </Target>
    </
    Project>

    Build the project with MSBuild:

    "C:\Windows\Microsoft.NET\Framework\v3.5\msbuild.exe" /target:Bootstrapper bootstrapper.proj

    More Info:
    - GenerateBootstrapper Task
    - Application Deployment Prerequisites
    - Possible issues with the Visual Studio 2008 bootstrapper and how to work around them

  4. Create an executor application: run.exe
    To install the MSI on a target machine we'll use msiexec application that belongs to the Windows Installer Service. It seems that in Vista the CAB installer refuses to execute any application that is not included in the CAB file.
    So, we will need a small utility that is able to run an external program which path is passed via the command line (if no path is passed it should successfully exit).

    C# code sample for the run.exe:



    static int Main()
    {
    // Get command line arguments.
    string[] args = Environment.GetCommandLineArgs();

    // If no arguments are passed then return.
    if (args.Length < 2)
    {
    return 0;
    }

    // Get the file name to run.
    string fileToRun = args[1];

    // Compile command line for the file to run.
    var cmdLine = new StringBuilder();

    for (int i = 2; i < args.Length; i++)
    {
    cmdLine.AppendFormat(arg.Contains(" ") ? "\"{0}\" " : "{0} ", arg[i]);
    }

    // Execute the external file.
    var process = Process.Start(fileToRun, cmdLine.ToString());
    // Wait the process to complete.
    process.WaitForExit();
    return process.ExitCode;

    }


  5. Create HTM file: MyControl.htm
    The HTM file is an HTML description of the ActiveX Control that is used by Internet Component Download service.


    <html>
    <
    head>
    <
    title>MyControl.CAB</title>
    </
    head>
    <
    body>

    <

    OBJECT ID="MyControl" CLASSID="CLSID:XXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" CODEBASE="MyControl.CAB#version=1,0,0,0"></OBJECT>

    </body>
    </
    html>


    Replace XXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX of CLASSID with a GUID of your class in the ActiveX Control.

  6. Create INF file: MyControl.inf
    The information file provides installation instructions that Internet Component Download service uses to download and install the CAB.

    [version]
    signature="$CHICAGO$"
    AdvancedINF=2.0

    [Setup Hooks]
    bootstrap=bootstrap
    install=install

    [bootstrap]
    run="""%EXTRACT_DIR%\setup.exe"""

    [install]
    run="""%EXTRACT_DIR%\run.exe""" msiexec.exe /i """%EXTRACT_DIR%\MyControl.msi""" /qb


    More Info:
    - Introduction to Internet Component Download
    - Packaging ActiveX Controls
    - About INF File Architecture

  7. Create CAB file: MyControl.cab

    Use CABARC utility from CAB SDK to create a cab:

    cabarc.exe n MyControl.cab MyControl.inf MyControl.msi run.exe setup.exe

    More Info:
    - MS CAB SDK

  8. Deploy an updated version of the control
    The control is automatically downloaded and installed when the version number is higher than that of the control currently installed on the client computer. So in order to deploy an updated control you must change the assembly and file versions.
    You should keep in mind that Windows Installer service uses 3 digits version format. The format of the version is as follows: major.minor.build
    The first field is the major version and has a maximum value of 255. The second field is the minor version and has a maximum value of 255. The third field is called the build version or the update version and has a maximum value of 65,535.
    For example, you have deployed a control of 1.0.0.0 version. To deploy the updated control you can change its version to 1.0.1.0. Also don't forget to change versions of the MSI and HTM files.

    More Info:
    - Windows Installer Guide: Patching and Upgrades
    - Windows Installer: File Versioning Rules
    - .NET Framework Developer's Guide: Assembly Versioning

Now you have MyControl.htm and MyControl.cab - it's all you need to deploy the ActiveX Control.

Some links that were used as sources for implementation ideas:

P.S.
If you target 32/64-bit platforms you can use the following trick.
- Create separate MSI packages for every platform: MyControl-X64.msi, MyControl-X86.msi.
- Change the [install] hook in the INF file to use a macro in a filename of MSI:

[install]
run="""%EXTRACT_DIR%\run.exe""" msiexec.exe /i """%EXTRACT_DIR%\MyControl-$(Platform).msi""" /qb


- Adjust the run.exe application to detect a platform it executes on and replace the macro with the proper platfrom value.



static int Main()
{
// Get command line arguments.
string[] args = Environment.GetCommandLineArgs();

// If no arguments are passed then return.
if (args.Length < 2)
{
return 0;
}

// Get the file name to run.
string fileToRun = args[1];

// Get platform value to replace macro in command line.
var macroPlatformValue = GetPlatformValue();

// Compile command line for the file to run.
var cmdLine = new StringBuilder();

for (int i = 2; i < args.Length; i++)
{
// Substitute the platform macro.
var arg = Regex.Replace(args[i], @"\$\(platform\)", macroPlatformValue, RegexOptions.IgnoreCase);
cmdLine.AppendFormat(arg.Contains(" ") ? "\"{0}\" " : "{0} ", arg);
}

// Execute the external file.
var process = Process.Start(fileToRun, cmdLine.ToString());
// Wait the process to complete.
process.WaitForExit();
return process.ExitCode;

}

static string GetPlatformValue()
{
string arch = Environment.GetEnvironmentVariable("PROCESSOR_ARCHITECTURE") ?? "x86";
string arch2 = Environment.GetEnvironmentVariable("PROCESSOR_ARCHITEW6432") ?? "x86";
if (arch == "AMD64" || arch2 == "AMD64")
{
return "x64";
}

return arch;
}

Actully, if you generate the MSI file through vs2008 and try to intall it to 64Bit env, you will find the IE64 still cannot work.
A good news is we can use Orca to edit the msi and fix this issue.

Open the MSI file using ORCA, look at the component table. Find component which ComponentId is equal to CLSID in .NET assembly.
Actual Results
The attribute value of the component is 4 (msidbComponentAttributesRegistryKeyPath). That indicates that the component is 32bit only.

http://msdn.microsoft.com/en-us/library/aa368007(VS.85).aspx
Expected Results
The attribute value of the component should be 260 (msidbComponentAttributesRegistryKeyPath | msidbComponentAttributes64bit).

Edit the MSI with ORCA: change 4 to 260. Install the edited MSI - the assembly is registered correctly and COM object can be created by an unmanaged 64bit application.
TAP Code (if applicable)