您的位置:程序门 -> vb ->



这个获取exe或dll文件版本,描述,公司信息的函数有时会导致程序崩溃,请帮忙看看


[收藏此页] [打印本页]选择字色:背景色:字体:[][][]


这个获取exe或dll文件版本,描述,公司信息的函数有时会导致程序崩溃,请帮忙看看[已结贴,结贴人:winland2006]
发表于:2007-02-19 19:41:16 楼主
我用下面的代码来获取exe或dll文件的信息(进程管理器一样的东西),但是偶而会在movememory时导致程序崩溃(一般在获取描述时),请各位帮忙看看哪个地方可能出错。

'---------------------------------------------------
'   文件信息模块
'--------------------------------------------------
private   type   vs_newinfo
        astr       as   string   *   1024
end   type
                           
private   type   vs_fixedfileinfo
        dwsignature       as   long
        dwstrucversionl       as   integer
        dwstrucversionh       as   integer
        dwfileversionmsl       as   integer
        dwfileversionmsh       as   integer
        dwfileversionlsl       as   integer
        dwfileversionlsh       as   integer
        dwproductversionmsl       as   integer
        dwproductversionmsh       as   integer
        dwproductversionlsl       as   integer
        dwproductversionlsh       as   integer
        dwfileflagsmask       as   long
        dwfileflags       as   long
        dwfileos       as   long
        dwfiletype       as   long
        dwfilesubtype       as   long
        dwfiledatems       as   long
        dwfiledatels       as   long
end   type
       
private   declare   function   getfileversioninfo   lib   "version.dll "   alias   _
        "getfileversioninfoa "   (byval   lptstrfilename   as   string,   byval   _
        dwhandle   as   long,   byval   dwlen   as   long,   lpdata   as   any)   as   long
private   declare   function   getfileversioninfosize   lib   "version.dll "   alias   _
        "getfileversioninfosizea "   (byval   lptstrfilename   as   string,   _
        lpdwhandle   as   long)   as   long
private   declare   function   verqueryvalue   lib   "version.dll "   alias   _
        "verqueryvaluea "   (pblock   as   any,   byval   lpsubblock   as   string,   _
        lplpbuffer   as   any,   pulen   as   long)   as   long
private   declare   sub   movememory   lib   "kernel32 "   alias   "rtlmovememory "   _
        (dest   as   any,   source   as   any,   byval   length   as   long)

'   获取文件信息,   需要文件的完整路径,   这里获取版本号,描述和公司信息,   当然还可以获得其它的信息,   方法和获取描述一样
public   function   getfileinfo(fullfilename   as   string)   as   string
        dim   rc   as   long
        dim   ldummy   as   long
        dim   sbuffer()   as   byte
        dim   lbufferlen   as   long
        dim   lverpointer   as   long
        dim   udtverbuffer   as   vs_fixedfileinfo
        dim   lverbufferlen   as   long
        dim   abuffer()   as   byte
        dim   astr   as   string
        dim   ltran   as   long
        dim   filever   as   string
        dim   filedesc   as   string
        dim   filecompany   as   string
        dim   hglobal   as   long
       
        filever   =   "   "
        filedesc   =   "   "
        filecompany   =   "   "
       
        '   获取缓存字符串长度
        lbufferlen   =   getfileversioninfosize(fullfilename,   ldummy)
        if   lbufferlen   <   1   then
                getfileinfo   =   "   __   __   "
                exit   function
        end   if
       
        '   获取文件信息并且保存到udtverbuffer结构中
        redim   sbuffer(lbufferlen)   as   byte
        rc   =   getfileversioninfo(fullfilename,   0&,   lbufferlen,   sbuffer(0))
        rc   =   verqueryvalue(sbuffer(0),   "\ ",   lverpointer,   lverbufferlen)
        movememory   udtverbuffer,   byval   lverpointer,   len(udtverbuffer)
       
        '   文件版本信息
        filever   =   format$(udtverbuffer.dwfileversionmsh)   &   ". "   &   _
                format$(udtverbuffer.dwfileversionmsl)   &   ". "   &   _
                format$(udtverbuffer.dwfileversionlsh)   &   ". "   &   _
                format$(udtverbuffer.dwfileversionlsl)
                                           
        redim   abuffer(lbufferlen)   as   byte
        dim   ab           as   vs_newinfo
       
        lverpointer   =   0
        rc   =   getfileversioninfo(fullfilename,   0&,   lbufferlen,   sbuffer(0))
        rc   =   verqueryvalue(sbuffer(0),   "\varfileinfo\translation ",   lverpointer,   lverbufferlen)
        movememory   ltran,   byval   lverpointer,   4&
        astr   =   "0 "   +   hex$(ltran)
        astr   =   right$(astr,   4)   +   left$(astr,   4)
       
        '   文件描述
        rc   =   verqueryvalue(sbuffer(0),   "\stringfileinfo\ "   +   astr   +   "\filedescription ",   lverpointer,   lverbufferlen)
        if   rc   <>   0   then
                movememory   ab,   byval   lverpointer,   len(ab)
                filedesc   =   left$(ab.astr,   (instr(ab.astr,   chr$(0))   -   1))
        end   if
                                       
        '   文件的公司信息
        rc   =   verqueryvalue(sbuffer(0),   "\stringfileinfo\ "   +   astr   +   "\companyname ",   lverpointer,   lverbufferlen)
        if   rc   <>   0   then
                movememory   ab,   byval   lverpointer,   len(ab)
                filecompany   =   left$(ab.astr,   (instr(ab.astr,   chr$(0))   -   1))
        end   if
                                       
        getfileinfo   =   filever   &   "__ "   &   filedesc   &   "__ "   &   filecompany
