I'm trying to use a function from a DLL in PowerShell. I currently have the code below, though it leads to a crash when calling the function. I'm fairly new at this, so any help is appreciated. The purpose of the code is to use EloGetDiagnosticsData()
in PowerShell to return SCREEN_PROPERTIES pData
to PowerShell, and use it in a $variable
.
$EloPath = "C:\\Program Files\\Elo Touch Solutions\\EloPubIf.dll"
$Signature = @"
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
namespace EloPublicInterface
{
[Flags]
public enum CONTRL_STAT // ctrl_status values
{
CS_OK = 0x00000000,
CS_ConstantTouch = 0x00000001,
CS_CanNotFindController = 0x00000002,
CS_NoResponse = 0x00000003,
CS_InvalidResponse = 0x00000004,
CS_CanNotSetBaudRate = 0x00000005,
CS_CommandNotSent = 0x00000006,
CS_SystemError = 0x00000007,
CS_InvalidCommPort = 0x00000008,
CS_CommPortFailedOpen = 0x00000009,
CS_CommPortCommandError = 0x00000010,
CS_CommPortNoController = 0x00000011,
CS_UndefinedController = 0x00000012
}
[StructLayout(LayoutKind.Sequential)]
public struct SCREEN_PROPERTIES
{
private const int COMPORT_NAME_LENGTH = 256;
public Int32 iWindowsMonNo ;
public UInt32 Type;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = COMPORT_NAME_LENGTH)] // unicode
public String Port;
private const int SERIALNUMBER_NAME_LENGTH = 18;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=SERIALNUMBER_NAME_LENGTH)] // the rest is ansi
public String SerialNumber;
public UInt32 HardwareHandshaking ;
public CONTRL_STAT ctrl_status;
public Int32 BaudRate;
public SByte crevminor;
public SByte crevmajor;
public SByte trevminor;
public SByte trevmajor;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=8)]
public String diagcodes;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=8)]
public String id;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=8)]
public String cnt_id;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=32)]
public String driver_id;
}
public class EloPubIf
{
private const int MAX_SUPPORTED_SCR = 256;
[DllImport(@"$EloPath")]
public static extern int EloGetScreenInfo([MarshalAs(UnmanagedType.LPArray, ArraySubType=UnmanagedType.I4, SizeConst = MAX_SUPPORTED_SCR)] [Out] UInt32[] dwMonNo, ref Int32 iScrCnt);
[DllImport(@"$EloPath")]
public static extern int EloGetDiagnosticsData(ref SCREEN_PROPERTIES pData, UInt32 nScrNo);
[DllImport(@"$EloPath")]
public static extern int EloGetSerialNumbers(UInt32 nScreenIndex, [In, Out] char[] pszUsbControllerSN, UInt32 nUsbControllerSNBufLen, [In, Out] char[] pszSensorSN, UInt32 nSensorSNBufLen);
}
}
"@
Add-Type -TypeDefinition $Signature -Language CSharp
$EloProperties = New-Object -TypeName EloPublicInterface.SCREEN_PROPERTIES
[System.UInt32]$EloScreenNumber = 1
[EloPublicInterface.EloPubIf]::EloGetDiagnosticsData([ref]$EloProperties, $EloScreenNumber)
Running this in PowerShell ISE leads to PowerShel ISE not responding and restarting on its own.
You've confirmed that the following was your problem:
The value of $EloPath
is used inside a verbatim string in the embedded C# code (@"..."
), so \
chars. shouldn't be escaped as \\
[1]; therefore:
$EloPath = "C:\Program Files\Elo Touch Solutions\EloPubIf.dll"
[1] Note that in PowerShell itself, \
never needs escaping in string literals, because \
isn't an escape char. in PowerShell.
PowerShell's escape character is `
( backtick) and inside double-quoted PowerShell strings it must itself be escaped as ``
to be used literally.
User contributions licensed under CC BY-SA 3.0