bat2pe 1.4.9__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,335 @@
1
+ # This file is automatically @generated by Cargo.
2
+ # It is not intended for manual editing.
3
+ version = 4
4
+
5
+ [[package]]
6
+ name = "autocfg"
7
+ version = "1.5.0"
8
+ source = "registry+https://github.com/rust-lang/crates.io-index"
9
+ checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8"
10
+
11
+ [[package]]
12
+ name = "bat2pe"
13
+ version = "0.1.0"
14
+ dependencies = [
15
+ "bat2pe-core",
16
+ "serde",
17
+ "serde_json",
18
+ ]
19
+
20
+ [[package]]
21
+ name = "bat2pe-core"
22
+ version = "0.1.0"
23
+ dependencies = [
24
+ "serde",
25
+ "serde_json",
26
+ "windows-sys",
27
+ ]
28
+
29
+ [[package]]
30
+ name = "bat2pe-py"
31
+ version = "0.1.0"
32
+ dependencies = [
33
+ "bat2pe-core",
34
+ "pyo3",
35
+ "serde",
36
+ "serde_json",
37
+ ]
38
+
39
+ [[package]]
40
+ name = "cfg-if"
41
+ version = "1.0.4"
42
+ source = "registry+https://github.com/rust-lang/crates.io-index"
43
+ checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
44
+
45
+ [[package]]
46
+ name = "heck"
47
+ version = "0.5.0"
48
+ source = "registry+https://github.com/rust-lang/crates.io-index"
49
+ checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
50
+
51
+ [[package]]
52
+ name = "indoc"
53
+ version = "2.0.7"
54
+ source = "registry+https://github.com/rust-lang/crates.io-index"
55
+ checksum = "79cf5c93f93228cf8efb3ba362535fb11199ac548a09ce117c9b1adc3030d706"
56
+ dependencies = [
57
+ "rustversion",
58
+ ]
59
+
60
+ [[package]]
61
+ name = "itoa"
62
+ version = "1.0.18"
63
+ source = "registry+https://github.com/rust-lang/crates.io-index"
64
+ checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682"
65
+
66
+ [[package]]
67
+ name = "libc"
68
+ version = "0.2.183"
69
+ source = "registry+https://github.com/rust-lang/crates.io-index"
70
+ checksum = "b5b646652bf6661599e1da8901b3b9522896f01e736bad5f723fe7a3a27f899d"
71
+
72
+ [[package]]
73
+ name = "memchr"
74
+ version = "2.8.0"
75
+ source = "registry+https://github.com/rust-lang/crates.io-index"
76
+ checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79"
77
+
78
+ [[package]]
79
+ name = "memoffset"
80
+ version = "0.9.1"
81
+ source = "registry+https://github.com/rust-lang/crates.io-index"
82
+ checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a"
83
+ dependencies = [
84
+ "autocfg",
85
+ ]
86
+
87
+ [[package]]
88
+ name = "once_cell"
89
+ version = "1.21.4"
90
+ source = "registry+https://github.com/rust-lang/crates.io-index"
91
+ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50"
92
+
93
+ [[package]]
94
+ name = "portable-atomic"
95
+ version = "1.13.1"
96
+ source = "registry+https://github.com/rust-lang/crates.io-index"
97
+ checksum = "c33a9471896f1c69cecef8d20cbe2f7accd12527ce60845ff44c153bb2a21b49"
98
+
99
+ [[package]]
100
+ name = "proc-macro2"
101
+ version = "1.0.106"
102
+ source = "registry+https://github.com/rust-lang/crates.io-index"
103
+ checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934"
104
+ dependencies = [
105
+ "unicode-ident",
106
+ ]
107
+
108
+ [[package]]
109
+ name = "pyo3"
110
+ version = "0.22.6"
111
+ source = "registry+https://github.com/rust-lang/crates.io-index"
112
+ checksum = "f402062616ab18202ae8319da13fa4279883a2b8a9d9f83f20dbade813ce1884"
113
+ dependencies = [
114
+ "cfg-if",
115
+ "indoc",
116
+ "libc",
117
+ "memoffset",
118
+ "once_cell",
119
+ "portable-atomic",
120
+ "pyo3-build-config",
121
+ "pyo3-ffi",
122
+ "pyo3-macros",
123
+ "unindent",
124
+ ]
125
+
126
+ [[package]]
127
+ name = "pyo3-build-config"
128
+ version = "0.22.6"
129
+ source = "registry+https://github.com/rust-lang/crates.io-index"
130
+ checksum = "b14b5775b5ff446dd1056212d778012cbe8a0fbffd368029fd9e25b514479c38"
131
+ dependencies = [
132
+ "once_cell",
133
+ "target-lexicon",
134
+ ]
135
+
136
+ [[package]]
137
+ name = "pyo3-ffi"
138
+ version = "0.22.6"
139
+ source = "registry+https://github.com/rust-lang/crates.io-index"
140
+ checksum = "9ab5bcf04a2cdcbb50c7d6105de943f543f9ed92af55818fd17b660390fc8636"
141
+ dependencies = [
142
+ "libc",
143
+ "pyo3-build-config",
144
+ ]
145
+
146
+ [[package]]
147
+ name = "pyo3-macros"
148
+ version = "0.22.6"
149
+ source = "registry+https://github.com/rust-lang/crates.io-index"
150
+ checksum = "0fd24d897903a9e6d80b968368a34e1525aeb719d568dba8b3d4bfa5dc67d453"
151
+ dependencies = [
152
+ "proc-macro2",
153
+ "pyo3-macros-backend",
154
+ "quote",
155
+ "syn",
156
+ ]
157
+
158
+ [[package]]
159
+ name = "pyo3-macros-backend"
160
+ version = "0.22.6"
161
+ source = "registry+https://github.com/rust-lang/crates.io-index"
162
+ checksum = "36c011a03ba1e50152b4b394b479826cad97e7a21eb52df179cd91ac411cbfbe"
163
+ dependencies = [
164
+ "heck",
165
+ "proc-macro2",
166
+ "pyo3-build-config",
167
+ "quote",
168
+ "syn",
169
+ ]
170
+
171
+ [[package]]
172
+ name = "quote"
173
+ version = "1.0.45"
174
+ source = "registry+https://github.com/rust-lang/crates.io-index"
175
+ checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924"
176
+ dependencies = [
177
+ "proc-macro2",
178
+ ]
179
+
180
+ [[package]]
181
+ name = "rustversion"
182
+ version = "1.0.22"
183
+ source = "registry+https://github.com/rust-lang/crates.io-index"
184
+ checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d"
185
+
186
+ [[package]]
187
+ name = "serde"
188
+ version = "1.0.228"
189
+ source = "registry+https://github.com/rust-lang/crates.io-index"
190
+ checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e"
191
+ dependencies = [
192
+ "serde_core",
193
+ "serde_derive",
194
+ ]
195
+
196
+ [[package]]
197
+ name = "serde_core"
198
+ version = "1.0.228"
199
+ source = "registry+https://github.com/rust-lang/crates.io-index"
200
+ checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad"
201
+ dependencies = [
202
+ "serde_derive",
203
+ ]
204
+
205
+ [[package]]
206
+ name = "serde_derive"
207
+ version = "1.0.228"
208
+ source = "registry+https://github.com/rust-lang/crates.io-index"
209
+ checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79"
210
+ dependencies = [
211
+ "proc-macro2",
212
+ "quote",
213
+ "syn",
214
+ ]
215
+
216
+ [[package]]
217
+ name = "serde_json"
218
+ version = "1.0.149"
219
+ source = "registry+https://github.com/rust-lang/crates.io-index"
220
+ checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86"
221
+ dependencies = [
222
+ "itoa",
223
+ "memchr",
224
+ "serde",
225
+ "serde_core",
226
+ "zmij",
227
+ ]
228
+
229
+ [[package]]
230
+ name = "syn"
231
+ version = "2.0.117"
232
+ source = "registry+https://github.com/rust-lang/crates.io-index"
233
+ checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99"
234
+ dependencies = [
235
+ "proc-macro2",
236
+ "quote",
237
+ "unicode-ident",
238
+ ]
239
+
240
+ [[package]]
241
+ name = "target-lexicon"
242
+ version = "0.12.16"
243
+ source = "registry+https://github.com/rust-lang/crates.io-index"
244
+ checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1"
245
+
246
+ [[package]]
247
+ name = "unicode-ident"
248
+ version = "1.0.24"
249
+ source = "registry+https://github.com/rust-lang/crates.io-index"
250
+ checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75"
251
+
252
+ [[package]]
253
+ name = "unindent"
254
+ version = "0.2.4"
255
+ source = "registry+https://github.com/rust-lang/crates.io-index"
256
+ checksum = "7264e107f553ccae879d21fbea1d6724ac785e8c3bfc762137959b5802826ef3"
257
+
258
+ [[package]]
259
+ name = "windows-sys"
260
+ version = "0.59.0"
261
+ source = "registry+https://github.com/rust-lang/crates.io-index"
262
+ checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b"
263
+ dependencies = [
264
+ "windows-targets",
265
+ ]
266
+
267
+ [[package]]
268
+ name = "windows-targets"
269
+ version = "0.52.6"
270
+ source = "registry+https://github.com/rust-lang/crates.io-index"
271
+ checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
272
+ dependencies = [
273
+ "windows_aarch64_gnullvm",
274
+ "windows_aarch64_msvc",
275
+ "windows_i686_gnu",
276
+ "windows_i686_gnullvm",
277
+ "windows_i686_msvc",
278
+ "windows_x86_64_gnu",
279
+ "windows_x86_64_gnullvm",
280
+ "windows_x86_64_msvc",
281
+ ]
282
+
283
+ [[package]]
284
+ name = "windows_aarch64_gnullvm"
285
+ version = "0.52.6"
286
+ source = "registry+https://github.com/rust-lang/crates.io-index"
287
+ checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
288
+
289
+ [[package]]
290
+ name = "windows_aarch64_msvc"
291
+ version = "0.52.6"
292
+ source = "registry+https://github.com/rust-lang/crates.io-index"
293
+ checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
294
+
295
+ [[package]]
296
+ name = "windows_i686_gnu"
297
+ version = "0.52.6"
298
+ source = "registry+https://github.com/rust-lang/crates.io-index"
299
+ checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
300
+
301
+ [[package]]
302
+ name = "windows_i686_gnullvm"
303
+ version = "0.52.6"
304
+ source = "registry+https://github.com/rust-lang/crates.io-index"
305
+ checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
306
+
307
+ [[package]]
308
+ name = "windows_i686_msvc"
309
+ version = "0.52.6"
310
+ source = "registry+https://github.com/rust-lang/crates.io-index"
311
+ checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
312
+
313
+ [[package]]
314
+ name = "windows_x86_64_gnu"
315
+ version = "0.52.6"
316
+ source = "registry+https://github.com/rust-lang/crates.io-index"
317
+ checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
318
+
319
+ [[package]]
320
+ name = "windows_x86_64_gnullvm"
321
+ version = "0.52.6"
322
+ source = "registry+https://github.com/rust-lang/crates.io-index"
323
+ checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
324
+
325
+ [[package]]
326
+ name = "windows_x86_64_msvc"
327
+ version = "0.52.6"
328
+ source = "registry+https://github.com/rust-lang/crates.io-index"
329
+ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
330
+
331
+ [[package]]
332
+ name = "zmij"
333
+ version = "1.0.21"
334
+ source = "registry+https://github.com/rust-lang/crates.io-index"
335
+ checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa"
@@ -0,0 +1,23 @@
1
+ [workspace]
2
+ resolver = "3"
3
+ members = ["crates/bat2pe-core", "crates/bat2pe-py"]
4
+
5
+ [workspace.package]
6
+ authors = ["Bat2PE Contributors"]
7
+ edition = "2024"
8
+ license = "MPL-2.0"
9
+ rust-version = "1.85"
10
+ version = "0.1.0"
11
+
12
+ [workspace.dependencies]
13
+ pyo3 = { version = "0.22", features = ["extension-module", "abi3-py310"] }
14
+ serde = { version = "1.0", features = ["derive"] }
15
+ serde_json = "1.0"
16
+ windows-sys = { version = "0.59", features = [
17
+ "Win32_Foundation",
18
+ "Win32_Storage_FileSystem",
19
+ "Win32_System_LibraryLoader",
20
+ "Win32_System_Console",
21
+ "Win32_System_Threading",
22
+ "Win32_UI_WindowsAndMessaging",
23
+ ] }
bat2pe-1.4.9/LICENSE ADDED
@@ -0,0 +1,5 @@
1
+ Mozilla Public License Version 2.0
2
+
3
+ This Source Code Form is subject to the terms of the Mozilla Public License,
4
+ v. 2.0. If a copy of the MPL was not distributed with this file, You can
5
+ obtain one at https://mozilla.org/MPL/2.0/.
bat2pe-1.4.9/PKG-INFO ADDED
@@ -0,0 +1,281 @@
1
+ Metadata-Version: 2.4
2
+ Name: bat2pe
3
+ Version: 1.4.9
4
+ Classifier: Development Status :: 3 - Alpha
5
+ Classifier: Environment :: Console
6
+ Classifier: Intended Audience :: Developers
7
+ Classifier: License :: OSI Approved :: Mozilla Public License 2.0 (MPL 2.0)
8
+ Classifier: Operating System :: Microsoft :: Windows
9
+ Classifier: Programming Language :: Python :: 3
10
+ Classifier: Programming Language :: Python :: 3.10
11
+ Classifier: Programming Language :: Python :: 3.11
12
+ Classifier: Programming Language :: Rust
13
+ License-File: LICENSE
14
+ Summary: Windows Bat/Cmd to Exe converter with Rust CLI and Python API.
15
+ Author: Bat2PE Contributors
16
+ License: MPL-2.0
17
+ Requires-Python: >=3.10
18
+ Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
19
+
20
+ # Bat2PE
21
+
22
+ <div align="center">
23
+
24
+ ![Bat2PE](https://socialify.git.ci/271374667/Bat2PE/image?description=1&language=1&name=1&owner=1&pattern=Plus&theme=Auto)
25
+
26
+ [![Python Version](https://img.shields.io/badge/python-3.10%2B-blue.svg)](#quick-start)
27
+ [![Rust](https://img.shields.io/badge/rust-1.85%2B-orange.svg)](#quick-start)
28
+ [![Platform](https://img.shields.io/badge/platform-Windows%2010%2F11-success.svg)](#highlights)
29
+ [![License](https://img.shields.io/badge/license-MPL--2.0-green.svg)](LICENSE)
30
+
31
+ [English README](README.md) | [中文说明](README_CN.md) | [Python API](docs/python-api.md)
32
+
33
+ **Convert `.bat` / `.cmd` scripts to standalone `.exe` via CLI or Python module**
34
+ **Fully compatible runtime behavior, custom icon & metadata, UAC elevation, passes Kaspersky and common AV scans, zero runtime dependencies**
35
+
36
+ </div>
37
+
38
+ > Existing solutions like Bat To Exe Converter fall short for professionals who need to integrate the conversion step into automated workflows. Bat2PE offers no GUI — instead it provides a CLI and a directly callable Python module, letting you convert batch scripts to executables in one command and fold distribution into your pipeline.
39
+
40
+ Executables generated by Bat2PE behave identically to the original batch script, preserving `%~dp0` and other special variables. You can embed a custom icon, set version info, company name, and other file metadata. One flag adds UAC elevation. The output passes Kaspersky (free edition) and common antivirus scans. The generated `.exe` runs standalone with zero extra dependencies.
41
+
42
+ ## Highlights
43
+
44
+ - **`build → inspect → verify` pipeline** — generate, examine, and validate without switching tools
45
+ - **`%~dp0` semantics preserved** — temp script is written beside the `.exe`, not in `%TEMP%`, minimizing broken relative paths
46
+ - **Window mode** — defaults to `hidden` (silent background); add `--visible` for a foreground console
47
+ - **Multi-encoding support** — `UTF-8` · `UTF-8 BOM` · `UTF-16 LE BOM` · `ANSI/GBK` auto-detected
48
+ - **Dual entry points** — CLI for terminals and CI/CD, Python API for scripting and automation workflows
49
+ - **Native Windows resource writing** — icon, version number, company name, and other metadata written to PE resource sections, visible in Explorer
50
+ - **UAC elevation** — a single `--uac` or `uac=True` makes the generated `.exe` request admin privileges
51
+ - **AV-friendly** — generated executables pass Kaspersky Free and common antivirus scans
52
+ - **Zero extra dependencies** — generated `.exe` runs standalone, no runtime installation required
53
+
54
+ ## Installation
55
+
56
+ ### Python Users
57
+
58
+ ```bash
59
+ pip install bat2pe
60
+ ```
61
+
62
+ After installation, call `from bat2pe import build` directly in your Python code.
63
+
64
+ ### CLI Users
65
+
66
+ Download `bat2pe.exe` from [GitHub Releases](https://github.com/271374667/Bat2PE/releases) and you're ready to go.
67
+
68
+ ### System Requirements
69
+
70
+ | Dependency | Minimum Version |
71
+ |------------|----------------|
72
+ | OS | Windows 10 / 11 (x64) |
73
+ | Python (only for Python API) | 3.10+ |
74
+ | Rust (only for building from source) | 1.85+ |
75
+
76
+ ## Quick Start
77
+
78
+ ### CLI Usage
79
+
80
+ **Simplest conversion** — one command, generates a same-name `.exe` beside the script:
81
+
82
+ ```powershell
83
+ bat2pe build run.bat
84
+ ```
85
+
86
+ **Specify output path and icon**:
87
+
88
+ ```powershell
89
+ bat2pe build run.bat --output-exe-path dist\run.exe --icon-path app.ico
90
+ ```
91
+
92
+ **Show console window** (for interactive foreground tools):
93
+
94
+ ```powershell
95
+ bat2pe build run.bat --visible
96
+ ```
97
+
98
+ **Add UAC admin elevation**:
99
+
100
+ ```powershell
101
+ bat2pe build admin.cmd --uac
102
+ ```
103
+
104
+ **Write full version metadata**:
105
+
106
+ ```powershell
107
+ bat2pe build run.bat ^
108
+ --company "Acme Corp" ^
109
+ --product "My Tool" ^
110
+ --description "Launcher" ^
111
+ --file-version 1.2.3 ^
112
+ --product-version 1.2.3
113
+ ```
114
+
115
+ > 💡 Besides `build`, there are also `inspect` (view exe metadata) and `verify` (check behavioral consistency) subcommands. Run `bat2pe <command> --help` for full details.
116
+
117
+ ### Python Usage
118
+
119
+ #### Functional API (recommended for quick use)
120
+
121
+ ```python
122
+ from bat2pe import build
123
+
124
+ result = build(input_bat_path="run.bat")
125
+ print(result.output_exe_path) # run.exe
126
+ ```
127
+
128
+ #### Object-Oriented API (recommended for complex scenarios)
129
+
130
+ ```python
131
+ from bat2pe import Builder
132
+
133
+ builder = Builder(
134
+ input_bat_path="run.bat",
135
+ output_exe_path="dist/run.exe",
136
+ # visible defaults to False (hidden); set True for console window
137
+ icon_path="app.ico",
138
+ company_name="Acme Corp",
139
+ product_name="My Tool",
140
+ file_version="1.2.3",
141
+ )
142
+ result = builder.build()
143
+ ```
144
+
145
+ #### UAC Elevation
146
+
147
+ ```python
148
+ from bat2pe import build
149
+
150
+ result = build(
151
+ input_bat_path="admin_task.bat",
152
+ uac=True,
153
+ )
154
+ ```
155
+
156
+ #### Error Handling
157
+
158
+ ```python
159
+ from bat2pe import build, BuildError, ERR_UNSUPPORTED_INPUT
160
+
161
+ try:
162
+ build(input_bat_path="readme.txt")
163
+ except BuildError as e:
164
+ if e.code == ERR_UNSUPPORTED_INPUT:
165
+ print("Only .bat or .cmd files are supported")
166
+ print(e.code, e.path, e.details)
167
+ ```
168
+
169
+ For the full Python API reference (including `inspect`, `verify`, and other advanced usage), see [docs/python-api.md](docs/python-api.md).
170
+
171
+ ## How It Works
172
+
173
+ Bat2PE embeds a batch script into a native Windows PE executable. At runtime, the generated `.exe`:
174
+
175
+ 1. Reads the embedded script content from its own PE resources
176
+ 2. Writes a temporary `.cmd` file (with hidden attribute) in the `.exe`'s directory
177
+ 3. Executes the temp script via `cmd.exe /d /c`, forwarding all command-line arguments
178
+ 4. Automatically deletes the temp file after execution, with orphan cleanup on abnormal termination
179
+
180
+ **Why not write to `%TEMP%`?** Because many batch scripts rely on `%~dp0` to locate adjacent config files or resource directories. Placing the temp script beside the `.exe` preserves this semantic as much as possible, keeping behavior consistent with the original script.
181
+
182
+ ### Architecture Overview
183
+
184
+ ```
185
+ ┌──────────────┐ ┌──────────────┐ ┌──────────────────┐
186
+ │ CLI Users │ │ Python Users │ │ CI/CD Pipelines │
187
+ └──────┬───────┘ └──────┬───────┘ └────────┬─────────┘
188
+ │ │ │
189
+ ▼ ▼ ▼
190
+ ┌──────────────┐ ┌──────────────┐ ┌──────────────────┐
191
+ │ bat2pe.exe │ │bat2pe._native│ │ bat2pe (Python) │
192
+ │ (Rust CLI) │ │(PyO3 Extension)│ │ pip install │
193
+ └──────┬───────┘ └──────┬───────┘ └────────┬─────────┘
194
+ │ │ │
195
+ └───────────────────┴─────────────────────┘
196
+
197
+
198
+ ┌─────────────────┐
199
+ │ bat2pe-core │
200
+ │ (Rust Core Lib)│
201
+ └─────────────────┘
202
+ ```
203
+
204
+
205
+ ## Building from Source (Developers)
206
+
207
+ If you want to build from source or contribute:
208
+
209
+ ### Setup
210
+
211
+ ```powershell
212
+ # Install dependencies
213
+ uv sync
214
+ ```
215
+
216
+ ### Build All Artifacts
217
+
218
+ ```powershell
219
+ # Recommended (one-step build for CLI + Python extension)
220
+ uv run python scripts/compile.py
221
+
222
+ # For debug builds
223
+ uv run python scripts/compile.py --debug
224
+ ```
225
+
226
+ Build outputs:
227
+
228
+ | Artifact | Description |
229
+ |----------|-------------|
230
+ | `target/release/bat2pe.exe` | Standalone CLI program |
231
+ | `python/bat2pe/_native.pyd` | Python native extension module |
232
+
233
+ ### Manual Build
234
+
235
+ ```powershell
236
+ cargo build --release -p bat2pe -p bat2pe-py
237
+ uv run maturin develop
238
+ ```
239
+
240
+ ### Running Tests
241
+
242
+ ```powershell
243
+ # Rust unit tests
244
+ cargo test --workspace
245
+
246
+ # Python integration tests (CLI, Python API, runtime behavior, etc.)
247
+ uv run pytest
248
+ ```
249
+
250
+ Test coverage includes:
251
+
252
+ - CLI help output, argument validation, full build/inspect/verify flow
253
+ - Python API functional + object-oriented dual interfaces
254
+ - Encoding detection and unsupported encoding rejection
255
+ - Typed exception mapping
256
+ - UAC manifest writing
257
+ - Native Windows version resource writing
258
+ - Runtime `%~dp0` behavior and working directory preservation
259
+ - Hidden window exit codes
260
+ - Temp file cleanup and forced termination cleanup
261
+ - Python 3.10 syntax compatibility checks
262
+
263
+
264
+ ## Current Stage & Known Limitations
265
+
266
+ Bat2PE is ready for **single-script, launcher-style batch projects**. The `build → inspect → verify` workflow is fully operational.
267
+
268
+
269
+ | Item | Status |
270
+ |------|--------|
271
+ | Single `.bat` / `.cmd` script conversion | ✅ Fully supported |
272
+ | Icon & version metadata | ✅ Written to native Windows PE resources |
273
+ | UAC admin elevation | ✅ Supported |
274
+ | Hidden window mode | ✅ Supported |
275
+ | Multi-encoding auto-detection | ✅ UTF-8 / UTF-8 BOM / UTF-16 LE BOM / ANSI/GBK |
276
+
277
+
278
+ ## License
279
+
280
+ This project is licensed under the [MPL-2.0](LICENSE) license.
281
+