首页 > 代码库 > C#中遍历当前所有进程时存在的陷阱

C#中遍历当前所有进程时存在的陷阱

有时候我们希望我们所写的exe在机器上同一时间只能有一个实例进行运行。通常我们会采取遍历当前所有的进程,如果有的进程exe所在的物理路径就是当前exe的物理路径的话,那么说明这个exe已经启动过一次了,就不再启动了。但是注意,这里有一些需要注意的小细节。

有时候对于编写一个应用程序的守护进程的时候,也要用到这个遍历方法。即我需要另外启动一个进程,这个进程启动后,要查看所有的进程,看看其所检测的进程是否已经启动。那么怎么判断遍历的那个进程是否是其目标进程呢?那么就需要看这个进程exe所在的路径是否与其检测的exe的路径是完全一致的。

首先,对于System与Idle进程的访问是没有权限的,一旦遍历到这个进程,并且调用p.MainModule.FileName方法的时候,就会抛出异常说Access denied. 这也容易理解,毕竟这是操作系统很高层次的进程,是不允许任何人有任何操作的。但是有时候不仅仅是这两个进程,如果你登录电脑的用户不是administrator用户,只是一般的用户,那么可能有更多的进程是不允许访问的。

其实对于我们的程序判断没有太大的影响,因为我们这个exe的层次跟那些拒绝访问的进程的层次不太一样。如果我的exe启动了一个进程,那么我的这个exe遍历所有进程的时候,对于这个已经启动的进程是肯定能访问的。也就是说,我们遍历的时候,肯定能访问我们想要访问的进程,只要它存在我们就能找到。所以对于这些抛出异常的进程,它如果抛出异常,我们程序就没法执行了,我们现在要做的就是,catch到异常,不去任何处理,继续运行我们的程序就行。

  Process[] processes = Process.GetProcesses();
  Process process = null;
  foreach (Process p in processes)
  {
		try
		{  
		   //这里加if就是因为这两个进程的某些属性一旦访问就抛出没有权限的异常
		   if (p.ProcessName != "System" && p.ProcessName != "Idle")
                   {
                     if (p.MainModule.FileName == address)
                     {
                        process = p;
                        break;
                     }
                   }
		}
		catch(Exception ex)
		{
 		    Log.Info(ex.Message);
                }
   }
这里还有一个要注意的东西很重要,就是Console控制台程序的进程。对于一个控制台程序如果你不想同一个时间内有多个实例来运行,那么用这种方法是行不通的!

对于一般Windows Form程序来讲,如果我的程序名为FormApplicationA.exe,那么启动的进程就是FormApplicationA.exe,如果我的程序名为FormApplicationB.exe,那么启动的进程就是FormApplicationB.exe,而且其exe地址也就是真正的地址,比如说C:\\MyFolder\\FormApplicationA.exe 但是Console程序不一样,所有的控制台程序的进程名都是cnhost.exe,不管你的控制台程序名字是什么,这个exe是哪里。比如说,你启动了一个完全不相关的控制台程序ConsoleA.exe,这时遍历所有进程,你会得到cnhost.exe这个进程,而这个进程与ConsoleB.exe要启动的进程是同名,会错误的认为这个ConsoleB.exe已经启动了,就不再启动这个B. 所以这个遍历所有进程的方法对于控制台程序是行不通的。所以,一个控制台进程去守护另外一个控制台进程,使用这种方法是行不通的。

而且有一个cnhost.exe进程,是操作系统在开机的时候自己启动的,它有一定的自己的作用。



What is conhost.exe and Why Is It Running?

You are no doubt reading this article because you are wondering what on earth this conhost.exe process is doing in Task Manager, and why it’s running on your shiny new Windows 7 PC. We’ve got the answer for you.

image

So What Is It?

The conhost.exe process fixes a fundamental problem in the way previous versions of Windows handled console windows, which broke drag & drop in Vista.

It’s a completely legitimate executable—as long as it’s running from the system32 folder, and is signed by Microsoft. Scanning your computer for viruses is never a bad idea, though.

Wait, What? So Why Do I Need It?

Oh, you wanted more information? I suppose I can oblige with some background information. Essentially, there’s a problem with the way the console process works on previous versions of Windows—they are all hosted under the csrss.exe (Client Server Runtime Process) service. This process runs as a system-privileged account.

If you take a look at the command prompt on Windows XP, you’ll probably notice that the window doesn’t use the active theme at all. This is because the CSRSS process doesn’t have the ability to be themed.

image

If you take a look at the console in Windows Vista, it looks like it uses the same theme as everything else, but you’ll notice that the scrollbars are still using the old style (look closely). This is because the DWM (Desktop Window Manager) process handles drawing the title bars, but underneath it still works the same way, and the scrollbars are part of the window itself.

image

You might also notice that Windows Vista broke the ability to drag and drop files from Explorer straight into the command prompt. It just flat out doesn’t work, because of security issues between the CSRSS process running with a higher level of privileges.

Windows 7 Does It Differently

Checking it out in Process Explorer under Windows 7 shows that the conhost.exe process is running underneath the csrss.exe process.

image

The conhost.exe process sitting in the middle between CSRSS and cmd.exe allows Windows 7 to fix both of the problems in previous versions of Windows—not only do the scrollbars draw correctly, but you can actually drag and drop a file from Explorer straight into the command prompt:

image

And it’ll paste in the path onto the command line. (of course this example isn’t very useful).

image

Still Aren’t Convinced?

I can see our relationship has some trust issues. If you really want to be sure, check out the file properties for the conhost.exe executable, and you’ll see that the description says Console Window Host:

image

If you look at the details of the process from within Process Explorer, you’ll notice that the ComSpec is set to cmd.exe, a clear indication that it’s hosting the command prompt.

image

So now you know what the conhost.exe process does, and why you should never attempt to delete it. Ever.