在 PowerShell 中使用 DLL

Use DLL in PowerShell

我正在尝试在 PowerShell 中使用 DLL 中的函数。我目前有下面的代码,尽管它在调用函数时会导致崩溃。我在这方面还很陌生,所以感谢您的帮助。该代码的目的是在 PowerShell 中使用 EloGetDiagnosticsData() 到 return SCREEN_PROPERTIES pData 到 PowerShell,并在 $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)

运行 PowerShell ISE 中的这个导致 PowerShell ISE 不响应并自行重启。

您已确认以下是您的问题:

$EloPath 的值在嵌入式 C# 代码 (@"...") 的逐字字符串中使用,因此 \ 个字符。不应转义为 \[1];因此:

$EloPath = "C:\Program Files\Elo Touch Solutions\EloPubIf.dll"

[1] 请注意,在 PowerShell 本身中,\ never 需要在字符串文字中转义,因为 \ 不是转义字符。在 PowerShell 中。
PowerShell 的转义字符是 `(反引号),在 双引号 PowerShell 字符串中,它本身必须转义为 `` 才能按字面意义使用。