5
0
mirror of https://github.com/wailsapp/wails.git synced 2025-05-03 04:42:00 +08:00

Fix single instance lock for macOS sandbox app (#3029)

* fix single instance lock for sandbox app

* fix single instance lock for sandbox app
This commit is contained in:
Andrey Pshenkin 2023-11-05 03:10:01 +00:00 committed by GitHub
parent 08e12de2a0
commit 426a569c89
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 33 additions and 5 deletions

View File

@ -28,4 +28,6 @@ extern void HandleSecondInstanceData(char * message);
void SendDataToFirstInstance(char * singleInstanceUniqueId, char * text); void SendDataToFirstInstance(char * singleInstanceUniqueId, char * text);
char* GetMacOsNativeTempDir();
#endif /* AppDelegate_h */ #endif /* AppDelegate_h */

View File

@ -48,17 +48,26 @@
} }
void SendDataToFirstInstance(char * singleInstanceUniqueId, char * message) { void SendDataToFirstInstance(char * singleInstanceUniqueId, char * message) {
// we pass message in object because otherwise sandboxing will prevent us from sending it https://developer.apple.com/forums/thread/129437
NSString * myString = [NSString stringWithUTF8String:message];
[[NSDistributedNotificationCenter defaultCenter] [[NSDistributedNotificationCenter defaultCenter]
postNotificationName:[NSString stringWithUTF8String:singleInstanceUniqueId] postNotificationName:[NSString stringWithUTF8String:singleInstanceUniqueId]
object:nil object:(__bridge const void *)(myString)
userInfo:@{@"message": [NSString stringWithUTF8String:message]} userInfo:nil
deliverImmediately:YES]; deliverImmediately:YES];
} }
char* GetMacOsNativeTempDir() {
NSString *tempDir = NSTemporaryDirectory();
char *copy = strdup([tempDir UTF8String]);
return copy;
}
- (void)handleSecondInstanceNotification:(NSNotification *)note; - (void)handleSecondInstanceNotification:(NSNotification *)note;
{ {
if (note.userInfo[@"message"] != nil) { if (note.object != nil) {
NSString *message = note.userInfo[@"message"]; NSString * message = (__bridge NSString *)note.object;
const char* utf8Message = message.UTF8String; const char* utf8Message = message.UTF8String;
HandleSecondInstanceData((char*)utf8Message); HandleSecondInstanceData((char*)utf8Message);
} }

View File

@ -12,13 +12,16 @@ package darwin
import "C" import "C"
import ( import (
"encoding/json" "encoding/json"
"fmt"
"github.com/wailsapp/wails/v2/pkg/options" "github.com/wailsapp/wails/v2/pkg/options"
"os" "os"
"strings"
"syscall" "syscall"
"unsafe"
) )
func SetupSingleInstance(uniqueID string) { func SetupSingleInstance(uniqueID string) {
lockFilePath := os.TempDir() lockFilePath := getTempDir()
lockFileName := uniqueID + ".lock" lockFileName := uniqueID + ".lock"
_, err := createLockFile(lockFilePath + "/" + lockFileName) _, err := createLockFile(lockFilePath + "/" + lockFileName)
@ -62,14 +65,28 @@ func HandleSecondInstanceData(secondInstanceMessage *C.char) {
func createLockFile(filename string) (*os.File, error) { func createLockFile(filename string) (*os.File, error) {
file, err := os.OpenFile(filename, os.O_WRONLY|os.O_CREATE, 0600) file, err := os.OpenFile(filename, os.O_WRONLY|os.O_CREATE, 0600)
if err != nil { if err != nil {
fmt.Printf("Failed to open lockfile %s: %s", filename, err)
return nil, err return nil, err
} }
err = syscall.Flock(int(file.Fd()), syscall.LOCK_EX|syscall.LOCK_NB) err = syscall.Flock(int(file.Fd()), syscall.LOCK_EX|syscall.LOCK_NB)
if err != nil { if err != nil {
// Flock failed for some other reason than other instance already lock it. Print it in logs for possible debugging.
if !strings.Contains(err.Error(), "resource temporarily unavailable") {
fmt.Printf("Failed to lock lockfile %s: %s", filename, err)
}
file.Close() file.Close()
return nil, err return nil, err
} }
return file, nil return file, nil
} }
// If app is sandboxed, golang os.TempDir() will return path that will not be accessible. So use native macOS temp dir function.
func getTempDir() string {
cstring := C.GetMacOsNativeTempDir()
path := C.GoString(cstring)
C.free(unsafe.Pointer(cstring))
return path
}