PowerShell и WinApi - PullRequest
       5

PowerShell и WinApi

1 голос
/ 12 апреля 2020

Я пытался это:

$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)

, но блокнот не запускается. Как мне правильно это записать?

1 Ответ

1 голос
/ 12 апреля 2020

Немедленное исправление имеет два аспекта:

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

    • Поскольку вы явно указали цель ShellExecuteW - версия API-функции Unicode - вы должны объявить этот факт через поле CharSet в атрибуте. [1]

    • Хотя это и не обязательно, int hwnd должно быть IntPtr hwnd.

  • $exec::ShellExecuteW(0, "open", "notepad.exe", 0, 0, 1) ->
    $exec::ShellExecute(0, "open", "notepad.exe", [NullString]::Value, [NullString]::Value, 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
)

Шаг назад: командлет Start-Process позволяет сделать то же самое без необходимости скомпилированных объявлений P / Invoke по запросу:

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

[1] Пропуск суффикса W (ShellExecute), в то время как не , указание значения CharSet тоже работает на практике, хотя документы подразумевает, что тогда вызывается версия ANSI . Однако на практике я этого не вижу: даже при явной передаче аргументов с символами за пределами диапазона ANSI (например, 'file€§ü.txt') в версию функции ANSI они, похоже, правильно передаются в Блокнот. Однако, наоборот, передача такой строки в приложение console never , кажется, передает их правильно, даже при явной ориентации на версию Unicode.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...