Powershell v2 :: Load a COM Interop DLL - powershell

I have this DataLink DLL on my system - Interop.MSDASC.dll I am trying to load the same from Powershell like this -
[Reflection.Assembly]::LoadFile("C:\Interop.MSDASC.dll") | out-null
But, I get the following error -
Exception calling "LoadFile" with "1" argument(s): "Could not load file or assembly 'Interop.MSDASC.dll' or one of its dependencies. is not a
valid Win32 application. (Exception from HRESULT: 0x800700C1)"
At line:1 char:32
+ [Reflection.Assembly]::LoadFile <<<< ("C:\Interop.MSDASC.dll") | out-null
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : DotNetMethodException
How do I correctly load this ?

This is a 32 bit COM object and therefore you must load it from a 32 bit instance of PowerShell. To do this on a 64 bit version of Windows you can execute powershell.exe or powershell_ISE.exe in this folder:
%SYSTEMROOT%\SysWow64\windowspowershell\v1.0
And, this is the complete code:
[Reflection.Assembly]::LoadFile("C:\Interop.MSDASC.dll")
$dataLinkInstance = new-object MSDASC.DataLinksClass
$dataLinkInstance.WriteStringToStorage("C:\\FrmPowershell.udl", "Provider=SQLOLEDB.1;", 2)

I've just downloaded it from http://datadictionary.codeplex.com/ and load assembly in the same way you use and no issue come:
[System.Reflection.Assembly]::LoadFile( "c:\Program Files\DataDictionaryCreator\Interop.MSDASC.dll")
GAC Version Location
--- ------- --------
False v2.0.50727 c:\Program Files\DataDictionaryCreator\Interop.MSDASC.dll
Are you maybe on a x64 operative system?
if yes read here http://datadictionary.codeplex.com/workitem/28807

$comInterOp = "C\Temp\Interop.YourAssembly.dll"
[System.Reflection.Assembly]::LoadFile($comInterOp)
$yourClassObj = new-object YourAssembly.YourClassNameClass
$yourResult = $yourClassObj.YourMethod()

Related

How can I use the unmanaged UI Automation API from PowerShell

