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:
parent
08e12de2a0
commit
426a569c89
@ -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 */
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user