我正在尝试使用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无法自行响应和重新启动。
您已确认以下是您的问题:
$EloPath
的值在嵌入式C#代码(@"..."
)中的逐字字符串中使用,因此\
字符。不应该像\\
那样逃脱[1];因此:
$EloPath = "C:\Program Files\Elo Touch Solutions\EloPubIf.dll"
[1]请注意,在PowerShell本身中,\
永远不需要在字符串文字中转义,因为\
不是转义字符。在PowerShell中。
PowerShell的转义字符是`
(反引号)和内部双引号PowerShell字符串,它本身必须作为``
转义才能直接使用。