Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/.htaccess/5.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
如何使用PSAPI在C#中获取进程列表?_C#_Pinvoke - Fatal编程技术网

如何使用PSAPI在C#中获取进程列表?

如何使用PSAPI在C#中获取进程列表?,c#,pinvoke,C#,Pinvoke,我试图得到一个进程ID和文件名列表,但它给了我很多问题 这里是控制台输出: success=True bytesCopied=344 Name '<unknown>' PID '0' Name '<unknown>' PID '4' Name '<unknown>' PID '308' Name '<unknown>' PID '440' Name '<unknown>' PID '488' Name '<unknown>'

我试图得到一个进程ID和文件名列表,但它给了我很多问题

这里是控制台输出:

success=True
bytesCopied=344
Name '<unknown>' PID '0'
Name '<unknown>' PID '4'
Name '<unknown>' PID '308'
Name '<unknown>' PID '440'
Name '<unknown>' PID '488'
Name '<unknown>' PID '512'
Name '<unknown>' PID '548'
Name '<unknown>' PID '572'
Name '<unknown>' PID '580'
Name '<unknown>' PID '644'
Name '<unknown>' PID '732'
Name '<unknown>' PID '792'
Name '<unknown>' PID '816'
Name '<unknown>' PID '860'
Name '<unknown>' PID '940'
Name '<unknown>' PID '992'
Name '<unknown>' PID '264'
Name '<unknown>' PID '1160'
Name '<unknown>' PID '1220'
Name '<unknown>' PID '1292'
Name '<unknown>' PID '1424'
Name '<unknown>' PID '1452'
Name '<unknown>' PID '1556'
Name '<unknown>' PID '1596'
Name '<unknown>' PID '2044'
Name '<unknown>' PID '1504'
Name '<unknown>' PID '1132'
Name '<unknown>' PID '1912'
Name '<unknown>' PID '1972'
Name '<unknown>' PID '2084'
Name '<unknown>' PID '2124'
Name '<unknown>' PID '2560'
Name '<unknown>' PID '2796'
Name '<unknown>' PID '2808'
Name '<unknown>' PID '3000'
Name '<unknown>' PID '2116'
Name 'DTAgent.exe' PID '2228'
Name 'ISUSPM.exe' PID '2644'
Name 'DTShellHlp.exe' PID '2652'
Name 'Dropbox.exe' PID '2664'
Name 'acrotray.exe' PID '3124'
Name 'RIMBBLaunchAgent.exe' PID '3180'
Name 'vmware-tray.exe' PID '3188'
Name '<unknown>' PID '3520'
Name '<unknown>' PID '3592'
Name '<unknown>' PID '3780'
Name '<unknown>' PID '3964'
Name 'TrueCrypt.exe' PID '3392'
Name '<unknown>' PID '3800'
Name '<unknown>' PID '4680'
Name '<unknown>' PID '680'
Name 'FileZilla server.exe' PID '2240'
Name 'mysqld.exe' PID '4160'
Name 'uTorrent.exe' PID '7796'
Name 'svchost.exe' PID '44412'
Name '<unknown>' PID '10624'
Name '<unknown>' PID '35644'
Name 'httpd.exe' PID '44260'
Name 'httpd.exe' PID '40556'
Name '<unknown>' PID '11488'
Name 'RIMDeviceManager.exe' PID '42832'
Name 'BbDevMgr.exe' PID '45108'
Name '<unknown>' PID '31208'
Name '<unknown>' PID '34812'
Name 'trillian.exe' PID '61420'
Name 'Microsoft Visual C++ 6.0.exe' PID '52212'
Name '<unknown>' PID '33752'
Name '<unknown>' PID '47564'
Name '<unknown>' PID '39952'
Name 'mysqld-opt.exe' PID '61884'
Name 'winamp.exe' PID '42008'
Name 'opera.exe' PID '4560'
Name 'PowerGREP.exe' PID '12860'
Name 'PowerGREP.exe' PID '13280'
Name 'GOLD Parser Builder.exe' PID '32368'
Name 'Server.exe' PID '16396'
Name '<unknown>' PID '50976'
Name 'xampp-control.exe' PID '56084'
Name 'notepad++.exe' PID '27932'
Name 'WinAMP2.exe' PID '23336'
Name '<unknown>' PID '8044'
Name 'devenv.exe' PID '61172'
Name '<unknown>' PID '14780'
Name '<unknown>' PID '52180'
Name 'Sputnik.vshost.exe' PID '3672'
Name '<unknown>' PID '39480'

正如你可以看到的,很多PID实际上都没有文件名,我也不知道为什么大部分的时候我也复制了C++中没有工作的代码,我也厌倦了pPoCKE上的代码,也没能做到。 这是c代码

