Code Bye

C#怎样在任务管理器中隐藏主程序的进程名

程序被比如说任务管理器强行关闭之后,托盘的图标会残留。
于是,费了很多周折调用了N多API之后,写出了刷新残留图标的代码,包括win7托盘的可见部分和隐藏部分的残留图标。
结果只能在程序启动时判断,如果有上次残留的图标就删掉。
然后开始看“守护进程”
看了大半天做出来了,在控制台项目中用 CreateProcess 将窗体项目程序作为子进程打开,然后 WaitForSingleObject
子进程正常关闭或者被强制关闭之后,我就可以调用之前写好的刷新图标功能了(因为只有一个图标提示文字作为参数)
然后废话说了这么多,现在有两个问题:

1.怎样隐藏“守护进程”,让它不要出现在任务管理器的进程列表中
2.第一个问题没解决掉的话,如果“守护进程”被关闭了,子进程还是在的,所以怎么检测守护进程的关闭然后重新打开,我的想法是用守护进程的守护进程来打开守护进程。

另外能不能不用新建一个控制台应用程序,直接在窗体项目的 Program.cs中用调用编译好的窗体程序?这样会不会导致循环调用然后失败,或者说这样的话窗体程序相当于不存在了,我没啥好的想法了。

这个是控制台程序也就是守护进程的代码:

            //子进程启动信息设置
            STARTUPINFO si = new STARTUPINFO();
            si.cb = Marshal.SizeOf(si);
            ProcessAPI.GetStartupInfo(out si);
            si.wShowWindow = SW_SHOWNORMAL;
            //si.dwFlags = STARTF_USESHOWWINDOW;

            // 运行子进程并等待其结束
            SECURITY_ATTRIBUTES sa = new SECURITY_ATTRIBUTES();
            PROCESS_INFORMATION pi;
            ProcessAPI.CreateProcess(
                "../../../窗体/bin/debug/窗体.exe",
                "", ref sa, ref sa, false, 0, new IntPtr(), null, ref si, out pi);
            ProcessAPI.WaitForSingleObject(pi.hProcess, INFINITE);

            // 获取子进程返回值
            uint pdwExitCode;
            bool flag = ProcessAPI.GetExitCodeProcess(pi.hProcess, out pdwExitCode);

            ProcessAPI.CloseHandle(pi.hProcess);

            if (flag)
            {
                Console.WriteLine("program exit with code {0}", pdwExitCode);
            }
            else
            {
                Console.WriteLine("Error: {0}", new System.ComponentModel.Win32Exception(Marshal.GetLastWin32Error()).Message);
            }

如果放到窗体程序里感觉会简单很多也不用那么蛋疼的路径

主要是想知道第一个问题的解决方法。

另外如果有对托盘图标很强迫症的也可以一起讨论下更好的解决办法。

 
真的是太蠢了。等我感觉到的时候发现进程数已经一千多个了,关也关不掉,到后面卡得各种无响应。
无意间做出了个杀毒软件也查不出来的恶意病毒程序

2分

既然用户想强制用任务管理器结束进程,那么他自己鼠标放到残留的图标上面,图标不就消失了

2分

1.怎样隐藏“守护进程”,让它不要出现在任务管理器的进程列表中
最好不要有这样的想法,你这是在做病毒

2.第一个问题没解决掉的话,如果“守护进程”被关闭了,子进程还是在的,所以怎么检测守护进程的关闭然后重新打开,我的想法是用守护进程的守护进程来打开守护进程。
你的守护进程可以与主进程相互守护,而不是必须用第3个程序监视第2个程序,那样就没完没了了

 
相互?现在是先启动守护进程,然后再创建窗体程序进程然后等待,这样的话窗体程序进程怎么检测到守护进程被关闭?
给个思路就好剩下的我去查

2分

你的守护进程怎么查询窗体进程的,反过来也就怎样查询。
 

没有查。用 WaitForSingleObject(pi.hProcess, INFINITE); 无线等待子进程退出。是不是要用到管道一类的东西啊?

2分

遍历进程列表,如果没有找到你的守护进程,就启动它
 
模仿QQ把守护进程名称改为 svchost.exe 得了,反正被关了也就是窗体程序强制关闭后图标无法正常消失而已不管了,结贴。
 

如果互相监测的话,只能用定时查询。但是和定时查询比起来,WaitForSingleObject INFINITE 浪费的cpu资源少一些。而且为了只能通过启动程序(守护进程)打开主程序,我又在 CreateProcess 里加了命令行参数然后在主程序启动时判断。这样主程序进程就成了守护进程的子进程,子进程获取父进程关闭要用管道。
如果用轮询,就在主程序里定时查查守护进程有没有被关掉,如果被关掉了就重启但是主程序又会被打开一次,所以打开之前再判断下主程序是不是已经在运行了,是这样的吗?
我就是乱七八糟的想法多 越搞越复杂。

2分

你想用管道传递消息,思路是可行的
就是不管进程是否还存在,只要它”死住”了,也就是通信异常了,那么就再启动一个进程

你可以在守护程序里也加个参数啊
如果是被主进程启动的,那么就不要再次启动主进程了
如果是双击exe文件启动的,那么就启动主进程

2分

其实用定时查询,也并不浪费多少CPU啊
进程列表里一共能有多少进程,100个顶天了吧
而且也没有必要每毫秒都轮询一次
每秒甚至每5秒检测一次足够了

2分

关键问题是你应该使用timer这种机制
而不是用个线程死循环
否则浪费CPU就不是检测进程的时候浪费了,而是不检查进程的时候才是在浪费
 
嗯。我的思路是运行守护进程程序时,先判断主程序是否在运行,如果没运行就 CreateProcess,如果在运行就 OpenProcess;同时也判断下自己是否已经在运行了,这样的话问题就都解决了。一开始我以为只有 CreateProcess 才能在后面加 WaitForSingleObject,刚才查了下 OpenProcess 也行的。
另外作为一只编程菜鸟,我最近用过WinAPI之后,甚至都不想用 C#封装好的命名空间里的东西了,这个不知道有没有什么不好的影响。

2分

不好的影响就是,你换个操作系统,API可能不一样的

 

原来如此。
问题终于解决了。双进程还真不是闹着玩的,一不小心就无限循环最后电脑爆炸,完完全全就是病毒啊

 
你的想法是利用守护程序的守护程序来打开守护程序。这种做法很残废,因为你的把残留图标在守护程序里刷新,在创建一个新的守护程序来监视守护程序,再创建一个来控制开合,你有没有想过无论你怎么做,监视和开合的守护程序是会存在残留托盘图标,理论上是不可行,这样只会无限循环。
 
如果真想隐藏掉进程,那就HOOK NtQuerySystemInformation这个函数,判断到你的进程就把他断掉就OK了,任务管理器就看不到了

CodeBye 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权 , 转载请注明C#怎样在任务管理器中隐藏主程序的进程名