I have been searching for a solution for a couple of days. None of the answers work in my case which is to reference (load?) assemblies .NET into app domain from PowerShell session.
I load references first (that are required to be referenced by the aforementioned DLL to be working [Reflection.Assembly]::LoadFile()
or [Reflection.Assembly]::LoadFrom()
) then I load my .NET DLL by calling Add-Type
.
Unfortunately that is not working so I cannot create a few instances from that DLL. I am getting the same errors when I use DLL without references attached in a normal C# project but as soon as I reference the other assemblies and recompile it works without errors (I can confirm it is because of referenced assemblies as I checked that in LinqPad as well).
PowerShell:
[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
third line of that PowerShell script throws:
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 query (C# Program; references Connector.dll) - this works fine
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
}
You should use Assembly.LoadFrom. Relevant blog posts: http://blogs.msdn.com/b/suzcook/archive/2003/09/19/loadfile-vs-loadfrom.aspx http://blogs.msdn.com/b/suzcook/archive/2003/05/29/57143.aspx
Step 1 Compile Connector.dll - presumably you already have that done
$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
Step 2 Use it in 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
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.