v8find4rs/
v8_app.rs

1use std::path::PathBuf;
2use std::fs::File;
3use std::io::Read;
4use exe::{PE, Arch};
5use std::env;
6
7/// Перечень возможных приложений 1С. Необходим для поиска пути к данным приложениям при использовании
8/// V8Finder
9pub enum V8AppType {
10    /// Толстый клиент
11    ThickClient,
12    /// Тонкий клиент
13    ThinClient,
14    /// Клиент удаленного администрирования
15    RAC,
16    /// Сервер удаленного администрирования
17    RAS,
18    /// Сервер отладки
19    DBGS,
20    /// Сервер приложений
21    AppServer,
22    /// Сервер хранилища
23    RepositoryServer,
24    /// Автономный сервер
25    IBSRV,
26    /// Утилита администрирования
27    IBCMD,
28}
29
30impl V8AppType {
31    /// Возвращает текстовое имя соответствующего вида приложения 1С
32    pub fn value(&self) -> &str {
33        match *self {
34            V8AppType::ThickClient => "1cv8",
35            V8AppType::ThinClient => "1cv8c",
36            V8AppType::RAC => "rac",
37            V8AppType::RAS => "ras",
38            V8AppType::DBGS => "dbgs",
39            V8AppType::AppServer => "ragent",
40            V8AppType::RepositoryServer => "crserver",
41            V8AppType::IBSRV => "ibsrv",
42            V8AppType::IBCMD => "ibcmd",
43        }
44    }
45}
46
47#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
48/// Перечень разрядностей платформы 1С
49pub enum V8Arch {
50    /// 32-х разрядная
51    X86,
52    /// 64-х разрядная
53    X64,
54}
55
56impl V8Arch {
57    /// Осуществляет попытку определения разрядности платформы 1С. Логика определения различается в
58    /// зависимости от текущей ОС:
59    /// * Windows - по файлу 1cv8s.exe находящегося в папке bin. Читается его PE
60    /// [сигнатура](https://docs.microsoft.com/en-us/windows/win32/debug/pe-format#machine-types)
61    /// * Linux - по пути платформы. 1С автоматически устанавливает платформу в папки i386 или x86_64, соответственно
62    /// разрядность определяется по наличию одной из подстрок в пути;
63    /// * macOS - всегда 64-х разрядная.
64    ///
65    /// Если по каким-то причинам метод не сможет определить разрядность самостоятельно,
66    /// по умолчанию присваивается разрядность 32
67    pub fn from_path(v8_path: &PathBuf) -> V8Arch {
68        let current_os = env::consts::OS;
69        return match current_os {
70            "windows" => V8Arch::v8_arch_from_exe(&v8_path.join(get_v8s_suffix())),
71            "linux" => V8Arch::v8_arch_from_linux_path(v8_path),
72            _ => V8Arch::X64
73        }
74    }
75
76    fn v8_arch_from_linux_path(path: &PathBuf) -> V8Arch {
77        let str_path = path.to_str().unwrap_or("");
78        if str_path.contains("i386") {
79            V8Arch::X86
80        } else {
81            V8Arch::X64
82        }
83    }
84
85    fn v8_arch_from_exe(path_to_exe: &PathBuf) -> V8Arch {
86        if path_to_exe.exists() {
87            let exe_file = File::open(path_to_exe);
88            if let Ok(mut exe_file) = exe_file {
89                let mut buf = Vec::new();
90                let _ = exe_file.read_to_end(&mut buf);
91
92                let pe_file = PE::new_disk(buf.as_slice());
93                let v8_arch = pe_file.get_arch();
94                return match v8_arch {
95                    Ok(Arch::X64) => V8Arch::X64,
96                    Ok(Arch::X86) => V8Arch::X86,
97                    Err(_) => V8Arch::X86,
98                };
99            }
100        }
101
102        V8Arch::X86
103    }
104}
105
106fn get_v8s_suffix() -> &'static str {
107    let current_os = env::consts::OS;
108    match current_os {
109        "windows" => r"bin\1cv8s.exe",
110        _ => "1cv8s",
111    }
112}