The UI Automation API for Windows is available from two DLLs.
One is a managed DLL, which is C:\Program Files\Reference Assemblies\Microsoft\Framework\v3.0\UIAutomationClient.dll.
The other is an unmanaged DLL, which is C:\Windows\System32\UIAutomationCore.dll.
According to this post, the unmanaged API is superior to the managed API in terms of the number of visible elements, so I would like to use the unmanaged API.
I have tried three approaches, but all of them failed.
Would you tell me the correct approach?
Approach #1: New-Object -ComObject
$uia = New-Object -ComObject <ProgID of CUIAutomation>
$root = $uia.GetRootElement()
Failed because New-Object requires ProgID but CUIAutomation does not have ProgID.
Approach #2: Instantiation from CLSID
The CLSID of CUIAutomation is ff48dba4-60ef-4201-aa87-54103eef594e, then,
$type = [Type]::GetTypeFromCLSID("ff48dba4-60ef-4201-aa87-54103eef594e")
$uia = [Activator]::CreateInstance($type)
$root = $uia.GetRootElement()
but failed with the following error message.
I still do not know why.
Method invocation failed because [System.__ComObject] does not contain a method named 'GetRootElement'.
At line:1 char:1
+ $root = $uia.GetRootElement()
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : MethodNotFound
Approach #3: Add-Type
Add-Type -Path "C:\Windows\System32\UIAutomationCore.dll"
$uia = New-Object UIAutomationClient.CUIAutomation
$root = $uia.GetRootElement()
Failed because Add-Type expects managed DLLs.
Error message:
Add-Type : Could not load file or assembly 'file:///C:\Windows\System32\UIAutomationCore.dll' or one of its dependencies. The module was expected to contain an assembly manifest. At line:1 char:1
+ Add-Type -Path "C:\Windows\System32\UIAutomationCore.dll"
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Add-Type], BadImageFormatException
+ FullyQualifiedErrorId : System.BadImageFormatException,Microsoft.PowerShell.Commands.AddTypeCommand
Edit (2018-06-12)
I tried another approach. (and failed)
Approach #4: Interop DLL
I do not really understand what exactly the Interop DLL is, but this post says the Interop DLL helped OP anyway.
I installed Visual Studio and generated Interop.UIAutomationClient.dll by following the procedures of the post.
Add-Type -Path "Interop.UIAutomationClient.dll"
$uia = New-Object UIAutomationClient.CUIAutomationClass
$root = $uia.GetRootElement()
$children = $root.FindAll([UIAutomationClient.TreeScope]::TreeScope_Children, $uia.CreateTrueCondition())
I succeeded in obtaining $root, but failed at the line of $children with the following error message.
Method invocation failed because [System.__ComObject] does not contain a method named 'FindAll'.
At line:1 char:1
+ $children = $root.FindAll([UIAutomationClient.TreeScope]::TreeScope_C ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : MethodNotFound
I still do not know why.
What about this?:
Add-Type -AssemblyName 'UIAutomationClient'
$ae = [System.Windows.Automation.AutomationElement]
$cTrue = [System.Windows.Automation.PropertyCondition]::TrueCondition
$root = $ae::RootElement
$winNames = $root.FindAll("Children", $cTrue).current.name
I have not yet resolved the problem, but finally found an alternative, that is C# Interactive.
I will leave this question for PowerShell users, but, if you can use C# Interactive as an alternative of PowerShell, the following section may help you.
Approach #5: C# Interactive
Install Visual Studio.
Generate Interop.UIAutomationClient.dll by following the procedures of this post.
Run the following script on csi.exe.
#r "Interop.UIAutomationClient.dll"
var uia = new UIAutomationClient.CUIAutomation();
var root = uia.GetRootElement();
var children = root.FindAll(UIAutomationClient.TreeScope.TreeScope_Children, uia.CreateTrueCondition());
FYI, C# Interactive works if only the following files exist in the same folder (i.e., you can use C# Interactive anywhere just by bringing the following files from the development environment).
C:\Program Files (x86)\MSBuild\14.0\Bin\csi.exe
C:\Program Files (x86)\MSBuild\14.0\Bin\csi.rsp
C:\Program Files (x86)\MSBuild\14.0\Bin\Microsoft.CodeAnalysis.CSharp.dll
C:\Program Files (x86)\MSBuild\14.0\Bin\Microsoft.CodeAnalysis.CSharp.Scripting.dll
C:\Program Files (x86)\MSBuild\14.0\Bin\Microsoft.CodeAnalysis.dll
C:\Program Files (x86)\MSBuild\14.0\Bin\Microsoft.CodeAnalysis.Scripting.dll
C:\Program Files (x86)\MSBuild\14.0\Bin\System.AppContext.dll
C:\Program Files (x86)\MSBuild\14.0\Bin\System.Collections.Immutable.dll
C:\Program Files (x86)\MSBuild\14.0\Bin\System.Diagnostics.StackTrace.dll
C:\Program Files (x86)\MSBuild\14.0\Bin\System.IO.FileSystem.dll
C:\Program Files (x86)\MSBuild\14.0\Bin\System.Reflection.Metadata.dll
Approach 2 you should get to the interface of
IID_IUIAutomation = "{30CBE57D-D9D0-452A-AB13-7AC5AC4825EE}"
CLSID_UIAutomationClient = "{944DE083-8FB8-45CF-BCB7-C477ACB2F897}"
;CoClasses
CLSID_CUIAutomation = "{FF48DBA4-60EF-4201-AA87-54103EEF594E}"
MS Doc states
Remarks
Every UI Automation client application must obtain this interface to a CUIAutomation object in order to gain access to the functionality of UI Automation.
The following example function creates a CUIAutomation object and obtains the
IUIAutomation interface.
IUIAutomation *g_pAutomation;
BOOL InitializeUIAutomation()
{
CoInitialize(NULL);
HRESULT hr = CoCreateInstance(__uuidof(CUIAutomation), NULL, CLSCTX_INPROC_SERVER,
__uuidof(IUIAutomation), (void**)&g_pAutomation);
return (SUCCEEDED(hr));
}
I was not able to get it working in PS but maybe this answers helps partly in the right direction (I have it working in AutoIt but that works differently, you can find it with AutoIt IUIAutomation on google)
$objCUI=[System.Runtime.InteropServices.Marshal]::GetTypeFromCLSID("30CBE57D-D9D0-452A-AB13-7AC5AC4825EE")
or
$Type = [Type]::GetTypeFromCLSID('30CBE57D-D9D0-452A-AB13-7AC5AC4825EE')
$objCUI = [System.Activator]::CreateInstance($Type)
both run but when I come to
$rootEl = $objCUI.GetType().InvokeMember(
"GetRootElement",
"InvokeMethod",
$Null,
$objCUI,
#()
)
I get errors

How to load in Powershell a DLL that is missing a manifest

These lines:
"[Environment]::Is64BitProcess"
"[Reflection.Assembly]::LoadFile("C:\MvxAPI\MvxSockx64.dll")
"
gives these results:
True
Exception calling "LoadFile" with "1" argument(s): "The module was expected to contain an assembly manifest. (Exception from HRESULT: 0x80131018)"
At C:\GitRepo\PowerShellScripts\ApiDllTest.ps1:11 char:1
+ [Reflection.Assembly]::LoadFile("C:\MvxAPI\MvxSockx64.dll")
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : BadImageFormatException
The DLL is supplied by the ERP manufacture (Infor M3) and I'm trying to use it to send transactions to the ERP from a PowerShell program I've created. Since I'm not a system admin but instead just a nerd that supports the ERP, I'm actually clueless as to what I'm doing related to the DLL. Google has gotten me this far but i can't get beyond this error. The same error returns when I attempt to use the non x64 version.
Thanks for your wisdom. All suggestions are appreciated.

Powershell fails to load DLL because manifest is missing

These statements:
[Environment]::Is64BitProcess
[Reflection.Assembly]::LoadFile("C:\MvxAPI\MvxSockx64.dll")
Generate:
True
Exception calling "LoadFile" with "1" argument(s): The module was expected to contain an assembly manifest. (Exception from HRESULT: 0x80131018)
At C:\GitRepo\PowerShellScripts\ApiDllTest.ps1:11 char:1
+ [Reflection.Assembly]::LoadFile("C:\MvxAPI\MvxSockx64.dll")
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : BadImageFormatException
From a PowerShell program I've written, I am trying to send transactions to the ERP system (Infor's M3) via a DLL for APIs. The DLL is provided by the manufacture. Since I am not a system admin but just a nerd supporting the ERP system, I'm clueless as to what I'm doing and have gotten this far with Google but can't get any further. Your suggestions will be greatly appreciated.