使用系统;
使用System.Collections.Generic;
使用系统文本;
使用System.IO;
使用System.Runtime.InteropServices;
使用系统诊断;
名称空间测试
{
公共类枚举进程
{
#地区API
[DllImport(“psapi”)]
私有静态外部bool enumprocess([marshallas(UnmanagedType.LPArray,ArraySubType=UnmanagedType.U4)][In][Out]IntPtr[]processid,UInt32 arraySizeBytes,[marshallas(UnmanagedType.U4)]Out UInt32 bytescomped);
[DllImport(“kernel32.dll”)]
静态外部IntPtr OpenProcess(ProcessAccessFlags dwDesiredAccess[Marshallas(UnmanagedType.Bool)]Bool bInheritHandle,IntPtr dwProcessId);
[DllImport(“kernel32.dll”,SetLastError=true)]
[返回:Marshallas(UnmanagedType.Bool)]
静态外部布尔闭合手柄(IntPtr hObject);
[DllImport(“psapi.dll”)]
静态外部uint GetModuleFileNameEx(IntPtr hProcess,IntPtr hModule,[Out]StringBuilder lpBaseName,[In][Marshallas(UnmanagedType.U4)]int nSize);
[DllImport(“psapi.dll”,SetLastError=true)]
公共静态外部布尔EnumProcessModule(IntPtr hProcess,
[Out]IntPtr lphModule,
uint cb,
[Marshallas(UnmanagedType.U4)]输出uint lpcbNeeded;
[DllImport(“psapi.dll”)]
静态外部单元GetModuleBaseName(IntPtr hProcess,IntPtr hModule,[Out]StringBuilder lpBaseName,[In][marshallas(UnmanagedType.U4)]int nSize);
#端区
#区域枚举
[旗帜]
枚举ProcessAccessFlags:uint
{
All=0x001F0FFF,
终止=0x00000001,
CreateThread=0x00000002,
VMOperation=0x00000008,
VMRead=0x00000010,
VMWrite=0x00000020,
DupHandle=0x00000040,
SetInformation=0x00000200,
查询信息=0x00000400,
同步=0x00100000
}
#端区
静态字符串PrintProcessName(IntPtr processID)
{
字符串sName=“”;
boolbfound=false;
IntPtr hProcess=OpenProcess(ProcessAccessFlags.QueryInformation | ProcessAccessFlags.VMRead,false,processID);
if(hProcess!=IntPtr.Zero)
{
StringBuilder szProcessName=新的StringBuilder(260);
IntPtr hMod=IntPtr.Zero;
uint cbNeeded=0;
EnumProcessModule(hProcess,hMod,(uint)Marshal.SizeOf(typeof(IntPtr)),out-cbNeeded);
if(GetModuleBaseName(hProcess,hMod,szProcessName,szProcessName.Capacity)>0)
{
sName=szProcessName.ToString();
bFound=真;
}
//关闭进程句柄
CloseHandle(hProcess);
}
如果(!bFound)
{
sName=“”;
}
返回sName;
}
公共静态void Testy()
{
UInt32阵列化=9000;
UInt32阵列字节大小=阵列大小*大小(UInt32);
IntPtr[]processIds=新的IntPtr[arraySize];
UInt32字节复制;
bool success=enumprocess(processid、arrayBytesSize、out bytescomped);
WriteLine(“success={0}”,success);
WriteLine(“bytescompiled={0}”,bytescompiled);
如果(!成功)
{
控制台。WriteLine(“Boo!”);
返回;
}
如果(0==字节复制)
{
控制台。WriteLine(“没人在家!”);
返回;
}
UInt32 numIdsCopied=字节复制>>2;
如果(0!=(字节和3))
{
UInt32 partialwordbytes=字节复制&3;
WriteLine(“枚举进程复制了{0}和{1}/4th DWORD…请向它请求另一个{2}/4th DWORD”,
numIdsCopied,partialWordBytes,4-partialWordBytes);
返回;
}
对于(UInt32 index=0;index
正如您所看到的,通过调用Testy函数,它将列出系统上的所有进程,但它将无法获取它们的所有名称。。。有人能解决这个问题吗?谢谢:)


为了记录在案,我也尝试过将模块作为一个数组,它也会产生完全相同的结果。

使用System.Diagnostics,我尝试了以下方法:

foreach(Process theprocess in Process.GetProcesses())
{
            Console.WriteLine("Process: {0} ID: {1}", theprocess.ProcessName, theprocess.Id);
}
得到了这个结果:

进程:代理ID:2948
进程:OUTLOOK ID:3144
进程:ctfmon ID:3136

现在,我是WinXP机器上的管理员。。。可以说是YMMV


我知道您已经声明要使用PSAPI,但您是否有理由使用PSAPI而不仅仅是常规托管C?

您可以使用System.Diagnostics命名空间来尝试此操作

    foreach (Process theProcess in Process.GetProcesses())
    {
        StringBuilder sb = new StringBuilder();
        try
        {
            sb.AppendLine(theProcess.Modules[0].FileName);
        }
        catch { }
        Console.WriteLine("Process: {0}  ID:  {1}", sb, theProcess.Id);
    }
这不会显示系统或空闲进程可执行文件名,因为它们不会加载模块

  • 您应该使用
    System.Diagnostics
    名称空间尝试此操作如果您想要完整路径,可以:

    process.MainModule.FileName
    
  • 要让它在其他用户进程上工作,您需要是管理员(真正的管理员,因此没有UAC或UAC提升),因为您需要启用
    SeDebugPrivilege
    。从C#开始:

    请参阅MSDN上的
        foreach (Process theProcess in Process.GetProcesses())
        {
            StringBuilder sb = new StringBuilder();
            try
            {
                sb.AppendLine(theProcess.Modules[0].FileName);
            }
            catch { }
            Console.WriteLine("Process: {0}  ID:  {1}", sb, theProcess.Id);
        }
    
    process.MainModule.FileName
    
    try { Process.EnterDebugMode(); } catch(Win32Exception) { /* Not admin */ }