在 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 字符串中,它本身必须转义为 ``
才能按字面意义使用。
我正在尝试在 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 字符串中,它本身必须转义为 ``
才能按字面意义使用。