Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions docs/en/makers/exe.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ create_desktop_icon: true
# install_dir_name: "D:\\HELLO-WORLD"
# This path is relative to the root directory of your project; The format of icon file must be ico, can not be png or others
# setup_icon_file: windows\runner\resources\app_icon.ico
# Custom Inno Setup installation path (optional, defaults to "C:\Program Files (x86)\Inno Setup 6")
# inno_setup_path: "C:\Program Files (x86)\Inno Setup 6"
locales:
- en
- zh
Expand All @@ -33,6 +35,15 @@ fastforge package --platform windows --targets exe

## Advanced usage

### Custom Inno Setup path

By default, `fastforge` looks for Inno Setup 6 at `C:\Program Files (x86)\Inno Setup 6`. If you have installed Inno Setup in a different location, you can specify the custom path using the `inno_setup_path` option in your `make_config.yaml`:

```yaml
# Custom Inno Setup installation path
inno_setup_path: "D:\Tools\Inno Setup 6"
```

### Custom Inno Setup template

By default, `fastforge` will generate an Inno Setup configuration (`.iss`) based on an internal template on build time, and populate it with the values provided in `make_config.yaml`. If you need more control over the Inno Setup configuration, you can provide a custom template using the `script_template` option.
Expand Down
11 changes: 11 additions & 0 deletions docs/zh/makers/exe.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ create_desktop_icon: true
# install_dir_name: "D:\\HELLO-WORLD"
# 这里的路径是相对于项目根目录的路径; 图标格式必须是ico格式,不能是png或其它
# setup_icon_file: windows\runner\resources\app_icon.ico
# 自定义 Inno Setup 安装路径(可选,默认为 "C:\Program Files (x86)\Inno Setup 6")
# inno_setup_path: "C:\Program Files (x86)\Inno Setup 6"
locales:
- en
- zh
Expand All @@ -33,6 +35,15 @@ fastforge package --platform windows --targets exe

## 高级用法

### 自定义 Inno Setup 路径

默认情况下,`fastforge` 在 `C:\Program Files (x86)\Inno Setup 6` 路径查找 Inno Setup 6。如果你将 Inno Setup 安装在其他位置,可以在 `make_config.yaml` 中使用 `inno_setup_path` 选项指定自定义路径:

```yaml
# 自定义 Inno Setup 安装路径
inno_setup_path: "D:\Tools\Inno Setup 6"
```

### 自定义 Inno Setup 模板

默认情况下,`fastforge` 会在构建时基于内部模板生成一个 Inno Setup 配置(`.iss`),并将其填充到 `make_config.yaml` 中提供的值。如果你需要对 Inno Setup 配置进行更多控制,你可以使用 `script_template` 选项提供一个自定义模板。
Expand Down
39 changes: 39 additions & 0 deletions examples/custom_inno_setup_path.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# Example: Using Custom Inno Setup Path

This example demonstrates how to configure fastforge to use a custom Inno Setup installation path.

## Configuration

Add the following to your `windows/packaging/exe/make_config.yaml`:

```yaml
# Basic app information
app_id: 5B599538-42B1-4826-A479-AF079F21A65D
publisher: LeanFlutter
publisher_url: https://github.com/fastforgedev/fastforge
display_name: Hello 世界
create_desktop_icon: true

# Custom Inno Setup path
inno_setup_path: "D:\Tools\Inno Setup 6"

locales:
- en
- zh
```

## Use Cases

This feature is useful when:

1. **Non-standard Installation**: You installed Inno Setup in a custom directory
2. **Portable Installation**: You're using a portable version of Inno Setup
3. **Multiple Versions**: You have multiple versions of Inno Setup and want to use a specific one
4. **CI/CD Environments**: You have Inno Setup installed in a specific location in your build agents

## Fallback Behavior

If `inno_setup_path` is not specified or is `null`, fastforge will use the default path:
`C:\Program Files (x86)\Inno Setup 6`

