mirror of
https://github.com/wailsapp/wails.git
synced 2025-05-02 06:19:43 +08:00
[v3] Add start_at_login plugin
[v3] Fix plugin startup/shutdown order
This commit is contained in:
parent
7ecbc846b4
commit
755e869fe7
1
.gitignore
vendored
1
.gitignore
vendored
@ -35,3 +35,4 @@ v2/cmd/wails/internal/commands/initialise/templates/testtemplates/
|
||||
/v3/.task
|
||||
/v3/examples/build/bin/testapp
|
||||
/websitev3/site/
|
||||
/v3/examples/plugins/bin/testapp
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 0 B After Width: | Height: | Size: 130 KiB |
@ -14,6 +14,7 @@ require (
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect
|
||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||
github.com/pkg/browser v0.0.0-20210706143420-7d21f8c997e2 // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
|
||||
github.com/samber/lo v1.37.0 // indirect
|
||||
github.com/wailsapp/mimetype v1.4.1 // indirect
|
||||
|
@ -24,6 +24,8 @@ github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9G
|
||||
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||
github.com/pkg/browser v0.0.0-20210706143420-7d21f8c997e2 h1:acNfDZXmm28D2Yg/c3ALnZStzNaZMSagpbr96vY6Zjc=
|
||||
github.com/pkg/browser v0.0.0-20210706143420-7d21f8c997e2/go.mod h1:HKlIX3XHQyzLZPlr7++PzdhaXEj94dEiJgZDTsxEqUI=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
|
||||
|
BIN
v3/examples/plugins/icon.ico
Normal file
BIN
v3/examples/plugins/icon.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 21 KiB |
BIN
v3/examples/plugins/icons.icns
Normal file
BIN
v3/examples/plugins/icons.icns
Normal file
Binary file not shown.
@ -8,6 +8,7 @@ import (
|
||||
"github.com/wailsapp/wails/v3/plugins/log"
|
||||
"github.com/wailsapp/wails/v3/plugins/single_instance"
|
||||
"github.com/wailsapp/wails/v3/plugins/sqlite"
|
||||
"github.com/wailsapp/wails/v3/plugins/start_at_login"
|
||||
"os"
|
||||
"plugin_demo/plugins/hashes"
|
||||
)
|
||||
@ -27,7 +28,9 @@ func main() {
|
||||
"hashes": hashes.NewPlugin(),
|
||||
"browser": browser.NewPlugin(),
|
||||
"log": log.NewPlugin(),
|
||||
"sqlite": sqlite.NewPlugin(&sqlite.Config{}),
|
||||
"sqlite": sqlite.NewPlugin(&sqlite.Config{
|
||||
DBFile: "test.db",
|
||||
}),
|
||||
"kvstore": kvstore.NewPlugin(&kvstore.Config{
|
||||
Filename: "store.json",
|
||||
AutoSave: true,
|
||||
@ -36,6 +39,7 @@ func main() {
|
||||
// When true, the original app will be activated when a second instance is launched
|
||||
ActivateAppOnSubsequentLaunch: true,
|
||||
}),
|
||||
"start_at_login": start_at_login.NewPlugin(),
|
||||
},
|
||||
Assets: application.AssetOptions{
|
||||
FS: assets,
|
||||
|
@ -67,11 +67,6 @@ func New(appOptions Options) *App {
|
||||
println("Fatal error in application initialisation: ", err.Error())
|
||||
os.Exit(1)
|
||||
}
|
||||
err = result.bindings.AddPlugins(appOptions.Plugins)
|
||||
if err != nil {
|
||||
println("Fatal error in application initialisation: ", err.Error())
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
result.plugins = NewPluginManager(appOptions.Plugins, srv)
|
||||
err = result.plugins.Init()
|
||||
@ -80,6 +75,12 @@ func New(appOptions Options) *App {
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
err = result.bindings.AddPlugins(appOptions.Plugins)
|
||||
if err != nil {
|
||||
println("Fatal error in application initialisation: ", err.Error())
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
|
24
v3/pkg/mac/mac.go
Normal file
24
v3/pkg/mac/mac.go
Normal file
@ -0,0 +1,24 @@
|
||||
//go:build darwin
|
||||
|
||||
// Package mac provides a set of functions to interact with the macOS platform.
|
||||
package mac
|
||||
|
||||
/*
|
||||
#cgo CFLAGS: -x objective-c
|
||||
#cgo LDFLAGS: -framework Foundation -framework ServiceManagement
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <ServiceManagement/ServiceManagement.h>
|
||||
|
||||
// Get the bundle ID
|
||||
char* getBundleID() {
|
||||
NSString *bundleID = [[NSBundle mainBundle] bundleIdentifier];
|
||||
return (char*)[bundleID UTF8String];
|
||||
}
|
||||
*/
|
||||
import "C"
|
||||
|
||||
// GetBundleID returns the bundle ID of the application.
|
||||
func GetBundleID() string {
|
||||
return C.GoString(C.getBundleID())
|
||||
}
|
@ -4,12 +4,20 @@ import (
|
||||
"database/sql"
|
||||
_ "embed"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/wailsapp/wails/v3/pkg/application"
|
||||
_ "modernc.org/sqlite"
|
||||
"strings"
|
||||
)
|
||||
|
||||
//go:embed plugin.js
|
||||
var js string
|
||||
//go:embed sqlite_close.js
|
||||
var closejs string
|
||||
|
||||
//go:embed sqlite_open.js
|
||||
var openjs string
|
||||
|
||||
//go:embed sqlite_execute_select.js
|
||||
var executeselectjs string
|
||||
|
||||
// ---------------- Plugin Setup ----------------
|
||||
// This is the main plugin struct. It can be named anything you like.
|
||||
@ -28,6 +36,7 @@ type Plugin struct {
|
||||
app *application.App
|
||||
conn *sql.DB
|
||||
callableMethods []string
|
||||
js string
|
||||
}
|
||||
|
||||
func NewPlugin(config *Config) *Plugin {
|
||||
@ -56,18 +65,24 @@ func (p *Plugin) Name() string {
|
||||
func (p *Plugin) Init(app *application.App) error {
|
||||
p.app = app
|
||||
p.callableMethods = []string{"Execute", "Select"}
|
||||
p.js = executeselectjs
|
||||
if p.config.CanOpenFromJS {
|
||||
p.callableMethods = append(p.callableMethods, "Open")
|
||||
p.js += openjs
|
||||
}
|
||||
if p.config.CanCloseFromJS {
|
||||
p.callableMethods = append(p.callableMethods, "Close")
|
||||
p.js += closejs
|
||||
}
|
||||
if p.config.DBFile != "" {
|
||||
_, err := p.Open(p.config.DBFile)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if p.config.DBFile == "" {
|
||||
return errors.New(`no database file specified. Please set DBFile in the config to either a filename or use ":memory:" to use an in-memory database`)
|
||||
}
|
||||
_, err := p.Open(p.config.DBFile)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
p.js += fmt.Sprintf("\nwindow.sqlite = { %s };", strings.Join(p.callableMethods, ", "))
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -77,7 +92,7 @@ func (p *Plugin) CallableByJS() []string {
|
||||
}
|
||||
|
||||
func (p *Plugin) InjectJS() string {
|
||||
return js
|
||||
return p.js
|
||||
}
|
||||
|
||||
// ---------------- Plugin Methods ----------------
|
||||
|
8
v3/plugins/sqlite/sqlite_close.js
Normal file
8
v3/plugins/sqlite/sqlite_close.js
Normal file
@ -0,0 +1,8 @@
|
||||
|
||||
/**
|
||||
* Close a sqlite DB.
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
function Close() {
|
||||
return wails.Plugin("sqlite", "Close");
|
||||
}
|
@ -1,19 +1,3 @@
|
||||
/**
|
||||
* Open a sqlite DB.
|
||||
* @param filename {string} - file to open.
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
function Open(filename) {
|
||||
return wails.Plugin("sqlite", "Open", filename);
|
||||
}
|
||||
|
||||
/**
|
||||
* Close a sqlite DB.
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
function Close() {
|
||||
return wails.Plugin("sqlite", "Close");
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute a SQL statement.
|
||||
@ -34,11 +18,3 @@ function Execute(statement, ...args) {
|
||||
function Select(statement, ...args) {
|
||||
return wails.Plugin("sqlite", "Select", statement, ...args);
|
||||
}
|
||||
|
||||
window.sqlite = {
|
||||
Open: Open,
|
||||
Close: Close,
|
||||
Execute: Execute,
|
||||
Select: Select
|
||||
};
|
||||
|
8
v3/plugins/sqlite/sqlite_open.js
Normal file
8
v3/plugins/sqlite/sqlite_open.js
Normal file
@ -0,0 +1,8 @@
|
||||
/**
|
||||
* Open a sqlite DB.
|
||||
* @param filename {string} - file to open.
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
function Open(filename) {
|
||||
return wails.Plugin("sqlite", "Open", filename);
|
||||
}
|
34
v3/plugins/start_at_login/README.md
Normal file
34
v3/plugins/start_at_login/README.md
Normal file
@ -0,0 +1,34 @@
|
||||
# start_at_login Plugin
|
||||
|
||||
This example plugin provides a way to generate hashes of strings.
|
||||
|
||||
## Installation
|
||||
|
||||
Add the plugin to the `Plugins` option in the Applications options:
|
||||
|
||||
```go
|
||||
Plugins: map[string]application.Plugin{
|
||||
"start_at_login": start_at_login.NewPlugin(),
|
||||
},
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
You can then call the methods from the frontend:
|
||||
|
||||
```js
|
||||
wails.Plugin("start_at_login","StartAtLogin", true).then((result) => console.log(result))
|
||||
wails.Plugin("start_at_login","IsStartAtLogin").then((result) => console.log(result))
|
||||
```
|
||||
|
||||
To use this from Go, create a new instance of the plugin, then call the methods on that:
|
||||
|
||||
```go
|
||||
start_at_login := start_at_login.NewPlugin()
|
||||
start_at_login.StartAtLogin(true)
|
||||
```
|
||||
|
||||
## Support
|
||||
|
||||
If you find a bug in this plugin, please raise a ticket [here](https://github.com/plugin/repository).
|
||||
Please do not contact the Wails team for support.
|
54
v3/plugins/start_at_login/plugin.go
Normal file
54
v3/plugins/start_at_login/plugin.go
Normal file
@ -0,0 +1,54 @@
|
||||
package start_at_login
|
||||
|
||||
import (
|
||||
"github.com/wailsapp/wails/v3/pkg/application"
|
||||
"github.com/wailsapp/wails/v3/pkg/logger"
|
||||
"github.com/wailsapp/wails/v3/pkg/mac"
|
||||
"runtime"
|
||||
)
|
||||
|
||||
type Plugin struct {
|
||||
app *application.App
|
||||
disabled bool
|
||||
}
|
||||
|
||||
func NewPlugin() *Plugin {
|
||||
return &Plugin{}
|
||||
}
|
||||
|
||||
// Shutdown is called when the app is shutting down
|
||||
// You can use this to clean up any resources you have allocated
|
||||
func (p *Plugin) Shutdown() {}
|
||||
|
||||
// Name returns the name of the plugin.
|
||||
// You should use the go module format e.g. github.com/myuser/myplugin
|
||||
func (p *Plugin) Name() string {
|
||||
return "github.com/wailsapp/wails/v3/plugins/start_at_login"
|
||||
}
|
||||
|
||||
func (p *Plugin) Init(app *application.App) error {
|
||||
p.app = app
|
||||
if runtime.GOOS == "darwin" {
|
||||
bundleID := mac.GetBundleID()
|
||||
if bundleID == "" {
|
||||
p.app.Log(&logger.Message{
|
||||
Level: "INFO",
|
||||
Message: "Application is not in bundle. StartAtLogin will not work.",
|
||||
})
|
||||
p.disabled = true
|
||||
return nil
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *Plugin) CallableByJS() []string {
|
||||
return []string{
|
||||
"StartAtLogin",
|
||||
"IsStartAtLogin",
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Plugin) InjectJS() string {
|
||||
return ""
|
||||
}
|
11
v3/plugins/start_at_login/plugin.toml
Normal file
11
v3/plugins/start_at_login/plugin.toml
Normal file
@ -0,0 +1,11 @@
|
||||
# This is the plugin definition file for the "start_at_login" plugin.
|
||||
|
||||
Name = "start_at_login"
|
||||
Description = "Plugin to control whether the application should start at login"
|
||||
Author = "Lea Anthony"
|
||||
Version = "v1.0.0"
|
||||
Website = "https://wails.io/plugins/start_at_login"
|
||||
Repository = "https://github.com/wailsapp/wails/v3/plugins/start_at_login"
|
||||
License = "MIT"
|
||||
|
||||
|
66
v3/plugins/start_at_login/plugin_darwin.go
Normal file
66
v3/plugins/start_at_login/plugin_darwin.go
Normal file
@ -0,0 +1,66 @@
|
||||
//go:build darwin
|
||||
|
||||
package start_at_login
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/samber/lo"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func (p *Plugin) StartAtLogin(enabled bool) error {
|
||||
if p.disabled {
|
||||
return nil
|
||||
}
|
||||
exe, err := os.Executable()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "Error running os.Executable:")
|
||||
}
|
||||
binName := filepath.Base(exe)
|
||||
if !strings.HasSuffix(exe, "/Contents/MacOS/"+binName) {
|
||||
return fmt.Errorf("app needs to be running as package.app file to start at login")
|
||||
}
|
||||
appPath := strings.TrimSuffix(exe, "/Contents/MacOS/"+binName)
|
||||
var command string
|
||||
if enabled {
|
||||
command = fmt.Sprintf("tell application \"System Events\" to make login item at end with properties {name: \"%s\",path:\"%s\", hidden:false}", binName, appPath)
|
||||
} else {
|
||||
command = fmt.Sprintf("tell application \"System Events\" to delete login item \"%s\"", binName)
|
||||
}
|
||||
|
||||
cmd := exec.Command("osascript", "-e", command)
|
||||
_, err = cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *Plugin) IsStartAtLogin() (bool, error) {
|
||||
if p.disabled {
|
||||
return false, nil
|
||||
}
|
||||
exe, err := os.Executable()
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
binName := filepath.Base(exe)
|
||||
if !strings.HasSuffix(exe, "/Contents/MacOS/"+binName) {
|
||||
return false, fmt.Errorf("app needs to be running as package.app file to start at login")
|
||||
}
|
||||
appPath := strings.TrimSuffix(exe, "/Contents/MacOS/"+binName)
|
||||
appName := strings.TrimSuffix(filepath.Base(appPath), ".app")
|
||||
cmd := exec.Command("osascript", "-e", `tell application "System Events" to get the name of every login item`)
|
||||
results, err := cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
resultsString := strings.TrimSpace(string(results))
|
||||
startupApps := strings.Split(resultsString, ", ")
|
||||
result := lo.Contains(startupApps, appName)
|
||||
return result, nil
|
||||
}
|
Loading…
Reference in New Issue
Block a user