Skip to content

Crash when setting Wails app as Windows Shell replacement #4303

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
seniloper opened this issue May 23, 2025 · 3 comments
Open

Crash when setting Wails app as Windows Shell replacement #4303

seniloper opened this issue May 23, 2025 · 3 comments
Labels
awaiting feedback More information is required from the requestor Bug Something isn't working

Comments

@seniloper
Copy link

Description

I'm building a Wails app and using it as a Windows Shell replacement (i.e., replacing explorer.exe as the default shell). After building and installing the app on the target machine, I set it to run as the shell and reboot the system.

After reboot, with Explorer completely disabled, the app starts after a short delay (around 5 to 30 seconds), but it eventually crashes for various reasons.

One consistent crash happens when I try to use runtime.OpenFileDialog from a Go function exposed via bind. It seems to be related to the fact that there's no Explorer shell available.

Please let me know if there are any known limitations when using Wails in this kind of setup, or if any workarounds are possible.

To Reproduce

Build a Wails application with OpenFileDialog called via a Go bind method.

func (app *App) OpenFileDialogQuery() (result map[string]interface{}) {
	result = map[string]interface{}{
		"message": "",
		"state":   false,
		"data":    map[string]interface{}{},
	}

	dialogString, dialogError := runtime.OpenFileDialog(app.Ctx, runtime.OpenDialogOptions{
		Title: "Choose Your Game, App, or File :",
		Filters: []runtime.FileFilter{
			{
				DisplayName: "Apps or Games",
				Pattern:     "*.exe",
			},
			{
				DisplayName: "All files",
				Pattern:     "*",
			},
		},
	})

	if dialogError != nil {
		result["state"] = false
		result["message"] = "❌ " + result["message"].(string) + "Failed to Open file dialog in game query. \u000A"
		return
	}

	fileInfo, fileInfoError := os.Stat(dialogString)
	if fileInfoError != nil {
		result["state"] = false
		result["message"] = "❌ " + result["message"].(string) + "Failed to Get file info in game query. \u000A"
		return
	}

	fileNameType := filepath.Base(dialogString)
	fileType := filepath.Ext(fileNameType)
	fileName := strings.TrimSuffix(fileNameType, fileType)

	result["state"] = true
	result["data"] = map[string]interface{}{
		"path":         dialogString,
		"fileNameType": fileNameType,
		"fileType":     fileType,
		"fileName":     fileName,
		"fileSize":     fileInfo.Size()}

	return
}

Install the application on a clean Windows machine.

Set the application as the shell (replacing explorer.exe) by modifying the registry key:
HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\Shell

Restart the computer.

Wait for the Wails application to launch automatically as the shell.

Trigger the method that opens the OpenFileDialog.

Expected behavior: The dialog opens successfully.
Actual behavior: The application crashes immediately (sometimes silently, sometimes with a Windows error dialog).

Expected behaviour

The application should launch normally as a shell replacement and remain stable.
When OpenFileDialog is triggered (via Go bind method), it should display the file selection dialog without crashing, just as it does when explorer.exe is running.

Screenshots

No response

Attempted Fixes

I confirmed that the application works perfectly when explorer.exe is running (normal shell environment).

The crash only occurs when explorer.exe is not running and the app is set as the system shell.

I wrapped the OpenFileDialog call with recover to catch any panics, but the application still crashes before recovery is triggered.

I attempted to delay the dialog call, assuming the shell environment may not be fully initialized, but this did not help.

I tested this behavior on multiple clean Windows setups with the same results.

System Details

o version go1.24.3 windows/amd64

# Wails
Version | v2.10.1


# System
┌────────────────────────────────────────────────────────────────────────┐
| OS           | Windows 10 Pro                                          |
| Version      | 2009 (Build: 22631)                                     |
| ID           | 23H2                                                    |
| Go Version   | go1.24.3                                                |
| Platform     | windows                                                 |
| Architecture | amd64                                                   |
| CPU          | Intel(R) Core(TM) i5-9400F CPU @ 2.90GHz                |
| GPU          | NVIDIA GeForce GTX 1650 (NVIDIA) - Driver: 32.0.15.6094 |
| Memory       | 16GB                                                    |
└────────────────────────────────────────────────────────────────────────┘

# Dependencies
┌───────────────────────────────────────────────────────┐
| Dependency | Package Name | Status    | Version       |
| WebView2   | N/A          | Installed | 136.0.3240.76 |
| Nodejs     | N/A          | Installed | 22.14.0       |
| npm        | N/A          | Installed | 10.9.2        |
| *upx       | N/A          | Installed | upx 4.2.4     |
| *nsis      | N/A          | Installed | v3.10         |
|                                                       |
└─────────────── * - Optional Dependency ───────────────┘

