Java如何读取.exe文件内的自定义配置文件

前言
因为之前开发过APP移动端的应用发布平台,移动端的配置文件解析都有相应的解析工具,从而想为啥不能开发个EXE程序管理平台把三种类型的文件放到同一个项目进行管理,且走相同的逻辑代码?

有目标了,开搞!!!!

首先网上百度EXE解析配置文件工具…嗯 基本没有,不太好写,先看EXE文件包
在这里插入图片描述
压缩文件结构
在这里插入图片描述
配置文件结构内容纯json配置
在这里插入图片描述

这里我们需要读取json文件里面的项目名称productName、appId、version版本、description项目描述

好了完事具备,只欠代码了…哦还差一步 ——依赖!依赖!依赖!

	<!-- https://mvnrepository.com/artifact/net.sf.sevenzipjbinding/sevenzipjbinding 7z解压工具主要依赖 -->
		<dependency>
			<groupId>net.sf.sevenzipjbinding</groupId>
			<artifactId>sevenzipjbinding</artifactId>
			<version>16.02-2.01</version>
		</dependency>
		<!-- https://mvnrepository.com/artifact/net.sf.sevenzipjbinding/sevenzipjbinding-all-windows 7Z解压window兼容初始化工具-->
		<dependency>
			<groupId>net.sf.sevenzipjbinding</groupId>
			<artifactId>sevenzipjbinding-all-windows</artifactId>
			<version>16.02-2.01</version>
		</dependency>

下面就是主体代码了:

package com.djcps.avm.commons.utils;

import com.djcps.log.DjcpsLogger;
import com.djcps.log.DjcpsLoggerFactory;
import org.apache.logging.log4j.core.util.Throwables;
import net.sf.sevenzipjbinding.ExtractAskMode;
import net.sf.sevenzipjbinding.ExtractOperationResult;
import net.sf.sevenzipjbinding.IArchiveExtractCallback;
import net.sf.sevenzipjbinding.ISequentialOutStream;
import net.sf.sevenzipjbinding.IInArchive;
import net.sf.sevenzipjbinding.PropID;
import net.sf.sevenzipjbinding.SevenZip;
import net.sf.sevenzipjbinding.simple.ISimpleInArchive;
import net.sf.sevenzipjbinding.simple.ISimpleInArchiveItem;
import net.sf.sevenzipjbinding.SevenZipException;
import net.sf.sevenzipjbinding.impl.RandomAccessFileInStream;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.RandomAccessFile;
import javax.swing.*;
import javax.swing.filechooser.FileSystemView;
import java.awt.*;

import java.util.regex.Pattern;


/**
 * @program: djapp-master
 * @description: //直接读取exe文件的版本信息
 * @author: Mr.Wang
 * @create: 2020-03-13 10:09
 **/
public class ZipUtils {


    private static DjcpsLogger LOGGER = DjcpsLoggerFactory.getLogger(ZipUtils.class);



    /**
     * 获取.exe文件的版本信息
     * @param file
     * @return
     */
    public static String getVersion(File file) {
        byte[] buffer;
        String str;
        RandomAccessFile raf = null;
        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 null;
            }

            int peOffset = unpack(new byte[]{buffer[60], buffer[61], buffer[62], buffer[63]});
            if (peOffset < 64) {
                return null;
            }

            raf.seek(peOffset);
            buffer = new byte[24];
            raf.read(buffer);
            str = "" + (char) buffer[0] + (char) buffer[1];
            if (!"PE".equals(str)) {
                return null;
            }
            int machine = unpack(new byte[]{buffer[4], buffer[5]});
            if (machine != 332) {
                return null;
            }

            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 null;
            }

            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 numDirs = unpack(new byte[]{buffer[14], buffer[15]});
            boolean infoFound = false;
            int subOff = 0;
            for (int i = 0; i < numDirs; 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) {
                    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 null;
            }

            subOff = subOff & 0x7fffffff;
            infoOff = unpack(new byte[]{buffer[subOff + 20], buffer[subOff + 21], buffer[subOff + 22], buffer[subOff + 23]});
            infoOff = infoOff & 0x7fffffff;
            infoOff = unpack(new byte[]{buffer[infoOff + 20], buffer[infoOff + 21], buffer[infoOff + 22], buffer[infoOff + 23]});
            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 version4 = unpack(new byte[]{buffer[dataOff + 48 + 6], buffer[dataOff + 48 + 7]});
            return version2 + "." + version1 + "." + version4 ;
        } catch (Exception e) {
            LOGGER.error("文件{}版本号解析失败!错误信息:{}", file.getAbsolutePath(), Throwables.getRootCause(e));
            return null;
        } finally {
            if (raf != null) {
                try {
                    raf.close();
                } catch (Exception e) {
                    LOGGER.error("关闭随机访问文件失败!", 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;
    }

    /**
     * 从exe file文件中获取icon
     * @param file
     * @return
     */
    public static Image getImgFromFile(File file){
       return ((ImageIcon) FileSystemView.getFileSystemView()
               .getSystemIcon(file))
               .getImage();
    }



        /**
         * <p>Discription:[将解压文件解压到指定目录下]</p>
         * @param
         * -支持压缩格式: 7Z,ZIP,TAR,RAR,LZMA,ISO,GZIP,BZIP2,CPIO,Z,ARJ,LZH,CAB,CHM,NSIS,DEB,RPM,UDF,WIM
         * @throws SevenZipException
         * @throws IOException
         * @update:[日期YYYY-MM-DD] [更改人姓名][变更描述]
         */
      public static void analysisMsg(String file) throws SevenZipException, IOException {
            IInArchive inArchive = null;
            RandomAccessFile randomAccessFile = null;
            StringBuilder stringBuilder = new StringBuilder();
            try {
                 randomAccessFile = new RandomAccessFile(new File(file), "r");
                inArchive = SevenZip.openInArchive(null, new RandomAccessFileInStream(randomAccessFile));
                ISimpleInArchive simpleInArchive = inArchive.getSimpleInterface();
                for (final ISimpleInArchiveItem item : simpleInArchive.getArchiveItems()) {
                    if (!item.isFolder()) {
                        ExtractOperationResult result;
                        String path = item.getPath();

                        if (Pattern.matches("manifest\\.json", path)) {
                            result = item.extractSlow(new ISequentialOutStream() {
                                public int write(byte[] data) throws SevenZipException {
                                    //写入指定文件
                                    stringBuilder.append(new String(data));
                                    // Return amount of consumed data
                                    return data.length;
                                }
                            });
                        }
                    }
                }
            } finally {
                if (inArchive != null) {
                    inArchive.close();
                }
                if (randomAccessFile != null) {
                    randomAccessFile.close();
                }
            }
            return stringBuilder.toString();
        }
}
 

demo测试代码:

 @Test
    public void testAnalysis()throws SevenZipException, IOException{
        String filePath = "D:\\xxx.exe";
        String analysisMsg = ZipUtils.analysisMsg(filePath );
          Map parseObject = JSONObject.parseObject(analysisMsg, Map.class);
            if(StringUtils.isBlank(analysisMsg)){
                return null;
            }
            String version = parseObject.get("version").toString();
            String appName=parseObject.get("productName");
            String appId= parseObject.get("appId");
    }

以上就是解析EXE配置文件的所有过程希望能帮助到大家,解析部分代码借鉴了彬彬大神的,按照自己项目的需求进行了修改

发布了47 篇原创文章 · 获赞 30 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/weixin_42083036/article/details/105064752