powershell 加载.NET程序集依赖项无效

sbdsn5lh  于 2023-02-04  发布在  Shell
关注(0)|答案(1)|浏览(164)

我已经寻找了几天的解决方案。没有一个答案在我的情况下工作,这是引用(加载?)程序集。NET到应用程序域从PowerShell会话。
我首先加载引用(前面提到的DLL需要引用这些引用才能运行[Reflection.Assembly]::LoadFile()[Reflection.Assembly]::LoadFrom()),然后通过调用Add-Type加载我的. NET DLL。
不幸的是,这是不工作,所以我不能从该DLL创建一些示例。我得到同样的错误时,我使用DLL没有引用附加在一个正常的C#项目,但只要我引用其他程序集和重新编译它的工作没有错误(我可以确认这是因为引用的程序集,因为我检查了LinqPad以及)。
动力 shell :

[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

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

LinqPad查询(C#程序;引用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
}
bf1o4zei

bf1o4zei1#

步骤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

步骤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

相关问题