end   function
发表于:2007-02-19 22:04:261楼 得分:20
你参考下
?   getversioninfo   ( "c:\windows\explorer.exe "   ,efvifileversion)
?   getversioninfo   ( "c:\windows\explorer.exe "   ,efvifiledescription)
?   getversioninfo   ( "c:\windows\explorer.exe "   ,efvicompanyname)


'/**************************************************************************
'                                   版权所有   (c),   2004   -   2xxx,   绿豆xx室
'
'   ************************       模   块   名       :mduversioninfo********************
'版   本   号:   v1.0
'作         者:   超级绿豆
'生成日期:   2004年03月07日
'最近修改:
'功能描述:
'函数列表:
'修改历史:
'日         期:   2004年03月07日
'修改人员:   超级绿豆
'修改内容:   生成
'******************************************************************************/
'
option   explicit
'本模块名称
private   const   this_module_name   as   string   =   "mduversioninfo "

public   declare   function   getfileversioninfosize   lib   "version.dll "   alias   "getfileversioninfosizea "   (byval   lptstrfilename   as   string,   lpdwhandle   as   long)   as   long
public   declare   function   getfileversioninfo   lib   "version.dll "   alias   "getfileversioninfoa "   (byval   lptstrfilename   as   string,   byval   dwhandle   as   long,   byval   dwlen   as   long,   lpdata   as   any)   as   long
public   declare   function   verqueryvalue   lib   "version.dll "   alias   "verqueryvaluea "   (byval   pblock   as   long,   byval   lpsubblock   as   string,   lplpbuffer   as   long,   pulen   as   long)   as   long

public   g_fileversioninfoentrynames(12)   as   string

public   const   flag_fviens_initialized   as   string   =   "999 "

public   enum   efileversioninfoentrynames
        efvicomments   =   0
        efviinternalname
        efviproductname
        efvicompanyname
        efvilegalcopyright
        efviproductversion
        efvifiledescription
        efvilegaltrademarks
        efviprivatebuild
        efvifileversion
        efvioriginalfilename
        efvispecialbuild
        efviinitializedflag
end   enum

private   declare   sub   copymemory   lib   "kernel32 "   alias   "rtlmovememory "   (destination   as   any,   source   as   any,   byval   length   as   long)


public   function   getversioninfofromresverbytes(bversionblock()   as   byte,   byval   lentryname   as   efileversioninfoentrynames)   as   string
        on   error   goto   error_handler
        dim   i   as   long
        dim   lversionsize   as   long
        dim   pblock()   as   byte,   subblock   as   string
        dim   lptranslate   as   long,   btranslate()   as   byte
        dim   lsizeoflptranslate   as   long
        dim   lplpbuffer()   as   byte,   pulen   as   long,   lpbuffer   as   long
       
        'lversionsize   =   getfileversioninfosize(sfilename,   0&)
        'if   lversionsize   <=   0   then   exit   function
       
        call   initfileversioninfonames
       
        'redim   pblock(lversionsize   -   1)
        'call   getfileversioninfo(sfilename,   0&,   lversionsize,   pblock(0))
        pblock   =   bversionblock
       
        verqueryvalue   varptr(pblock(0)),   "\\varfileinfo\\translation ",   lptranslate,   lsizeoflptranslate
        redim   btranslate(lsizeoflptranslate   -   1)
        copymemory   btranslate(0),   byval   lptranslate,   lsizeoflptranslate
       
        for   i   =   1   to   lsizeoflptranslate   /   (ubound(btranslate)   +   1)
                subblock   =   "\\stringfileinfo\\ "
                subblock   =   subblock   &   byte2hex(btranslate(),   0,   1,   true)
                subblock   =   subblock   &   byte2hex(btranslate(),   2,   3,   true)
                subblock   =   subblock   &   "\\ "   &   g_fileversioninfoentrynames(lentryname)
       
                verqueryvalue   varptr(pblock(0)),   subblock,   lpbuffer,   pulen
                if   lpbuffer   <>   0   and   pulen   <>   0   then
                        redim   lplpbuffer(pulen   -   1)
                        copymemory   lplpbuffer(0),   byval   lpbuffer,   pulen
                        redim   preserve   lplpbuffer(instrb(lplpbuffer,   chrb(0))   -   2)
                        getversioninfofromresverbytes   =   strconv(lplpbuffer,   vbunicode)
                end   if
        next

        exit   function
