我在dll地狱中。
我正在为名为ANSYS的庞大,古老且功能强大的软件套件构建插件。他们有一个插件框架。我曾希望他们能够通过AssemblyContext
或AppDomain
或我不理解的其他一些巧妙的dotnet设备为我神奇地处理一切。他们没有。
结果是我通过nuget创建了一个依赖于GRPC.core 1.16.0的应用程序。我写了一个小应用程序,用winform主机驱动我的插件。它加载并运行完美,可以在~/myproject/bin/debug/grpc.core.1.1.16.dll
中找到我的库,该库就在作为我的插件的类库旁边,没问题。
当我在还依赖于grpc 1.0.0.0的ANSYS进程空间中运行插件时,链接器会找到C:\Program FIles\ANSYS\...\WIN64\grpc.core.dll
。不好。
关于Nuget GRPC软件包的一个奇怪的事情是,它添加了一个具有1.0.0.0的“参考版本”的参考,其中大多数其他nuget软件包的参考版本都与nuget软件包版本相匹配。如果我手动更改参考版本,则编译器将找不到该库。
<Reference Include="Grpc.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=d754f35622e28bad">
<HintPath>..\packages\Grpc.Core.1.16.1\lib\net45\Grpc.Core.dll</HintPath>
</Reference>
编辑:密钥在上面的行中。 Nuget发布的Grpc.core工件位于
AssemblyInformationVersion=1.16.1.0, AssemblyFileVersion=1.16.1.0, AssemblyVersion=1.0.0.0
。我将此记录为a request against GRPC。下面有更多内容。
因此,我需要告诉运行时链接工具不要使用在ANSYS自己的二进制目录中找到的grpc.core ... dll。此外,我希望从父进程上下文中加载一个dll(及其依赖文件)。 :这就是ANSYS API dll本身,可能已经在GAC中了。在我的项目中,我已将其作为非nudent引用并选择了“构建操作:请勿复制”。
所以我的问题:
grpc.core
的程序集中加载类型时,不要加载1.0.0.0,找到到底是1.16.0.0”?运行时已经通过“ strong”匹配了所需的库 名称”。问题在于1.16.0的使用不当。该版本 字符串仅供参考,但程序集本身是版本 1.0.0.0。 Fusion已经通过完全匹配加载了我想要的库。
我尝试自己研究这个问题,但我不是dotnet专家,而是要确定我是在寻找nuget软件包配置选项-与我无关,还是老式的dotnet运行时选项,非常棘手。
更新1:
我尝试使用AppDomain.CreateDomain
,确实可以解决我的问题,但是还需要我为已经加载的API对象提供编组策略。换句话说,如果您要针对具有类似于以下内容的api的插件框架进行编程:
public void DoMyPluginsFunctionality(ApiProvidedInputContext context){
var myPlugin = AppDomain.Create(
strongName: "MyCompany.MyPlugin.; Version=1.2.3.4 ...",
baseDirectory: "C:\\Program Files\\MyPlugin\\bin"
)
//success! MyCompany.MyPlugin loads the version of GRPC I want!
myPlugin.unWrapAsDynamicProxy().doFunctionality(context)
//error: No marshalling strategy and/or not serializable and/or swizzling errors
}
然后,运行时将要求您封送(序列化)context
变量,因为.net不允许您跨AppDomain边界共享内存。
所以我的新问题是:
-鉴于我自己无法使用AppDomains
-鉴于Grpc.core始终发布为AssemblyVersion=1.0.0.0
我有什么选择?
更新2:
GRPC构建系统似乎非常庞大且维护良好,因此我希望可以简单地构建它并更改vcproj文件以包含更新的版本字符串。
不幸的是,这似乎也很复杂,而且我还没有确定目标/交叉编译(x64目标是x86)。