|
520 | 520 | C:\> output.exe
|
521 | 521 |
|
522 | 522 | Note: make sure not to use --debug flag in production.
|
| 523 | + |
| 524 | +### Injecting Windows Executable Metadata After Packaging |
| 525 | +Executables created with `pkg` are based on a Node.js binary and, by default, |
| 526 | +inherit its embedded metadata – such as version number, product name, company |
| 527 | +name, icon, and description. This can be misleading or unpolished in |
| 528 | +distributed applications. |
| 529 | + |
| 530 | +There are two ways to customize the metadata of the resulting `.exe`: |
| 531 | +1. **Use a custom Node.js binary** with your own metadata already embedded. |
| 532 | + See: [Use Custom Node.js Binary](#use-custom-nodejs-binary) |
| 533 | + |
| 534 | +2. **Post-process the generated executable** using |
| 535 | + [`resedit`](https://www.npmjs.com/package/resedit), a Node.js-compatible |
| 536 | + tool for modifying Windows executable resources. This allows injecting |
| 537 | + correct version info, icons, copyright, |
| 538 | + and more. |
| 539 | + |
| 540 | +This section focuses on the second approach: post-processing the packaged |
| 541 | +binary using [`resedit`](https://www.npmjs.com/package/resedit). |
| 542 | + |
| 543 | +> ⚠️ Other tools may corrupt the executable, resulting in runtime errors such as |
| 544 | +> `Pkg: Error reading from file.` – |
| 545 | +> [`resedit`](https://www.npmjs.com/package/resedit) has proven to work reliably |
| 546 | +> with `pkg`-generated binaries. |
| 547 | +
|
| 548 | +Below is a working example for post-processing an `.exe` file using the Node.js API of [`resedit`](https://www.npmjs.com/package/resedit): |
| 549 | + |
| 550 | +```ts |
| 551 | +import * as ResEdit from "resedit"; |
| 552 | +import * as fs from "fs"; |
| 553 | +import * as path from "path"; |
| 554 | + |
| 555 | +// Set your inputs: |
| 556 | +const exePath = "dist/my-tool.exe"; // Path to the generated executable |
| 557 | +const outputPath = exePath; // Overwrite or use a different path |
| 558 | +const version = "1.2.3"; // Your application version |
| 559 | + |
| 560 | +const lang = 1033; // en-US |
| 561 | +const codepage = 1200; // Unicode |
| 562 | + |
| 563 | +const exeData = fs.readFileSync(exePath); |
| 564 | +const exe = ResEdit.NtExecutable.from(exeData); |
| 565 | +const res = ResEdit.NtExecutableResource.from(exe); |
| 566 | + |
| 567 | +const viList = ResEdit.Resource.VersionInfo.fromEntries(res.entries); |
| 568 | +const vi = viList[0]; |
| 569 | + |
| 570 | +const [major, minor, patch] = version.split("."); |
| 571 | +vi.setFileVersion(Number(major), Number(minor), Number(patch), 0, lang); |
| 572 | +vi.setProductVersion(Number(major), Number(minor), Number(patch), 0, lang); |
| 573 | + |
| 574 | +vi.setStringValues({ lang, codepage }, { |
| 575 | + FileDescription: "ACME CLI Tool", |
| 576 | + ProductName: "ACME Application", |
| 577 | + CompanyName: "ACME Corporation", |
| 578 | + ProductVersion: version, |
| 579 | + FileVersion: version, |
| 580 | + OriginalFilename: path.basename(exePath), |
| 581 | + LegalCopyright: `© ${new Date().getFullYear()} ACME Corporation` |
| 582 | +}); |
| 583 | + |
| 584 | +vi.outputToResourceEntries(res.entries); |
| 585 | +res.outputResource(exe); |
| 586 | +const newBinary = exe.generate(); |
| 587 | + |
| 588 | +fs.writeFileSync(outputPath, Buffer.from(newBinary)); |
| 589 | +``` |
| 590 | + |
| 591 | +As an alternative to the Node.js API, |
| 592 | +[`resedit`](https://www.npmjs.com/package/resedit) also supports command–line |
| 593 | +usage. This can be convenient for simple use cases in build scripts. |
| 594 | + |
| 595 | +The following command examples inject an icon and metadata into the executable |
| 596 | +`dist/bin/app_with_metadata.exe`, based on the original built file |
| 597 | +`dist/bin/app.exe`. |
| 598 | + |
| 599 | +- **Example (PowerShell on Windows)** |
| 600 | + ```powershell |
| 601 | + npx resedit dist/bin/app.exe dist/bin/app_with_metadata.exe ` |
| 602 | + --icon 1,dist/favicon.ico ` |
| 603 | + --company-name "ACME Corporation" ` |
| 604 | + --file-description "ACME CLI Tool" ` |
| 605 | + --product-name "ACME Application" ` |
| 606 | + --file-version 1.2.3.4 |
| 607 | + ``` |
| 608 | + |
| 609 | +- **Example (bash on Linux/macOS)** |
| 610 | + ```bash |
| 611 | + npx resedit dist/bin/app.exe dist/bin/app_with_metadata.exe \ |
| 612 | + --icon 1,dist/favicon.ico \ |
| 613 | + --company-name "ACME Corporation" \ |
| 614 | + --file-description "ACME CLI Tool" \ |
| 615 | + --product-name "ACME Application" \ |
| 616 | + --file-version 1.2.3.4 |
| 617 | + ``` |
| 618 | + > 💡 This is especially useful when cross-compiling Windows executables from |
| 619 | + > Linux or macOS using `pkg`. |
| 620 | +
|
| 621 | +> 📚 **More information:** See the |
| 622 | +> [`resedit`](https://www.npmjs.com/package/resedit) package on npm for |
| 623 | +> additional examples and full API documentation. |
0 commit comments