electron-forge-maker-innosetup 0.2.9 → 0.3.0

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.
package/README.md CHANGED
@@ -1,11 +1,11 @@
1
- # @electron-forge/maker-innosetup
1
+ # electron-forge-maker-innosetup
2
2
 
3
3
  一个用于 [Electron Forge](https://www.electronforge.io/) 的 Innosetup Maker,支持使用 Innosetup 为 Windows 平台创建安装程序。继承自 `@electron-forge/maker-base`。
4
4
 
5
5
  ## 安装
6
6
 
7
7
  ```bash
8
- npm install --save-dev @electron-forge/maker-innosetup
8
+ npm install --save-dev electron-forge-maker-innosetup
9
9
  ```
10
10
 
11
11
  ## 前置要求
@@ -33,16 +33,16 @@ vendor/
33
33
 
34
34
  ```typescript
35
35
  // 命名导入(推荐)
36
- import { MakerInnosetup } from "@electron-forge/maker-innosetup";
36
+ import { MakerInnosetup } from "electron-forge-maker-innosetup";
37
37
 
38
38
  // 默认导入
39
- import MakerInnosetup from "@electron-forge/maker-innosetup";
39
+ import MakerInnosetup from "electron-forge-maker-innosetup";
40
40
 
41
41
  // 导入解析器
42
42
  import {
43
43
  MakerInnosetup,
44
44
  InnoScriptParser,
45
- } from "@electron-forge/maker-innosetup";
45
+ } from "electron-forge-maker-innosetup";
46
46
  ```
47
47
 
48
48
  ### 方式一:在配置文件中使用(推荐)
@@ -51,7 +51,7 @@ import {
51
51
 
52
52
  ```typescript
53
53
  import type { ForgeConfig } from "@electron-forge/shared-types";
54
- import MakerInnosetup from "@electron-forge/maker-innosetup";
54
+ import MakerInnosetup from "electron-forge-maker-innosetup";
55
55
 
56
56
  const config: ForgeConfig = {
57
57
  makers: [
@@ -78,7 +78,7 @@ export default config;
78
78
  module.exports = {
79
79
  makers: [
80
80
  {
81
- name: "@electron-forge/maker-innosetup",
81
+ name: "electron-forge-maker-innosetup",
82
82
  config: {
83
83
  appName: "MyApp",
84
84
  appPublisher: "My Company",
@@ -92,7 +92,7 @@ module.exports = {
92
92
  ### 完整配置示例
93
93
 
94
94
  ```typescript
95
- import type { MakerInnosetupConfig } from "@electron-forge/maker-innosetup";
95
+ import type { MakerInnosetupConfig } from "electron-forge-maker-innosetup";
96
96
 
97
97
  const config: MakerInnosetupConfig = {
98
98
  // 应用信息
@@ -185,7 +185,7 @@ const config: MakerInnosetupConfig = {
185
185
 
186
186
  ```javascript
187
187
  {
188
- name: '@electron-forge/maker-innosetup',
188
+ name: 'electron-forge-maker-innosetup',
189
189
  config: {
190
190
  scriptPath: './installer.iss'
191
191
  }
@@ -196,7 +196,7 @@ const config: MakerInnosetupConfig = {
196
196
  #### 方法 2: 解析 ISS 文件为配置
197
197
 
198
198
  ```typescript
199
- import { MakerInnosetup } from "@electron-forge/maker-innosetup";
199
+ import { MakerInnosetup } from "electron-forge-maker-innosetup";
200
200
 
201
201
  // 从 ISS 文件解析配置
202
202
  const config = MakerInnosetup.fromIssFile("./installer.iss");
@@ -209,7 +209,7 @@ const config2 = MakerInnosetup.fromIssContent(issContent);
209
209
  const forgeConfig: ForgeConfig = {
210
210
  makers: [
211
211
  {
212
- name: "@electron-forge/maker-innosetup",
212
+ name: "electron-forge-maker-innosetup",
213
213
  config: config, // 使用解析后的配置
214
214
  platforms: ["win32"],
215
215
  },
@@ -268,6 +268,74 @@ const forgeConfig: ForgeConfig = {
268
268
 
269
269
  ## 高级用法
270
270
 
271
+ ### 使用预处理器常量 (#define)
272
+
273
+ 使用 `Defines` 字段可以定义预处理器常量,在配置中使用 `{#ConstantName}` 引用:
274
+
275
+ ```typescript
276
+ config: {
277
+ config: {
278
+ // 定义预处理器常量
279
+ Defines: {
280
+ MyAppName: "Police Self Report",
281
+ MyAppVersion: "1.0.0",
282
+ MyAppPublisher: "合肥视尔信息科技有限公司",
283
+ MyAppExeName: "Police Self Report.exe",
284
+ MyAppAssocName: "Police Self Report File",
285
+ MyAppAssocExt: ".myp",
286
+ MyAppShortcutName: "公安自助接报案系统",
287
+ },
288
+ Setup: {
289
+ // 使用 {#ConstantName} 引用预处理器常量
290
+ AppName: "{#MyAppName}",
291
+ AppVersion: "{#MyAppVersion}",
292
+ AppPublisher: "{#MyAppPublisher}",
293
+ DefaultDirName: "{autopf}\\{#MyAppName}",
294
+ OutputBaseFilename: "{#MyAppName}_{#MyAppVersion}",
295
+ ChangesAssociations: true,
296
+ },
297
+ Icons: [
298
+ {
299
+ Name: "{group}\\{#MyAppShortcutName}",
300
+ Filename: "{app}\\{#MyAppExeName}",
301
+ },
302
+ ],
303
+ Registry: [
304
+ {
305
+ Root: "HKCR",
306
+ Subkey: "{#MyAppAssocExt}",
307
+ ValueType: "string",
308
+ ValueName: "",
309
+ ValueData: "{#MyAppAssocName}",
310
+ },
311
+ ],
312
+ },
313
+ }
314
+ ```
315
+
316
+ 生成的 ISS 脚本将包含:
317
+
318
+ ```iss
319
+ ; Script generated by the Inno Setup Script Wizard.
320
+ ; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!
321
+
322
+ #define MyAppName "Police Self Report"
323
+ #define MyAppVersion "1.0.0"
324
+ #define MyAppPublisher "合肥视尔信息科技有限公司"
325
+ #define MyAppExeName "Police Self Report.exe"
326
+
327
+ [Setup]
328
+ AppName={#MyAppName}
329
+ AppVersion={#MyAppVersion}
330
+ AppPublisher={#MyAppPublisher}
331
+ ```
332
+
333
+ **优势:**
334
+
335
+ - 🔄 更易维护:集中管理常量,修改一处即可
336
+ - 📖 更清晰:生成的 ISS 脚本更具可读性
337
+ - 🔧 更灵活:支持 Inno Setup 原生的预处理器功能
338
+
271
339
  ### 添加自定义 Pascal 代码
272
340
 
273
341
  ```typescript
@@ -174,7 +174,7 @@ class MakerInnosetup extends maker_base_1.default {
174
174
  AppName: this.config.appName || appName,
175
175
  AppVersion: this.config.appVersion || appVersion,
176
176
  AppPublisher: this.config.appPublisher || "",
177
- AppId: this.config.appId || `{{${appName}}`,
177
+ AppId: this.config.appId || `{{${appName}}}`,
178
178
  DefaultDirName: `{autopf}\\${appName}`,
179
179
  DefaultGroupName: appName,
180
180
  OutputDir: outputDir,
@@ -234,6 +234,7 @@ class MakerInnosetup extends maker_base_1.default {
234
234
  return defaultConfig;
235
235
  }
236
236
  return {
237
+ Defines: userConfig.Defines || defaultConfig.Defines,
237
238
  Setup: { ...defaultConfig.Setup, ...userConfig.Setup },
238
239
  Languages: userConfig.Languages || defaultConfig.Languages,
239
240
  Tasks: userConfig.Tasks || defaultConfig.Tasks,
@@ -260,7 +261,12 @@ class MakerInnosetup extends maker_base_1.default {
260
261
  if (!config.Tasks) {
261
262
  config.Tasks = [];
262
263
  }
263
- if (this.config.createDesktopIcon !== false) {
264
+ // 检查用户是否已经自定义了桌面图标任务
265
+ const hasDesktopTask = config.Tasks.some((task) => task.Name === "desktopicon");
266
+ const hasDesktopIcon = config.Icons?.some((icon) => icon.Name?.includes("{autodesktop}") && icon.Tasks === "desktopicon");
267
+ if (this.config.createDesktopIcon !== false &&
268
+ !hasDesktopTask &&
269
+ !hasDesktopIcon) {
264
270
  config.Tasks.push({
265
271
  Name: "desktopicon",
266
272
  Description: "Create a &desktop icon",
@@ -275,7 +281,12 @@ class MakerInnosetup extends maker_base_1.default {
275
281
  });
276
282
  }
277
283
  }
278
- if (this.config.createQuickLaunchIcon) {
284
+ // 检查用户是否已经自定义了快速启动任务
285
+ const hasQuickLaunchTask = config.Tasks.some((task) => task.Name === "quicklaunchicon");
286
+ const hasQuickLaunchIcon = config.Icons?.some((icon) => icon.Name?.includes("Quick Launch") && icon.Tasks === "quicklaunchicon");
287
+ if (this.config.createQuickLaunchIcon &&
288
+ !hasQuickLaunchTask &&
289
+ !hasQuickLaunchIcon) {
279
290
  config.Tasks.push({
280
291
  Name: "quicklaunchicon",
281
292
  Description: "Create a &Quick Launch icon",
@@ -306,6 +317,30 @@ class MakerInnosetup extends maker_base_1.default {
306
317
  });
307
318
  let output = "";
308
319
  let errorOutput = "";
320
+ let isResolved = false;
321
+ const timeout = this.config.compileTimeout || 300000;
322
+ const timeoutHandle = setTimeout(() => {
323
+ if (!isResolved) {
324
+ isResolved = false;
325
+ console.error("Innosetup compilation timeout, killing process...");
326
+ try {
327
+ iscc.kill("SIGKILL");
328
+ }
329
+ catch (e) {
330
+ console.error("Failed to kill process", e);
331
+ }
332
+ reject(new Error(`Innosetup compilation timeout after ${timeout} ms`));
333
+ }
334
+ }, timeout);
335
+ const cleanup = () => {
336
+ clearTimeout(timeoutHandle);
337
+ try {
338
+ if (iscc && !iscc.killed) {
339
+ iscc.kill("SIGKILL");
340
+ }
341
+ }
342
+ catch (e) { }
343
+ };
309
344
  iscc.stdout.on("data", (data) => {
310
345
  const text = data.toString();
311
346
  output += text;
@@ -317,16 +352,29 @@ class MakerInnosetup extends maker_base_1.default {
317
352
  console.error(text);
318
353
  });
319
354
  iscc.on("close", (code) => {
355
+ if (isResolved)
356
+ return;
357
+ isResolved = true;
358
+ clearTimeout(timeoutHandle);
320
359
  if (code === 0) {
321
360
  resolve(output);
322
361
  }
323
362
  else {
363
+ cleanup();
324
364
  reject(new Error(`Innosetup compilation failed with code ${code}\n${errorOutput}`));
325
365
  }
326
366
  });
327
367
  iscc.on("error", (err) => {
368
+ if (isResolved)
369
+ return;
370
+ isResolved = true;
371
+ cleanup();
328
372
  reject(new Error(`Failed to start Innosetup compiler: ${err.message}`));
329
373
  });
374
+ // 处理进程意外退出
375
+ process.on("exit", cleanup);
376
+ process.on("SIGINT", cleanup);
377
+ process.on("SIGTERM", cleanup);
330
378
  });
331
379
  }
332
380
  /**
@@ -7,6 +7,10 @@ export declare class InnoScriptGenerator {
7
7
  * 生成脚本内容
8
8
  */
9
9
  generate(config: InnoSetupConfig): string;
10
+ /**
11
+ * 生成 #define 指令部分
12
+ */
13
+ private generateDefinesSection;
10
14
  /**
11
15
  * 生成 Setup 部分
12
16
  */
@@ -77,6 +81,7 @@ export declare class InnoScriptGenerator {
77
81
  private generateCodeSection;
78
82
  /**
79
83
  * 将脚本保存到文件
84
+ * 注意:使用 UTF-8 编码保存,并在文件开头添加 BOM 标记
80
85
  */
81
86
  saveToFile(scriptContent: string, filePath: string): void;
82
87
  }
package/dist/generator.js CHANGED
@@ -45,6 +45,10 @@ class InnoScriptGenerator {
45
45
  */
46
46
  generate(config) {
47
47
  const sections = [];
48
+ // 生成 #define 指令
49
+ if (config.Defines && Object.keys(config.Defines).length > 0) {
50
+ sections.push(this.generateDefinesSection(config.Defines));
51
+ }
48
52
  // 生成 [Setup] 部分
49
53
  if (config.Setup) {
50
54
  sections.push(this.generateSetupSection(config.Setup));
@@ -114,7 +118,40 @@ class InnoScriptGenerator {
114
118
  if (config.Code) {
115
119
  sections.push(this.generateCodeSection(config.Code));
116
120
  }
117
- return sections.join("\n\n");
121
+ // 添加 UTF-8 BOM 标记,确保 Inno Setup 正确识别中文
122
+ return "\uFEFF" + sections.join("\n\n");
123
+ }
124
+ /**
125
+ * 生成 #define 指令部分
126
+ */
127
+ generateDefinesSection(defines) {
128
+ const lines = [
129
+ "; Script generated by the Inno Setup Script Wizard.",
130
+ "; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!",
131
+ "",
132
+ ];
133
+ for (const [key, value] of Object.entries(defines)) {
134
+ if (value !== undefined && value !== null) {
135
+ const strValue = String(value);
136
+ // 检查是否是表达式(包含函数调用、引用或拼接)
137
+ const isExpression = strValue.includes("(") ||
138
+ strValue.includes("+") ||
139
+ (strValue.match(/^\w+$/) && !strValue.match(/^\d+$/));
140
+ if (typeof value === "string" && !isExpression) {
141
+ // 普通字符串,添加引号
142
+ lines.push(`#define ${key} "${value}"`);
143
+ }
144
+ else if (typeof value === "string" && isExpression) {
145
+ // 表达式,不添加引号
146
+ lines.push(`#define ${key} ${value}`);
147
+ }
148
+ else {
149
+ // 数字等其他类型
150
+ lines.push(`#define ${key} ${value}`);
151
+ }
152
+ }
153
+ }
154
+ return lines.join("\n");
118
155
  }
119
156
  /**
120
157
  * 生成 Setup 部分
@@ -130,7 +167,15 @@ class InnoScriptGenerator {
130
167
  lines.push(`${key}=${value}`);
131
168
  }
132
169
  else {
133
- lines.push(`${key}=${value}`);
170
+ // 检查值是否包含 {#...} 引用
171
+ const stringValue = String(value);
172
+ if (stringValue.includes("{#")) {
173
+ // 如果包含常量引用,不添加额外引号
174
+ lines.push(`${key}=${stringValue}`);
175
+ }
176
+ else {
177
+ lines.push(`${key}=${stringValue}`);
178
+ }
134
179
  }
135
180
  }
136
181
  }
@@ -366,14 +411,34 @@ class InnoScriptGenerator {
366
411
  const lines = ["[Registry]"];
367
412
  for (const item of items) {
368
413
  const parts = [`Root: ${item.Root}`];
369
- parts.push(`Subkey: "${item.Subkey}"`);
414
+ // Subkey: 检查是否包含 {#...} 引用或函数调用
415
+ const subkey = String(item.Subkey);
416
+ if (subkey.includes("{#") || subkey.includes("StringChange(")) {
417
+ // 如果包含常量引用或函数,不添加引号
418
+ parts.push(`Subkey: "${subkey}"`);
419
+ }
420
+ else {
421
+ parts.push(`Subkey: "${subkey}"`);
422
+ }
370
423
  if (item.ValueType)
371
424
  parts.push(`ValueType: ${item.ValueType}`);
372
- if (item.ValueName !== undefined)
373
- parts.push(`ValueName: "${item.ValueName}"`);
425
+ // ValueName: 检查是否包含引用或函数调用
426
+ if (item.ValueName !== undefined) {
427
+ const valueName = String(item.ValueName);
428
+ if (valueName.includes("{#") || valueName.includes("StringChange(")) {
429
+ // 如果包含常量引用或函数,不添加引号
430
+ parts.push(`ValueName: "${valueName}"`);
431
+ }
432
+ else {
433
+ parts.push(`ValueName: "${valueName}"`);
434
+ }
435
+ }
374
436
  if (item.ValueData !== undefined) {
375
437
  if (typeof item.ValueData === "string") {
376
- parts.push(`ValueData: "${item.ValueData}"`);
438
+ const valueData = item.ValueData;
439
+ // 直接使用原始值,不需要额外转义
440
+ // Inno Setup 中的引号转义应该由用户自己处理
441
+ parts.push(`ValueData: "${valueData}"`);
377
442
  }
378
443
  else {
379
444
  parts.push(`ValueData: ${item.ValueData}`);
@@ -483,12 +548,14 @@ class InnoScriptGenerator {
483
548
  }
484
549
  /**
485
550
  * 将脚本保存到文件
551
+ * 注意:使用 UTF-8 编码保存,并在文件开头添加 BOM 标记
486
552
  */
487
553
  saveToFile(scriptContent, filePath) {
488
554
  const dir = path.dirname(filePath);
489
555
  if (!fs.existsSync(dir)) {
490
556
  fs.mkdirSync(dir, { recursive: true });
491
557
  }
558
+ // 使用 UTF-8 编码保存,scriptContent 已经包含 BOM
492
559
  fs.writeFileSync(filePath, scriptContent, "utf-8");
493
560
  }
494
561
  }
package/dist/parser.d.ts CHANGED
@@ -10,8 +10,22 @@ export declare class InnoScriptParser {
10
10
  static parseFile(issFilePath: string): InnoSetupConfig;
11
11
  /**
12
12
  * 解析 ISS 脚本内容
13
+ * @param content ISS 脚本内容
14
+ * @param preserveDefineReferences 是否保留 {#...} 引用(不替换为实际值)
13
15
  */
14
- static parse(content: string): InnoSetupConfig;
16
+ static parse(content: string, preserveDefineReferences?: boolean): InnoSetupConfig;
17
+ /**
18
+ * 保留 #define 的原始表达式
19
+ */
20
+ private static preserveDefineExpression;
21
+ /**
22
+ * 解析 #define 的值,支持字符串拼接和函数调用
23
+ */
24
+ private static parseDefineValue;
25
+ /**
26
+ * 替换字符串中的常量引用 {#ConstantName}
27
+ */
28
+ private static replaceDefines;
15
29
  /**
16
30
  * 解析 Setup 段落的一行
17
31
  */
package/dist/parser.js CHANGED
@@ -49,19 +49,51 @@ class InnoScriptParser {
49
49
  }
50
50
  /**
51
51
  * 解析 ISS 脚本内容
52
+ * @param content ISS 脚本内容
53
+ * @param preserveDefineReferences 是否保留 {#...} 引用(不替换为实际值)
52
54
  */
53
- static parse(content) {
55
+ static parse(content, preserveDefineReferences = true) {
54
56
  const config = {};
57
+ const defines = {};
55
58
  const lines = content.split(/\r?\n/);
56
59
  let currentSection = null;
57
60
  let codeSection = "";
58
61
  let inCodeSection = false;
62
+ // 第一次扫描:提取所有 #define 定义
59
63
  for (let i = 0; i < lines.length; i++) {
60
64
  let line = lines[i].trim();
61
65
  // 跳过空行和注释
62
66
  if (!line || line.startsWith(";") || line.startsWith("//")) {
63
67
  continue;
64
68
  }
69
+ // 解析 #define 指令
70
+ const defineMatch = line.match(/^#define\s+(\w+)\s+(.+)$/);
71
+ if (defineMatch) {
72
+ const [, varName, varValue] = defineMatch;
73
+ // 如果保留引用,则保存原始表达式;否则计算值
74
+ defines[varName] = preserveDefineReferences
75
+ ? this.preserveDefineExpression(varValue)
76
+ : this.parseDefineValue(varValue, defines);
77
+ }
78
+ }
79
+ // 如果有 defines,添加到配置中
80
+ if (Object.keys(defines).length > 0) {
81
+ config.Defines = defines;
82
+ }
83
+ // 第二次扫描:解析配置段落
84
+ for (let i = 0; i < lines.length; i++) {
85
+ let line = lines[i].trim();
86
+ // 跳过空行、注释和 #define 指令
87
+ if (!line ||
88
+ line.startsWith(";") ||
89
+ line.startsWith("//") ||
90
+ line.startsWith("#define")) {
91
+ continue;
92
+ }
93
+ // 如果不保留引用,则替换常量引用 {#ConstantName}
94
+ if (!preserveDefineReferences) {
95
+ line = this.replaceDefines(line, defines);
96
+ }
65
97
  // 检测段落
66
98
  const sectionMatch = line.match(/^\[(\w+)\]$/);
67
99
  if (sectionMatch) {
@@ -78,7 +110,11 @@ class InnoScriptParser {
78
110
  }
79
111
  // 如果在 Code 段落中,收集所有代码
80
112
  if (inCodeSection) {
81
- codeSection += lines[i] + "\n";
113
+ // 对于 Code 段落,使用原始行(带缩进)
114
+ const processedLine = preserveDefineReferences
115
+ ? lines[i]
116
+ : this.replaceDefines(lines[i], defines);
117
+ codeSection += processedLine + "\n";
82
118
  continue;
83
119
  }
84
120
  // 解析不同段落
@@ -137,6 +173,83 @@ class InnoScriptParser {
137
173
  }
138
174
  return config;
139
175
  }
176
+ /**
177
+ * 保留 #define 的原始表达式
178
+ */
179
+ static preserveDefineExpression(value) {
180
+ value = value.trim();
181
+ // 移除外层引号(如果有)
182
+ if (value.startsWith('"') && value.endsWith('"')) {
183
+ return value.slice(1, -1);
184
+ }
185
+ return value;
186
+ }
187
+ /**
188
+ * 解析 #define 的值,支持字符串拼接和函数调用
189
+ */
190
+ static parseDefineValue(value, defines) {
191
+ value = value.trim();
192
+ // 处理字符串拼接 (e.g., MyAppName + " File")
193
+ if (value.includes("+")) {
194
+ const parts = value.split("+").map((p) => p.trim());
195
+ let result = "";
196
+ for (const part of parts) {
197
+ if (part.startsWith('"') && part.endsWith('"')) {
198
+ // 直接的字符串字面量
199
+ result += part.slice(1, -1);
200
+ }
201
+ else if (defines[part]) {
202
+ // 引用已定义的常量
203
+ result += defines[part];
204
+ }
205
+ else {
206
+ // 未知引用,保持原样
207
+ result += part;
208
+ }
209
+ }
210
+ return result;
211
+ }
212
+ // 处理 StringChange 函数 (e.g., StringChange(MyAppAssocName, " ", ""))
213
+ const stringChangeMatch = value.match(/StringChange\(([^,]+),\s*"([^"]*)",\s*"([^"]*)"\)/);
214
+ if (stringChangeMatch) {
215
+ const [, varRef, searchStr, replaceStr] = stringChangeMatch;
216
+ const varName = varRef.trim();
217
+ const sourceValue = defines[varName] ? String(defines[varName]) : varName;
218
+ let result = sourceValue.replace(new RegExp(searchStr, "g"), replaceStr);
219
+ // 处理后续的拼接,例如 StringChange(...) + ".myp"
220
+ const fullMatch = value.match(/StringChange\([^)]+\)(.*)$/);
221
+ if (fullMatch && fullMatch[1]) {
222
+ const suffix = fullMatch[1].trim();
223
+ if (suffix.startsWith("+")) {
224
+ const suffixPart = suffix.substring(1).trim();
225
+ if (suffixPart.startsWith('"') && suffixPart.endsWith('"')) {
226
+ result += suffixPart.slice(1, -1);
227
+ }
228
+ else {
229
+ result += suffixPart;
230
+ }
231
+ }
232
+ }
233
+ return result;
234
+ }
235
+ // 处理常量引用 (e.g., MyAppName)
236
+ if (defines[value]) {
237
+ return String(defines[value]);
238
+ }
239
+ // 移除外层引号
240
+ if (value.startsWith('"') && value.endsWith('"')) {
241
+ return value.slice(1, -1);
242
+ }
243
+ return value;
244
+ }
245
+ /**
246
+ * 替换字符串中的常量引用 {#ConstantName}
247
+ */
248
+ static replaceDefines(text, defines) {
249
+ return text.replace(/\{#(\w+)\}/g, (match, varName) => {
250
+ return defines[varName] !== undefined ? String(defines[varName]) : match;
251
+ });
252
+ }
140
253
  /**
141
254
  * 解析 Setup 段落的一行
142
255
  */
@@ -171,7 +284,7 @@ class InnoScriptParser {
171
284
  */
172
285
  static parseParams(line) {
173
286
  const params = {};
174
- const parts = line.split(";").map(p => p.trim());
287
+ const parts = line.split(";").map((p) => p.trim());
175
288
  for (const part of parts) {
176
289
  const match = part.match(/^(\w+):\s*(.+)$/);
177
290
  if (match) {
@@ -253,7 +366,9 @@ class InnoScriptParser {
253
366
  Description: params.Description,
254
367
  Types: params.Types,
255
368
  Flags: params.Flags,
256
- ExtraDiskSpaceRequired: params.ExtraDiskSpaceRequired ? parseInt(params.ExtraDiskSpaceRequired) : undefined,
369
+ ExtraDiskSpaceRequired: params.ExtraDiskSpaceRequired
370
+ ? parseInt(params.ExtraDiskSpaceRequired)
371
+ : undefined,
257
372
  });
258
373
  }
259
374
  }
package/dist/types.d.ts CHANGED
@@ -1,10 +1,18 @@
1
1
  /**
2
2
  * Innosetup 完整的 TypeScript 类型定义
3
3
  */
4
+ /**
5
+ * Defines 部分配置 - 预处理器常量定义
6
+ */
7
+ export interface InnoSetupDefines {
8
+ [key: string]: string | number;
9
+ }
4
10
  /**
5
11
  * Setup 部分配置
6
12
  */
7
13
  export interface InnoSetupConfig {
14
+ /** Defines 部分配置 - 预处理器常量定义 */
15
+ Defines?: InnoSetupDefines;
8
16
  /** Setup 部分配置 */
9
17
  Setup?: {
10
18
  /** 应用程序名称 */
@@ -604,4 +612,6 @@ export interface MakerInnosetupConfig {
604
612
  createDesktopIcon?: boolean;
605
613
  /** 是否创建快速启动图标 */
606
614
  createQuickLaunchIcon?: boolean;
615
+ /** 编译超时时间(毫秒),默认 5 分钟 */
616
+ compileTimeout?: number;
607
617
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "electron-forge-maker-innosetup",
3
- "version": "0.2.9",
3
+ "version": "0.3.0",
4
4
  "description": "An Electron Forge maker for creating Windows installers using Innosetup with full TypeScript support",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
Binary file
Binary file
Binary file