加载.NET程序集依赖项不起作用

alg*_*mus 6 c# dll powershell .net-assembly

我一直在寻找一个解决方案.在我的案例中,没有一个答案适用于从PowerShell会话引用(加载?)程序集.NET到app域.

我首先加载引用(需要由上述DLL引用才能工作[Reflection.Assembly]::LoadFile()或者[Reflection.Assembly]::LoadFrom())然后通过调用加载我的.NET DLL Add-Type.

不幸的是,这不起作用,所以我无法从该DLL创建一些实例.当我使用DLL但没有在正常的C#项目中附加引用时,我得到了相同的错误但是一旦我引用其他程序集并重新编译它就没有错误(我可以确认它是因为我在LinqPad中检查了引用的程序集好).

电源外壳:

[System.Reflection.Assembly]::LoadFile((Get-Item -Path ".\System.Data.SQLite.dll" ).FullName)
Add-Type -Path (Get-Item -Path ".\Connector.dll" ).FullName -ReferencedAssemblies (Get-Item -Path ".\System.Data.SQLite.dll" ).FullName -PassThru | Out-Null
$certMGT = New-Object Connector
Run Code Online (Sandbox Code Playgroud)

该PowerShell脚本的第三行抛出:

New-Object : Exception calling ".ctor" with "0" argument(s): "Failed to find or load the registered .Net Framework Data Provider."
At C:\Repos\Connector\bin\Installer.ps1:306 char:20
+         $certMGT = New-Object Connector
+                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:) [New-Object], MethodInvocationException
    + FullyQualifiedErrorId : ConstructorInvokedThrowException,Microsoft.PowerShell.Commands.NewObjectCommand

PSMessageDetails      : 
Exception             : System.Management.Automation.MethodInvocationException: Exception calling ".ctor" with "0" argument(s): "Failed to find or load the registered .Net Framework
                         Data Provider." ---> System.Configuration.ConfigurationErrorsException: Failed to find or load the registered .Net Framework Data Provider.
                           at System.Data.Common.DbProviderFactories.GetFactory(DataRow providerRow)
                           at System.Data.EntityClient.EntityConnection.GetFactory(String providerString)
                           at System.Data.EntityClient.EntityConnection.ChangeConnectionString(String newConnectionString)
                           at System.Data.Objects.ObjectContext..ctor(String connectionString, String defaultContainerName)
                           at Connector.Entity.ConnectorDBEntities..ctor(String connectionString)
                           at Connector.DBManager..ctor()
                           at Connector.DAL.ConfigurationDAL..ctor()
                           at Connector.ConnectorConfig..ctor()
                           at Connector.ConnectorCertMGT..ctor()
                           --- End of inner exception stack trace ---
                           at System.Management.Automation.DotNetAdapter.AuxiliaryConstructorInvoke(MethodInformation methodInformation, Object[] arguments, Object[] originalArgumen
                        ts)
                           at System.Management.Automation.DotNetAdapter.ConstructorInvokeDotNet(Type type, ConstructorInfo[] constructors, Object[] arguments)
                           at Microsoft.PowerShell.Commands.NewObjectCommand.CallConstructor(Type type, ConstructorInfo[] constructors, Object[] args)
TargetObject          : 
CategoryInfo          : InvalidOperation: (:) [New-Object], MethodInvocationException
FullyQualifiedErrorId : ConstructorInvokedThrowException,Microsoft.PowerShell.Commands.NewObjectCommand
ErrorDetails          : 
InvocationInfo        : System.Management.Automation.InvocationInfo
Run Code Online (Sandbox Code Playgroud)

LinqPad查询(C#Program;引用Connector.dll) - 这个工作正常

void Main()
{
    Assembly.LoadFile(@"C:\Repos\Connector\bin\System.Data.SQLite.dll");
    Connector connector = new Connector();//this also throws exactly the same error if I do not LoadFile as in above line
}
Run Code Online (Sandbox Code Playgroud)

Gre*_*r y 0

第 1 步编译 Connector.dll - 大概您已经完成了

$SQLitePath = convert-path '.\res\sqlite-netFx46-binary-bundle-x64-2015-1.0.114.0\System.Data.SQLite.dll'
add-type -path $SQLitePath

$null = new-item '.\Connector.cs' -value @'
using System;
using System.Data.SQLite;

namespace Powershell.Examples{
public class Connector : System.IDisposable {
   SQLiteConnection con;

   public Connector(){}
   
   public void connect(string Path){
      con = new SQLiteConnection();
      con.ConnectionString = "Data Source=" + Path;
      con.Open();
   }
   
   public void close(){
      if(con.State == System.Data.ConnectionState.Open)
         con.Close();
   }

   bool _disposed = false;
   public void Dispose(){
      Dispose(disposing: true);
      GC.SuppressFinalize(this);
   }
   protected virtual void Dispose(bool disposing){
      if(_disposed) return;
      if(disposing){
         // free managed objects here
         con.Dispose();
      }
      // freee unmanaged objects here
      
      _disposed = true;
   }
   ~Connector(){ Dispose(disposing:false); }
}}
'@
$pams = @{
   TypeDefinition = get-content '.\Connector.cs' -raw
   OutputAssembly = '.\Connector.dll'
   OutputType     = 'Library'
   ReferencedAssemblies = @($SQLitePath,'System.Data')
}
$null = add-type @pams -PassThru
Run Code Online (Sandbox Code Playgroud)

步骤 2 在 Powershell 中使用它

PS C:\Working\Folder> $SQLitePath = convert-path '.\res\sqlite-netFx46-binary-bundle-x64-2015-1.0.114.0\System.Data.SQLite.dll'
PS C:\Working\Folder> add-type -Path $SQLitePath
PS C:\Working\Folder> add-type -Path (convert-path '.\Connector.dll') -ReferencedAssemblies $SQLitePath

PS C:\Working\Folder> $obj = [Powershell.Examples.Connector]::new()
PS C:\Working\Folder> $obj.connect((Convert-Path .)+'\MyData.db')
PS C:\Working\Folder> $obj.close()
PS C:\Working\Folder> $obj.Dispose()
PS C:\Working\Folder> rv obj
Run Code Online (Sandbox Code Playgroud)