This ensures backward compatibility with existing configurations.
2 changes: 2 additions & 0 deletions examples/hello_world/windows/packaging/exe/make_config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,7 @@ display_name: Hello 世界
create_desktop_icon: true
launch_at_startup: true
# install_dir_name: "D:\\HELLO-WORLD"
# Custom Inno Setup path (optional, defaults to "C:\Program Files (x86)\Inno Setup 6")
# inno_setup_path: "D:\Tools\Inno Setup 6"
locales:
- zh
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ class AppPackageMakerExe extends AppPackageMaker {
InnoSetupScript script = InnoSetupScript.fromMakeConfig(makeConfig);
InnoSetupCompiler compiler = InnoSetupCompiler();

bool compiled = await compiler.compile(script);
bool compiled = await compiler.compile(script, customPath: makeConfig.innoSetupPath);

if (!compiled) {
throw MakeError();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@ import 'package:path/path.dart' as p;
import 'package:shell_executor/shell_executor.dart';

class InnoSetupCompiler {
Future<bool> compile(InnoSetupScript script) async {
Directory innoSetupDirectory =
Directory('C:\\Program Files (x86)\\Inno Setup 6');
Future<bool> compile(InnoSetupScript script, {String? customPath}) async {
String innoSetupPath = customPath ?? 'C:\\Program Files (x86)\\Inno Setup 6';
Directory innoSetupDirectory = Directory(innoSetupPath);

if (!innoSetupDirectory.existsSync()) {
throw Exception('`Inno Setup 6` was not installed.');
throw Exception('`Inno Setup 6` was not found at: $innoSetupPath');
}

File file = await script.createFile();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import 'package:path/path.dart' as p;
class MakeExeConfig extends MakeConfig {
MakeExeConfig({
this.scriptTemplate,
this.innoSetupPath,
required this.appId,
this.executableName,
this.displayName,
Expand Down Expand Up @@ -33,6 +34,7 @@ class MakeExeConfig extends MakeConfig {

MakeExeConfig makeExeConfig = MakeExeConfig(
scriptTemplate: json['script_template'],
innoSetupPath: json['inno_setup_path'],
appId: json['app_id'] ?? json['appId'],
executableName: json['executable_name'],
displayName: json['display_name'],
Expand All @@ -49,6 +51,7 @@ class MakeExeConfig extends MakeConfig {
}

String? scriptTemplate;
String? innoSetupPath;
final String appId;
String? executableName;
String? displayName;
Expand Down Expand Up @@ -80,6 +83,7 @@ class MakeExeConfig extends MakeConfig {
Map<String, dynamic> toJson() {
return {
'script_template': scriptTemplate,
'inno_setup_path': innoSetupPath,
'app_id': appId,
'app_name': appName,
'app_version': appVersion.toString(),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
import 'dart:io';

import 'package:flutter_app_packager/src/makers/exe/make_exe_config.dart';
import 'package:pub_semver/pub_semver.dart';
import 'package:pubspec_parse/pubspec_parse.dart';
import 'package:test/test.dart';

void main() {
group('MakeExeConfig', () {
test('fromJson should parse inno_setup_path correctly', () {
final json = {
'app_id': 'test-app-id',
'inno_setup_path': 'D:\\CustomPath\\Inno Setup 6',
'display_name': 'Test App',
'publisher_name': 'Test Publisher',
'locales': ['en', 'zh'],
};

final config = MakeExeConfig.fromJson(json);

expect(config.appId, equals('test-app-id'));
expect(config.innoSetupPath, equals('D:\\CustomPath\\Inno Setup 6'));
expect(config.displayName, equals('Test App'));
expect(config.publisherName, equals('Test Publisher'));
expect(config.locales, equals(['en', 'zh']));
});

test('fromJson should handle missing inno_setup_path', () {
final json = {
'app_id': 'test-app-id',
'display_name': 'Test App',
'locales': ['en'],
};

final config = MakeExeConfig.fromJson(json);

expect(config.appId, equals('test-app-id'));
expect(config.innoSetupPath, isNull);
expect(config.displayName, equals('Test App'));
});

test('toJson should include inno_setup_path when present', () {
final config = MakeExeConfig(
appId: 'test-app-id',
innoSetupPath: 'D:\\CustomPath\\Inno Setup 6',
displayName: 'Test App',
publisherName: 'Test Publisher',
locales: ['en'],
);

// Set required fields for the base config
config.buildOutputDirectory = Directory('build');
config.buildOutputFiles = [];
config.platform = 'windows';
config.packageFormat = 'exe';
config.outputDirectory = Directory('dist/');
config.pubspec = Pubspec(
'test_app',
version: Version.parse('1.0.0'),
);

final json = config.toJson();

expect(json['app_id'], equals('test-app-id'));
expect(json['inno_setup_path'], equals('D:\\CustomPath\\Inno Setup 6'));
expect(json['display_name'], equals('Test App'));
expect(json['publisher_name'], equals('Test Publisher'));
});

test('toJson should exclude null inno_setup_path', () {
final config = MakeExeConfig(
appId: 'test-app-id',
displayName: 'Test App',
locales: ['en'],
);

// Set required fields for the base config
config.buildOutputDirectory = Directory('build');
config.buildOutputFiles = [];
config.platform = 'windows';
config.packageFormat = 'exe';
config.outputDirectory = Directory('dist/');
config.pubspec = Pubspec(
'test_app',
version: Version.parse('1.0.0'),
);

final json = config.toJson();

expect(json['app_id'], equals('test-app-id'));
expect(json.containsKey('inno_setup_path'), isFalse);
expect(json['display_name'], equals('Test App'));
});
});
}