# Diagnosis
 SUCCESS  Your system is ready for Wails development!

Additional context

2025/05/23 11:50:34 1: github.com/wailsapp/go-webview2/pkg/edge.(*Chromium).errorCallback
C:/Users/Seniloper/go/pkg/mod/github.com/wailsapp/[email protected]/pkg/edge/chromium.go:151
2025/05/23 11:50:34 2: github.com/wailsapp/go-webview2/pkg/edge.(*Chromium).Focus
C:/Users/Seniloper/go/pkg/mod/github.com/wailsapp/[email protected]/pkg/edge/chromium.go:580
2025/05/23 11:50:34 3: github.com/wailsapp/wails/v2/internal/frontend/desktop/windows.(*Frontend).onFocus
C:/Users/Seniloper/go/pkg/mod/github.com/wailsapp/wails/[email protected]/internal/frontend/desktop/windows/frontend.go:931
2025/05/23 11:50:34 4: github.com/wailsapp/wails/v2/internal/frontend/desktop/windows/winc.(*EventManager).Fire
C:/Users/Seniloper/go/pkg/mod/github.com/wailsapp/wails/[email protected]/internal/frontend/desktop/windows/winc/eventmanager.go:18
2025/05/23 11:50:34 5: github.com/wailsapp/wails/v2/internal/frontend/desktop/windows/winc.generalWndProc
C:/Users/Seniloper/go/pkg/mod/github.com/wailsapp/wails/[email protected]/internal/frontend/desktop/windows/winc/wndproc.go:92
2025/05/23 11:50:34 6: runtime.callbackWrap
C:/Program Files/Go/src/runtime/syscall_windows.go:396
2025/05/23 11:50:34 7: runtime.cgocallbackg1
C:/Program Files/Go/src/runtime/cgocall.go:446
2025/05/23 11:50:34 8: runtime.cgocallbackg
C:/Program Files/Go/src/runtime/cgocall.go:350
2025/05/23 11:50:34 9: runtime.cgocallback
C:/Program Files/Go/src/runtime/asm_amd64.s:1084
2025/05/23 11:50:34 10: runtime.systemstack_switch
C:/Program Files/Go/src/runtime/asm_amd64.s:479
2025/05/23 11:50:34 11: runtime.cgocall
C:/Program Files/Go/src/runtime/cgocall.go:185
2025/05/23 11:50:34 12: runtime.syscall_syscalln
C:/Program Files/Go/src/runtime/syscall_windows.go:521
2025/05/23 11:50:34 13: syscall.SyscallN
C:/Program Files/Go/src/runtime/syscall_windows.go:500
2025/05/23 11:50:34 14: github.com/wailsapp/wails/v2/internal/go-common-file-dialog/cfd.(*iModalWindowVtbl).show
C:/Users/Seniloper/go/pkg/mod/github.com/wailsapp/wails/[email protected]/internal/go-common-file-dialog/cfd/vtblCommonFunc.go:28
2025/05/23 11:50:34 15: github.com/wailsapp/wails/v2/internal/go-common-file-dialog/cfd.(*iFileOpenDialog).Show
C:/Users/Seniloper/go/pkg/mod/github.com/wailsapp/wails/[email protected]/internal/go-common-file-dialog/cfd/iFileOpenDialog.go:39
2025/05/23 11:50:34 16: github.com/wailsapp/wails/v2/internal/go-common-file-dialog/cfd.(*iFileOpenDialog).ShowAndGetResult
C:/Users/Seniloper/go/pkg/mod/github.com/wailsapp/wails/[email protected]/internal/go-common-file-dialog/cfd/iFileOpenDialog.go:55
2025/05/23 11:50:34 17: github.com/wailsapp/wails/v2/internal/frontend/desktop/windows.(*Frontend).showCfdDialog.func1
C:/Users/Seniloper/go/pkg/mod/github.com/wailsapp/wails/[email protected]/internal/frontend/desktop/windows/dialog.go:156
2025/05/23 11:50:34 18: github.com/wailsapp/wails/v2/internal/frontend/desktop/windows.invokeSync[...].func1
C:/Users/Seniloper/go/pkg/mod/github.com/wailsapp/wails/[email protected]/internal/frontend/desktop/windows/window.go:344
2025/05/23 11:50:34 19: github.com/wailsapp/wails/v2/internal/frontend/desktop/windows/winc.(*ControlBase).invokeCallbacks
C:/Users/Seniloper/go/pkg/mod/github.com/wailsapp/wails/[email protected]/internal/frontend/desktop/windows/winc/controlbase.go:550
2025/05/23 11:50:34 20: github.com/wailsapp/wails/v2/internal/frontend/desktop/windows/winc.generalWndProc
C:/Users/Seniloper/go/pkg/mod/github.com/wailsapp/wails/[email protected]/internal/frontend/desktop/windows/winc/wndproc.go:148
2025/05/23 11:50:34 21: runtime.callbackWrap
C:/Program Files/Go/src/runtime/syscall_windows.go:396
2025/05/23 11:50:34 22: runtime.cgocallbackg1
C:/Program Files/Go/src/runtime/cgocall.go:446
2025/05/23 11:50:34 23: runtime.cgocallbackg
C:/Program Files/Go/src/runtime/cgocall.go:350
2025/05/23 11:50:34 24: runtime.cgocallback
C:/Program Files/Go/src/runtime/asm_amd64.s:1084
2025/05/23 11:50:34 25: runtime.systemstack_switch
C:/Program Files/Go/src/runtime/asm_amd64.s:479
2025/05/23 11:50:34 26: runtime.cgocall
C:/Program Files/Go/src/runtime/cgocall.go:185
2025/05/23 11:50:34 27: runtime.syscall_syscalln
C:/Program Files/Go/src/runtime/syscall_windows.go:521
2025/05/23 11:50:34 28: syscall.SyscallN
C:/Program Files/Go/src/runtime/syscall_windows.go:500
2025/05/23 11:50:34 29: github.com/wailsapp/wails/v2/internal/go-common-file-dialog/cfd.(*iModalWindowVtbl).show
C:/Users/Seniloper/go/pkg/mod/github.com/wailsapp/wails/[email protected]/internal/go-common-file-dialog/cfd/vtblCommonFunc.go:28
2025/05/23 11:50:34 30: github.com/wailsapp/wails/v2/internal/go-common-file-dialog/cfd.(*iFileOpenDialog).Show
C:/Users/Seniloper/go/pkg/mod/github.com/wailsapp/wails/[email protected]/internal/go-common-file-dialog/cfd/iFileOpenDialog.go:39
2025/05/23 11:50:34 31: github.com/wailsapp/wails/v2/internal/go-common-file-dialog/cfd.(*iFileOpenDialog).ShowAndGetResult
C:/Users/Seniloper/go/pkg/mod/github.com/wailsapp/wails/[email protected]/internal/go-common-file-dialog/cfd/iFileOpenDialog.go:55
2025/05/23 11:50:34 32: github.com/wailsapp/wails/v2/internal/frontend/desktop/windows.(*Frontend).showCfdDialog.func1
C:/Users/Seniloper/go/pkg/mod/github.com/wailsapp/wails/[email protected]/internal/frontend/desktop/windows/dialog.go:156
2025/05/23 11:50:34 33: github.com/wailsapp/wails/v2/internal/frontend/desktop/windows.invokeSync[...].func1
C:/Users/Seniloper/go/pkg/mod/github.com/wailsapp/wails/[email protected]/internal/frontend/desktop/windows/window.go:344
2025/05/23 11:50:34 34: github.com/wailsapp/wails/v2/internal/frontend/desktop/windows/winc.(*ControlBase).invokeCallbacks
C:/Users/Seniloper/go/pkg/mod/github.com/wailsapp/wails/[email protected]/internal/frontend/desktop/windows/winc/controlbase.go:550
2025/05/23 11:50:34 35: github.com/wailsapp/wails/v2/internal/frontend/desktop/windows/winc.generalWndProc
C:/Users/Seniloper/go/pkg/mod/github.com/wailsapp/wails/[email protected]/internal/frontend/desktop/windows/winc/wndproc.go:148
2025/05/23 11:50:34 36: runtime.callbackWrap
C:/Program Files/Go/src/runtime/syscall_windows.go:396
2025/05/23 11:50:34 37: runtime.cgocallbackg1
C:/Program Files/Go/src/runtime/cgocall.go:446
2025/05/23 11:50:34 38: runtime.cgocallbackg
C:/Program Files/Go/src/runtime/cgocall.go:350
2025/05/23 11:50:34 39: runtime.cgocallback
C:/Program Files/Go/src/runtime/asm_amd64.s:1084
2025/05/23 11:50:34 40: runtime.systemstack_switch
C:/Program Files/Go/src/runtime/asm_amd64.s:479
2025/05/23 11:50:34 41: runtime.cgocall
C:/Program Files/Go/src/runtime/cgocall.go:185
2025/05/23 11:50:34 42: runtime.syscall_syscalln
C:/Program Files/Go/src/runtime/syscall_windows.go:521
2025/05/23 11:50:34 43: syscall.SyscallN
C:/Program Files/Go/src/runtime/syscall_windows.go:500
2025/05/23 11:50:34 44: syscall.(*Proc).Call
C:/Program Files/Go/src/syscall/dll_windows.go:167
2025/05/23 11:50:34 45: syscall.(*LazyProc).Call
C:/Program Files/Go/src/syscall/dll_windows.go:287
2025/05/23 11:50:34 46: github.com/wailsapp/wails/v2/internal/frontend/desktop/windows/winc/w32.DispatchMessage
C:/Users/Seniloper/go/pkg/mod/github.com/wailsapp/wails/[email protected]/internal/frontend/desktop/windows/winc/w32/user32.go:364
2025/05/23 11:50:34 47: github.com/wailsapp/wails/v2/internal/frontend/desktop/windows/winc.RunMainLoop
C:/Users/Seniloper/go/pkg/mod/github.com/wailsapp/wails/[email protected]/internal/frontend/desktop/windows/winc/app.go:84
2025/05/23 11:50:34 48: github.com/wailsapp/wails/v2/internal/frontend/desktop/windows.(*Frontend).RunMainLoop
C:/Users/Seniloper/go/pkg/mod/github.com/wailsapp/wails/[email protected]/internal/frontend/desktop/windows/frontend.go:223
2025/05/23 11:50:34 49: github.com/wailsapp/wails/v2/internal/app.(*App).Run
C:/Users/Seniloper/go/pkg/mod/github.com/wailsapp/wails/[email protected]/internal/app/app_production.go:19
2025/05/23 11:50:34 50: github.com/wailsapp/wails/v2/pkg/application.(*Application).Run
C:/Users/Seniloper/go/pkg/mod/github.com/wailsapp/wails/[email protected]/pkg/application/application.go:73
2025/05/23 11:50:34 51: github.com/wailsapp/wails/v2.Run
C:/Users/Seniloper/go/pkg/mod/github.com/wailsapp/wails/[email protected]/wails.go:14
2025/05/23 11:50:34 52: main.main
D:/GitHub/Desktop/netloper/main.go:32
2025/05/23 11:50:34 53: runtime.main
C:/Program Files/Go/src/runtime/proc.go:283

