mirror of
https://github.com/wailsapp/wails.git
synced 2025-05-02 18:42:23 +08:00

* implement MacOS openFile/openFiles events * wip: windows file association * fix macro import * add file icon copy * try copy icon * keep only required part of scripts * update config schema * fix json * set fileAssociation for mac via config * proper iconName handling * add fileAssociation icon generator * fix file association icons bundle * don't break compatibility * remove mimeType as not supported linux for now * add documentation * adjust config schema * restore formatting * try implement single instance lock with params passing * fix focusing * fix focusing * formatting * use channel buffer for second instance events * handle errors * add comment * remove unused option in file association * wip: linux single instance lock * wip: linux single instance * some experiments with making window active * try to use unminimise * remove unused * try present for window * try present for window * fix build * cleanup * cleanup * implement single instance lock on mac os * implement proper show for windows * proper unmimimise * get rid of openFiles mac os. change configuration structure * remove unused channel * remove unused function * add documentation for single instance lock * add PR link * changes after review * update docs * changes after review --------- Co-authored-by: Lea Anthony <lea.anthony@gmail.com>
229 lines
7.9 KiB
Plaintext
229 lines
7.9 KiB
Plaintext
# File Association
|
||
|
||
File association feature allows you to associate specific file types with your app so that when users open those files,
|
||
your app is launched to handle them. This can be particularly useful for text editors, image viewers, or any application
|
||
that works with specific file formats. In this guide, we'll walk through the steps to implement file association in Wails app.
|
||
|
||
|
||
## Set Up File Association:
|
||
To set up file association, you need to modify your application's wails.json file.
|
||
In "info" section add a "fileAssociations" section specifying the file types your app should be associated with.
|
||
|
||
For example:
|
||
```json
|
||
{
|
||
"info": {
|
||
"fileAssociations": [
|
||
{
|
||
"ext": "wails",
|
||
"name": "Wails",
|
||
"description": "Wails Application File",
|
||
"iconName": "wailsFileIcon",
|
||
"role": "Editor"
|
||
},
|
||
{
|
||
"ext": "jpg",
|
||
"name": "JPEG",
|
||
"description": "Image File",
|
||
"iconName": "jpegFileIcon",
|
||
"role": "Editor"
|
||
}
|
||
]
|
||
}
|
||
}
|
||
```
|
||
|
||
| Property | Description |
|
||
|:------------|:---------------------------------------------------------------------------------------------------------------------------------------------------|
|
||
| ext | The extension (minus the leading period). e.g. png |
|
||
| name | The name. e.g. PNG File |
|
||
| iconName | The icon name without extension. Icons should be located in build folder. Proper icons will be generated from .png file for both macOS and Windows |
|
||
| description | Windows-only. The description. It is displayed on the `Type` column on Windows Explorer. |
|
||
| role | macOS-only. The app’s role with respect to the type. Corresponds to CFBundleTypeRole. |
|
||
|
||
## Platform Specifics:
|
||
|
||
### macOS
|
||
When you open file (or files) with your app, the system will launch your app and call the `OnFileOpen` function in your Wails app. Example:
|
||
```go title="main.go"
|
||
func main() {
|
||
// Create application with options
|
||
err := wails.Run(&options.App{
|
||
Title: "wails-open-file",
|
||
Width: 1024,
|
||
Height: 768,
|
||
AssetServer: &assetserver.Options{
|
||
Assets: assets,
|
||
},
|
||
BackgroundColour: &options.RGBA{R: 27, G: 38, B: 54, A: 1},
|
||
Mac: &mac.Options{
|
||
OnFileOpen: func(filePaths []string) { println(filestring) },
|
||
},
|
||
Bind: []interface{}{
|
||
app,
|
||
},
|
||
})
|
||
|
||
if err != nil {
|
||
println("Error:", err.Error())
|
||
}
|
||
}
|
||
```
|
||
|
||
|
||
### Windows
|
||
On Windows file association is supported only with NSIS installer. During installation, the installer will create a
|
||
registry entry for your file associations. When you open file with your app, new instance of app is launched and file path is passed
|
||
as argument to your app. To handle this you should parse command line arguments in your app. Example:
|
||
```go title="main.go"
|
||
func main() {
|
||
argsWithoutProg := os.Args[1:]
|
||
|
||
if len(argsWithoutProg) != 0 {
|
||
println("launchArgs", argsWithoutProg)
|
||
}
|
||
}
|
||
```
|
||
|
||
You also can enable single instance lock for your app. In this case, when you open file with your app, new instance of app is not launched
|
||
and arguments are passed to already running instance. Check single instance lock guide for details. Example:
|
||
```go title="main.go"
|
||
func main() {
|
||
// Create application with options
|
||
err := wails.Run(&options.App{
|
||
Title: "wails-open-file",
|
||
Width: 1024,
|
||
Height: 768,
|
||
AssetServer: &assetserver.Options{
|
||
Assets: assets,
|
||
},
|
||
BackgroundColour: &options.RGBA{R: 27, G: 38, B: 54, A: 1},
|
||
SingleInstanceLock: &options.SingleInstanceLock{
|
||
UniqueId: "e3984e08-28dc-4e3d-b70a-45e961589cdc",
|
||
OnSecondInstanceLaunch: app.onSecondInstanceLaunch,
|
||
},
|
||
Bind: []interface{}{
|
||
app,
|
||
},
|
||
})
|
||
}
|
||
```
|
||
|
||
### Linux
|
||
Currently, Wails doesn't support bundling for Linux. So, you need to create file associations manually.
|
||
For example if you distribute your app as a .deb package, you can create file associations by adding required files in you bundle.
|
||
You can use [nfpm](https://nfpm.goreleaser.com/) to create .deb package for your app.
|
||
|
||
1. Create a .desktop file for your app and specify file associations there. Example:
|
||
```ini
|
||
[Desktop Entry]
|
||
Categories=Office
|
||
Exec=/usr/bin/wails-open-file %u
|
||
Icon=wails-open-file.png
|
||
Name=wails-open-file
|
||
Terminal=false
|
||
Type=Application
|
||
MimeType=application/x-wails;application/x-test
|
||
```
|
||
|
||
2. Create mime types file. Example:
|
||
```xml
|
||
<?xml version="1.0" encoding="UTF-8"?>
|
||
<mime-info xmlns="http://www.freedesktop.org/standards/shared-mime-info">
|
||
<mime-type type="application/x-wails">
|
||
<comment>Wails Application File</comment>
|
||
<glob pattern="*.wails"/>
|
||
</mime-type>
|
||
</mime-info>
|
||
```
|
||
|
||
3. Create icons for your file types. SVG icons are recommended.
|
||
4. Prepare postInstall/postRemove scripts for your package. Example:
|
||
```sh
|
||
# reload mime types to register file associations
|
||
update-mime-database /usr/share/mime
|
||
# reload desktop database to load app in list of available
|
||
update-desktop-database /usr/share/applications
|
||
# update icons
|
||
update-icon-caches /usr/share/icons/*
|
||
```
|
||
5. Configure nfpm to use your scripts and files. Example:
|
||
```yaml
|
||
name: "wails-open-file"
|
||
arch: "arm64"
|
||
platform: "linux"
|
||
version: "1.0.0"
|
||
section: "default"
|
||
priority: "extra"
|
||
maintainer: "FooBarCorp <FooBarCorp@gmail.com>"
|
||
description: "Sample Package"
|
||
vendor: "FooBarCorp"
|
||
homepage: "http://example.com"
|
||
license: "MIT"
|
||
contents:
|
||
- src: ../bin/wails-open-file
|
||
dst: /usr/bin/wails-open-file
|
||
- src: ./main.desktop
|
||
dst: /usr/share/applications/wails-open-file.desktop
|
||
- src: ./application-wails-mime.xml
|
||
dst: /usr/share/mime/packages/application-x-wails.xml
|
||
- src: ./application-test-mime.xml
|
||
dst: /usr/share/mime/packages/application-x-test.xml
|
||
- src: ../appicon.svg
|
||
dst: /usr/share/icons/hicolor/scalable/apps/wails-open-file.svg
|
||
- src: ../wailsFileIcon.svg
|
||
dst: /usr/share/icons/hicolor/scalable/mimetypes/application-x-wails.svg
|
||
- src: ../testFileIcon.svg
|
||
dst: /usr/share/icons/hicolor/scalable/mimetypes/application-x-test.svg
|
||
# copy icons to Yaru theme as well. For some reason Ubuntu didn't pick up fileicons from hicolor theme
|
||
- src: ../appicon.svg
|
||
dst: /usr/share/icons/Yaru/scalable/apps/wails-open-file.svg
|
||
- src: ../wailsFileIcon.svg
|
||
dst: /usr/share/icons/Yaru/scalable/mimetypes/application-x-wails.svg
|
||
- src: ../testFileIcon.svg
|
||
dst: /usr/share/icons/Yaru/scalable/mimetypes/application-x-test.svg
|
||
scripts:
|
||
postinstall: ./postInstall.sh
|
||
postremove: ./postRemove.sh
|
||
```
|
||
6. Build your .deb package using nfpm:
|
||
```sh
|
||
nfpm pkg --packager deb --target .
|
||
```
|
||
7. Now when your package is installed, your app will be associated with specified file types. When you open file with your app,
|
||
new instance of app is launched and file path is passed as argument to your app.
|
||
To handle this you should parse command line arguments in your app. Example:
|
||
```go title="main.go"
|
||
func main() {
|
||
argsWithoutProg := os.Args[1:]
|
||
|
||
if len(argsWithoutProg) != 0 {
|
||
println("launchArgs", argsWithoutProg)
|
||
}
|
||
}
|
||
```
|
||
|
||
You also can enable single instance lock for your app. In this case, when you open file with your app, new instance of app is not launched
|
||
and arguments are passed to already running instance. Check single instance lock guide for details. Example:
|
||
```go title="main.go"
|
||
func main() {
|
||
// Create application with options
|
||
err := wails.Run(&options.App{
|
||
Title: "wails-open-file",
|
||
Width: 1024,
|
||
Height: 768,
|
||
AssetServer: &assetserver.Options{
|
||
Assets: assets,
|
||
},
|
||
BackgroundColour: &options.RGBA{R: 27, G: 38, B: 54, A: 1},
|
||
SingleInstanceLock: &options.SingleInstanceLock{
|
||
UniqueId: "e3984e08-28dc-4e3d-b70a-45e961589cdc",
|
||
OnSecondInstanceLaunch: app.onSecondInstanceLaunch,
|
||
},
|
||
Bind: []interface{}{
|
||
app,
|
||
},
|
||
})
|
||
}
|
||
```
|