CasualX / pelite

Lightweight, memory-safe, zero-allocation library for reading and navigating PE binaries.
MIT License
280 stars 42 forks source link

Please help me get the version of the file in string format #264

Closed Zalexanninev15 closed 1 year ago

Zalexanninev15 commented 1 year ago

Please help me get the version of the file in string format (for comparison with another version). I've been trying to do everything normally for several days, but it doesn't work out. I'm still studying Rust, so I don't know much, please explain.

use pelite::{
    resources::{version_info::VersionInfo, FindError, Resources},
    PeFile,
};

pub fn is_new_version(new_version: &str, application_path: &str) -> i32 {
    let file_map =
        pelite::FileMap::open(application_path).expect("Cannot open the file specified!");
    let image = pelite::PeFile::from_bytes(file_map.as_ref()).expect("File is not a PE image!");
    let current_version = get_file_version(image).replace(", ", "");
    println!("{} - {}", current_version, new_version);
    if current_version.contains(&new_version) {
        1
    } else {
        if current_version == "" {
            -1
        } else {
            0
        }
    }
}

fn get_file_version(bin: PeFile<'_>) -> String {
    let resources = bin.resources().expect("Resources not found!");
    let lang: Option<u16> = None;
    let version_info = match lang {
        Some(lang) => resources
            .find_resource_ex(&[pelite::resources::Name::VERSION, 1.into(), lang.into()])
            .and_then(|bytes| {
                Ok(pelite::resources::version_info::VersionInfo::try_from(
                    bytes,
                )?)
            }),
        None => resources.version_info(),
    }
    .expect("Version info not found!");
    let lang = version_info.translation()[0];
    // TODO Fix this error (?)
    let file_version = format!("{:?}", version_info.value(lang, "FileVersion"));
    file_version
}
Zalexanninev15 commented 1 year ago

I solved the problem by digging into the questions. I leave an answer in case anyone has the same problem.

use pelite::FileMap;

fn parse_pe_version(file_path: &str) -> String {
    match FileMap::open(file_path) {
        Err(_) => "".to_string(),
        Ok(file_map) => {
            let result = match pelite::PeFile::from_bytes(&file_map) {
                Err(e) => Err(e),
                Ok(f) => f.resources(),
            };

            match result {
                Err(_) => "".to_string(),
                Ok(resources) => match resources.version_info() {
                    Err(_) => "".to_string(),
                    Ok(version_info) => match version_info.fixed() {
                        None => "".to_string(),
                        Some(fixed_info) => {
                            let version = fixed_info.dwFileVersion.to_string();
                            if version.len() > 0 {
                                version
                            } else {
                                fixed_info.dwProductVersion.to_string()
                            }
                        }
                    },
                },
            }
        }
    }
}