【问题标题】:ComVisible .NET assembly and app.configComVisible .NET 程序集和 app.config
【发布时间】:2011-12-28 13:10:52
【问题描述】:
  • 我有一些类标记为ComVisible 的.NET 程序集
  • 这个程序集注册到regasm /codebase "assembly_path"
  • 我有 app.config 名称(实际上是 - MyAssemblyName.dll.config),它们位于程序集的文件夹中
  • 我通过ConfigurationManager.AppSettings["SettingName"] 访问我的程序集中的appSettings
  • 我有 VBScript 文件,它通过CreateObject("...") 创建我的 COM 对象
  • 创建对象时(从 VBScript),ConfigurationManager.AppSettings["SettingName"] 返回 null。看起来程序集没有看到配置文件。

我应该怎么做才能使它可行?

【问题讨论】:

    标签: c# .net-4.0 app-config comvisible


    【解决方案1】:

    正如 Komyg 所说,一种可能的方法是直接读取配置文件,而不是使用 ConfigurationManager 的嵌入式行为。对于那些会遇到同样问题的人:而不是

    ConfigurationManager.AppSettings["SettingName"]
    

    你可以使用:

    var _setting = ConfigurationManager.AppSettings["SettingName"];
    // If we didn't find setting, try to load it from current dll's config file
    if (string.IsNullOrEmpty(_setting))
    {
        var filename = Assembly.GetExecutingAssembly().Location;
        var configuration = ConfigurationManager.OpenExeConfiguration(filename);
        if (configuration != null)
            _setting = configuration.AppSettings.Settings["SettingName"].Value;
    }
    

    这样您将始终使用位于程序集文件夹中的文件YourAssemblyName.dll.config 中的读取设置。它还允许您使用 app.config 的其他功能(例如 appSettingfile 属性),如果您使用 XPath 或类似的东西,这些功能将不可用。

    【讨论】:

      【解决方案2】:

      我遇到了同样的问题。需要 app.config 文件的资源管理器 shell 扩展(Com 可见,通过 regasm /codebase 注册)既找不到连接字符串,也找不到设置。

      我做了什么:

      string assemblyLoc          = GetType().Assembly.Location;
      string configName           = assemblyLoc + ".config";
      AppDomain.CurrentDomain.SetData("APP_CONFIG_FILE", configName);
      

      假设配置文件与程序集存储在同一目录中。

      【讨论】:

        【解决方案3】:

        我使用了 sputnik 的答案,在一个 IIS 测试环境中工作得很好,但在另一个环境中却不行。事实证明,设置 APP_CONFIG_FILE 属性后,您可能需要使用反射来触摸 ConfigurationManager 类以使更改生效。我在设置 APP_CONFIG_FILE 属性后使用了这个函数:

            private static void ResetConfiguration()
            {
                typeof(ConfigurationManager)
                    .GetField("s_initState", BindingFlags.NonPublic | BindingFlags.Static)
                    .SetValue(null, 0);
        
                typeof(ConfigurationManager)
                    .GetField("s_configSystem", BindingFlags.NonPublic | BindingFlags.Static)
                    .SetValue(null, null);
        
                typeof(ConfigurationManager)
                    .Assembly.GetTypes()
                    .Where(x => x.FullName == "System.Configuration.ClientConfigPaths")
                    .First()
                    .GetField("s_current", BindingFlags.NonPublic | BindingFlags.Static)
                    .SetValue(null, null);
            }
        

        除此之外,最好先保存属性,然后在完成后恢复它:

        string oldConfigName = AppDomain.CurrentDomain.GetData("APP_CONFIG_FILE").ToString();
                //do custom stuff in here
                AppDomain.CurrentDomain.SetData("APP_CONFIG_FILE", oldConfigName); //re-point to the original configuration.
                ResetConfiguration();
        

        【讨论】:

          【解决方案4】:

          所有内容都在同一个文件夹中吗(您的 dll、vb 脚本、配置文件等)?如果没有,您可以尝试在 PATH 环境变量中添加配置文件的完整路径...

          此外,如果您在 Internet Explorer 中运行此 VB 脚本,您可能会遇到一些安全问题(通常 IE 不允许您访问硬盘驱动器)。在这种情况下,您可以尝试将配置文件放在桌面上,我不知道为什么,但这似乎是它运行 ActiveX 程序时的默认路径,因此对于 VB 脚本也可能如此。

          最后你可以在你的 dll 中添加一些调试,比如创建一个简单的文本文件然后查找它,这样你就可以看到你的系统实际上在哪里运行你的库。

          【讨论】:

          • 当然,所有东西都不在同一个文件夹中。 Dll 和配置文件在一个文件夹中,vbscript - 在另一个文件夹中。并且 vbscript 正在运行通过wscript.exe。所以 99% 的默认文件夹是 c:\windows\system32(我现在会检查)
          • Directory.GetCurrentDirectory() 返回脚本的文件夹
          • 也许您可以直接打开您的配置文件并使用 XPath 获取您的配置,这不是理想的方式,但它可能会工作......
          • 是的,我现在正在尝试,但总的来说 - 有没有办法“开箱即用”?
          猜你喜欢
          • 2011-11-18
          • 2010-10-24
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2010-11-11
          • 2013-06-21
          • 2015-02-17
          • 1970-01-01
          相关资源
          最近更新 更多