【Java】java获取exe文件版本(跨系统版本) - Go语言中文社区

【Java】java获取exe文件版本(跨系统版本)


  exe文件版本一般用于版本管理和客户版本更新,对exe右键->属性,选择版本就能看见。如下图

  如果需要再windows上使用java读取exe文件版本,推荐使用jna.jar。本jar包可以调用本地c/c++类库,非常方便就能获取到exe文件版本。但如果是在其他系统上,那就没法用了,因为本地根本就没有此类库。

  跨系统读取exe文件版本其实想法很简单,版本号就在文件里,去读文件不就行了。但由于一般人都不会了解exe文件结构,所以需要去学习文件结构,再开始学代码。最后贴上我的代码:

public class TstThree {
    public static void main(String[] args) {
        getVersion();
    }
    
    public static boolean getVersion() {
        String filePath = "F:\Test\test.exe";
        File file = new File(filePath);
        RandomAccessFile raf = null;
        byte[] buffer;
        String str;
        try {
            raf = new RandomAccessFile(file, "r");
            buffer = new byte[64];
            raf.read(buffer);
            str = "" + (char)buffer[0] + (char)buffer[1];
            if(!"MZ".equals(str)) {
                return false;
            }

            int peOffset = unpack(new byte[]{buffer[60], buffer[61], buffer[62], buffer[63]});
            if(peOffset < 64) {
                return false;
            }
            
            raf.seek(peOffset);
            buffer = new byte[24];
            raf.read(buffer);
            str = "" + (char)buffer[0] + (char)buffer[1];
            if(!"PE".equals(str)) {
                return false;
            }
            int machine = unpack(new byte[]{buffer[4], buffer[5]});    
            if(machine != 332) {
                return false;
            }
            
            int noSections = unpack(new byte[]{buffer[6], buffer[7]});
            int optHdrSize = unpack(new byte[]{buffer[20], buffer[21]});
            raf.seek(raf.getFilePointer() + optHdrSize);
            boolean resFound = false;
            for(int i=0; i < noSections; i++) {
                buffer = new byte[40];
                raf.read(buffer);
                str = "" + (char)buffer[0] + (char)buffer[1] +
                        (char)buffer[2] + (char)buffer[3] + (char)buffer[4];
                if(".rsrc".equals(str)) {
                    resFound = true;
                    break;
                }
            }
            if(!resFound) {
                return false;
            }
            
            int infoVirt = unpack(new byte[]{buffer[12], buffer[13], buffer[14], buffer[15]});
            int infoSize = unpack(new byte[]{buffer[16], buffer[17], buffer[18], buffer[19]});
            int infoOff = unpack(new byte[]{buffer[20], buffer[21], buffer[22], buffer[23]});
            raf.seek(infoOff);
            buffer = new byte[infoSize];
            raf.read(buffer);
            int nameEntries = unpack(new byte[]{buffer[12], buffer[13]});
            int idEntries = unpack(new byte[]{buffer[14], buffer[15]});
            boolean infoFound = false;
            int subOff = 0;
            for(int i=0; i < (nameEntries+idEntries); i++) {
                int type = unpack(new byte[]{buffer[i*8+16], buffer[i*8+17], buffer[i*8+18], buffer[i*8+19]});
                if(type == 16) {                          //FILEINFO resource
                    infoFound = true;
                    subOff = unpack(new byte[]{buffer[i*8+20], buffer[i*8+21], buffer[i*8+22], buffer[i*8+23]});
                    break;
                }
            }
            if(!infoFound) {
                return false;
            }
            
            subOff = subOff&0x7fffffff;
            infoOff = unpack(new byte[]{buffer[subOff+20], buffer[subOff+21], buffer[subOff+22], buffer[subOff+23]}); //offset of first FILEINFO
            infoOff = infoOff&0x7fffffff;
            infoOff = unpack(new byte[]{buffer[infoOff+20], buffer[infoOff+21], buffer[infoOff+22], buffer[infoOff+23]});    //offset to data
            int dataOff = unpack(new byte[]{buffer[infoOff], buffer[infoOff+1], buffer[infoOff+2], buffer[infoOff+3]});
            dataOff = dataOff - infoVirt;
            
            int version1 = unpack(new byte[]{buffer[dataOff+48], buffer[dataOff+48+1]});
            int version2 = unpack(new byte[]{buffer[dataOff+48+2], buffer[dataOff+48+3]});
            int version3 = unpack(new byte[]{buffer[dataOff+48+4], buffer[dataOff+48+5]});
            int version4 = unpack(new byte[]{buffer[dataOff+48+6], buffer[dataOff+48+7]});
            System.out.println(version2 + "." + version1 + "." + version4 + "." + version3);    
            return true;
            
        } catch (FileNotFoundException e) {
            return false;
        } catch (IOException e) {
            return false;
        } finally {
            if(raf != null) {
                try {
                    raf.close();
                } catch (IOException e) {
                }
            }
        }
    }
    
    public static int unpack(byte[] b) {
        int num = 0;
        for(int i=0; i < b.length; i++) {
            num = 256 * num + (b[b.length - 1 - i]&0xff);
        }
        return num;
    }
}


版权声明:本文来源CSDN,感谢博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/zfpigpig/article/details/8086276
站方申明:本站部分内容来自社区用户分享,若涉及侵权,请联系站方删除。
  • 发表于 2020-03-01 21:19:04
  • 阅读 ( 1294 )
  • 分类:

0 条评论

请先 登录 后评论

官方社群

GO教程

猜你喜欢