- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
问题
在同一个单线程 COM 客户端中实例化两个独立的 .NET COM 可见类时,.NET 将它们加载到同一个 AppDomain 中。
我猜这是因为它们被加载到同一个线程/进程中。
此行为的示例显示在 this GitHub repository 中。 .
本质上,演示如下:
CurrentDomain
上的 SetData
。AppDomain
属性AppDomain
中获取哈希码,注意它也是相同的为什么这是个问题?
当两个类都实现了 AppDomain.CurrentDomain.AssemblyResolve
事件(或任何其他 AppDomain 事件)时,这些事件可能会相互干扰。这至少是一个并发症;我猜可能还有其他人。
一个想法
我认为处理此问题的最佳方法是为每个 COM 对象创建一个新的 AppDomain。因为我找不到(或谷歌)以托管方式执行此操作的方法,所以我认为可能有必要在非托管代码中执行此操作。
我做了一点侦探工作。在 OleView 中,.NET COM 可见类的 InprocServer32 属性是 mscoree.dll
。因此,我创建了一个“垫片”DLL,它将其所有 EXPORTS
转发到 mscoree.dll。通过消除过程(消除导出直到 COM 不再加载),我发现 DllGetClassObject
在 mscoree
中负责启动 .NET 运行时,并返回实例化的 COM 对象。
所以,我能做的就是实现我自己的 DllGetClassObject
,如下所示:
AppDomain
中创建对象,并返回它(不过我猜这并不像听起来那么简单)
问题
在开始这个可能困难且漫长的过程之前,我想知道:
最佳答案
如果代码不必在同一进程中运行,进程外服务器将是最简单的修复方法。将 CLSCTX_LOCAL_SERVER
传递给 CoCreateInstance
,每个类都将在 dllhost
托管进程中创建。
例如在客户端:
public static object CreateLocalServer(Guid clsid)
{
return CoCreateInstance(clsid, null, CLSCTX.LOCAL_SERVER, IID_IUnknown);
}
public static object CreateLocalServer(string progid)
{
Contract.Requires(!string.IsNullOrEmpty(progid));
Guid clsid;
CLSIDFromProgID(progid, out clsid);
return CreateLocalServer(clsid);
}
enum CLSCTX : uint
{
INPROC_SERVER = 0x1,
INPROC_HANDLER = 0x2,
LOCAL_SERVER = 0x4,
INPROC_SERVER16 = 0x8,
REMOTE_SERVER = 0x10,
INPROC_HANDLER16 = 0x20,
RESERVED1 = 0x40,
RESERVED2 = 0x80,
RESERVED3 = 0x100,
RESERVED4 = 0x200,
NO_CODE_DOWNLOAD = 0x400,
RESERVED5 = 0x800,
NO_CUSTOM_MARSHAL = 0x1000,
ENABLE_CODE_DOWNLOAD = 0x2000,
NO_FAILURE_LOG = 0x4000,
DISABLE_AAA = 0x8000,
ENABLE_AAA = 0x10000,
FROM_DEFAULT_CONTEXT = 0x20000,
ACTIVATE_32_BIT_SERVER = 0x40000,
ACTIVATE_64_BIT_SERVER = 0x80000
}
[DllImport(Ole32, ExactSpelling = true, PreserveSig = false)]
[return: MarshalAs(UnmanagedType.Interface)]
public static extern object CoCreateInstance(
[In, MarshalAs(UnmanagedType.LPStruct)] Guid rclsid,
[MarshalAs(UnmanagedType.IUnknown)] object pUnkOuter,
CLSCTX dwClsContext,
[In, MarshalAs(UnmanagedType.LPStruct)] Guid riid);
[DllImport(Ole32, CharSet = CharSet.Unicode, PreserveSig = false)]
public static extern void CLSIDFromProgID(string progId, out Guid rclsid);
您还可以注册自定义主机,并将标准 InProcServer32
替换为 LocalServer32
。对于示例服务器
// StandardOleMarshalObject keeps us single-threaded on the UI thread
// https://msdn.microsoft.com/en-us/library/74169f59(v=vs.110).aspx
[ComVisible(true)]
[ClassInterface(ClassInterfaceType.None)]
[ProgId(IpcConstants.CoordinatorProgID)]
public sealed class Coordinator : StandardOleMarshalObject, ICoordinator
{
public Coordinator()
{
// required for regasm
}
#region Registration
[ComRegisterFunction]
internal static void RegasmRegisterLocalServer(string path)
{
// path is HKEY_CLASSES_ROOT\\CLSID\\{clsid}", we only want CLSID...
path = path.Substring("HKEY_CLASSES_ROOT\\".Length);
using (RegistryKey keyCLSID = Registry.ClassesRoot.OpenSubKey(path, writable: true))
{
// Remove the auto-generated InprocServer32 key after registration
// (REGASM puts it there but we are going out-of-proc).
keyCLSID.DeleteSubKeyTree("InprocServer32");
// Create "LocalServer32" under the CLSID key
using (RegistryKey subkey = keyCLSID.CreateSubKey("LocalServer32"))
{
subkey.SetValue("", Assembly.GetExecutingAssembly().Location, RegistryValueKind.String);
}
}
}
[ComUnregisterFunction]
internal static void RegasmUnregisterLocalServer(string path)
{
// path is HKEY_CLASSES_ROOT\\CLSID\\{clsid}", we only want CLSID...
path = path.Substring("HKEY_CLASSES_ROOT\\".Length);
Registry.ClassesRoot.DeleteSubKeyTree(path, throwOnMissingSubKey: false);
}
#endregion
}
关于c# - 如何在单线程客户端中将 ComVisible 类实例化到自己的 AppDomain 中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41616334/
有没有一种方法可以使用标准类型构造函数(例如 int、set、dict、list、tuple 等)以用户定义的方式将用户定义类的实例强制转换为其中一种类型?例如 class Example:
我知道这个问题在Stackoverflow中有很多问题,但是即使有很多答案,这些答案也帮不了我什么,也没有找到答案。 在我的WebAPP中,它可以正常工作,但是当我将其转换为API时,它失败了(主题标
这个问题已经有答案了: Why does the ternary operator unexpectedly cast integers? (3 个回答) 已关闭 9 年前。 最近遇到一个Java的陷
我尝试使用 FirebaseApp.configure() 配置 Firebase,但遇到以下崩溃: *** Terminating app due to uncaught exception 'c
我有一个自连接员工实体类,其中包含与其自身相关的 id、name 和 ref 列。我想创建它的新实例并将其保存到数据库。 首先我创建了一个 Employee 类的实例并将其命名为 manager。然后
我有一个用于添加新公寓的表单,在该表单中我有一个下拉列表,用户可以在其中选择负责的人员。 显然,当您从下拉列表中选择并尝试保存公寓时,我的应用程序认为该人已被修改。它给了我下面的错误,指示我应该首先保
从 Visualforce 页面,我需要检索我们组织的 salesforce 实例的 URL,而不是 Visual Force URL。 例如我需要https://cs1.salesforce.com
我遇到了一些可能的问题答案,但这是关于从 Hibernate 3.4.0GA 升级到 Hibernate 4.1.8 的问题。所以这曾经在以前的版本下工作,我已经四处搜索了为什么它在这个新版本中出现了
似乎一遍又一遍地问这个问题,我仍然找不到解决我问题的答案。我在下面有一个域模型。每个新创建或更新的“安全用户”都需要我确保其具有配置文件,如果没有,则创建一个新的配置文件并分配给它。 配置文件的要求相
我很难调试为什么 JPA 不级联我的 @ManyToMany 关系。我发现的所有答案都与缺少级联语句有关。但我确实拥有它们并且仍然得到: Caused by: org.hibernate.Transi
Play 服务 API 表明有一个叫做 Instance ID 的东西 但是,在 Android Studio 中包含以下内容后,我无法导入 InstanceID 类 compile "com.goo
我正在使用 Seam 框架。我有 2 个实体: 请求.java @Entity @Table(name = "SRV_REQUEST") public class Request { private
This question处理构建一个适当的Monad来自单子(monad)的实例,但仅在某些约束下 - 例如Set .诀窍是将其包装成 ContT ,它将约束推迟到包装/展开其值。 现在我想对 Ap
我正在尝试执行此查询: StringBuffer sb = new StringBuffer(); sb.append("select p from PointsEntity p " + "where
我试图了解是否可以更改我的 hibernate 配置并使用单个 MySQL 实例(而不是我当前拥有的多个 MySQL 实例): 我有一个使用 hibernate 的 Java 应用程序,与 2 个模式
我有一个选项卡滑动布局,其中包括四个选项卡,每个选项卡都有自己的布局和 fragment ,在我的主要 Activity 布局中,viewpager 参与更改选项卡。特定 View (选项卡)在应用程
我看到很多帖子声称他们正在运行 MySql 的 RDS 实例,但无法连接到该实例,但我没有运行 RDS。 我使用 EC2 实例来托管我的 WordPress 博客,该博客是使用 Web 平台安装程序安
因为我在我的 ec-2 实例上的 python 虚拟环境中运行应用程序( Airflow ),并且我想在同一个 ec2 实例上的默认 python 环境中运行命令,所以我认为 ssh 到我自己的实例更
这个问题已经有答案了: How to fix the Hibernate "object references an unsaved transient instance - save the tra
例子: run APP1 .. ... run APP1 ... run APP2 如何在 APP2 中对 Vue 说我需要调用 APP1?
我是一名优秀的程序员,十分优秀!