PowerShell和WinApi

PowerShell和WinApi,powershell,winapi,Powershell,Winapi,我试着这样做: $signature = @' [DllImport("shell32.dll")] public static extern int ShellExecuteW( int hwnd, string lpOperation, string lpFile, string lpParameters, string lpDirectory, int nShowCmd ); '@ $exec = Add-Type -memberDefinition

我试着这样做:

$signature = @'
[DllImport("shell32.dll")]
public static extern int ShellExecuteW(
  int    hwnd,
  string lpOperation,
  string lpFile,
  string lpParameters,
  string lpDirectory,
  int     nShowCmd
);
'@

$exec = Add-Type -memberDefinition $signature -name "win" -namespace Win32Functions -passThru

$exec::ShellExecuteW(0, "open", "notepad.exe", 0, 0, 1)

但是记事本没有启动。我如何正确地写下它?

即时解决方案有两个方面:

  • [DllImport(“shell32.dll”)]
    ->
    [DllImport(“Shell32.dll”,CharSet=CharSet.Unicode)]

    • 由于您明确地以API函数的Unicode版本
      ShellExecuteW
      为目标,因此必须通过属性中的
      CharSet
      字段声明该事实。[1]

    • 虽然不是严格必需的,
      int-hwnd
      应该是
      IntPtr-hwnd

  • $exec::ShellExecuteW(0,“打开”,“notepad.exe”,0,0,1)
    ->
    $exec::ShellExecute(0,“打开”,“notepad.exe”,[NullString]::值,[NullString]::值,1)

    • 注意使用
      [NullString]::Value
      null
      传递给
      string
      类型的参数;默认情况下,PowerShell将字符串上下文中的
      $null
      视为空字符串,而不是
      null
      ;但是,在这种特殊情况下,空字符串(因此,
      $null
      )也可以工作
总而言之:

$exec = Add-Type -name "win" -namespace Win32Functions -passThru -memberDefinition @'
[DllImport("shell32.dll", CharSet=CharSet.Unicode)]
public static extern int ShellExecuteW(
  IntPtr hwnd,
  string lpOperation,
  string lpFile,
  string lpParameters,
  string lpDirectory,
  int    nShowCmd
);
'@

$exec::ShellExecuteW(
  0, 
  'open', 
  'notepad.exe', 
  [NullString]::Value, 
  [NullString]::Value, 
  1
)

退一步:cmdlet允许您执行相同的操作,而无需按需编译p/Invoke声明:

# Use -WorkingDirectory, if  needed.
Start-Process Notepad.Exe -Verb Open -WindowStyle Normal

[1] 省略
W
后缀(
ShellExecute
),而不指定
CharSet
值在实践中也会起作用,尽管这意味着随后会调用ANSI版本。然而,我在实践中看不到这一点:即使将字符超出ANSI范围的参数(例如,
'file§.txt'
)显式地传递到函数的ANSI版本,它们似乎也能正确地传递到记事本。然而,相反地,将这样的字符串传递给控制台应用程序似乎永远不会正确地传递它们,即使是显式地以Unicode版本为目标