Cannot load dll assembly in windows 10 (Exception from HRESULT: 0x80131515)

I was trying to load the compiled dll assembly of JSON.NET. However I get the following error message:
PS C:\Users\tamas\Desktop\garbage> Add-Type -path .\Newtonsoft.Json.dll
Add-Type : Could not load file or assembly 'file:///C:\Users\tamas\Desktop\garbage\Newtonsoft.Json.dll' or one of its d
ependencies. Operation is not supported. (Exception from HRESULT: 0x80131515)
At line:1 char:1
+ Add-Type -path .\Newtonsoft.Json.dll
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Add-Type], FileLoadException
+ FullyQualifiedErrorId : System.IO.FileLoadException,Microsoft.PowerShell.Commands.AddTypeCommand
On a different computer, under windows 7 I was able to do the same thing without any problem.
What could be the cause and the solution?
My .NET version:
PS C:\Users\tamas\Desktop\garbage> [System.Environment]::Version
Major Minor Build Revision
----- ----- ----- --------
4 0 30319 42000
PowerShell version:
PS C:\Users\tamas\Desktop\garbage> $Host.Version
Major Minor Build Revision
----- ----- ----- --------
5 1 14393 206
Thanks to #martin-brandl 's suggeston I was able to figure out the problem (I actually had to modify his code, becuase it did not output anything ($global:error[0].Exception has no LoaderExceptions field.))
PS C:\Users\tamas\Desktop\garbage>
>> try
>> {
>> Add-Type -Path .\Newtonsoft.Json.dll
>> }
>> catch
>> {
>> write-host $global:error[0].Exception.InnerException
>> }
System.NotSupportedException: An attempt was made to load an assembly from a network location which would have caused th
e assembly to be sandboxed in previous versions of the .NET Framework. This release of the .NET Framework does not enabl
e CAS policy by default, so this load may be dangerous. If this load is not intended to sandbox the assembly, please ena
ble the loadFromRemoteSources switch. See http://go.microsoft.com/fwlink/?LinkId=155569 for more information.
It turned out that since the dll file was from an external source, for safety reasons powershell threw an exception. Using th UnsafeLoadFrom(...) method I was able to load the dll assembly:
PS C:\Users\tamas\Desktop\garbage> [System.Reflection.Assembly]::UnsafeLoadFrom("c:\users\tamas\Desktop\garbage\Newtonso
ft.Json.dll") # absolute path required here!!
GAC Version Location
--- ------- --------
False v4.0.30319 C:\Users\tamas\Desktop\garbage\Newtonsoft.Json.dll
More info on this issue can be found on the msdn site here .
I can't tell you which of the dependencies you are missing but I can tell you how to find it out. Just surround your Add-Type within a try-catch cand retrieve the LoaderException:
try
{
Add-Type -Path .\Newtonsoft.Json.dll
}
catch
{
$global:error[0].Exception.LoaderExceptions | % { Write-Host $_ }
}

Problems loading iTextSharp in PowerShell

I am having problem loading the iTextSharp.dll in PowerShell. Sometimes it works fine using either:
[System.Reflection.Assembly]::LoadFrom("C:\dll\itextsharp.dll")
Add-Type -Path C:\dll\itextsharp.dll'
However, most times I get the following error:
Exception calling "LoadFrom" with "1" argument(s):
"Could not load file or assembly 'file:/// C:\dll\itextsharp.dll'
or one of its dependencies. Operation is not supported.
(Exception from HRESULT: 0x80131515)"
At line:1 char:1
+ [System.Reflection.Assembly]::LoadFrom("itextsharp.dll")
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : FileLoadException
I have tried unblocking the file but I still get the error above.
Looks like this on StackOverflow will probably solve your problem. Apparently you need to add the option <loadFromRemoteSources enabled="true" /> to the .EXEs config file to load an assembly from a network share.
I found this by searching for the HRESULT 0x80131515
I have found that the DLL works with PowerShell ISE (x86), but not the 64-bit version of PowerShell ISE.