









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.
- 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
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
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;}
<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.
[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
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
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)

此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。