mirror of
https://github.com/wailsapp/wails.git
synced 2025-05-02 23:51:44 +08:00
Implement custom protocol association support (#3000)
* 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 * wip mac os deeplinks * put custom url listner on top to catch link on app opening * put custom url listner on top to catch link on app opening * try add custom url windows * adjust custom url * add docs * merge master * update documentation * add comment for darwin * add PR link * change naming * change naming * change naming * change naming * fix formatting * fix naming * Fix typo --------- Co-authored-by: Lea Anthony <lea.anthony@gmail.com>
This commit is contained in:
parent
e960798e85
commit
ae688aa07d
14
v2/internal/frontend/desktop/darwin/CustomProtocol.h
Normal file
14
v2/internal/frontend/desktop/darwin/CustomProtocol.h
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
#ifndef CustomProtocol_h
|
||||||
|
#define CustomProtocol_h
|
||||||
|
|
||||||
|
#import <Cocoa/Cocoa.h>
|
||||||
|
|
||||||
|
extern void HandleCustomProtocol(char*);
|
||||||
|
|
||||||
|
@interface CustomProtocolSchemeHandler : NSObject
|
||||||
|
+ (void)handleGetURLEvent:(NSAppleEventDescriptor *)event withReplyEvent:(NSAppleEventDescriptor *)replyEvent;
|
||||||
|
@end
|
||||||
|
|
||||||
|
void StartCustomProtocolHandler(void);
|
||||||
|
|
||||||
|
#endif /* CustomProtocol_h */
|
20
v2/internal/frontend/desktop/darwin/CustomProtocol.m
Normal file
20
v2/internal/frontend/desktop/darwin/CustomProtocol.m
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
#include "CustomProtocol.h"
|
||||||
|
|
||||||
|
@implementation CustomProtocolSchemeHandler
|
||||||
|
+ (void)handleGetURLEvent:(NSAppleEventDescriptor *)event withReplyEvent:(NSAppleEventDescriptor *)replyEvent {
|
||||||
|
[event paramDescriptorForKeyword:keyDirectObject];
|
||||||
|
|
||||||
|
NSString *urlStr = [[event paramDescriptorForKeyword:keyDirectObject] stringValue];
|
||||||
|
|
||||||
|
HandleCustomProtocol((char*)[[[event paramDescriptorForKeyword:keyDirectObject] stringValue] UTF8String]);
|
||||||
|
}
|
||||||
|
@end
|
||||||
|
|
||||||
|
void StartCustomProtocolHandler(void) {
|
||||||
|
NSAppleEventManager *appleEventManager = [NSAppleEventManager sharedAppleEventManager];
|
||||||
|
|
||||||
|
[appleEventManager setEventHandler:[CustomProtocolSchemeHandler class]
|
||||||
|
andSelector:@selector(handleGetURLEvent:withReplyEvent:)
|
||||||
|
forEventClass:kInternetEventClass
|
||||||
|
andEventID: kAEGetURL];
|
||||||
|
}
|
@ -8,6 +8,7 @@ package darwin
|
|||||||
#cgo LDFLAGS: -framework Foundation -framework Cocoa -framework WebKit
|
#cgo LDFLAGS: -framework Foundation -framework Cocoa -framework WebKit
|
||||||
#import <Foundation/Foundation.h>
|
#import <Foundation/Foundation.h>
|
||||||
#import "Application.h"
|
#import "Application.h"
|
||||||
|
#import "CustomProtocol.h"
|
||||||
#import "WailsContext.h"
|
#import "WailsContext.h"
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@ -39,6 +40,7 @@ var messageBuffer = make(chan string, 100)
|
|||||||
var requestBuffer = make(chan webview.Request, 100)
|
var requestBuffer = make(chan webview.Request, 100)
|
||||||
var callbackBuffer = make(chan uint, 10)
|
var callbackBuffer = make(chan uint, 10)
|
||||||
var openFilepathBuffer = make(chan string, 100)
|
var openFilepathBuffer = make(chan string, 100)
|
||||||
|
var openUrlBuffer = make(chan string, 100)
|
||||||
var secondInstanceBuffer = make(chan options.SecondInstanceData, 1)
|
var secondInstanceBuffer = make(chan options.SecondInstanceData, 1)
|
||||||
|
|
||||||
type Frontend struct {
|
type Frontend struct {
|
||||||
@ -79,6 +81,9 @@ func NewFrontend(ctx context.Context, appoptions *options.App, myLogger *logger.
|
|||||||
}
|
}
|
||||||
result.startURL, _ = url.Parse(startURL)
|
result.startURL, _ = url.Parse(startURL)
|
||||||
|
|
||||||
|
// this should be initialized as early as possible to handle first instance launch
|
||||||
|
C.StartCustomProtocolHandler()
|
||||||
|
|
||||||
if _starturl, _ := ctx.Value("starturl").(*url.URL); _starturl != nil {
|
if _starturl, _ := ctx.Value("starturl").(*url.URL); _starturl != nil {
|
||||||
result.startURL = _starturl
|
result.startURL = _starturl
|
||||||
} else {
|
} else {
|
||||||
@ -110,6 +115,7 @@ func NewFrontend(ctx context.Context, appoptions *options.App, myLogger *logger.
|
|||||||
go result.startMessageProcessor()
|
go result.startMessageProcessor()
|
||||||
go result.startCallbackProcessor()
|
go result.startCallbackProcessor()
|
||||||
go result.startFileOpenProcessor()
|
go result.startFileOpenProcessor()
|
||||||
|
go result.startUrlOpenProcessor()
|
||||||
go result.startSecondInstanceProcessor()
|
go result.startSecondInstanceProcessor()
|
||||||
|
|
||||||
return result
|
return result
|
||||||
@ -121,6 +127,12 @@ func (f *Frontend) startFileOpenProcessor() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (f *Frontend) startUrlOpenProcessor() {
|
||||||
|
for url := range openUrlBuffer {
|
||||||
|
f.ProcessOpenUrlEvent(url)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (f *Frontend) startSecondInstanceProcessor() {
|
func (f *Frontend) startSecondInstanceProcessor() {
|
||||||
for secondInstanceData := range secondInstanceBuffer {
|
for secondInstanceData := range secondInstanceBuffer {
|
||||||
if f.frontendOptions.SingleInstanceLock != nil &&
|
if f.frontendOptions.SingleInstanceLock != nil &&
|
||||||
@ -385,6 +397,12 @@ func (f *Frontend) ProcessOpenFileEvent(filePath string) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (f *Frontend) ProcessOpenUrlEvent(url string) {
|
||||||
|
if f.frontendOptions.Mac != nil && f.frontendOptions.Mac.OnUrlOpen != nil {
|
||||||
|
f.frontendOptions.Mac.OnUrlOpen(url)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (f *Frontend) Callback(message string) {
|
func (f *Frontend) Callback(message string) {
|
||||||
escaped, err := json.Marshal(message)
|
escaped, err := json.Marshal(message)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -434,3 +452,9 @@ func HandleOpenFile(filePath *C.char) {
|
|||||||
goFilepath := C.GoString(filePath)
|
goFilepath := C.GoString(filePath)
|
||||||
openFilepathBuffer <- goFilepath
|
openFilepathBuffer <- goFilepath
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//export HandleCustomProtocol
|
||||||
|
func HandleCustomProtocol(url *C.char) {
|
||||||
|
goUrl := C.GoString(url)
|
||||||
|
openUrlBuffer <- goUrl
|
||||||
|
}
|
||||||
|
@ -222,6 +222,7 @@ type Info struct {
|
|||||||
Copyright *string `json:"copyright"`
|
Copyright *string `json:"copyright"`
|
||||||
Comments *string `json:"comments"`
|
Comments *string `json:"comments"`
|
||||||
FileAssociations []FileAssociation `json:"fileAssociations"`
|
FileAssociations []FileAssociation `json:"fileAssociations"`
|
||||||
|
Protocols []Protocol `json:"protocols"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type FileAssociation struct {
|
type FileAssociation struct {
|
||||||
@ -232,6 +233,12 @@ type FileAssociation struct {
|
|||||||
Role string `json:"role"`
|
Role string `json:"role"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Protocol struct {
|
||||||
|
Scheme string `json:"scheme"`
|
||||||
|
Description string `json:"description"`
|
||||||
|
Role string `json:"role"`
|
||||||
|
}
|
||||||
|
|
||||||
type Bindings struct {
|
type Bindings struct {
|
||||||
TsGeneration TsGeneration `json:"ts_generation"`
|
TsGeneration TsGeneration `json:"ts_generation"`
|
||||||
}
|
}
|
||||||
|
@ -42,6 +42,23 @@
|
|||||||
{{end}}
|
{{end}}
|
||||||
</array>
|
</array>
|
||||||
{{end}}
|
{{end}}
|
||||||
|
{{if .Info.Protocols}}
|
||||||
|
<key>CFBundleURLTypes</key>
|
||||||
|
<array>
|
||||||
|
{{range .Info.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}}
|
||||||
<key>NSAppTransportSecurity</key>
|
<key>NSAppTransportSecurity</key>
|
||||||
<dict>
|
<dict>
|
||||||
<key>NSAllowsLocalNetworking</key>
|
<key>NSAllowsLocalNetworking</key>
|
||||||
|
@ -42,5 +42,22 @@
|
|||||||
{{end}}
|
{{end}}
|
||||||
</array>
|
</array>
|
||||||
{{end}}
|
{{end}}
|
||||||
|
{{if .Info.Protocols}}
|
||||||
|
<key>CFBundleURLTypes</key>
|
||||||
|
<array>
|
||||||
|
{{range .Info.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>
|
||||||
|
@ -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
|
||||||
|
@ -218,3 +218,32 @@ RequestExecutionLevel "${REQUEST_EXECUTION_LEVEL}"
|
|||||||
Delete "$INSTDIR\{{.IconName}}.ico"
|
Delete "$INSTDIR\{{.IconName}}.ico"
|
||||||
{{end}}
|
{{end}}
|
||||||
!macroend
|
!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 .Info.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 .Info.Protocols}}
|
||||||
|
!insertmacro CUSTOM_PROTOCOL_UNASSOCIATE "{{.Scheme}}"
|
||||||
|
{{end}}
|
||||||
|
!macroend
|
||||||
|
@ -24,5 +24,6 @@ type Options struct {
|
|||||||
//ActivationPolicy ActivationPolicy
|
//ActivationPolicy ActivationPolicy
|
||||||
About *AboutInfo
|
About *AboutInfo
|
||||||
OnFileOpen func(filePath string) `json:"-"`
|
OnFileOpen func(filePath string) `json:"-"`
|
||||||
|
OnUrlOpen func(filePath string) `json:"-"`
|
||||||
//URLHandlers map[string]func(string)
|
//URLHandlers map[string]func(string)
|
||||||
}
|
}
|
||||||
|
189
website/docs/guides/custom-protocol-schemes.mdx
Normal file
189
website/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,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
```
|
@ -28,6 +28,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
- Added new community template wails-htmx-templ-chi-tailwind. Added by [@pylotlight](https://github.com/pylotlight) in [PR](https://github.com/wailsapp/wails/pull/2984)
|
- Added new community template wails-htmx-templ-chi-tailwind. Added by [@pylotlight](https://github.com/pylotlight) in [PR](https://github.com/wailsapp/wails/pull/2984)
|
||||||
- Added CPU/GPU/Memory detection for `wails doctor`. Added by @leaanthony in #d51268b8d0680430f3a614775b13e6cd2b906d1c
|
- Added CPU/GPU/Memory detection for `wails doctor`. Added by @leaanthony in #d51268b8d0680430f3a614775b13e6cd2b906d1c
|
||||||
- The [AssetServer](/docs/reference/options#assetserver) now injects the runtime/IPC into all index html files and into all html files returned when requesting a folder path. Added by @stffabi in [PR](https://github.com/wailsapp/wails/pull/2203)
|
- The [AssetServer](/docs/reference/options#assetserver) now injects the runtime/IPC into all index html files and into all html files returned when requesting a folder path. Added by @stffabi in [PR](https://github.com/wailsapp/wails/pull/2203)
|
||||||
|
- Added Custom Protocol Schemes associations support for macOS and Windows. Added by @APshenkin in [PR](https://github.com/wailsapp/wails/pull/3000)
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
|
@ -200,6 +200,31 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"protocols": {
|
||||||
|
"type": "array",
|
||||||
|
"description": "Custom URI protocols that should be opened by the application",
|
||||||
|
"items": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"scheme": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "protocol scheme. e.g. myapp"
|
||||||
|
},
|
||||||
|
"description": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Windows-only. The description. It is displayed on the `Type` column on Windows Explorer."
|
||||||
|
},
|
||||||
|
"role": {
|
||||||
|
"description": "macOS-only. The app’s role with respect to the type. Corresponds to CFBundleTypeRole.",
|
||||||
|
"allOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/definitions/BundleTypeRole"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
Loading…
Reference in New Issue
Block a user