【问题标题】:Reading config file from shell extension从 shell 扩展读取配置文件
【发布时间】:2019-11-13 20:47:40
【问题描述】:

我有一个项目被设置为带有 SharpShell 库的 shell 扩展。当我使用regasm 工具(打开/codebase 标志)注册它时,它一直有效,直到我需要通过EntityNetwork 使用数据库。我收到此错误:

找不到名为“EntitiesName”的连接字符串 应用程序配置文件。

当然我在config 文件中有正确的ConnectionString。看来整个 config 文件根本没有被读取。

于是我找到了一种hack解决方案,我把这个放在构造函数中:

    Dim assemblyLoc As String = [GetType].Assembly.Location
    Dim configName As String = assemblyLoc + ".config"
    AppDomain.CurrentDomain.SetData("APP_CONFIG_FILE", configName)

似乎已读取某些内容,但并非所有内容,我收到一个新错误:

System.TypeInitializationException:“System.Data.Entity.Internal.AppConfig”的类型初始化程序引发了异常。 ---> System.Configuration.ConfigurationErrorsException:为 entityFramework 创建配置节处理程序时出错:无法加载文件或程序集“EntityFramework,Version=6.0.0.0,Culture=neutral,PublicKeyToken=b77a5c561934e089”或其依赖项之一。系统找不到指定的文件。

如何使用配置文件或如何使用EntityFramework 进行这种设置?

这就是我的config 文件的样子:

    <?xml version="1.0" encoding="utf-8"?>
    <configuration>
      <configSections>
        <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
        <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
      </configSections>
      <connectionStrings>
        <add name="EntitiesName" connectionString="metadata=res://*/Model1.csdl|res://*/Model1.ssdl|res://*/Model1.msl;provider=System.Data.SqlClient;provider connection string=&quot;***&quot;" providerName="System.Data.EntityClient" />
      </connectionStrings>
      <startup>
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
      </startup>
      <entityFramework>
        <defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
          <parameters>
            <parameter value="mssqllocaldb" />
          </parameters>
        </defaultConnectionFactory>
        <providers>
          <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
        </providers>
      </entityFramework>
    </configuration>

我怀疑我可能需要使用Code-based configuration。如果是这种情况,我会很感激vb.net 指向那个方向的指针。

【问题讨论】:

    标签: .net dll app-config regasm sharpshell


    【解决方案1】:

    经过两天左右的疯狂搜索(对于 vb.net 几乎不存在,甚至对于 c# 总是缺少一些东西),我将这两个类放在一起:

    Imports System.Data.Entity
    Imports System.Data.Entity.Core.EntityClient
    Imports System.Data.SqlClient
    
    Partial Public Class MyConfig
        Inherits DbConfiguration
    
        Public Sub New()
            Me.SetProviderServices("System.Data.SqlClient", Entity.SqlServer.SqlProviderServices.Instance)
        End Sub
    End Class
    
    Public Class ConnectionStringBuilder
        Public Shared Function Construct() As String
            Dim newConnStringBuilder = New SqlConnectionStringBuilder With {
                .UserID = "user",
                .Password = "pass",
                .InitialCatalog = "database",
                .DataSource = "server"
            }
            Dim entityConnectionBuilder = New EntityConnectionStringBuilder With {
                .Provider = "System.Data.SqlClient",
                .ProviderConnectionString = newConnStringBuilder.ToString(),
                .Metadata = "res://*/Model1.csdl|
                                res://*/Model1.ssdl|
                                res://*/Model1.msl"
            }
            Return entityConnectionBuilder.ToString()
        End Function
    End Class
    

    然后,在edmx 模型类(在我的情况下为Model1.Context.vb)中,如下所示:

    '------------------------------------------------------------------------------
    ' <auto-generated>
    '     This code was generated from a template.
    '
    '     Manual changes to this file may cause unexpected behavior in your application.
    '     Manual changes to this file will be overwritten if the code is regenerated.
    ' </auto-generated>
    '------------------------------------------------------------------------------
    
    Imports System
    Imports System.Data.Entity
    Imports System.Data.Entity.Infrastructure
    
    <DbConfigurationType(GetType(MyConfig))>
    Partial Public Class MyEntities
        Inherits DbContext
    
        Public Sub New()
            MyBase.New(ConnectionStringBuilder.Construct())
            'MyBase.New("name=MyEntities")
        End Sub
    
        Protected Overrides Sub OnModelCreating(modelBuilder As DbModelBuilder)
            Throw New UnintentionalCodeFirstException()
        End Sub
    
        Public Overridable Property XXXs() As DbSet(Of XXX)
        'etc...
    
    End Class
    

    我确信可能有更好的方法,但到目前为止这是我所拥有的最好的方法,我将其发布在此处以可能提供帮助和/或进一步讨论/更正。

    【讨论】:

      最近更新 更多