mirror of
https://github.com/wailsapp/wails.git
synced 2025-05-02 20:03:01 +08:00
WIP
This commit is contained in:
parent
276a1a22a5
commit
7ebb000253
189
docs/src/content/docs/guides/custom-protocol-schemes.mdx
Normal file
189
docs/src/content/docs/guides/custom-protocol-schemes.mdx
Normal file
@ -0,0 +1,189 @@
|
|||||||
|
# Custom Protocol Scheme association
|
||||||
|
|
||||||
|
Custom Protocols feature allows you to associate specific custom protocol with your app so that when users open links with this protocol,
|
||||||
|
your app is launched to handle them. This can be particularly useful to connect your desktop app with your web app.
|
||||||
|
In this guide, we'll walk through the steps to implement custom protocols in Wails app.
|
||||||
|
|
||||||
|
|
||||||
|
## Set Up Custom Protocol Schemes Association:
|
||||||
|
To set up custom protocol, you need to modify your application's wails.json file.
|
||||||
|
In "info" section add a "protocols" section specifying the protocols your app should be associated with.
|
||||||
|
|
||||||
|
For example:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"info": {
|
||||||
|
"protocols": [
|
||||||
|
{
|
||||||
|
"scheme": "myapp",
|
||||||
|
"description": "My App Protocol",
|
||||||
|
"role": "Editor"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
| Property | Description |
|
||||||
|
|:------------|:--------------------------------------------------------------------------------------|
|
||||||
|
| scheme | Custom Protocol scheme. e.g. myapp |
|
||||||
|
| description | Windows-only. The description. |
|
||||||
|
| role | macOS-only. The app’s role with respect to the type. Corresponds to CFBundleTypeRole. |
|
||||||
|
|
||||||
|
## Platform Specifics:
|
||||||
|
|
||||||
|
### macOS
|
||||||
|
When you open custom protocol with your app, the system will launch your app and call the `OnUrlOpen` 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{
|
||||||
|
OnUrlOpen: func(url string) { println(url) },
|
||||||
|
},
|
||||||
|
Bind: []interface{}{
|
||||||
|
app,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
println("Error:", err.Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### Windows
|
||||||
|
On Windows Custom Protocol Schemes is supported only with NSIS installer. During installation, the installer will create a
|
||||||
|
registry entry for your schemes. When you open url with your app, new instance of app is launched and url 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 url 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 (note that `%u` is important in Exec). 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=x-scheme-handler/myapp;
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Prepare postInstall/postRemove scripts for your package. Example:
|
||||||
|
```sh
|
||||||
|
# reload desktop database to load app in list of available
|
||||||
|
update-desktop-database /usr/share/applications
|
||||||
|
```
|
||||||
|
3. 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: ../appicon.svg
|
||||||
|
dst: /usr/share/icons/hicolor/scalable/apps/wails-open-file.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
|
||||||
|
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 custom protocol scheme. When you open url 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 url 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,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
```
|
@ -126,6 +126,7 @@ type FileAssociation struct {
|
|||||||
type UpdateConfig struct {
|
type UpdateConfig struct {
|
||||||
UpdateBuildAssetsOptions
|
UpdateBuildAssetsOptions
|
||||||
FileAssociations []FileAssociation `yaml:"fileAssociations"`
|
FileAssociations []FileAssociation `yaml:"fileAssociations"`
|
||||||
|
Protocols []Protocol `yaml:"protocols"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type WailsConfig struct {
|
type WailsConfig struct {
|
||||||
@ -139,6 +140,13 @@ type WailsConfig struct {
|
|||||||
Version string `yaml:"version"`
|
Version string `yaml:"version"`
|
||||||
} `yaml:"info"`
|
} `yaml:"info"`
|
||||||
FileAssociations []FileAssociation `yaml:"fileAssociations"`
|
FileAssociations []FileAssociation `yaml:"fileAssociations"`
|
||||||
|
Protocols []Protocol `yaml:"protocols"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Protocol struct {
|
||||||
|
Scheme string `json:"scheme"`
|
||||||
|
Role string `json:"role"`
|
||||||
|
Description string `json:"description"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func UpdateBuildAssets(options *UpdateBuildAssetsOptions) error {
|
func UpdateBuildAssets(options *UpdateBuildAssetsOptions) error {
|
||||||
@ -169,6 +177,7 @@ func UpdateBuildAssets(options *UpdateBuildAssetsOptions) error {
|
|||||||
options.ProductCopyright = wailsConfig.Info.Copyright
|
options.ProductCopyright = wailsConfig.Info.Copyright
|
||||||
options.ProductComments = wailsConfig.Info.Comments
|
options.ProductComments = wailsConfig.Info.Comments
|
||||||
options.ProductVersion = wailsConfig.Info.Version
|
options.ProductVersion = wailsConfig.Info.Version
|
||||||
|
config.Protocols = wailsConfig.Protocols
|
||||||
config.FileAssociations = wailsConfig.FileAssociations
|
config.FileAssociations = wailsConfig.FileAssociations
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,7 +44,7 @@ dev_mode:
|
|||||||
type: primary
|
type: primary
|
||||||
|
|
||||||
# File Associations
|
# File Associations
|
||||||
# More information at: https://v3alpha.wails.io/noit/done/yet
|
# More information at: https://v3.wails.io/not/done/yet
|
||||||
fileAssociations:
|
fileAssociations:
|
||||||
# - ext: wails
|
# - ext: wails
|
||||||
# name: Wails
|
# name: Wails
|
||||||
@ -57,6 +57,14 @@ fileAssociations:
|
|||||||
# iconName: jpegFileIcon
|
# iconName: jpegFileIcon
|
||||||
# role: Editor
|
# role: Editor
|
||||||
|
|
||||||
|
# Custom URL Protocols
|
||||||
|
# A list of custom URL protocols associated with this application
|
||||||
|
# More information at: https://v3.wails.io/not/done/yet
|
||||||
|
protocols:
|
||||||
|
# - scheme: "magnet"
|
||||||
|
# description: "Magnet URI Scheme"
|
||||||
|
# role: "Editor"
|
||||||
|
|
||||||
# Other data
|
# Other data
|
||||||
other:
|
other:
|
||||||
- name: My Other Data
|
- name: My Other Data
|
@ -92,6 +92,7 @@ Section
|
|||||||
CreateShortCut "$DESKTOP\${INFO_PRODUCTNAME}.lnk" "$INSTDIR\${PRODUCT_EXECUTABLE}"
|
CreateShortCut "$DESKTOP\${INFO_PRODUCTNAME}.lnk" "$INSTDIR\${PRODUCT_EXECUTABLE}"
|
||||||
|
|
||||||
!insertmacro wails.associateFiles
|
!insertmacro wails.associateFiles
|
||||||
|
!insertmacro wails.associateCustomProtocols
|
||||||
|
|
||||||
!insertmacro wails.writeUninstaller
|
!insertmacro wails.writeUninstaller
|
||||||
SectionEnd
|
SectionEnd
|
||||||
@ -107,6 +108,7 @@ Section "uninstall"
|
|||||||
Delete "$DESKTOP\${INFO_PRODUCTNAME}.lnk"
|
Delete "$DESKTOP\${INFO_PRODUCTNAME}.lnk"
|
||||||
|
|
||||||
!insertmacro wails.unassociateFiles
|
!insertmacro wails.unassociateFiles
|
||||||
|
!insertmacro wails.unassociateCustomProtocols
|
||||||
|
|
||||||
!insertmacro wails.deleteUninstaller
|
!insertmacro wails.deleteUninstaller
|
||||||
SectionEnd
|
SectionEnd
|
||||||
|
@ -28,5 +28,22 @@
|
|||||||
<key>NSAllowsLocalNetworking</key>
|
<key>NSAllowsLocalNetworking</key>
|
||||||
<true/>
|
<true/>
|
||||||
</dict>
|
</dict>
|
||||||
|
{{if .Protocols}}
|
||||||
|
<key>CFBundleURLTypes</key>
|
||||||
|
<array>
|
||||||
|
{{range .Protocols}}
|
||||||
|
<dict>
|
||||||
|
<key>CFBundleURLName</key>
|
||||||
|
<string>com.wails.{{.Scheme}}</string>
|
||||||
|
<key>CFBundleURLSchemes</key>
|
||||||
|
<array>
|
||||||
|
<string>{{.Scheme}}</string>
|
||||||
|
</array>
|
||||||
|
<key>CFBundleTypeRole</key>
|
||||||
|
<string>{{.Role}}</string>
|
||||||
|
</dict>
|
||||||
|
{{end}}
|
||||||
|
</array>
|
||||||
|
{{end}}
|
||||||
</dict>
|
</dict>
|
||||||
</plist>
|
</plist>
|
@ -23,5 +23,22 @@
|
|||||||
<string>true</string>
|
<string>true</string>
|
||||||
<key>NSHumanReadableCopyright</key>
|
<key>NSHumanReadableCopyright</key>
|
||||||
<string>{{.ProductCopyright}}</string>
|
<string>{{.ProductCopyright}}</string>
|
||||||
|
{{if .Protocols}}
|
||||||
|
<key>CFBundleURLTypes</key>
|
||||||
|
<array>
|
||||||
|
{{range .Protocols}}
|
||||||
|
<dict>
|
||||||
|
<key>CFBundleURLName</key>
|
||||||
|
<string>com.wails.{{.Scheme}}</string>
|
||||||
|
<key>CFBundleURLSchemes</key>
|
||||||
|
<array>
|
||||||
|
<string>{{.Scheme}}</string>
|
||||||
|
</array>
|
||||||
|
<key>CFBundleTypeRole</key>
|
||||||
|
<string>{{.Role}}</string>
|
||||||
|
</dict>
|
||||||
|
{{end}}
|
||||||
|
</array>
|
||||||
|
{{end}}
|
||||||
</dict>
|
</dict>
|
||||||
</plist>
|
</plist>
|
@ -215,4 +215,33 @@ RequestExecutionLevel "${REQUEST_EXECUTION_LEVEL}"
|
|||||||
!insertmacro APP_UNASSOCIATE "{{.Ext}}" "{{.Name}}"
|
!insertmacro APP_UNASSOCIATE "{{.Ext}}" "{{.Name}}"
|
||||||
Delete "$INSTDIR\{{.IconName}}.ico"
|
Delete "$INSTDIR\{{.IconName}}.ico"
|
||||||
{{end}}
|
{{end}}
|
||||||
|
!macroend
|
||||||
|
|
||||||
|
!macro CUSTOM_PROTOCOL_ASSOCIATE PROTOCOL DESCRIPTION ICON COMMAND
|
||||||
|
DeleteRegKey SHELL_CONTEXT "Software\Classes\${PROTOCOL}"
|
||||||
|
WriteRegStr SHELL_CONTEXT "Software\Classes\${PROTOCOL}" "" "${DESCRIPTION}"
|
||||||
|
WriteRegStr SHELL_CONTEXT "Software\Classes\${PROTOCOL}" "URL Protocol" ""
|
||||||
|
WriteRegStr SHELL_CONTEXT "Software\Classes\${PROTOCOL}\DefaultIcon" "" "${ICON}"
|
||||||
|
WriteRegStr SHELL_CONTEXT "Software\Classes\${PROTOCOL}\shell" "" ""
|
||||||
|
WriteRegStr SHELL_CONTEXT "Software\Classes\${PROTOCOL}\shell\open" "" ""
|
||||||
|
WriteRegStr SHELL_CONTEXT "Software\Classes\${PROTOCOL}\shell\open\command" "" "${COMMAND}"
|
||||||
|
!macroend
|
||||||
|
|
||||||
|
!macro CUSTOM_PROTOCOL_UNASSOCIATE PROTOCOL
|
||||||
|
DeleteRegKey SHELL_CONTEXT "Software\Classes\${PROTOCOL}"
|
||||||
|
!macroend
|
||||||
|
|
||||||
|
!macro wails.associateCustomProtocols
|
||||||
|
; Create custom protocols associations
|
||||||
|
{{range .Protocols}}
|
||||||
|
!insertmacro CUSTOM_PROTOCOL_ASSOCIATE "{{.Scheme}}" "{{.Description}}" "$INSTDIR\${PRODUCT_EXECUTABLE},0" "$INSTDIR\${PRODUCT_EXECUTABLE} $\"%1$\""
|
||||||
|
|
||||||
|
{{end}}
|
||||||
|
!macroend
|
||||||
|
|
||||||
|
!macro wails.unassociateCustomProtocols
|
||||||
|
; Delete app custom protocol associations
|
||||||
|
{{range .Protocols}}
|
||||||
|
!insertmacro CUSTOM_PROTOCOL_UNASSOCIATE "{{.Scheme}}"
|
||||||
|
{{end}}
|
||||||
!macroend
|
!macroend
|
@ -195,6 +195,8 @@ type MacOptions struct {
|
|||||||
ActivationPolicy ActivationPolicy
|
ActivationPolicy ActivationPolicy
|
||||||
// If set to true, the application will terminate when the last window is closed.
|
// If set to true, the application will terminate when the last window is closed.
|
||||||
ApplicationShouldTerminateAfterLastWindowClosed bool
|
ApplicationShouldTerminateAfterLastWindowClosed bool
|
||||||
|
// OnURLOpen is a function that is called when the user opens an associated url such as `magnet://l234i2li34h`.
|
||||||
|
OnUrlOpen func(filePath string)
|
||||||
}
|
}
|
||||||
|
|
||||||
/****** Windows Options *******/
|
/****** Windows Options *******/
|
||||||
|
Loading…
Reference in New Issue
Block a user