我正在尝试这个:
$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)]
由于您明确指定了目标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
-typed参数;默认情况下,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
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版本。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句