我很难使用Dll导入的win api函数来正确工作,这可能与字符串的编码方式有关。
实际上,我正在尝试使用kernel32.dll中的CreateProcess。
它是以下列方式导入的:
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern bool CreateProcess(
[MarshalAs(UnmanagedType.LPStr)] string ApplicationName,
[MarshalAs(UnmanagedType.LPStr)] ref string CommandLine,
ref SECURITY_ATTRIBUTES ProcessAttributes,
ref SECURITY_ATTRIBUTES ThreadAttributes,
bool InheritHandles,
uint CreationFlags,
IntPtr Environment,
[MarshalAs(UnmanagedType.LPStr)] string CurrentDirectory,
[In] ref StartupInfo StartupInfo,
out PROCESS_INFORMATION ProcessInformation);在代码中,调用如下:
var fileName = PInvokeEncode(FileName);
var arguments = PInvokeEncode(Arguments);
workingDirectory = PInvokeEncode(workingDirectory);
//var arguments = Arguments.ToString(pinvokeEncoding);
if (!ProcessUtility.CreateProcess(
fileName,
ref arguments,
ref processAttributes,
ref threadAttributes,
true, //inherit handles
(uint)(CreationFlags.CREATE_NEW_CONSOLE | CreationFlags.CREATE_UNICODE_ENVIRONMENT),
IntPtr.Zero, //inherits current environement
workingDirectory,
ref startupInfo,
out processInformation))
{
throw new Win32Exception("CreateProcessAsUser");
}
...
...
...
private static readonly Encoding PInvokeEncoding = Encoding.ASCII;
private static string PInvokeEncode(string value)
{
var bytes = Encoding.Default.GetBytes(value);
var encodedString = PInvokeEncoding.GetString(bytes);
return encodedString;
}在一个夹具中,我启动了一个调用CreateProcess的测试,使用文件名= @"c:\Windows\System32\cmd.exe"和参数= @"/C ""c:\Windows\System32\ping.exe /?"""
如您所见,在任务管理器中,当我启动一个新的cmd.exe时,命令行列中显示的值无效:

它应该显示c:\Windows\System32\cmd.exe /C "c:\Windows\System32\ping.exe /?"
知道如何纠正任务管理器的编码以显示正确的字符串吗?
发布于 2015-08-07 08:42:44
是的,你的调用是错误的。您已经询问了该函数的Unicode版本,但也要求传递ANSI字符串。您的屏幕截图不符合问题中的代码。如果您在问题中确实使用了代码,那么系统就不可能对任何一个字符串进行解码。
另一个错误是在第二个参数上使用ref。你必须把它移除。
pinvoke.net的版本很好:
[DllImport("kernel32.dll", SetLastError=true, CharSet=CharSet.Auto)]
static extern bool CreateProcess(
string lpApplicationName,
string lpCommandLine,
ref SECURITY_ATTRIBUTES lpProcessAttributes,
ref SECURITY_ATTRIBUTES lpThreadAttributes,
bool bInheritHandles,
uint dwCreationFlags,
IntPtr lpEnvironment,
string lpCurrentDirectory,
[In] ref STARTUPINFO lpStartupInfo,
out PROCESS_INFORMATION lpProcessInformation);您可能更喜欢使用IntPtr SECURITY_ATTRIBUTES来代替ref SECURITY_ATTRIBUTES,以便为这些参数传递IntPtr.Zero。
https://stackoverflow.com/questions/31872962
复制相似问题