Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions analysis_options.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,6 @@ include: package:flutter_lints/flutter.yaml

# Additional information about this file can be found at
# https://dart.dev/guides/language/analysis-options

formatter:
trailing_commas: preserve
50 changes: 32 additions & 18 deletions lib/src/windows_single_instance.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@ import 'dart:ffi';
import 'dart:io';
import 'dart:isolate';

import 'package:ffi/ffi.dart';
import 'package:flutter/services.dart';

import 'package:ffi/ffi.dart';
import 'package:win32/win32.dart';

class WindowsSingleInstance {
Expand All @@ -14,40 +15,53 @@ class WindowsSingleInstance {

WindowsSingleInstance._();

static int _openPipe(String filename) {
final cPipe = filename.toNativeUtf16();
static HANDLE _openPipe(String filename) {
final cPipe = filename.toPcwstr();
try {
return CreateFile(cPipe, GENERIC_WRITE, 0, nullptr, OPEN_EXISTING, 0, 0);
final Win32Result(:value) = CreateFile(
cPipe,
GENERIC_WRITE,
FILE_SHARE_NONE,
null,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
null,
);
return value;
} finally {
free(cPipe);
}
}

static int _createPipe(String filename) {
final cPipe = filename.toNativeUtf16();
static HANDLE _createPipe(String filename) {
final cPipe = filename.toPcwstr();
try {
return CreateNamedPipe(
cPipe,
PIPE_ACCESS_INBOUND | FILE_FLAG_FIRST_PIPE_INSTANCE | FILE_FLAG_OVERLAPPED,
PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT,
FILE_FLAGS_AND_ATTRIBUTES(
PIPE_ACCESS_INBOUND | FILE_FLAG_FIRST_PIPE_INSTANCE | FILE_FLAG_OVERLAPPED,
),
NAMED_PIPE_MODE(
PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT,
),
PIPE_UNLIMITED_INSTANCES,
4096,
4096,
0,
nullptr,
null,
);
} finally {
malloc.free(cPipe);
free(cPipe);
}
}

static void _readPipe(SendPort writer, int pipeHandle) {
static void _readPipe(SendPort writer, HANDLE pipeHandle) {
final overlap = calloc<OVERLAPPED>();
try {
while (true) {
while (true) {
ConnectNamedPipe(pipeHandle, overlap);
final err = GetLastError();
final Win32Result(:error) = ConnectNamedPipe(pipeHandle, overlap);
final err = error;
if (err == _kErrorPipeConnected) {
sleep(const Duration(milliseconds: 200));
continue;
Expand All @@ -57,11 +71,11 @@ class WindowsSingleInstance {
break;
}

var dataSize = 16384;
var data = calloc<Uint8>(dataSize);
const dataSize = 16384;
final data = calloc<Uint8>(dataSize);
final numRead = calloc<Uint32>();
try {
while (GetOverlappedResult(pipeHandle, overlap, numRead, 0) == 0) {
while (!GetOverlappedResult(pipeHandle, overlap, numRead, false).value) {
sleep(const Duration(milliseconds: 200));
}

Expand All @@ -87,7 +101,7 @@ class WindowsSingleInstance {
final bytes = bytesString.toNativeUtf8();
final numWritten = malloc<Uint32>();
try {
WriteFile(pipe, bytes.cast<Uint8>(), bytes.length, numWritten, nullptr);
WriteFile(pipe, bytes.cast<Uint8>(), bytes.length, numWritten, null);
} finally {
free(numWritten);
free(bytes);
Expand All @@ -104,7 +118,7 @@ class WindowsSingleInstance {
_readPipe(args["port"] as SendPort, pipe);
}

/// Checks that the current window is unique, and exits the app not.
/// Checks that the current window is unique, and exits the app if not.
///
/// __Arguments__\
/// `arguments`: List of strings that will be passed to the callback function of the open instance if this window is not unique\
Expand Down
8 changes: 4 additions & 4 deletions pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,23 +1,23 @@
name: windows_single_instance
description: Forces a single instance of your Windows app, bringing the existing window to the front when a new instance is opened.
version: 1.1.0
version: 2.0.1
homepage: https://github.com/SongbookPro/flutter_windows_single_instance

environment:
sdk: ">=2.16.2 <4.0.0"
sdk: ">=3.11.0 <4.0.0"
flutter: ">=2.5.0"

dependencies:
flutter:
sdk: flutter

win32: ">=2.5.0 <6.0.0"
win32: ^6.3.0
ffi: ">=1.0.0 <3.0.0"

dev_dependencies:
flutter_test:
sdk: flutter
flutter_lints: ^2.0.0
flutter_lints: ^6.0.0

flutter:
plugin:
Expand Down