Use DLL in PowerShell


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

    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;

        public static extern int EloGetScreenInfo([MarshalAs(UnmanagedType.LPArray, ArraySubType=UnmanagedType.I4, SizeConst = MAX_SUPPORTED_SCR)] [Out] UInt32[] dwMonNo, ref Int32 iScrCnt);

        public static extern int EloGetDiagnosticsData(ref SCREEN_PROPERTIES pData, UInt32 nScrNo);

        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.

asked on Stack Overflow Apr 25, 2019 by Marc05 • edited Apr 25, 2019 by mklement0

1 Answer


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.

answered on Stack Overflow Apr 25, 2019 by mklement0 • edited Jun 28, 2019 by mklement0

User contributions licensed under CC BY-SA 3.0