# xll-utils
PE/COFF parsing and export verification utilities for Excel XLL development.
`xll-utils` complements [`xll-rs`](https://crates.io/crates/xll-rs) (runtime) and [`xllgen`](https://crates.io/crates/xllgen) (proc-macros) by providing tools to inspect, verify, and manage XLL add-in binaries.
## Features
- **PE/COFF parsing** — Read export tables, architectures, and metadata from DLL/XLL files
- **Export verification** — Verify that a built XLL contains all required exports
- **XLL metadata** — Extract XLL-specific information (entry points, export lists)
- **Windows registry** — Find, register, and unregister XLLs in Excel's registry keys *(Windows only)*
- **Build script helpers** — Verify exports at compile time from `build.rs`
- **CLI tool** — `xllutils` binary for command-line inspection
## Installation
Add to your `Cargo.toml`:
```toml
[dependencies]
xll-utils = "0.1"
```
### Feature flags
| `serde` | no | Enables JSON serialization for all public types |
| `cli` | no | Builds the `xllutils` CLI binary |
| `build` | no | Build script helpers (`verify_exports_in_build`, etc.) |
To install the CLI:
```sh
cargo install xll-utils --features cli
```
## Quick start
### Parse a PE file and list exports
```rust,no_run
use xll_utils::pe::parse_pe_file;
let pe = parse_pe_file("path/to/my_xll.xll").unwrap();
println!("Architecture: {}", pe.architecture());
println!("Exports: {}", pe.exports().len());
for name in pe.export_names() {
println!(" {name}");
}
```
### Verify expected exports
```rust,no_run
use xll_utils::exports::verify_dll_exports;
let expected = &["xlAutoOpen", "xlAutoClose", "xlAutoFree12"];
let report = verify_dll_exports("my_xll.xll", expected).unwrap();
if report.complete {
println!("All exports present");
} else {
println!("Missing: {:?}", report.missing);
}
```
### Extract XLL metadata
```rust,no_run
use xll_utils::xll::xll_info;
let info = xll_info("my_xll.xll").unwrap();
println!("{}: {} exports, xlAutoOpen={}", info.name, info.export_count, info.has_auto_open);
```
### Build script verification
In your `Cargo.toml`:
```toml
[build-dependencies]
xll-utils = { version = "0.1", features = ["build"] }
```
In your `build.rs`:
```rust,ignore
fn main() {
xll_utils::build::verify_exports_in_build(
"target/release/my_xll.xll",
&["xlAutoOpen", "xlAutoClose", "xlAutoFree12"],
).expect("XLL export verification failed");
}
```
## CLI usage
```text
xllutils list-exports my_xll.xll [-o] [-A]
xllutils verify my_xll.xll -e xlAutoOpen,xlAutoClose,xlAutoFree12 [-s]
xllutils xll-info my_xll.xll [--json]
xllutils diff first.xll second.xll
xllutils find-xlls # Windows only
```
### Examples
List exports with ordinals:
```text
$ xllutils list-exports my_xll.xll -o
my_xll.xll (x64, 9 exports)
xlAutoOpen ordinal=1
xlAutoClose ordinal=2
xlAutoFree12 ordinal=3
...
```
Verify required exports:
```text
$ xllutils verify my_xll.xll -e xlAutoOpen,xlAutoClose,xlAutoFree12
Verification: my_xll.xll
Architecture: x64
Total exports: 9
Found: 3 / 3
Result: OK
```