mirror of
https://github.com/Yubico/yubioath-flutter.git
synced 2024-11-22 08:22:16 +03:00
Replace socket approach with native Windows mutex.
This commit is contained in:
parent
71b66f53b0
commit
af1a2dad05
@ -1,68 +0,0 @@
|
||||
import 'dart:io';
|
||||
import 'package:logging/logging.dart';
|
||||
import 'package:path/path.dart' as path;
|
||||
|
||||
import 'package:path_provider/path_provider.dart';
|
||||
import 'package:window_manager/window_manager.dart';
|
||||
|
||||
const _lockFileName = 'lockfile';
|
||||
const _pingMessage = 'YA-PING';
|
||||
const _pongMessage = 'YA-PONG';
|
||||
|
||||
final log = Logger('single_instance');
|
||||
|
||||
void _startServer(File lockfile) async {
|
||||
final socket = await ServerSocket.bind(InternetAddress.loopbackIPv4, 0);
|
||||
lockfile.writeAsString('${socket.port}');
|
||||
|
||||
log.info('Lock file and socket created.');
|
||||
socket.listen((client) {
|
||||
client.listen((data) async {
|
||||
final message = String.fromCharCodes(data);
|
||||
if (message == _pingMessage) {
|
||||
log.info('Got incomming connection');
|
||||
|
||||
if (!await WindowManager.instance.isMinimized()) {
|
||||
// Causes the window to be brought to the front.
|
||||
await WindowManager.instance.setAlwaysOnTop(true);
|
||||
await WindowManager.instance.setAlwaysOnTop(false);
|
||||
} else {
|
||||
await WindowManager.instance.restore();
|
||||
}
|
||||
|
||||
// This doesn't seem to always work
|
||||
await WindowManager.instance.focus();
|
||||
client.write(_pongMessage);
|
||||
}
|
||||
client.close();
|
||||
}, cancelOnError: true);
|
||||
});
|
||||
}
|
||||
|
||||
Future<void> ensureSingleInstance() async {
|
||||
final appSupport = await getApplicationSupportDirectory();
|
||||
final lockfile = File(path.join(appSupport.path, _lockFileName));
|
||||
log.info('Lock file: $lockfile');
|
||||
|
||||
if (await lockfile.exists()) {
|
||||
try {
|
||||
final port = int.parse(await lockfile.readAsString());
|
||||
final client = await Socket.connect(InternetAddress.loopbackIPv4, port);
|
||||
client.write(_pingMessage);
|
||||
client.listen((data) async {
|
||||
final message = String.fromCharCodes(data);
|
||||
await client.close();
|
||||
if (message == _pongMessage) {
|
||||
log.info('Other application instance already running, exit.');
|
||||
exit(0);
|
||||
}
|
||||
}, cancelOnError: true);
|
||||
} on Exception {
|
||||
// No server listening on the port, or bad data in the file
|
||||
await lockfile.delete();
|
||||
_startServer(lockfile);
|
||||
}
|
||||
} else {
|
||||
_startServer(lockfile);
|
||||
}
|
||||
}
|
@ -6,7 +6,6 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
import 'package:logging/logging.dart';
|
||||
import 'package:window_manager/window_manager.dart';
|
||||
import 'package:yubico_authenticator/desktop/single_instance.dart';
|
||||
|
||||
import 'app/app.dart';
|
||||
import 'app/views/main_page.dart';
|
||||
@ -20,9 +19,6 @@ final log = Logger('main');
|
||||
void main() async {
|
||||
_initLogging(Level.INFO);
|
||||
WidgetsFlutterBinding.ensureInitialized();
|
||||
if (Platform.isWindows) {
|
||||
await ensureSingleInstance();
|
||||
}
|
||||
await windowManager.ensureInitialized();
|
||||
|
||||
// Either use the _YKMAN_EXE environment variable, or look relative to executable.
|
||||
|
@ -5,12 +5,10 @@
|
||||
import FlutterMacOS
|
||||
import Foundation
|
||||
|
||||
import path_provider_macos
|
||||
import shared_preferences_macos
|
||||
import window_manager
|
||||
|
||||
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
||||
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
|
||||
SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin"))
|
||||
WindowManagerPlugin.register(with: registry.registrar(forPlugin: "WindowManagerPlugin"))
|
||||
}
|
||||
|
28
pubspec.lock
28
pubspec.lock
@ -352,27 +352,6 @@ packages:
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.8.0"
|
||||
path_provider:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: path_provider
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.8"
|
||||
path_provider_android:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path_provider_android
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.11"
|
||||
path_provider_ios:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path_provider_ios
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.7"
|
||||
path_provider_linux:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -380,13 +359,6 @@ packages:
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.1.5"
|
||||
path_provider_macos:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path_provider_macos
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.5"
|
||||
path_provider_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -37,7 +37,6 @@ dependencies:
|
||||
|
||||
async: ^2.8.2
|
||||
logging: ^1.0.2
|
||||
path_provider: ^2.0.8
|
||||
shared_preferences: ^2.0.12
|
||||
flutter_riverpod: ^1.0.0
|
||||
json_annotation: ^4.4.0
|
||||
|
@ -107,6 +107,28 @@ bool Win32Window::CreateAndShow(const std::wstring& title,
|
||||
const Size& size) {
|
||||
Destroy();
|
||||
|
||||
// Attempt to create a mutex to enforce single instance.
|
||||
CreateMutex(NULL, TRUE, L"com.yubico.authenticator.mutex");
|
||||
if (GetLastError() == ERROR_ALREADY_EXISTS) {
|
||||
HWND handle=FindWindowA(NULL, "Yubico Authenticator");
|
||||
WINDOWPLACEMENT place = { sizeof(WINDOWPLACEMENT) };
|
||||
GetWindowPlacement(handle, &place);
|
||||
switch(place.showCmd) {
|
||||
case SW_SHOWMAXIMIZED:
|
||||
ShowWindow(handle, SW_SHOWMAXIMIZED);
|
||||
break;
|
||||
case SW_SHOWMINIMIZED:
|
||||
ShowWindow(handle, SW_RESTORE);
|
||||
break;
|
||||
default:
|
||||
ShowWindow(handle, SW_NORMAL);
|
||||
break;
|
||||
}
|
||||
SetWindowPos(0, HWND_TOP, 0, 0, 0, 0, SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOMOVE);
|
||||
SetForegroundWindow(handle);
|
||||
return 0;
|
||||
}
|
||||
|
||||
const wchar_t* window_class =
|
||||
WindowClassRegistrar::GetInstance()->GetWindowClass();
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user