gpt4 book ai didi

c# - ConfigurationManager.OpenMappedExeConfiguration 问题

转载 作者:太空宇宙 更新时间:2023-11-03 10:36:57 24 4
gpt4 key购买 nike

我有这个被加载到第三方系统中的类库。多年来我一直使用自定义配置并通过 ConfigurationManager.OpenMappedExeConfiguration() 访问它们,因为这始终允许我将配置文件与 dll 相关联并避免修改第三方系统配置文件。我们目前正在升级系统,现在这不起作用。这个异常给我的印象是它从主机 exe 的位置开始探测程序集。我的组件存储在一个单独的位置,以避免将我的所有东西与他们的混在一起(因为我们有非常多样化的组件集,所以更容易维护)。我发现通过将程序集及其配置放在 exe 的主安装目录中它确实有效,所以我确实认为绑定(bind)是今天的问题,但就像我说的那样,我宁愿避免将我的所有东西复制到该目录。这可能是程序集如何加载到他们的系统中的问题吗? ConfigurationManager 的代码库是否发生了变化?那么远程访问配置文件的更简单的方法是什么?

我在他们的网站上发布了一个论坛问题,但我想我会在这里发布一些内容,以防有人知道不需要了解第三方系统 API (AutoCAD 2015) 的 .NET 解决方法。这是我得到的异常,在我看来像是某种具有约束力的问题。也许他们改变了我们的程序集加载到系统中的方式?他们进行了多项安全更改,所以我想这是可能的。

System.IO.FileNotFoundException was caught _HResult=-2147024894 _message=Could not load file or assembly 'TestAutoCADApp, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified. HResult=-2147024894 IsTransient=false Message=Could not load file or assembly 'TestAutoCADApp, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified. Source=System.Configuration FileName=TestAutoCADApp, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null

FusionLog==== Pre-bind state information === LOG: DisplayName = TestAutoCADApp, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null (Fully-specified) LOG: Appbase = file:///C:/Program Files/Autodesk/AutoCAD 2015/ LOG: Initial PrivatePath = NULL

Calling assembly : System.Configuration, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a.

LOG: This bind starts in default load context. LOG: Using application configuration file: C:\Program Files\Autodesk\AutoCAD 2015\acad.exe.Config LOG: Using host configuration file: LOG: Using machine configuration file from C:\Windows\Microsoft.NET\Framework64\v4.0.30319\co​nfig\machine.config. LOG: Policy not being applied to reference at this time (private, custom, partial, or location-based assembly bind). LOG: Attempting download of new URL file:///C:/Program Files/Autodesk/AutoCAD 2015/TestAutoCADApp.DLL. LOG: Attempting download of new URL file:///C:/Program Files/Autodesk/AutoCAD 2015/TestAutoCADApp/TestAutoCADApp.DLL. LOG: Attempting download of new URL file:///C:/Program Files/Autodesk/AutoCAD 2015/TestAutoCADApp.EXE. LOG: Attempting download of new URL file:///C:/Program Files/Autodesk/AutoCAD 2015/TestAutoCADApp/TestAutoCADApp.EXE.

StackTrace: at System.Configuration.TypeUtil.GetTypeWithReflectio​nPermission(IInternalConfigHost host, String typeString, Boolean throwOnError) at System.Configuration.MgmtConfigurationRecord.Creat​eSectionGroupFactory(FactoryRecord factoryRecord) at System.Configuration.MgmtConfigurationRecord.Ensur​eSectionGroupFactory(FactoryRecord factoryRecord) at System.Configuration.MgmtConfigurationRecord.GetSe​ctionGroup(String configKey) at System.Configuration.Configuration.GetSectionGroup​(String sectionGroupName) at TestAutoCADApp.Commands.TestConfigSettingsAccess(A​ction`1 writeAction) in c:\Development-TVA\Visual Studio 2013\TestCode\TestAutoCADApp\TestAutoCADApp\Comman​ds.cs:line 49 InnerException:

我可以展示自定义配置代码,但如果您不熟悉该系统,那么它对您没有任何好处。所以现在,这里有一个非常 super 通用的示例,说明我如何访问它,它已经有一段时间了。

  Uri uriCodeBase = new Uri(Assembly.GetExecutingAssembly().CodeBase);
FileInfo appfilePath = new FileInfo(uriCodeBase.LocalPath + ".config");

ExeConfigurationFileMap fileMap = new ExeConfigurationFileMap();
fileMap.ExeConfigFilename = appfilePath.FullName;

Configuration configuration = null;

//Retrieve the Configuration file data and return
configuration = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None);

MainGroup mainGroup = configuration.GetSectionGroup("mainGroup") as MainGroup;

MainSection mainSection = mainGroup.Sections["mainSection"] as MainSection;

SomeElement someElement = mainSection.SomeElement;

最佳答案

好吧,我终于收到了供应商的消息,事实证明他们曾经在他们的 API 中处理 AssemblyResolve 事件,如果在加载主 dll 时发生问题,该事件碰巧解决了加载次级 dll 的问题。他们显然对此有疑问,并决定在最新版本中将其删除。他们建议我通过自己注册事件并使用以下代码来处理这个问题(对于那些也对此问题感兴趣的人)。

在原题所示的代码中,在开头添加:

AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;

事件委托(delegate):

    Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{
Assembly assembly = null;
Assembly[] assems = AppDomain.CurrentDomain.GetAssemblies();
String name;
if (args.Name.IndexOf(",") > -1)
name = args.Name.Substring(0, args.Name.IndexOf(","));
else
name = args.Name;

foreach (Assembly assem in assems)
{
if (assem.GetName().Name == name)
{
return assem;
}
}

return assembly;
}

我希望这比实际更有意义,但我猜测 ConfigurationManager 必须尝试访问 dll,就好像它是辅助 dll 一样,以便它可以读取和合并配置文件。它必须正在探测装配并失败。但这只是我的猜测。我不确定。无论哪种方式,实现此方法都会导致在失败时返回正确的程序集。

关于c# - ConfigurationManager.OpenMappedExeConfiguration 问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27401841/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com