我正在尝试为我使用 Visual Studio 2008 在 C# 中编写的类库驱动程序编写一个安装项目/安装程序。驱动程序项目有一段代码看起来像这样......
[ComRegisterFunction]
public static void RegisterASCOM(Type t)
{
Trace.WriteLine("Registration Started.");
DoRegistration(true);
}
在驱动程序项目属性 - >“程序集信息”中,我设置了选中 Make COM-Visible = true 的框。
我在 VS 的解决方案中添加了一个安装项目,从驱动程序项目中添加了输出 dll,以便它安装在目标机器上,并将 dll 的 Register 属性设置为“vsdraCOM”。所以,我的理解是,当安装程序运行时,它应该执行标有 [COMRegisterFunction] 的 dll 方法。
使用 SysInternals Debug View 我可以通过观察窗口中显示的“注册开始”文本来监视何时命中上述代码片段。当我构建解决方案时,我可以看到显示的文本,所以我知道驱动程序正在正确注册。问题是当我运行安装程序时,我不认为它在做注册位。我在调试 View 中看不到任何内容。如果我尝试通过另一个应用程序访问我的驱动程序,我会收到一条错误消息,指出“无法创建 ActiveX 对象”。为什么在安装过程中没有发生注册?
驱动程序确实注册了 COM,但它没有调用我的自定义注册方法。
有没有人对我可能缺少的东西有任何建议?还有另一种方法可以调试吗?
(如果有人想看,我可以提供更多代码!!)
最佳答案
如果安装程序没有使用默认机制注册 COM 对象,您可以尝试使用自定义操作强制它。这种技术的一个额外好处是,您可以单步执行自定义操作以了解正在发生的事情。
向您的项目中添加一个继承自 Installer 的类,并使用此属性进行修饰
[RunInstaller(true)]
并覆盖以下一种或多种方法:
Install()
Uninstall()
Commit()
Rollback()
这是一个使用 COM Interop 执行注册的完整示例。它散布着跟踪输出(与某些意见相反)将显示在 Sysinternals DebugVw 中。当内置调试配置时,它会弹出一个对话框,允许您附加调试器并单步执行自定义操作。
using System.ComponentModel;
using System.Configuration.Install;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace TiGra
{
/// <summary>
/// Custom install actions that must be carried out during product installation.
/// </summary>
[RunInstaller(true)]
public class MyInstaller : Installer
{
/// <summary>
/// Custom Install Action that performs custom registration steps as well as
/// registering for COM Interop.
/// </summary>
/// <param name="stateSaver">Not used<see cref="Installer"/></param>
public override void Install(System.Collections.IDictionary stateSaver)
{
Trace.WriteLine("Install custom action - Starting registration for COM Interop");
#if DEBUG
MessageBox.Show("Attach debugger to this process now, if required", "Custom Action Debug", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
#endif
base.Install(stateSaver);
RegistrationServices regsrv = new RegistrationServices();
if (!regsrv.RegisterAssembly(this.GetType().Assembly, AssemblyRegistrationFlags.SetCodeBase))
{
Trace.WriteLine("COM registration failed");
throw new InstallException("Failed To Register for COM Interop");
}
Trace.WriteLine("Completed registration for COM Interop");
}
/// <summary>
/// Custom Install Action that removes the COM Interop component registrations.
/// </summary>
/// <param name="savedState">Not used<see cref="Installer"/></param>
public override void Uninstall(System.Collections.IDictionary savedState)
{
Trace.WriteLine("Uninstall custom action - unregistering from COM Interop");
try
{
base.Uninstall(savedState);
RegistrationServices regsrv = new RegistrationServices();
if (!regsrv.UnregisterAssembly(this.GetType().Assembly))
{
Trace.WriteLine("COM Interop deregistration failed");
throw new InstallException("Failed To Unregister from COM Interop");
}
}
finally
{
Trace.WriteLine("Completed uninstall custom action");
}
}
}
}
剩下最后一件事要做。除非安装程序配置为这样做,否则自定义操作将不会运行。就是这样:
如果您需要对此进行更好的控制,您可以将自定义操作类添加到某些安装程序阶段而不是其他阶段。例如,如果安装和卸载由不同的程序集处理,您可以在 Install 和 Commit 节点下添加一个程序集,在 Uninstall 和 Rollback 节点下添加另一个程序集。
就是这样,现在将在设置期间调用您的自定义操作。调试自定义操作的快速提示。在调试版本中使用条件指令(如上例所示)显示消息框。然后将在安装过程中显示此消息框。这有效地暂停了安装过程,直到您在消息框上单击“确定”,这为您提供了您可能称之为“机会之窗”(双关语)将调试器附加到 msiexec.exe 进程的东西。将有几个 msiexec.exe 进程在运行,您需要选择一个说它是托管代码的进程。调试器将附加并且您的断点将“亮起”,因此您可以拦截执行并单步执行您的自定义操作。
关于visual-studio - 为什么我的安装项目不执行我的自定义注册过程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2151003/