5
0
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:
Lea Anthony 2023-04-05 21:22:02 +10:00
parent 7ecbc846b4
commit 755e869fe7
17 changed files with 243 additions and 38 deletions

1
.gitignore vendored
View File

@ -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

View File

@ -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

View File

@ -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=

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

View File

@ -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,

View File

@ -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
View 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())
}

View File

@ -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 ----------------

View File

@ -0,0 +1,8 @@
/**
* Close a sqlite DB.
* @returns {Promise<void>}
*/
function Close() {
return wails.Plugin("sqlite", "Close");
}

View File

@ -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
};

View 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);
}

View 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.

View 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 ""
}

View 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"

View 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
}