none
VB.net ProcessModule类枚举进程模块的问题. RRS feed

  • 问题

  • 本人用processmodule类写了一个枚举本地进程和模块的小程序,如下:

    Imports System.Diagnostics
    Imports System.IO
    
    Module Module1
    
        Sub Main()
            ListProcess()
            Console.ReadKey()
        End Sub
    
        Sub ListProcess()
            Dim pProcessList() As Process
            Dim stcMyProcessParams() As stcProcessParams
            Dim pProcess As Process
    
            pProcessList = Process.GetProcesses()
    
            ReDim stcMyProcessParams(pProcessList.GetUpperBound(0))
    
    
            For m As Integer = 0 To pProcessList.GetUpperBound(0)
    
                pProcess = pProcessList(m)
    
                stcMyProcessParams(m).ModuleName = pProcess.ProcessName                                                      '主进程名
    
    
                Try
                    stcMyProcessParams(m).ModulePathName = pProcess.MainModule.FileName.ToString                             '主进程路径
                Catch ex As Exception
                    WriteLog("Error # 1")
                    WriteLog(ex.GetType.ToString)
                    WriteLog(ex.Message)
                End Try
    
                Try
                    stcMyProcessParams(m).ModuleDescription = pProcess.MainModule.FileVersionInfo.FileDescription.ToString   '主进程文件描述
    
                Catch ex As Exception
                    WriteLog("Error # 2")
                    WriteLog(ex.GetType.ToString)
                    WriteLog(ex.Message)
                End Try
    
                Console.WriteLine("==================================================")
                Console.WriteLine("主进程名:" & stcMyProcessParams(m).ModuleName)
                Console.WriteLine("主进程路径:" & stcMyProcessParams(m).ModulePathName)
                Console.WriteLine("描述:" & stcMyProcessParams(m).ModuleDescription)
                Console.WriteLine("==================================================")
    
                ListModule(pProcess)
    
            Next
        End Sub
    
        Structure stcProcessParams
            Dim ModuleName As String
            Dim ModulePathName As String
            Dim ModuleDescription As String
        End Structure
    
        Sub ListModule(ByVal pProcess As Process)
            Dim myProcessModuleCollection As ProcessModuleCollection
            Dim myProcessModule As ProcessModule
            Dim stcProcessParams() As stcProcessParams
    
            Try
                myProcessModuleCollection = pProcess.Modules
    
                ReDim stcProcessParams(myProcessModuleCollection.Count - 1)
    
    
                For i As Integer = 0 To myProcessModuleCollection.Count - 1
                    myProcessModule = myProcessModuleCollection(i)
                    Try
                        stcProcessParams(i).ModuleName = myProcessModule.ModuleName.ToString
                    Catch ex As Exception
                        WriteLog("Error # 3")
                        WriteLog(ex.GetType.ToString)
                        WriteLog(ex.Message)
                    End Try
    
                    Try
                        stcProcessParams(i).ModulePathName = myProcessModule.FileName.ToString
                    Catch ex As Exception
                        WriteLog("Error # 4")
                        WriteLog(ex.GetType.ToString)
                        WriteLog(ex.Message)
                    End Try
    
    
                    Try
                        stcProcessParams(i).ModuleDescription = myProcessModule.FileVersionInfo.FileDescription.ToString
                    Catch ex As Exception
                        WriteLog("Error # 5")
                        WriteLog(ex.GetType.ToString)
                        WriteLog(ex.Message)
                    End Try
    
                    Console.WriteLine("模块名:" & stcProcessParams(i).ModuleName)
                    Console.WriteLine("模块路径:" & stcProcessParams(i).ModulePathName)
                    Console.WriteLine("模块描述:" & stcProcessParams(i).ModuleDescription)
                Next
            Catch ex As Exception
                WriteLog("Error # 6")
                WriteLog(ex.GetType.ToString)
                WriteLog(ex.Message)
            End Try
    
    
    
        End Sub
    
        Public Sub WriteLog(ByVal sLog As String)
            Dim MyLogFileName As String
            MyLogFileName = Format(Now(), "yyyyMMdd") & ".log"
            Dim MyLogFile As New FileStream(MyLogFileName, FileMode.Append)
            Dim MyLogWriter As New StreamWriter(MyLogFile)
            MyLogWriter.WriteLine(Now.ToString & "  " & sLog)
            MyLogWriter.Close()
            MyLogFile.Close()
        End Sub
    
    End Module
    运行后有好多类型的错误,Error 1 ,2 ,5,6都有碰到,出错信息有:未将对象引用设置到对象的实例。路径中具有非法字符。拒绝访问。无法枚举进程模块。
    其中,无法枚举进程模块问题出在system和idle这两个进程,查了下资料说这两个系统进程没有模块,所以枚举的话就出错.
    拒绝访问的一般是想卡巴这类驱动级的进程,还有两个错误就不知道问题在哪里了.
    现在的疑惑是该怎么处理上述错误?(程序本身不是目的,是怀着学习的态度来思考,所以别说就这样交给try catch 来处理,呵呵)
    1:我想做到碰到system和idle这类型的进程就不枚举他的模块,当然可以把这两个排除掉,但是碰到未知的这种类型进程还是会出错.
    2:对于拒绝访问的进程,该通过什么方法去枚举?
    3:未将对象引用设置到对象的实例。路径中具有非法字符。这两种出错怎么回事啊?
    2009年4月11日 5:56

