Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/332.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/158.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何将ProcessInfo转换为WTS\u PROCESS\u INFO_C#_C++_Process_Pinvoke_Marshalling - Fatal编程技术网

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(
    ....
);