mirror of
https://github.com/wavetermdev/wails.git
synced 2026-08-05 13:53:43 -07:00
Implement file association Open a file from Finder/Explorer (#2918)
* 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 * remove unused option in file association * get rid of openFiles mac os. change configuration structure * remove unused channel * fix documentation * fix typo --------- Co-authored-by: Lea Anthony <lea.anthony@gmail.com>
This commit is contained in:
co-authored by
Lea Anthony
parent
42708e7f40
commit
6c46f6b41c
@@ -0,0 +1,184 @@
|
||||
# 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)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 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)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Limitations:
|
||||
On Windows and Linux when associated file is opened, new instance of your app is launched.
|
||||
Currently, Wails doesn't support opening files in already running app. There is plugin for single instance support for v3 in development.
|
||||
@@ -18,6 +18,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
- Added support for enabling/disabling swipe gestures for Windows WebView2. Added by @leaanthony in [PR](https://github.com/wailsapp/wails/pull/2878)
|
||||
- When building with `-devtools` flag, CMD/CTRL+SHIFT+F12 can be used to open the devtools. Added by @leaanthony in [PR](https://github.com/wailsapp/wails/pull/2915)
|
||||
– Added file association support for macOS and Windows. Added by @APshenkin in [PR](https://github.com/wailsapp/wails/pull/2918)
|
||||
- Added support for setting some of the Webview preferences, `textInteractionEnabled` and `tabFocusesLinks` on Mac. Added by @fkhadra in [PR](https://github.com/wailsapp/wails/pull/2937)
|
||||
- Added support for enabling/disabling fullscreen of the Webview on Mac. Added by @fkhadra in [PR](https://github.com/wailsapp/wails/pull/2953)
|
||||
- Added French README.fr.md page. Added by @nejos97 in [PR](https://github.com/wailsapp/wails/pull/2943)
|
||||
|
||||
@@ -72,10 +72,17 @@
|
||||
"frontend:dev:serverUrl": {
|
||||
"type": "string",
|
||||
"description": "URL to a 3rd party dev server to be used to serve assets (eg. Vite). If this is set to 'auto', then the devServerUrl will be inferred from the Vite output",
|
||||
"examples": [ "auto", "http://localhost:3000" ],
|
||||
"examples": [
|
||||
"auto",
|
||||
"http://localhost:3000"
|
||||
],
|
||||
"oneOf": [
|
||||
{ "format": "uri" },
|
||||
{ "const": "auto" }
|
||||
{
|
||||
"format": "uri"
|
||||
},
|
||||
{
|
||||
"const": "auto"
|
||||
}
|
||||
]
|
||||
},
|
||||
"wailsjsdir": {
|
||||
@@ -87,7 +94,9 @@
|
||||
"version": {
|
||||
"description": "Project config version",
|
||||
"default": "2",
|
||||
"enum": [ "2" ]
|
||||
"enum": [
|
||||
"2"
|
||||
]
|
||||
},
|
||||
"outputfilename": {
|
||||
"type": "string",
|
||||
@@ -123,7 +132,9 @@
|
||||
"type": "object",
|
||||
"description": "The application author",
|
||||
"properties": {
|
||||
"name": { "type": "string" },
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"email": {
|
||||
"type": "string",
|
||||
"format": "email"
|
||||
@@ -156,6 +167,39 @@
|
||||
"type": "string",
|
||||
"description": "A short comment for the app",
|
||||
"default": "Built using Wails (https://wails.io)"
|
||||
},
|
||||
"fileAssociations": {
|
||||
"type": "array",
|
||||
"description": "File associations for the app",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"ext": {
|
||||
"type": "string",
|
||||
"description": "The extension (minus the leading period). e.g. png"
|
||||
},
|
||||
"name": {
|
||||
"type": "string",
|
||||
"description": "The name. e.g. PNG File"
|
||||
},
|
||||
"description": {
|
||||
"type": "string",
|
||||
"description": "Windows-only. The description. It is displayed on the `Type` column on Windows Explorer."
|
||||
},
|
||||
"iconName": {
|
||||
"type": "string",
|
||||
"description": "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)"
|
||||
},
|
||||
"role": {
|
||||
"description": "macOS-only. The app’s role with respect to the type. Corresponds to CFBundleTypeRole.",
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/BundleTypeRole"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -185,7 +229,9 @@
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"garbleargs": ["obfuscated"]
|
||||
"garbleargs": [
|
||||
"obfuscated"
|
||||
]
|
||||
},
|
||||
"definitions": {
|
||||
"OsHook": {
|
||||
@@ -203,11 +249,21 @@
|
||||
"description": "Build hooks for different targets.",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"{GOOS}/{GOARCH}": { "$ref": "#/definitions/OsArchHook" },
|
||||
"{GOOS}/*": { "$ref": "#/definitions/OsHook" },
|
||||
"windows/*": { "$ref": "#/definitions/OsHook" },
|
||||
"linux/*": { "$ref": "#/definitions/OsHook" },
|
||||
"darwin/*": { "$ref": "#/definitions/OsHook" },
|
||||
"{GOOS}/{GOARCH}": {
|
||||
"$ref": "#/definitions/OsArchHook"
|
||||
},
|
||||
"{GOOS}/*": {
|
||||
"$ref": "#/definitions/OsHook"
|
||||
},
|
||||
"windows/*": {
|
||||
"$ref": "#/definitions/OsHook"
|
||||
},
|
||||
"linux/*": {
|
||||
"$ref": "#/definitions/OsHook"
|
||||
},
|
||||
"darwin/*": {
|
||||
"$ref": "#/definitions/OsHook"
|
||||
},
|
||||
"*/*": {
|
||||
"type": "string",
|
||||
"description": "Executed at build level before/after a build"
|
||||
@@ -225,26 +281,66 @@
|
||||
"description": "Executed at build level before/after a build of the specific platform"
|
||||
}
|
||||
}
|
||||
},
|
||||
"BundleTypeRole": {
|
||||
"description": "macOS-only. Corresponds to CFBundleTypeRole",
|
||||
"oneOf": [
|
||||
{
|
||||
"description": "CFBundleTypeRole.Editor. Files can be read and edited.",
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"Editor"
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "CFBundleTypeRole.Viewer. Files can be read.",
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"Viewer"
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "CFBundleTypeRole.Shell",
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"Shell"
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "CFBundleTypeRole.QLGenerator",
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"QLGenerator"
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "CFBundleTypeRole.None",
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"None"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"bindings": {
|
||||
"type": "object",
|
||||
"description": "Bindings configurations",
|
||||
"properties": {
|
||||
"ts_generation": {
|
||||
"type": "object",
|
||||
"description": "model.ts file generation config",
|
||||
"properties": {
|
||||
"prefix": {
|
||||
"type": "string",
|
||||
"description": "All generated JavaScript entities will be prefixed with this value"
|
||||
},
|
||||
"suffix": {
|
||||
"type": "string",
|
||||
"description": "All generated JavaScript entities will be suffixed with this value"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
"bindings": {
|
||||
"type": "object",
|
||||
"description": "Bindings configurations",
|
||||
"properties": {
|
||||
"ts_generation": {
|
||||
"type": "object",
|
||||
"description": "model.ts file generation config",
|
||||
"properties": {
|
||||
"prefix": {
|
||||
"type": "string",
|
||||
"description": "All generated JavaScript entities will be prefixed with this value"
|
||||
},
|
||||
"suffix": {
|
||||
"type": "string",
|
||||
"description": "All generated JavaScript entities will be suffixed with this value"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user