全部回复

  • 1:我想做到碰到system和idle这类型的进程就不枚举他的模块,当然可以把这两个排除掉,但是碰到未知的这种类型进程还是会出错.
    System 和idle 本身就不是什么进程  而是系统占用和没有使用的两块“显示为进程”的资源快  既然不是进程 自然没有

    2:对于拒绝访问的进程,该通过什么方法去枚举?
    拒绝访问就是拒绝  你没有权限去枚举  那就提升你的权限  没错   你只要得到比卡巴司机更高级的权限就可以了。
     你得不到就更对了   卡巴斯基就是靠这个才能曾为安全保障的

    3:未将对象引用设置到对象的实例。路径中具有非法字符。这两种出错怎么回事啊?
    这个就需要你用debug去跟了

    另外  exception  有多种类型   一般通过 Catch不同类型的 exception  来分析异常的原因
    “所以别说就这样交给try catch 来处理”这句话你说的太狂了  标准错误处理模式你都不用  脖子上给你套饼你都不咬, 非要喂你吃龙虾你才张嘴? 
    工作突然有点忙 嘿嘿
    2009年4月12日 3:24
  • 1:我想做到碰到system和idle这类型的进程就不枚举他的模块,当然可以把这两个排除掉,但是碰到未知的这种类型进程还是会出错.
    System 和idle 本身就不是什么进程  而是系统占用和没有使用的两块“显示为进程”的资源快  既然不是进程 自然没有
    System和idle有些文章称之为"虚拟进程",也就是说并没有system.exe和idle.exe这两个程序的,是系统运行之后虚拟出来的,这个我是知道的.
    其实我的问题在于:如果哪天又冒出来一个类似Null这样的虚拟进程,那么到时候又会碰到无法枚举这样的错误,因为事先我只知道system和idle是这样的,是不是有什么属性(比如某个属性能够指明某个进程是"虚拟进程",那我就可以根据这个属性判断,遇到"虚拟进程"的,就不用调用listmodule()过程了),方法之类的可以避免枚举这样的假进程?我查了MSDN上的类库说明,没有找到.

    2:对于拒绝访问的进程,该通过什么方法去枚举?
    拒绝访问就是拒绝  你没有权限去枚举  那就提升你的权限  没错   你只要得到比卡巴司机更高级的权限就可以了。
     你得不到就更对了   卡巴斯基就是靠这个才能曾为安全保障的
    提升权限的思路我想到的是把程序做成服务形式,让服务以System权限运行,然后就可以去枚举,这样是不是就可以了呢?
    另外:像pv.exe这类程序,都是直接以当前账户运行的,但没有碰到拒绝访问的问题,我想应该是直接在程序中就提升了权限,我不知道用vb.net这个该怎么做,不过我知道可以用api来实现.

    另外  exception  有多种类型   一般通过 Catch不同类型的 exception  来分析异常的原因
    “所以别说就这样交给try catch 来处理”这句话你说的太狂了  标准错误处理模式你都不用  脖子上给你套饼你都不咬, 非要喂你吃龙虾你才张嘴? 
    这话绝对不是狂妄,可能你理解错我的意思了,不过你也不要那样揶揄我嘛,呵呵.我是菜鸟而已,vb.net只是怀着兴趣自己一点点在摸索.
    我说这话的意思其实是这样的:当catch出exception来之后,总要希望把异常处理掉,以使程序完美起来,我想完美的程序应该是catch不出来exception才对(当然对大型程序可能苛刻了点),就像第一点里我说的,我就是想碰到"无法枚举进程模块"的时候在try段里就避免掉这个异常,而不是等待catch.在try里避免是上策,等待catch到异常是下策,个人觉得:try catch结构更多的应该是在debug阶段使用,正式代码里使用仅仅是为了避免未知的异常,而不是把debug阶段的已知异常不加处理直接交给catch完事,那样的话太不负责任了,我这么说不算狂妄吧?呵呵

    最后,我发现我上面写的这个程序运行的时候cpu占用蛮大的,瞬间有25-50%左右,不知道是不是因为枚举的时候exception太多造成的?如果是的话那就更应该把exception的出现几率降到最低了.

    再次申明:本人只是菜鸟,不懂的太多,以上有说错的,还请大家不吝赐教.本人绝对没有狂妄的意思.
    2009年4月12日 8:48
  • 老弟你态度很端正  我错怪你了 原谅我的毒舌




    " 是不是有什么属性(比如某个属性能够指明某个进程是"虚拟进程" " 
    没班法   process 是调用windows api 
    在没有调用任何api之前 .net framework是什么也不知道的  调用的话 就必然发出异常


    提升权限的思路我想到的是把程序做成服务形式,让服务以System权限运行,然后就可以去枚举,这样是不是就可以了呢?
    你实验下就知道了  部分service 是可以的  但是个别kav这样的程序是驱动级别的 保护得更绝对 


    “正式代码里使用仅仅是为了避免未知的异常,而不是把debug阶段的已知异常不加处理直接交给catch完事,那样的话太不负责任了,我这么说不算狂妄吧?”
    你应该是中了一些人的毒了 所以这里还是要批评一下给你传毒的人。  高性能程序确实要求尽量少产生异常  但是在传播这一精神德时候并没有说清楚 如何正确的使用异常

    不负责任的异常处理  是把已经捕获的异常向上级继续 throw 。
    如果已经确认异常的类型  当时进行完整的处理 
    或者把异常当作返回值向外传递,那么性能不会受到影响  
    不会存在什么不负责任的问题

    当然 这是一个“在.net架构内最负责的办法”


    如果你一定要做这一方面的尝试  可以用 windows api 根据 process id  来判断进程的用户   如果是system 用户就不进行读取操作。
     





     
    工作突然有点忙 嘿嘿
    2009年4月12日 14:07