error_handler:
        '自定义错误处理

        '调用默认错误处理函数
        call   defaulterrorhandler(this_module_name)
end   function


public   function   getversioninfo(byval   sfilename   as   string,   byval   lentryname   as   efileversioninfoentrynames)   as   string
        on   error   goto   error_handler
        dim   i   as   long
        dim   lversionsize   as   long
        dim   pblock()   as   byte,   subblock   as   string
        dim   lptranslate   as   long,   btranslate()   as   byte
        dim   lsizeoflptranslate   as   long
        dim   lplpbuffer()   as   byte,   pulen   as   long,   lpbuffer   as   long
       
        lversionsize   =   getfileversioninfosize(sfilename,   0&)
        if   lversionsize   <=   0   then   exit   function
       
        call   initfileversioninfonames
       
        redim   pblock(lversionsize   -   1)
        call   getfileversioninfo(sfilename,   0&,   lversionsize,   pblock(0))
       
        verqueryvalue   varptr(pblock(0)),   "\\varfileinfo\\translation ",   lptranslate,   lsizeoflptranslate
        redim   btranslate(lsizeoflptranslate   -   1)
        copymemory   btranslate(0),   byval   lptranslate,   lsizeoflptranslate
       
        for   i   =   1   to   lsizeoflptranslate   /   (ubound(btranslate)   +   1)
                subblock   =   "\\stringfileinfo\\ "
                subblock   =   subblock   &   byte2hex(btranslate(),   0,   1,   true)
                subblock   =   subblock   &   byte2hex(btranslate(),   2,   3,   true)
                subblock   =   subblock   &   "\\ "   &   g_fileversioninfoentrynames(lentryname)
       
                verqueryvalue   varptr(pblock(0)),   subblock,   lpbuffer,   pulen
                if   lpbuffer   <>   0   and   pulen   <>   0   then
                        redim   lplpbuffer(pulen   -   1)
                        copymemory   lplpbuffer(0),   byval   lpbuffer,   pulen
                        redim   preserve   lplpbuffer(instrb(lplpbuffer,   chrb(0))   -   2)
                        getversioninfo   =   strconv(lplpbuffer,   vbunicode)
                end   if
        next

        exit   function
error_handler:
        '自定义错误处理

        '调用默认错误处理函数
        call   defaulterrorhandler(this_module_name)
end   function

private   function   byte2hex(barray()   as   byte,   optional   byval   lstart   as   long   =   0,   optional   byval   lend   as   long   =   -1,   optional   freversed   as   boolean   =   false)   as   string
        dim   i   as   long
        lstart   =   iif(lstart   <   0,   0,   lstart)
        lend   =   iif(lend   <   0,   ubound(barray),   lend)
       
        if   freversed   then
                for   i   =   lend   to   lstart   step   -1
                        byte2hex   =   byte2hex   &   right$( "00 "   &   hex(barray(i)),   2)
                next
        else
                for   i   =   lstart   to   lend
                        byte2hex   =   byte2hex   &   right$( "00 "   &   hex(barray(i)),   2)
                next
        end   if
end   function

public   sub   initfileversioninfonames()
        if   g_fileversioninfoentrynames(12)   =   flag_fviens_initialized   then   exit   sub
        g_fileversioninfoentrynames(efvicomments)   =   "comments "     '注释
        g_fileversioninfoentrynames(efvicompanyname)   =   "companyname "     '公司名
        g_fileversioninfoentrynames(efviproductname)   =   "productname "     '产品名
        g_fileversioninfoentrynames(efviproductversion)   =   "productversion "     '产品版本
        g_fileversioninfoentrynames(efviinternalname)   =   "internalname "     '内部名称
        g_fileversioninfoentrynames(efvifiledescription)   =   "filedescription "     '文件描述
        g_fileversioninfoentrynames(efvifileversion)   =   "fileversion "     '文件版本
        g_fileversioninfoentrynames(efvioriginalfilename)   =   "originalfilename "     '原始文件名
        g_fileversioninfoentrynames(efvispecialbuild)   =   "specialbuild "     '特殊编译号
        g_fileversioninfoentrynames(efviprivatebuild)   =   "privatebuild "     '私有编译号
        g_fileversioninfoentrynames(efvilegalcopyright)   =   "legalcopyright "     '合法版权
        g_fileversioninfoentrynames(efvilegaltrademarks)   =   "legaltrademarks "     '合法商标
        g_fileversioninfoentrynames(efviinitializedflag)   =   flag_fviens_initialized       '是否已经初始化标记
end   sub
发表于:2007-02-19 22:59:202楼 得分:0
mark
发表于:2007-02-21 17:41:263楼 得分:0
多谢绿豆,我比较一下你的代码和我的代码之间的区别,觉得关键的区别是在用vs_newinfo这个结构在movememory里,每次都是固定的长度1024。我改成用字节数组,movememory的字节数用verqueryvalue调用后得到的lverbufferlen,试了几十次没有发现崩溃的现象,应该解决问题了。


快速检索

最新资讯
热门点击