@seniloper seniloper added the Bug Something isn't working label May 23, 2025
Copy link
Contributor

👋 Thanks for reporting this issue! To help us investigate, could you please:

  1. Add the output of wails doctor if not already included
  2. Provide clear steps to reproduce the issue
  3. If possible, create a minimal reproduction of the issue

This will help us resolve your issue much faster. Thank you!

@github-actions github-actions bot added the awaiting feedback More information is required from the requestor label May 23, 2025
@wailsapp wailsapp deleted a comment from github-actions bot May 23, 2025
@leaanthony
Copy link
Member

We don't do anything funky with dialogs so I'm guessing there's something dialogs need from explorer.exe? I know there's other she'll replacements so it's not a great guess 😅 did you look at this line? C:/Users/Seniloper/go/pkg/mod/github.com/wailsapp/[email protected]/pkg/edge/chromium.go:151

@seniloper
Copy link
Author

Thanks for your response.
I've decided to go with an approach other than what Chromium provides.
The following two methods are currently my best options.
I'll test them and report back as soon as possible.

✅ sqweek/dialog
This package is a Go library that provides a simple, high-level way to open file dialogs, save dialogs, and folder pickers based on the Win32 API. It's very easy to use—just a few lines of code can launch a graphical dialog that filters for specific file extensions. These dialogs are fully native (using the official Windows UI) and work without relying on explorer.exe or any external dependencies. It's a great fit for common use cases like selecting .exe or .txt files.

✅ Direct Win32 API (via syscall or cgo)
Instead of using ready-made libraries, this method directly calls Windows functions like GetOpenFileNameW or GetSaveFileNameW from system DLLs. You can do this either through Go’s syscall package or by using cgo with C code. This approach offers maximum flexibility (e.g., multi-file selection, complex filters, custom configurations), but it’s harder to implement and requires a deeper understanding of the WinAPI and its structures. It's best suited for advanced or professional use cases.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
awaiting feedback More information is required from the requestor Bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants