在PowerShell中使用DLL

问题描述 投票:0回答:1

我正在尝试使用PowerShell中的DLL函数。我目前有以下代码,但在调用函数时会导致崩溃。我对此很新,所以任何帮助都表示赞赏。代码的目的是在PowerShell中使用EloGetDiagnosticsData()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无法自行响应和重新启动。

c# powershell escaping pinvoke
1个回答
1
投票

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

$EloPath的值在嵌入式C#代码(@"...")中的逐字字符串中使用,因此\字符。不应该像\\那样逃脱[1];因此:

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

[1]请注意,在PowerShell本身中,\永远不需要在字符串文字中转义,因为\不是转义字符。在PowerShell中。 PowerShell的转义字符是`(反引号)和内部双引号PowerShell字符串,它本身必须作为``转义才能直接使用。

© www.soinside.com 2019 - 2024. All rights reserved.