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;
    }
}
未经允许禁止转载~
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