Skip to content
Merged
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
17 changes: 11 additions & 6 deletions docs/packaging.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,17 +32,21 @@ Default when the host runs as a normal Win32 process (installer or portable zip)

```
MyApp/
DesktopWebView.exe
DesktopWebView.ini # optional, beside the exe
MyApp.exe # native host (package.name.exe or host_executable)
MyApp.ini # optional, beside the exe (<exe_basename>.ini)
beam/
bin/
my_app.bat # or my_app (escript/release)
...
```

- Ini discovery: `--edw-config` → `DesktopWebView.ini` beside the executable.
- Installed host name defaults to `package.name` + `.exe` on Windows host-first
(override with `package.host_executable`). The source binary may still be
`DesktopWebView.exe` from `desktop_webview` / `DESKTOP_HOST_BINARY`.
- Ini discovery: `--edw-config` → `<exe_basename>.ini` beside the executable →
`DesktopWebView.ini` beside the executable.
- Relative `beam.path` / `working_dir` resolve against the directory containing
`DesktopWebView.exe`.
the host executable.
- Forwarded argv and `EDW_PORT` / `EDW_HOST` are unchanged.
- Release asset name: `DesktopWebView-windows-x64.exe` (see Binaries).
- WebView2: document Evergreen Runtime dependency in the app installer; the host
Expand Down Expand Up @@ -82,8 +86,9 @@ MyApp/
## Config discovery

1. `--edw-config=/path/to.ini`
2. `DesktopWebView.ini` beside the executable
3. macOS only: `Contents/Resources/DesktopWebView.ini` (app bundle)
2. `<exe_basename>.ini` beside the executable (e.g. `dDrive.ini` for `dDrive.exe`)
3. `DesktopWebView.ini` beside the executable
4. macOS only: `Contents/Resources/DesktopWebView.ini` (app bundle)

### Example ini

Expand Down
2 changes: 1 addition & 1 deletion native/windows/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ else()
set(WEBVIEW2_LIB_DIR "${WEBVIEW2_ROOT}/build/native/x86")
endif()

add_executable(DesktopWebView
add_executable(DesktopWebView WIN32
src/main.cpp
src/config.cpp
src/json_util.cpp
Expand Down
16 changes: 15 additions & 1 deletion native/windows/src/config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,21 @@ std::string HostConfig::resources_root() const {

std::optional<std::string> HostConfig::resolve_ini_path() const {
if (config_path) return *config_path;
auto beside = join_path(resources_root(), "DesktopWebView.ini");
auto root = resources_root();
// Prefer <exe_basename>.ini so renamed hosts (e.g. dDrive.exe → dDrive.ini)
// pick up the packaged config; fall back to the conventional name.
char buf[MAX_PATH];
DWORD n = GetModuleFileNameA(nullptr, buf, MAX_PATH);
if (n > 0 && n < MAX_PATH) {
std::string exe = buf;
auto slash = exe.find_last_of("/\\");
std::string base = (slash == std::string::npos) ? exe : exe.substr(slash + 1);
auto dot = base.find_last_of('.');
if (dot != std::string::npos) base = base.substr(0, dot);
auto beside_exe = join_path(root, base + ".ini");
if (file_exists(beside_exe)) return beside_exe;
}
auto beside = join_path(root, "DesktopWebView.ini");
if (file_exists(beside)) return beside;
return std::nullopt;
}
Expand Down
24 changes: 17 additions & 7 deletions native/windows/src/host_controller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -317,11 +317,16 @@ void HostController::spawn_beam() {
return;
}
std::string script = join_path(join_path(beam_dir, "bin"), app_name);
if (!file_exists(script)) {
if (file_exists(script + ".bat"))
script += ".bat";
else if (file_exists(script + ".cmd"))
script += ".cmd";
// Mix releases ship both a Unix `bin/<app>` shell script and `bin/<app>.bat`.
// Prefer the batch file when present so CreateProcess does not attempt to
// execute the extensionless shell script (Windows error 193).
if (file_exists(script + ".bat"))
script += ".bat";
else if (file_exists(script + ".cmd"))
script += ".cmd";
else if (!file_exists(script)) {
fprintf(stderr, "edw: beam script not found: %s\n", script.c_str());
return;
}
std::string wd =
config_.beam_working_dir
Expand Down Expand Up @@ -367,8 +372,12 @@ void HostController::spawn_beam() {
}
env_block.push_back(L'\0');

// OTP 26's user/logger need a real console (NUL triggers `nouser`; missing
// handles crash logger). Give BEAM a hidden private console.
STARTUPINFOW si{};
si.cb = sizeof(si);
si.dwFlags = STARTF_USESHOWWINDOW;
si.wShowWindow = SW_HIDE;
PROCESS_INFORMATION pi{};
std::wstring wcmd = utf8_to_wide(cmdline);
std::wstring wwd = utf8_to_wide(wd);
Expand All @@ -381,8 +390,9 @@ void HostController::spawn_beam() {
beam_process_ = nullptr;
}

if (!CreateProcessW(nullptr, mutable_cmd.data(), nullptr, nullptr, FALSE, CREATE_UNICODE_ENVIRONMENT,
env_block.data(), wwd.c_str(), &si, &pi)) {
DWORD flags = CREATE_UNICODE_ENVIRONMENT | CREATE_NEW_CONSOLE;
if (!CreateProcessW(nullptr, mutable_cmd.data(), nullptr, nullptr, FALSE, flags, env_block.data(),
wwd.c_str(), &si, &pi)) {
fprintf(stderr, "edw: failed to spawn beam (%lu): %s\n", GetLastError(), cmdline.c_str());
return;
}
Expand Down
2 changes: 1 addition & 1 deletion native/windows/src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ std::vector<std::string> argv_utf8() {

} // namespace

int main(int, char**) {
int WINAPI wWinMain(HINSTANCE, HINSTANCE, PWSTR, int) {
HRESULT hr = CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED);
if (FAILED(hr)) {
fprintf(stderr, "edw: CoInitializeEx failed\n");
Expand Down
Loading