Open daimall opened 2 weeks ago
3.0 依然有此问题
下面代码改成直接调用 windows api 就没有问题 package main
import ( "context" "fmt" "syscall" "unsafe" )
// App struct type App struct { ctx context.Context }
var ( modComdlg32 = syscall.NewLazyDLL("comdlg32.dll") procGetSaveFileName = modComdlg32.NewProc("GetSaveFileNameW")
modKernel32 = syscall.NewLazyDLL("kernel32.dll")
procGetLastError = modKernel32.NewProc("GetLastError")
)
const ( OFN_FILEMUSTEXIST = 0x00001000 OFN_PATHMUSTEXIST = 0x00000800 OFN_OVERWRITEPROMPT = 0x00000002 )
type OPENFILENAME struct { lStructSize uint32 hwndOwner uintptr hInstance uintptr lpstrFilter uint16 lpstrCustomFilter uint16 nMaxCustFilter uint32 nFilterIndex uint32 lpstrFile uint16 nMaxFile uint32 lpstrFileTitle uint16 nMaxFileTitle uint32 lpstrInitialDir uint16 lpstrTitle uint16 Flags uint32 nFileOffset uint16 nFileExtension uint16 lpstrDefExt uint16 lCustData uintptr lpfnHook uintptr lpTemplateName uint16 pvReserved uintptr dwReserved uint32 FlagsEx uint32 }
// NewApp creates a new App application struct func NewApp() *App { return &App{} }
// startup is called when the app starts. The context is saved // so we can call the runtime methods func (a *App) startup(ctx context.Context) { a.ctx = ctx }
// Greet returns a greeting for the given name func (a *App) Greet(name string) string { var ofn OPENFILENAME file := make([]uint16, 260) ofn.lStructSize = uint32(unsafe.Sizeof(ofn)) ofn.lpstrFile = &file[0] ofn.nMaxFile = uint32(len(file)) ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST | OFN_OVERWRITEPROMPT
ret, _, err := procGetSaveFileName.Call(uintptr(unsafe.Pointer(&ofn)))
if ret == 0 {
fmt.Printf("Error: %v\n", err)
errorCode, _, _ := procGetLastError.Call()
fmt.Printf("CommDlgExtendedError: %d\n", errorCode)
} else {
fmt.Printf("Selected file: %s\n", syscall.UTF16ToString(file))
}
return syscall.UTF16ToString(file)
}
Description
基于最简单的样例,只要打开对话框,无论选择确认还是取消都会crash package main
import ( "context"
)
// App struct type App struct { ctx context.Context }
// NewApp creates a new App application struct func NewApp() *App { return &App{} }
// startup is called when the app starts. The context is saved // so we can call the runtime methods func (a *App) startup(ctx context.Context) { a.ctx = ctx }
// Greet returns a greeting for the given name func (a App) Greet(name string) string { filePath, err := runtime.SaveFileDialog(a.ctx, runtime.SaveDialogOptions{ Filters: []runtime.FileFilter{{Pattern: ".*"}}, DefaultFilename: "myproject", Title: "Save", }) if err != nil { return err.Error() }
} 上面就是最简单的代码,错误提示如下 To develop in the browser and call your bound Go methods from Javascript, navigate to: http://localhost:34115 2024/06/12 09:44:06 The parameter is incorrect. [0612/094406.974:ERROR:window_impl.cc(121)] Failed to unregister class Chrome_WidgetWin_0. Error = 0
该问题不必现,出现后重启电脑大概率能消失,过一段时间又出现了
To Reproduce
1、运行上面最简单的demo 2、Click Greet
3、click 取消
4、crash
2024/06/12 09:53:12 The parameter is incorrect.
[0612/095312.565:ERROR:window_impl.cc(121)] Failed to unregister class Chrome_WidgetWin_0. Error = 0
Expected behaviour
正常运行
Screenshots
Attempted Fixes
重启电脑,大概率能恢复
System Details
Additional context
跟踪代码发现是 v2\internal\go-common-file-dialog\cfd\vtblCommonFunc.go 中的 iModalWindowVtbl.show 方法crash的 func (vtbl *iModalWindowVtbl) show(objPtr unsafe.Pointer, hwnd uintptr) error { fmt.Println("iModalWindowVtbl>>>>>>>>>>>>>111111", vtbl.Show, objPtr, hwnd) fmt.Printf("Function address: %x\n", vtbl.Show) fmt.Println("iModalWindowVtbl>>>>>>>>>>>>>111111") ret, , := syscall.Syscall(vtbl.Show, 1, uintptr(objPtr), hwnd, 0) fmt.Println("iModalWindowVtbl>>>>>>>>>>>>>22222") return hresultToError(ret) }
输出的结果如下:
iModalWindowVtbl>>>>>>>>>>>>>111111 140703621641488 0x2016af66958 3346448 Function address: 7ff81d62f510 iModalWindowVtbl>>>>>>>>>>>>>111111 2024/06/12 11:45:27 The parameter is incorrect. [0612/114527.816:ERROR:window_impl.cc(121)] Failed to unregister class Chrome_WidgetWin_0. Error = 0