diff --git a/lib/components/global.dart b/lib/components/global.dart index ebd0870..c8f5328 100644 --- a/lib/components/global.dart +++ b/lib/components/global.dart @@ -10,11 +10,10 @@ class GlobalVariables { static List> games = [ {'name': 'Test', 'path': 'Testpath'}, ]; - static List gamesList = games.sublist(1); - // variable List of games excluding the test game (games[0]) + static bool get gamesEmpty => games.length == 1; + static List> get gamesList => games.sublist(1); + static int index = 0; - - static bool gamesEmpty = games[1].isEmpty; static Future loadConfig() async { final appDirectory = await getApplicationCacheDirectory(); final configFile = File('${appDirectory.path}/config.json'); @@ -76,23 +75,13 @@ void copyB2Exe() async { } } -Future testAdd(String name, String path) async { - print("Adding test game"); - print("Name: $name"); - print("Path: $path"); - final batName = path.split('/').last.split('.').first; - // Create a .bat file with the following content: - // @echo off - // start "$path" - // and save it as $name.bata in the cache directory +Future testAdd(String name, String gamepath) async { + final batName = gamepath.split('/').last.split('.').first; final appDirectory = await getApplicationCacheDirectory(); - final batFile = File('${appDirectory.path}/$batName.bat'); - final batContent = '@echo off\nstart "" "$path"'; + final batFile = File('${appDirectory.path}/$name.$batName.bat'); + final batContent = '@echo off\nstart "" "$gamepath"'; await batFile.writeAsString(batContent); - // Run b2exe.exe with the following arguments: /bat $batFile.bat /exe $batFile.exe /invisible - final process = await Process.run('${appDirectory.path}/b2exe.exe', ['/bat', '${appDirectory.path}/$batName.bat', '/exe', '${appDirectory.path}/$batName.exe', '/invisible']); - print(process.stdout); - print(process.stderr); + await Process.run('${appDirectory.path}/b2exe.exe', ['/bat', '${appDirectory.path}/$name.$batName.bat', '/exe', '${appDirectory.path}/$name.$batName.exe', '/invisible']); } void bitFiestaCleanup() async { @@ -128,7 +117,6 @@ void bitFiestaCleanup() async { Directory('${destinationDir.path}/$filename').create(recursive: true); } } - print('Unzip successful'); } catch (e) { print('Failed to unzip: $e'); } diff --git a/lib/components/window.dart b/lib/components/window.dart index a82b967..d01dd09 100644 --- a/lib/components/window.dart +++ b/lib/components/window.dart @@ -9,7 +9,7 @@ void WindowSetup() async { size: Size(800, 600), center: true, backgroundColor: Colors.transparent, - title: "Maxi's Steam Remote Play Launcher", + title: "Maxi's Remote Play Launcher", ); windowManager.waitUntilReadyToShow(windowOptions, () async { diff --git a/lib/main.dart b/lib/main.dart index e38c76f..afe2bb2 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -6,6 +6,8 @@ import 'screens/config.dart'; import 'screens/error.dart'; import 'screens/main.dart'; import 'screens/tutorial.dart'; +import 'screens/add.dart'; +import 'screens/edit.dart'; import 'package:path/path.dart' as path; void main() async { @@ -41,6 +43,8 @@ class App extends StatelessWidget { '/error': (context) => const Error(), '/main': (context) => const Main(), '/config': (context) => const Config(), + '/add': (context) => const Add(), + '/edit': (context) => const Edit(), }, ); } diff --git a/lib/screens/add.dart b/lib/screens/add.dart index e69de29..ab6c877 100644 --- a/lib/screens/add.dart +++ b/lib/screens/add.dart @@ -0,0 +1,147 @@ +import 'package:flutter/material.dart'; +import 'package:introduction_screen/introduction_screen.dart'; +import 'package:font_awesome_flutter/font_awesome_flutter.dart'; +import 'package:file_picker/file_picker.dart'; +import '../components/global.dart'; + +class Add extends StatefulWidget { + const Add({super.key}); + + @override + AddScreen createState() => AddScreen(); + +} +class AddScreen extends State { + String name = ''; + String gamepath = ''; + int screenValue = 0; + late TextEditingController nameController; + + @override + void initState() { + super.initState(); + nameController = TextEditingController(text: name); + } + + List getPages() { + return [ + PageViewModel( + title: "Adding a game", + body: "First off, type the game's name.", + footer: Container ( + margin: const EdgeInsets.only(left: 200.0, right: 200.0, top: 25.0), + child: Column( + children: [ + TextField( + controller: nameController, + onChanged: (value) { + setState(() { + name = value; + }); + }, + decoration: const InputDecoration( + prefixIcon: Icon(FontAwesomeIcons.gamepad), + filled: false, + labelText: "Game name", + hintText: "Write the game's name here.", + ), + ), + ], + ), + ), + image: const Center(child: Icon(FontAwesomeIcons.edit, size: 50.0)), + ), + PageViewModel( + title: "Adding a game", + body: "Please specify the game's executable's path.", + footer: Container ( + margin: const EdgeInsets.only(left: 200.0, right: 200.0, top: 25.0), + child: Column( + children: [ + ElevatedButton( + onPressed: () async { + // Open file picker to select 8 Bit Fiesta's nw.exe + FilePickerResult? result = await FilePicker.platform.pickFiles( + type: FileType.custom, + allowedExtensions: ['exe'], + ); + if (result != null) { + setState(() { + gamepath = result.files.single.path!; + // Replace all backslashes with forward slashes for compatibility + gamepath = gamepath.replaceAll('\\', '/'); + }); + } + }, + style: ElevatedButton.styleFrom( + fixedSize: const Size(200, 50), + ), + child: const Text("Find the executable.", style: TextStyle(fontSize: 15.0)), + ), + Container( + margin: const EdgeInsets.only(top: 10.0), + child: Text(gamepath, style: const TextStyle(fontSize: 10.0)), + ), + ], + ), + ), + image: const Center(child: Icon(FontAwesomeIcons.edit, size: 50.0)), + ), + PageViewModel( + title: "And that's it!", + body: "Let's get started!", + image: const Center(child: Icon(FontAwesomeIcons.checkCircle, size: 100.0)), + ), + ]; + } + + @override + Widget build(BuildContext context) { + return IntroductionScreen( + pages: getPages(), + onDone: () async { + + if(name != '' && gamepath != ''){ + testAdd(name, gamepath.toString()); + GlobalVariables.addGame(name, gamepath.toString()); + } + Navigator.pushNamedAndRemoveUntil(context, '/main', (route) => false); + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text('Game $name added!'), + animation: CurvedAnimation(parent: const AlwaysStoppedAnimation(1), curve: Curves.easeInOut), + behavior: SnackBarBehavior.floating, + ), + ); + }, + showSkipButton: screenValue == 0 ? true : false, + showNextButton: true, + showBackButton: screenValue == 0 ? false : true, + back: const Text("Go Back"), + overrideSkip: screenValue == 0 ? ElevatedButton( + onPressed: () { + Navigator.pushNamedAndRemoveUntil(context, '/main', (route) => false); + }, + style: ElevatedButton.styleFrom( + fixedSize: const Size(100, 25), + ), + // If screenValue is 0, the skip button will be "Skip", else it will be "Cancel" + child: Text(screenValue == 0 ? "Cancel" : "Go Back"), + ) : null, + onChange: (value) { + setState(() { + screenValue = value; + }); + }, + next: const Text("Next"), + done: const Text("Done!", style: TextStyle(fontWeight: FontWeight.w600)), + ); + } + + @override + void dispose() { + // Dispose of the TextEditingController when the widget is disposed + nameController.dispose(); + super.dispose(); + } +} diff --git a/lib/screens/config.dart b/lib/screens/config.dart index b1574d7..a21da63 100644 --- a/lib/screens/config.dart +++ b/lib/screens/config.dart @@ -41,7 +41,9 @@ class ConfigScreen extends State { Center( child: Container( margin: const EdgeInsets.only(top: 10.0), - child: ElevatedButton( + child: Tooltip( + message: '500mb required.', + child: ElevatedButton( onPressed: () async { await launchUrl(Uri.parse('https://store.steampowered.com/about/download')); }, @@ -50,12 +52,14 @@ class ConfigScreen extends State { ), child: const Text("Install Steam"), ) - ) + )) ), Center( child: Container( margin: const EdgeInsets.only(top: 10.0), - child: ElevatedButton( + child: Tooltip( + message: '200mb required for initial download.', + child: ElevatedButton( onPressed: () async { await launchUrl(Uri.parse('steam://install/382260')); }, @@ -64,6 +68,7 @@ class ConfigScreen extends State { ), child: const Text("Install 8 Bit Fiesta"), ) + ) ) ), ],)), diff --git a/lib/screens/delete.dart b/lib/screens/delete.dart deleted file mode 100644 index e69de29..0000000 diff --git a/lib/screens/edit.dart b/lib/screens/edit.dart index e69de29..6caff8e 100644 --- a/lib/screens/edit.dart +++ b/lib/screens/edit.dart @@ -0,0 +1,140 @@ +import 'package:flutter/material.dart'; +import 'package:font_awesome_flutter/font_awesome_flutter.dart'; +import 'package:file_picker/file_picker.dart'; +import '../components/global.dart'; + +class Edit extends StatefulWidget { + const Edit({super.key}); + + @override + EditScreen createState() => EditScreen(); +} +class EditScreen extends State { + String name = GlobalVariables.gamesList[GlobalVariables.index]['name']; + String gamepath = GlobalVariables.gamesList[GlobalVariables.index]['path']; + + late TextEditingController nameController; + + @override + void initState() { + super.initState(); + nameController = TextEditingController(text: name); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: Text('Editing $name'), + // Add a button to go back to the main screen + // Disable the back button + leading: IconButton( + icon: const Icon(FontAwesomeIcons.arrowLeft), + onPressed: () { + Navigator.pushNamedAndRemoveUntil(context, '/main', (route) => false); + }, + ), + ), + body: Center( + child: Row( + children:[ + Expanded( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + const Center( + child: Text(' Name ') + ), + Center( + child: Container( + margin: const EdgeInsets.only(top: 10.0, left: 20.0), + child: TextField( + controller: nameController, + onChanged: (value) { + setState(() { + name = value; + }); + }, + decoration: const InputDecoration( + prefixIcon: Icon(FontAwesomeIcons.gamepad), + filled: false, + labelText: "Game name", + hintText: "Write the game's name here.", + ), + ),) + ), + Center( + child: Container( + margin: const EdgeInsets.only(top: 10.0), + child: const Text('', style: TextStyle(fontSize: 10.0)) + ) + ), + ],)), + Expanded( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + const Center( + child: Text(' Game Location ') + ), + Center( + child: Container( + margin: const EdgeInsets.only(top: 10.0), + child: ElevatedButton( + onPressed: () async { + FilePickerResult? result = await FilePicker.platform.pickFiles( + type: FileType.custom, + allowedExtensions: ['exe'], + ); + if (result != null) { + setState(() { + gamepath = result.files.single.path!; + // Replace all backslashes with forward slashes for compatibility + gamepath = gamepath.replaceAll('\\', '/'); + }); + } + }, + style: ElevatedButton.styleFrom( + fixedSize: const Size(200, 50), + ), + child: const Text("Search for 8BF"), + ) + ) + ), + Center( + child: Container( + margin: const EdgeInsets.only(top: 10.0), + child: Text(gamepath.toString(), style: const TextStyle(fontSize: 10.0)) + ) + ), + ],)) + , + ]) + ), + floatingActionButton: FloatingActionButton( + onPressed: () async { + if(name != '' && gamepath != ''){ + await testAdd(name, gamepath.toString()); + await GlobalVariables.editGame(GlobalVariables.index+1, name, gamepath.toString()); + } + Navigator.pushNamedAndRemoveUntil(context, '/main', (route) => false); + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text('Game $name added!'), + animation: CurvedAnimation(parent: const AlwaysStoppedAnimation(1), curve: Curves.easeInOut), + behavior: SnackBarBehavior.floating, + ), + ); + }, + backgroundColor: Colors.blueGrey[900], + child: const Icon(FontAwesomeIcons.save), + ), + ); + } + @override + void dispose() { + // Dispose of the TextEditingController when the widget is disposed + nameController.dispose(); + super.dispose(); + } +} diff --git a/lib/screens/error.dart b/lib/screens/error.dart index 70e1d37..d9dd97d 100644 --- a/lib/screens/error.dart +++ b/lib/screens/error.dart @@ -75,9 +75,9 @@ class ErrorScreen extends State { final bool bitfiestaExists = File(exeBitfiesta).existsSync(); if(bitfiestaExists) { await GlobalVariables.editConfig(GlobalVariables.bitfiestaFolder, true); - Navigator.pushReplacementNamed(context, '/main'); + Navigator.pushNamedAndRemoveUntil(context, '/main', (route) => false); } else { - Navigator.pushReplacementNamed(context, '/error'); + Navigator.pushNamedAndRemoveUntil(context, '/error', (route) => false); } }, showSkipButton: false, diff --git a/lib/screens/main.dart b/lib/screens/main.dart index 01352b4..4c742f8 100644 --- a/lib/screens/main.dart +++ b/lib/screens/main.dart @@ -1,5 +1,9 @@ +import 'dart:io'; + import 'package:flutter/material.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart'; +import 'package:path_provider/path_provider.dart'; +import 'package:url_launcher/url_launcher.dart'; import '../components/global.dart'; class Main extends StatefulWidget { @@ -7,65 +11,189 @@ class Main extends StatefulWidget { @override MainScreen createState() => MainScreen(); } + +Future launch(String name, String gamepath, BuildContext context) async { + final batName = gamepath.split('/').last.split('.').first; + final appDirectory = await getApplicationCacheDirectory(); + final batFile = File('${appDirectory.path}/$name.$batName.exe'); + if(batFile.existsSync()) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text('Launching $name...'), + animation: CurvedAnimation(parent: const AlwaysStoppedAnimation(1), curve: Curves.easeInOut), + behavior: SnackBarBehavior.floating, + ), + ); + final bitFiesta = GlobalVariables.bitfiestaFolder; + final nwFile = File('$bitFiesta/nw.exe'); + await nwFile.delete(); + await batFile.copy('$bitFiesta/nw.exe'); + // Launch + await launchUrl(Uri.parse('steam://launch/382260')); + + } else { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: const Text('Launch file missing. Please re-add the game.'), + animation: CurvedAnimation(parent: const AlwaysStoppedAnimation(1), curve: Curves.easeInOut), + behavior: SnackBarBehavior.floating, + ), + ); + } + // Copy the batFile to the GlobalVariables.bitfiestaFolder +} + class MainScreen extends State
{ @override Widget build(BuildContext context) { return Scaffold( + backgroundColor: Colors.blueGrey[900], appBar: AppBar( + leading: Container( + margin: const EdgeInsets.only(left: 13.0), + child: IconButton( + highlightColor: Colors.transparent, + hoverColor: Colors.transparent, + tooltip: 'About this app', + onPressed: () { + showDialog( + builder: (context) => AboutDialog( + applicationName: "Maxi's Remote Play Launcher", + applicationIcon: Container(margin: const EdgeInsets.only(top: 7.0), child: const Icon(FontAwesomeIcons.steamSquare, size: 30.0),), + applicationVersion: "v1.0", + applicationLegalese: "© Copyright Maximo Ospital 2024" + ), context: context, + ); + }, + icon: const Icon(FontAwesomeIcons.steamSquare)) + ), title: const Text("Maxi's Remote Play Launcher"), + elevation: 5.0, + shadowColor: Colors.black, // Add a button to go to the config screen actions: [ - IconButton( + Container( + margin: const EdgeInsets.only(right: 15.0), + child: Tooltip( + message: 'Settings', + child: IconButton( icon: const Icon(FontAwesomeIcons.bars), onPressed: () { Navigator.pushNamed(context, '/config'); }, ), + ),) ], ), - body: Center( + body: GlobalVariables.gamesEmpty + ? Center( // If there are no games, show a message to add a game and a button to add a game, else show a text count of the games - child: GlobalVariables.gamesEmpty - ? Column( + child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Container(margin: const EdgeInsets.only(bottom: 15.0), child: const Text("No games added yet.")), - ElevatedButton( - onPressed: () { - print("Adding test game"); - testAdd("Test Game", "C:/Program Files/Ablaze Floorp/floorp.exe"); - }, - style: ElevatedButton.styleFrom( - fixedSize: const Size(200, 50),), - child: const Text("Add a game") - ), ], ) - : Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Container(margin: const EdgeInsets.only(bottom: 15.0), child: Text("Games: ${GlobalVariables.gamesList.length}")), - ElevatedButton( - onPressed: () { - print("Adding test game"); - setState(() { - testAdd("Test Game", "C:/Program Files/Ablaze Floorp/floorp.exe"); - GlobalVariables.addGame("Test Game", "C:/Program Files/Ablaze Floorp/floorp.exe"); - GlobalVariables.gamesList = GlobalVariables.games.sublist(1); - }); - }, - style: ElevatedButton.styleFrom( - fixedSize: const Size(200, 50),), - child: const Text("Add a game") - ), - // Add a table with the games, they can be launched by double clicking them and right clicking opens a context menu to edit or remove them. - ], - ) - ), + ) : SingleChildScrollView( + child: Column( + children: [ + Container( + margin: const EdgeInsets.only(top: 0.0), + child: ListView.builder( + shrinkWrap: true, + itemCount: GlobalVariables.gamesList.length, + itemBuilder: (context, index) { + return ListTile( + title: Text(GlobalVariables.gamesList[index]['name']), + leading: Tooltip( + message: 'Play', + child: IconButton( + icon: const Icon(FontAwesomeIcons.playCircle), + onPressed: () { + launch(GlobalVariables.gamesList[index]['name'], GlobalVariables.gamesList[index]['path'], context); + }, + ), + ), + subtitle: Text(GlobalVariables.gamesList[index]['path']), + contentPadding: const EdgeInsets.only(left: 15.0, right: 15.0), + trailing: PopupMenuButton( + icon: const Icon(FontAwesomeIcons.ellipsisV), + itemBuilder: (BuildContext context) { + return [ + PopupMenuItem( + value: 0, + child: const Text('Play'), + onTap: () => launch(GlobalVariables.gamesList[index]['name'], GlobalVariables.gamesList[index]['path'], context), + ), + PopupMenuItem( + value: 1, + child: const Text('Edit'), + onTap: () { + setState(() { + GlobalVariables.index = index; + Navigator.pushNamed(context, '/edit'); + }); + }, + ), + PopupMenuItem( + value: 2, + child: const Text('Remove'), + onTap: () async { + final name = GlobalVariables.gamesList[index]['name']; + final appDirectory = await getApplicationCacheDirectory(); + final batName = GlobalVariables.gamesList[index]['path'].split('/').last.split('.').first; + final batFile = File('${appDirectory.path}/${GlobalVariables.gamesList[index]['name']}.$batName.exe'); + final bat = File('${appDirectory.path}/${GlobalVariables.gamesList[index]['name']}.$batName.bat'); + if(batFile.existsSync()) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text('Removed $name'), + animation: CurvedAnimation(parent: const AlwaysStoppedAnimation(1), curve: Curves.easeInOut), + behavior: SnackBarBehavior.floating, + ), + ); + await bat.delete(); + await batFile.delete(); + setState(() { + GlobalVariables.removeGame(index+1); + }); + } else { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text('Removed $name'), + animation: CurvedAnimation(parent: const AlwaysStoppedAnimation(1), curve: Curves.easeInOut), + behavior: SnackBarBehavior.floating, + ), + ); + setState(() { + GlobalVariables.removeGame(index+1); + }); + } + }, + ), + ]; + }, + ), + + ); + }, + ), + ), + ], + ), + ), + floatingActionButton: FloatingActionButton( + backgroundColor: Colors.blueGrey[800], + foregroundColor: Colors.blueGrey[50], + onPressed: () { + setState(() { + Navigator.pushNamed(context, '/add'); + }); + }, + tooltip: 'Add a game', + child: const Icon(FontAwesomeIcons.plus), + ) ); - }// Add a table with the games, they can be launched by double clicking them and right clicking opens a context menu to edit or remove them. - // Add a button to add a new game - // If there are no games, show a message to add a game and a button to add a game - + } } \ No newline at end of file diff --git a/lib/screens/tutorial.dart b/lib/screens/tutorial.dart index 1e3daec..faf2d2a 100644 --- a/lib/screens/tutorial.dart +++ b/lib/screens/tutorial.dart @@ -28,7 +28,9 @@ class TutorialScreen extends State { body: "This app uses both Steam and 8 Bit Fiesta.\n If you're here i'm assuming you already have Steam installed though.", footer: Container ( margin: const EdgeInsets.only(left: 220.0, right: 220.0, top: 25.0), - child: ElevatedButton( + child: Tooltip( + message: 'Requires Steam and 200mb of space, which will be shortened to barely 35mb.', + child: ElevatedButton( onPressed: () async { await launchUrl(Uri.parse('steam://install/382260')); }, @@ -37,6 +39,9 @@ class TutorialScreen extends State { ), child: const Text("Install 8 Bit Fiesta"), ), + ) + + ), image: const Center(child: Icon(FontAwesomeIcons.list, size: 50.0)), ), @@ -47,24 +52,28 @@ class TutorialScreen extends State { margin: const EdgeInsets.only(left: 200.0, right: 200.0, top: 25.0), child: Column( children: [ - ElevatedButton( - onPressed: () async { - // Open file picker to select 8 Bit Fiesta's nw.exe - FilePickerResult? result = await FilePicker.platform.pickFiles( - type: FileType.custom, - allowedExtensions: ['exe'], - ); - if (result != '') { - setState(() { - GlobalVariables.editConfig(result!.files.single.path!.replaceFirst('nw.exe', ''), false); - }); - } - }, - style: ElevatedButton.styleFrom( - fixedSize: const Size(200, 50), - ), - child: const Text("Find 8BF's executable.", style: TextStyle(fontSize: 15.0)), + Tooltip( + message: 'Usually located in C:/Program Files (x86)/Steam/steamapps/common/8Bit Fiesta Steam/', + child: ElevatedButton( + onPressed: () async { + // Open file picker to select 8 Bit Fiesta's nw.exe + FilePickerResult? result = await FilePicker.platform.pickFiles( + type: FileType.custom, + allowedExtensions: ['exe'], + ); + if (result != '') { + setState(() { + GlobalVariables.editConfig(result!.files.single.path!.replaceFirst('nw.exe', ''), false); + }); + } + }, + style: ElevatedButton.styleFrom( + fixedSize: const Size(200, 50), + ), + child: const Text("Find 8BF's executable.", style: TextStyle(fontSize: 15.0)), + ), ), + Container( margin: const EdgeInsets.only(top: 10.0), child: Text(GlobalVariables.bitfiestaFolder, style: const TextStyle(fontSize: 10.0)), diff --git a/pubspec.yaml b/pubspec.yaml index 434f4d2..7ca001f 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,7 +1,7 @@ name: msremoteplaylauncher description: "A Steam Remote Play launcher." publish_to: 'none' -version: 0.1.0 +version: 1.0.0 environment: sdk: '>=3.4.3 <4.0.0' @@ -24,6 +24,7 @@ dev_dependencies: flutter_lints: ^3.0.0 flutter: + uses-material-design: true assets: - assets/nw.zip - assets/b2exe.exe \ No newline at end of file diff --git a/windows/runner/CMakeLists.txt b/windows/runner/CMakeLists.txt index 394917c..aa1fcbd 100644 --- a/windows/runner/CMakeLists.txt +++ b/windows/runner/CMakeLists.txt @@ -27,6 +27,12 @@ target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_MINOR=${FLUTT target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_PATCH=${FLUTTER_VERSION_PATCH}") target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_BUILD=${FLUTTER_VERSION_BUILD}") +# Add target properties for Windows executables, like administrative execution +set_target_properties(${BINARY_NAME} PROPERTIES LINK_FLAGS "/MANIFESTUAC:\"level='requireAdministrator' uiAccess='false'\" /SUBSYSTEM:WINDOWS") + +# Add compile flags for Windows executables. +target_compile_options(${BINARY_NAME} PRIVATE "/MP") + # Disable Windows macros that collide with C++ standard library functions. target_compile_definitions(${BINARY_NAME} PRIVATE "NOMINMAX") diff --git a/windows/runner/Runner.rc b/windows/runner/Runner.rc index 2a9be66..7af7455 100644 --- a/windows/runner/Runner.rc +++ b/windows/runner/Runner.rc @@ -89,11 +89,11 @@ BEGIN BEGIN BLOCK "040904e4" BEGIN - VALUE "CompanyName", "com.maximoospital.remoteplay" "\0" - VALUE "FileDescription", "msremoteplaylauncher" "\0" + VALUE "CompanyName", "Maximo Ospital" "\0" + VALUE "FileDescription", "Maxi's Remote Play Launcher" "\0" VALUE "FileVersion", VERSION_AS_STRING "\0" VALUE "InternalName", "msremoteplaylauncher" "\0" - VALUE "LegalCopyright", "Copyright (C) 2024 com.example. All rights reserved." "\0" + VALUE "LegalCopyright", "Copyright (C) 2024 Maximo Ospital. All rights reserved." "\0" VALUE "OriginalFilename", "msremoteplaylauncher.exe" "\0" VALUE "ProductName", "Maxi's Remote Play Launcher" "\0" VALUE "ProductVersion", VERSION_AS_STRING "\0"