C# 如何将ProcessInfo转换为WTS\u PROCESS\u INFO
我试图调用C# 如何将ProcessInfo转换为WTS\u PROCESS\u INFO,c#,c++,process,pinvoke,marshalling,C#,C++,Process,Pinvoke,Marshalling,我试图调用wtsenumerateprocesss(),但在将类型ProcessInfo转换为WTS\u PROCESS\u INFO时遇到一些问题 这是我目前掌握的代码: ProcessInfo class ProcessInfo { public int basePriority; public int handleCount; public int mainModuleId; public long pageF
wtsenumerateprocesss()
,但在将类型ProcessInfo
转换为WTS\u PROCESS\u INFO
时遇到一些问题
这是我目前掌握的代码:
ProcessInfo
class ProcessInfo
{
public int basePriority;
public int handleCount;
public int mainModuleId;
public long pageFileBytes;
public long pageFileBytesPeak;
public long poolNonpagedBytes;
public long poolPagedBytes;
public long privateBytes;
public int processId;
public string processName;
public int sessionId;
public ArrayList threadInfoList;
public long virtualBytes;
public long virtualBytesPeak;
public long workingSet;
public long workingSetPeak;
public ProcessInfo()
{
}
}
WTS\u流程\u信息
public struct WTS_PROCESS_INFO
{
public int SessionID;
public int ProcessID;
// This is spointer to a string...
public IntPtr ProcessName;
public IntPtr userSid;
}
wtsenumerateprocesss()
我认为在定义WTS\u PROCESS\u INFO
和ProcessInfo
之间的关系时,我可能遗漏了一步,但我不确定如何做到这一点。有人能给我指出正确的方向吗
这就是我看到的错误:
// Cannot implicitly convert type 'ProcessInfo' to 'WTS_PROCESS_INFO'
您的
ProcessInfo
类型与WTS\u PROCESS\u INFO
无关。所以这一行:
processInfos[i] = (ProcessInfo)Marshal.PtrToStructure(pProcessInfo, typeof(WTS_PROCESS_INFO));
processInfos[i] = (ProcessInfo)Marshal.PtrToStructure(pProcessInfo,
typeof(WTS_PROCESS_INFO));
实际上包含两个错误。编译器选择一个。具体而言,ProcessInfo[i]
属于WTS\u PROCESS\u INFO
类型,并且与ProcessInfo
不兼容。另一个错误更为微妙。将Marshal.PtrToStructure()
返回的值强制转换为类型ProcessInfo
是错误的。Marshal.PtrToStructure()
返回的值是一个装箱的WTS\u进程\u信息
。因此,代码行应该是:
processInfos[i] = (WTS_PROCESS_INFO)Marshal.PtrToStructure(pProcessInfo,
typeof(WTS_PROCESS_INFO));
您的指针算法可能在64位进程中失败。如果您使用的是最新版本的.net,则可以直接在IntPtr上执行算术:
pProcessInfo += Marshal.SizeOf(processInfos[i]);
或者,如果您以较旧的.net版本为目标,则应在64位上下文中执行该算法,方法是强制转换为ulong
,而不是int
至于你的ProcessInfo
类型,我认为这只是你的错误想法。这种类型在这里似乎没有用处
如果我是你,我会强制使用Unicode版本的WTSEnumerateProcessesW
,例如:
[DllImport("wtsapi32.dll", EntryPoint = "WTSEnumerateProcessesW", SetLastError = true)]
static extern bool WTSEnumerateProcesses(
....
);
要以字符串形式读取进程名称,请将
WTS\u进程信息
struct中返回的指针传递给marshall.PtrToStringUni
您需要在c代码中定义结构WTS\u进程信息。感谢David,您的第一个建议似乎解决了我的问题,因此我最终得到了一个填充的WTS\u进程信息[]!但是,这些项目都有一个ProcessName
属性,它似乎由一组数字组成-有没有办法将其转换为字符串名称(例如explorer.exe)或者这不是那种进程名称?哇,非常感谢David Hefferman-非常有帮助。当我使用string name=Marshal.PtrToStringUni(processInfos[I].processName)
转换我的名字时,我以“睤\u2e6d硥E瑣杸 (但更长的时间)-我猜这就是您推荐使用Unicode版本的部分原因。发生的事情是,您转换了一个ANSI编码的字节数组,就像它是UTF-16一样。并且确实添加了EntryPoint=“WTSEnumerateProcessesW“
到Dllimport解决了最后一个问题。我非常感谢,因为这将帮助我阅读和理解更多有关编组和Dllimports的信息!!FWIW,我认为带有损坏编码的进程实际上被命名为dwm.exe
。
[DllImport("wtsapi32.dll", EntryPoint = "WTSEnumerateProcessesW", SetLastError = true)]
static extern bool WTSEnumerateProcesses(
....
);