package main import ( "fmt" "syscall" "unicode/utf16" "unsafe" ) var ( comdlg32 = syscall.NewLazyDLL("Comdlg32.dll") procGetOpenFileName = comdlg32.NewProc("GetOpenFileNameW") ) var ( Err_No_File_Chosen = fmt.Errorf("no file was chosen") ) func OpenFileDialog(title string) (filepath string, err error) { type OPENFILENAMEW struct { LStructSize uint32 HwndOwner syscall.Handle HInstance syscall.Handle Filter *uint16 CustomFilter *uint16 MaxCustFilter uint32 FilterIndex uint32 File *uint16 MaxFile uint32 FileTitle *uint16 MaxFileTitle uint32 InitialDir *uint16 Title *uint16 Flags uint32 FileOffset uint16 FileExtension uint16 DefExt *uint16 CustData uintptr FnHook syscall.Handle TemplateName *uint16 PvReserved uintptr DwReserved uint32 FlagsEx uint32 } titleByteArr := utf16.Encode([]rune(title + "\x00")) filterByteArr := utf16.Encode([]rune("All Files (*.*)\x00*.*\x00Text Files (*.txt)\x00*.txt\x00\x00")) filenameByteArr := make([]uint16, syscall.MAX_LONG_PATH) ofn := &OPENFILENAMEW{ HwndOwner: 0, HInstance: 0, LStructSize: uint32(unsafe.Sizeof(OPENFILENAMEW{})), Title: &titleByteArr[0], Filter: &filterByteArr[0], File: &filenameByteArr[0], MaxFile: syscall.MAX_LONG_PATH, // OFN_FILEMUSTEXIST Flags: 0x00001000, } ret, _, _ := procGetOpenFileName.Call(uintptr(unsafe.Pointer(ofn))) if ret == 0 { return "", Err_No_File_Chosen } filepath = syscall.UTF16ToString(filenameByteArr) return filepath, nil }