安装的 COM 对象使用错误的 DLL,如果程序运行我无法重建
我为 Enterprise Architect 编写了一个插件。它是一个 COM 对象。该加载项使用了一些其他项目 dll。
我创建了一个注册加载项 dll 的安装程序。该类位于加载项的项目中,我们将其命名为 MyProject.dll。
/// <summary>
/// Installer class for Enterprise Architect Add-In
/// </summary>
[RunInstaller(true)]
public class ComInstaller : Installer
{
#region Public Methods
public override void Install( System.Collections.IDictionary stateSaver )
{
base.Install( stateSaver );
RegistrationServices regsrv = new RegistrationServices();
if ( !regsrv.RegisterAssembly( GetType().Assembly, AssemblyRegistrationFlags.SetCodeBase ) )
{
throw new InstallException( "Failed to register type library for COM" );
}
}
public override void Uninstall( System.Collections.IDictionary savedState )
{
base.Uninstall( savedState );
RegistrationServices regsrv = new RegistrationServices();
if ( !regsrv.UnregisterAssembly( GetType().Assembly ) )
{
throw new InstallException("Failed to unregister type library for COM");
}
}
#endregion
}
如果加载项运行,我将无法构建解决方案,因为访问被拒绝。该加载项使用 Debug 文件夹中的 MyProject.dll,而不是已安装的 MyProject.dll。
我该如何解决这个问题?
谢谢, 大师
I wrote an add-in for Enterprise Architect. It's a COM Object. This add-in uses some other project dll's.
I created an installer which registers the Add-In's dll. This class is in the add-in's project, let's call it MyProject.dll.
/// <summary>
/// Installer class for Enterprise Architect Add-In
/// </summary>
[RunInstaller(true)]
public class ComInstaller : Installer
{
#region Public Methods
public override void Install( System.Collections.IDictionary stateSaver )
{
base.Install( stateSaver );
RegistrationServices regsrv = new RegistrationServices();
if ( !regsrv.RegisterAssembly( GetType().Assembly, AssemblyRegistrationFlags.SetCodeBase ) )
{
throw new InstallException( "Failed to register type library for COM" );
}
}
public override void Uninstall( System.Collections.IDictionary savedState )
{
base.Uninstall( savedState );
RegistrationServices regsrv = new RegistrationServices();
if ( !regsrv.UnregisterAssembly( GetType().Assembly ) )
{
throw new InstallException("Failed to unregister type library for COM");
}
}
#endregion
}
If the add-in runs, I can't build my solution because access is denied. The add-in uses the MyProject.dll which is in the Debug folder instead of the installed one.
How can I solve this?
Thanks,
Maestro
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这就是注册的工作原理。您可以在构建时禁用自动注册:
请注意,有一种方法可以摆脱 COM DLL 地狱(Vista+?)清单文件:
This is how registration works. You can disable automatic registration at build:
Note that there is a way out of COM DLL hell with (Vista+?) manifest files:
欢迎回到 Dll 地狱时代:)
不幸的是,COM dll 是在调用者的处理程序上实例化的,因此一旦您的 dll 被调用者应用程序使用,即使您已取消注册它(在您使用卸载程序的情况下),该 dll 仍可能在使用中,并且您需要杀死所有调用者进程以便能够覆盖 dll。
大多数时候,如果您完全终止调用者应用程序(在您的情况下是 EA 的实例)并等待几秒钟,您应该能够重新编译,但有时该进程会保留在内存中,因此您需要运行类似 < a href="http://technet.microsoft.com/en-us/sysinternals/bb795533" rel="nofollow">列出 sysinternals 中的 DLL 以检查谁在使用您的 dll 并终止整个进程树。
Welcome back to the Dll hell days :)
Unfortunately COM dlls are instatiated on the handler of the caller, so once your dlls is in use by the caller app, even that you have unregistered it (in your case with the uninstaller), the dll could still be in use, and you need to kill all the caller processes to be able to overwrite the dll.
Most of the times if you completely kill the caller app (in your case the instances of EA) and wait a few seconds you should be able to re-compile, but sometimes the process stay in memory so you would need to run something like ListDLLs from sysinternals to check who is using your dll and kill the whole process tree.