55 Commits
Author SHA1 Message Date
Stone_Red 302ff3aa05 Merge pull request #8 from Stone-Red-Code/develop
Develop
2025-07-05 17:42:00 +02:00
Stone_Red d285bdc489 Update version 2025-07-05 17:39:07 +02:00
Stone_Red 0a64184c32 Fix plugin manager crash when opening it 2025-05-17 15:45:43 +02:00
Stone_Red 2df00fbeeb Properly remove the plugin window from the lists in the main window when an exception occurs 2025-02-26 20:22:42 +01:00
Stone_Red 088f51410a Send plugin windows to front when edit mode enabled and to back when disabled 2025-02-26 19:28:42 +01:00
Stone_Red 70d08aa4c3 Set WindowState of main window to Minimized when closing 2025-02-25 23:04:44 +01:00
Stone_Red af9aa60bd9 Rename ModEntry UserControl to PluginEntry 2025-02-25 23:03:14 +01:00
Stone_Red 695cb867ee Add autostart checkbox 2025-02-25 19:20:02 +01:00
Stone_Red 376176460b Update modio.net library links in README.md 2025-02-25 03:09:35 +01:00
Stone_Red 327b79d69c Remove Extended.Wpf.Toolkit from thrid party licenses section in README.md 2025-02-25 03:04:43 +01:00
Stone_Red c74bc60209 Add login/logout button to plugin manger to sync subscriptions 2025-02-24 22:02:58 +01:00
Stone_Red 930da5d679 Correctly update .csproj file when creating new plugin 2025-02-23 15:53:41 +01:00
Stone_Red ffd92d2259 Add create new plugin button to plugin manager 2025-02-23 15:32:56 +01:00
Stone_Red 6100f444a8 Center dialogs on parent window 2025-02-23 15:32:25 +01:00
Stone_Red ead20d1279 Change GetLanguageDictionary method to LanguageDictionary property 2024-12-30 16:54:04 +01:00
Stone_Red b638eff451 Add missing translations 2024-12-28 23:16:23 +01:00
Stone_Red 793dcbad38 Small fixes 2024-12-28 16:40:06 +01:00
Stone_Red c2474e6425 Plugin manager layout improvments 2024-12-05 15:00:48 +01:00
Stone_Red cbeaaee88e Standardize README 2024-12-03 00:43:51 +01:00
Stone_Red 92c13c5ed0 Change app name from "Desktop Magic" to "DesktopMagic" and some QOL improvments 2024-12-03 00:16:37 +01:00
Stone_Red 26e979af79 Standardize default plugin setting names 2024-12-03 00:16:37 +01:00
Stone_Red 29619dbdda Rename download plugins to browse plugins in README.md 2024-11-30 00:38:56 +01:00
Stone_Red bc11832f9f Add right click actions to tray icon 2024-11-29 18:40:00 +01:00
Stone_Red f8f06a9e2c Improve plugin window performance by not constantly updating properties of UI elements 2024-11-29 17:55:33 +01:00
Stone_Red 35d64ef2c3 Don't unnecessarily redraw time plugin bitmap every second 2024-11-29 17:55:33 +01:00
Stone_Red 3b9d49e8da Update README.md 2024-11-29 00:57:02 +01:00
Stone_Red aada1b8807 Add Microsoft Store link and fix twitter/x link 2024-11-28 17:47:36 +01:00
Stone_Red 9abfb9cb66 Merge pull request #7 from Stone-Red-Code/main
Readme updates
2024-11-18 23:00:21 +01:00
Stone_Red ce1c181b14 Add MsixPackaging project 2024-11-16 14:36:04 +01:00
Stone_Red e6be5c011b Replace deprecated Modio library with alternative library 2024-11-15 19:55:12 +01:00
Stone_Red c6e858764f Remove unnecessary files 2024-11-15 19:53:19 +01:00
Stone_Red f684cdb051 Show error when failing to delete plugin files 2024-11-15 19:41:34 +01:00
Stone_Red 3993e6d612 Fix multiple warnings 2024-11-15 19:41:16 +01:00
Stone_Red 8e187f91fa Update README.md 2024-10-31 13:19:28 +01:00
Stone_Red 566bcee426 Update README.md 2024-10-30 21:51:00 +01:00
Stone_Red 038074cd87 Update README.md 2024-10-30 21:50:22 +01:00
Stone_Red 7e1736696d Rename BuiltInWindowElements to BuiltInPlugins 2024-10-26 14:43:14 +02:00
Stone_Red e545f27461 Replace Xceed.Wpf.Toolkit.IntegerUpDown with MaterialDesignThemes.Wpf.NumericUpDown 2024-10-26 00:25:53 +02:00
Stone_Red d458feca1e Add DesktopMagicPluginAPI.xml to .gitignore 2024-10-25 23:28:52 +02:00
Stone_Red f899fd3e9b Merge branch 'main' into develop 2024-10-25 23:22:23 +02:00
Stone_Red c3b867ff67 Merge pull request #6 from dylanrenwick/main
Updated documentation file path to be relative to project
2024-10-25 23:19:29 +02:00
drenwick 1fe59e6338 Updated documentation file path to be relative to project 2024-10-25 15:10:58 -04:00
Stone_Red 242f6a8388 Merge pull request #4 from Stone-Red-Code/develop
Develop
2024-05-01 18:22:10 +02:00
Stone_Red f7f75a4580 Fix Installer.iss 2024-05-01 18:21:23 +02:00
Stone_Red 475623f333 Change file version 2024-05-01 18:20:08 +02:00
Stone_Red aa1733e0c6 Update libraries 2024-05-01 17:41:27 +02:00
Stone_Red 5804bade47 Fix plugin dependencies not getting loaded 2024-05-01 15:51:19 +02:00
Stone_Red ca9f426bba Fix null warning 2024-05-01 15:26:14 +02:00
Stone_Red 4cd8c51592 Make installed plugins panel scrollable 2024-05-01 15:23:53 +02:00
Stone_Red d4cd384ce4 Merge pull request #3 from Stone-Red-Code/develop
Develop
2024-02-22 09:58:24 +01:00
Stone_Red 414f84a024 Update installer 2024-02-22 09:57:41 +01:00
Stone_Red 3c732117d3 Remove auto update 2024-02-22 09:50:30 +01:00
Stone_Red 9a75cbd8e7 Fix or disable multiple warnings 2024-02-22 09:34:01 +01:00
Stone_Red 536890a5e4 Update twitter link in README.md to always show the latest updates 2024-01-03 12:24:13 +01:00
Stone_Red 975831eb18 Add "Follow the development" section to readme 2024-01-02 16:38:38 +01:00
106 changed files with 1595 additions and 609 deletions
+3
View File
@@ -6,6 +6,9 @@
bin/ bin/
obj/ obj/
# Project-specific files
/src/DesktopMagicPluginAPI/DesktopMagicPluginAPI.xml
# User-specific files # User-specific files
*.rsuser *.rsuser
*.suo *.suo
+17 -10
View File
@@ -1,18 +1,25 @@
# DesktopMagic ![DesktopMagic](https://socialify.git.ci/Stone-Red-Code/DesktopMagic/image?description=1&descriptionEditable=DesktopMagic%20allows%20you%20to%20improve%20the%20looks%20of%20your%20desktop!&forks=1&issues=1&logo=https%3A%2F%2Fgithub.com%2Fuser-attachments%2Fassets%2F34f3c473-a29a-4d71-9ec0-1387b04ad2c5&name=1&pattern=Formal%20Invitation&pulls=1&stargazers=1&theme=Auto)
> DesktopMagic allows you to improve the looks of your Windows desktop!\ > You can add useful widgets to your desktop like a clock, an audio visualizer or even your own plugins using mod.io!
> You can add useful elements to your desktop like a clock, an audio visualizer or even your own plugins using mod.io!
- [Releases](https://github.com/Stone-Red-Code/DesktopMagic/releases) - [Releases](https://github.com/Stone-Red-Code/DesktopMagic/releases)
- [Download plugins](https://mod.io/g/desktopmagic) - [Browse plugins](https://mod.io/g/desktopmagic)
- [Plugin creation guide](https://mod.io/g/desktopmagic/r/plugin-creation-guide) - [Plugin creation guide](https://mod.io/g/desktopmagic/r/plugin-creation-guide)
- [Licence](https://github.com/Stone-Red-Code/DesktopMagic/blob/main/LICENSE) - [Licence](https://github.com/Stone-Red-Code/DesktopMagic/blob/main/LICENSE)
## Setup ## Usage
1. Download one of the [releases](https://github.com/Stone-Red-Code/DesktopMagic/releases). 1. Download & install the latest release
1. Execute the `DesktopMagic-Installer.exe` file. - Microsoft Store: [Store Page](https://www.microsoft.com/store/productId/9NPV8F9K1CWM?ocid=pdpshare)
1. (Optional) Put a shortcut to the `DesktopMagic.exe` file in the install directory into the `shell:startup` directory. - GitHub: [Releases](https://github.com/Stone-Red-Code/DesktopMagic/releases)
1. (Optional) Put a shortcut to the `DesktopMagic.exe` file in the installation directory into the `shell:startup` directory.
1. Start the app and select the widgets you want to see on your desktop.
1. Check the "Edit" Checkbox to move the widgets.
1. Open the plugin manager to install third-party plugins.
## Follow the development
[![Twitter(X)](http://img.shields.io/badge/Twitter-black.svg?&logo=x&style=for-the-badge&logoColor=white)](https://x.com/search?q=from%3A%40StoneRedCode%20%23DesktopMagic)
## Preview ## Preview
@@ -20,8 +27,8 @@
![Screenshot 2023-12-31 164853](https://github.com/Stone-Red-Code/DesktopMagic/assets/56473591/22de55d2-dde3-43a5-b77b-c773a7697e8c) ![Screenshot 2023-12-31 164853](https://github.com/Stone-Red-Code/DesktopMagic/assets/56473591/22de55d2-dde3-43a5-b77b-c773a7697e8c)
## Third party licenses ## Third party licenses
- [BusyIndicator](https://github.com/moh3ngolshani/BusyIndicator) - [MIT](https://github.com/Moh3nGolshani/BusyIndicator/blob/master/LICENSE) - [BusyIndicator](https://github.com/moh3ngolshani/BusyIndicator) - [MIT](https://github.com/Moh3nGolshani/BusyIndicator/blob/master/LICENSE)
- [Extended.Wpf.Toolkit](https://github.com/xceedsoftware/wpftoolkit) - [XCEED SOFTWARE COMMUNITY LICENSE AGREEMENT](https://github.com/xceedsoftware/wpftoolkit/blob/master/license.md)
- [Material Design In XAML Toolkit](https://github.com/MaterialDesignInXAML/MaterialDesignInXamlToolkit) - [MIT](https://github.com/MaterialDesignInXAML/MaterialDesignInXamlToolkit/blob/master/LICENSE) - [Material Design In XAML Toolkit](https://github.com/MaterialDesignInXAML/MaterialDesignInXamlToolkit) - [MIT](https://github.com/MaterialDesignInXAML/MaterialDesignInXamlToolkit/blob/master/LICENSE)
- [Modio.NET](https://github.com/thetestgame/modio.net) - [Apache-2.0](https://github.com/thetestgame/Modio.NET/blob/main/LICENSE-APACHE), [MIT](https://github.com/thetestgame/Modio.NET/blob/main/LICENSE-MIT) - [Modio.NET](https://github.com/nickelc/modio.net) - [Apache-2.0](https://github.com/nickelc/modio.net/blob/master/LICENSE-APACHE), [MIT](https://github.com/nickelc/modio.net/blob/master/LICENSE-MIT)
- [NAudio](https://github.com/naudio/NAudio) - [MIT](https://github.com/naudio/NAudio/blob/master/license.txt) - [NAudio](https://github.com/naudio/NAudio) - [MIT](https://github.com/naudio/NAudio/blob/master/license.txt)
Binary file not shown.
+1 -1
View File
@@ -4,7 +4,7 @@
#expr Exec('cmd.exe /C ', 'dotnet build -o "' + SourcePath + '\publish" -c Release ' + SourcePath + '..\src\DesktopMagic\') #expr Exec('cmd.exe /C ', 'dotnet build -o "' + SourcePath + '\publish" -c Release ' + SourcePath + '..\src\DesktopMagic\')
#define MyAppName "DesktopMagic" #define MyAppName "DesktopMagic"
#define MyAppVersion GetVersionNumbersString("/publish/DesktopMagic.exe") #define MyAppVersion GetStringFileInfo("/publish/DesktopMagic.exe","ProductVersion")
#define MyAppPublisher "Stone_Red" #define MyAppPublisher "Stone_Red"
#define MyAppExeName "DesktopMagic.exe" #define MyAppExeName "DesktopMagic.exe"
+92 -4
View File
@@ -9,24 +9,112 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DesktopMagic.Api", "Desktop
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DesktopMagic.PluginTest", "DesktopMagicPlugin.Test\DesktopMagic.PluginTest.csproj", "{EF8407AB-28AE-4B5E-AC2E-D4C4A575FBC7}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DesktopMagic.PluginTest", "DesktopMagicPlugin.Test\DesktopMagic.PluginTest.csproj", "{EF8407AB-28AE-4B5E-AC2E-D4C4A575FBC7}"
EndProject EndProject
Project("{C7167F0D-BC9F-4E6E-AFE1-012C56B48DB5}") = "MsixPackaging", "MsixPackaging\MsixPackaging.wapproj", "{CC2850EF-1451-4D0C-9474-4CBEBB28A2C8}"
EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU Debug|Any CPU = Debug|Any CPU
Debug|ARM = Debug|ARM
Debug|ARM64 = Debug|ARM64
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|Any CPU = Release|Any CPU Release|Any CPU = Release|Any CPU
Release|ARM = Release|ARM
Release|ARM64 = Release|ARM64
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution GlobalSection(ProjectConfigurationPlatforms) = postSolution
{B56B4CCC-CF92-4C05-9DEA-57666D81889A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {B56B4CCC-CF92-4C05-9DEA-57666D81889A}.Debug|Any CPU.ActiveCfg = Debug|x64
{B56B4CCC-CF92-4C05-9DEA-57666D81889A}.Debug|Any CPU.Build.0 = Debug|Any CPU {B56B4CCC-CF92-4C05-9DEA-57666D81889A}.Debug|Any CPU.Build.0 = Debug|x64
{B56B4CCC-CF92-4C05-9DEA-57666D81889A}.Release|Any CPU.ActiveCfg = Release|Any CPU {B56B4CCC-CF92-4C05-9DEA-57666D81889A}.Debug|ARM.ActiveCfg = Debug|Any CPU
{B56B4CCC-CF92-4C05-9DEA-57666D81889A}.Release|Any CPU.Build.0 = Release|Any CPU {B56B4CCC-CF92-4C05-9DEA-57666D81889A}.Debug|ARM.Build.0 = Debug|Any CPU
{B56B4CCC-CF92-4C05-9DEA-57666D81889A}.Debug|ARM64.ActiveCfg = Debug|Any CPU
{B56B4CCC-CF92-4C05-9DEA-57666D81889A}.Debug|ARM64.Build.0 = Debug|Any CPU
{B56B4CCC-CF92-4C05-9DEA-57666D81889A}.Debug|x64.ActiveCfg = Debug|x64
{B56B4CCC-CF92-4C05-9DEA-57666D81889A}.Debug|x64.Build.0 = Debug|x64
{B56B4CCC-CF92-4C05-9DEA-57666D81889A}.Debug|x86.ActiveCfg = Debug|Any CPU
{B56B4CCC-CF92-4C05-9DEA-57666D81889A}.Debug|x86.Build.0 = Debug|Any CPU
{B56B4CCC-CF92-4C05-9DEA-57666D81889A}.Release|Any CPU.ActiveCfg = Release|x64
{B56B4CCC-CF92-4C05-9DEA-57666D81889A}.Release|Any CPU.Build.0 = Release|x64
{B56B4CCC-CF92-4C05-9DEA-57666D81889A}.Release|ARM.ActiveCfg = Release|Any CPU
{B56B4CCC-CF92-4C05-9DEA-57666D81889A}.Release|ARM.Build.0 = Release|Any CPU
{B56B4CCC-CF92-4C05-9DEA-57666D81889A}.Release|ARM64.ActiveCfg = Release|Any CPU
{B56B4CCC-CF92-4C05-9DEA-57666D81889A}.Release|ARM64.Build.0 = Release|Any CPU
{B56B4CCC-CF92-4C05-9DEA-57666D81889A}.Release|x64.ActiveCfg = Release|x64
{B56B4CCC-CF92-4C05-9DEA-57666D81889A}.Release|x64.Build.0 = Release|x64
{B56B4CCC-CF92-4C05-9DEA-57666D81889A}.Release|x86.ActiveCfg = Release|Any CPU
{B56B4CCC-CF92-4C05-9DEA-57666D81889A}.Release|x86.Build.0 = Release|Any CPU
{9D193A10-3E8E-447F-89F1-4B316C2EE37D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {9D193A10-3E8E-447F-89F1-4B316C2EE37D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{9D193A10-3E8E-447F-89F1-4B316C2EE37D}.Debug|Any CPU.Build.0 = Debug|Any CPU {9D193A10-3E8E-447F-89F1-4B316C2EE37D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9D193A10-3E8E-447F-89F1-4B316C2EE37D}.Debug|ARM.ActiveCfg = Debug|Any CPU
{9D193A10-3E8E-447F-89F1-4B316C2EE37D}.Debug|ARM.Build.0 = Debug|Any CPU
{9D193A10-3E8E-447F-89F1-4B316C2EE37D}.Debug|ARM64.ActiveCfg = Debug|Any CPU
{9D193A10-3E8E-447F-89F1-4B316C2EE37D}.Debug|ARM64.Build.0 = Debug|Any CPU
{9D193A10-3E8E-447F-89F1-4B316C2EE37D}.Debug|x64.ActiveCfg = Debug|x64
{9D193A10-3E8E-447F-89F1-4B316C2EE37D}.Debug|x64.Build.0 = Debug|x64
{9D193A10-3E8E-447F-89F1-4B316C2EE37D}.Debug|x86.ActiveCfg = Debug|Any CPU
{9D193A10-3E8E-447F-89F1-4B316C2EE37D}.Debug|x86.Build.0 = Debug|Any CPU
{9D193A10-3E8E-447F-89F1-4B316C2EE37D}.Release|Any CPU.ActiveCfg = Release|Any CPU {9D193A10-3E8E-447F-89F1-4B316C2EE37D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9D193A10-3E8E-447F-89F1-4B316C2EE37D}.Release|Any CPU.Build.0 = Release|Any CPU {9D193A10-3E8E-447F-89F1-4B316C2EE37D}.Release|Any CPU.Build.0 = Release|Any CPU
{9D193A10-3E8E-447F-89F1-4B316C2EE37D}.Release|ARM.ActiveCfg = Release|Any CPU
{9D193A10-3E8E-447F-89F1-4B316C2EE37D}.Release|ARM.Build.0 = Release|Any CPU
{9D193A10-3E8E-447F-89F1-4B316C2EE37D}.Release|ARM64.ActiveCfg = Release|Any CPU
{9D193A10-3E8E-447F-89F1-4B316C2EE37D}.Release|ARM64.Build.0 = Release|Any CPU
{9D193A10-3E8E-447F-89F1-4B316C2EE37D}.Release|x64.ActiveCfg = Release|x64
{9D193A10-3E8E-447F-89F1-4B316C2EE37D}.Release|x64.Build.0 = Release|x64
{9D193A10-3E8E-447F-89F1-4B316C2EE37D}.Release|x86.ActiveCfg = Release|Any CPU
{9D193A10-3E8E-447F-89F1-4B316C2EE37D}.Release|x86.Build.0 = Release|Any CPU
{EF8407AB-28AE-4B5E-AC2E-D4C4A575FBC7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {EF8407AB-28AE-4B5E-AC2E-D4C4A575FBC7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{EF8407AB-28AE-4B5E-AC2E-D4C4A575FBC7}.Debug|Any CPU.Build.0 = Debug|Any CPU {EF8407AB-28AE-4B5E-AC2E-D4C4A575FBC7}.Debug|Any CPU.Build.0 = Debug|Any CPU
{EF8407AB-28AE-4B5E-AC2E-D4C4A575FBC7}.Debug|ARM.ActiveCfg = Debug|Any CPU
{EF8407AB-28AE-4B5E-AC2E-D4C4A575FBC7}.Debug|ARM.Build.0 = Debug|Any CPU
{EF8407AB-28AE-4B5E-AC2E-D4C4A575FBC7}.Debug|ARM64.ActiveCfg = Debug|Any CPU
{EF8407AB-28AE-4B5E-AC2E-D4C4A575FBC7}.Debug|ARM64.Build.0 = Debug|Any CPU
{EF8407AB-28AE-4B5E-AC2E-D4C4A575FBC7}.Debug|x64.ActiveCfg = Debug|x64
{EF8407AB-28AE-4B5E-AC2E-D4C4A575FBC7}.Debug|x64.Build.0 = Debug|x64
{EF8407AB-28AE-4B5E-AC2E-D4C4A575FBC7}.Debug|x86.ActiveCfg = Debug|Any CPU
{EF8407AB-28AE-4B5E-AC2E-D4C4A575FBC7}.Debug|x86.Build.0 = Debug|Any CPU
{EF8407AB-28AE-4B5E-AC2E-D4C4A575FBC7}.Release|Any CPU.ActiveCfg = Release|Any CPU {EF8407AB-28AE-4B5E-AC2E-D4C4A575FBC7}.Release|Any CPU.ActiveCfg = Release|Any CPU
{EF8407AB-28AE-4B5E-AC2E-D4C4A575FBC7}.Release|Any CPU.Build.0 = Release|Any CPU {EF8407AB-28AE-4B5E-AC2E-D4C4A575FBC7}.Release|Any CPU.Build.0 = Release|Any CPU
{EF8407AB-28AE-4B5E-AC2E-D4C4A575FBC7}.Release|ARM.ActiveCfg = Release|Any CPU
{EF8407AB-28AE-4B5E-AC2E-D4C4A575FBC7}.Release|ARM.Build.0 = Release|Any CPU
{EF8407AB-28AE-4B5E-AC2E-D4C4A575FBC7}.Release|ARM64.ActiveCfg = Release|Any CPU
{EF8407AB-28AE-4B5E-AC2E-D4C4A575FBC7}.Release|ARM64.Build.0 = Release|Any CPU
{EF8407AB-28AE-4B5E-AC2E-D4C4A575FBC7}.Release|x64.ActiveCfg = Release|x64
{EF8407AB-28AE-4B5E-AC2E-D4C4A575FBC7}.Release|x64.Build.0 = Release|x64
{EF8407AB-28AE-4B5E-AC2E-D4C4A575FBC7}.Release|x86.ActiveCfg = Release|Any CPU
{EF8407AB-28AE-4B5E-AC2E-D4C4A575FBC7}.Release|x86.Build.0 = Release|Any CPU
{CC2850EF-1451-4D0C-9474-4CBEBB28A2C8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{CC2850EF-1451-4D0C-9474-4CBEBB28A2C8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{CC2850EF-1451-4D0C-9474-4CBEBB28A2C8}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
{CC2850EF-1451-4D0C-9474-4CBEBB28A2C8}.Debug|ARM.ActiveCfg = Debug|ARM
{CC2850EF-1451-4D0C-9474-4CBEBB28A2C8}.Debug|ARM.Build.0 = Debug|ARM
{CC2850EF-1451-4D0C-9474-4CBEBB28A2C8}.Debug|ARM.Deploy.0 = Debug|ARM
{CC2850EF-1451-4D0C-9474-4CBEBB28A2C8}.Debug|ARM64.ActiveCfg = Debug|ARM64
{CC2850EF-1451-4D0C-9474-4CBEBB28A2C8}.Debug|ARM64.Build.0 = Debug|ARM64
{CC2850EF-1451-4D0C-9474-4CBEBB28A2C8}.Debug|ARM64.Deploy.0 = Debug|ARM64
{CC2850EF-1451-4D0C-9474-4CBEBB28A2C8}.Debug|x64.ActiveCfg = Debug|x64
{CC2850EF-1451-4D0C-9474-4CBEBB28A2C8}.Debug|x64.Build.0 = Debug|x64
{CC2850EF-1451-4D0C-9474-4CBEBB28A2C8}.Debug|x64.Deploy.0 = Debug|x64
{CC2850EF-1451-4D0C-9474-4CBEBB28A2C8}.Debug|x86.ActiveCfg = Debug|x86
{CC2850EF-1451-4D0C-9474-4CBEBB28A2C8}.Debug|x86.Build.0 = Debug|x86
{CC2850EF-1451-4D0C-9474-4CBEBB28A2C8}.Debug|x86.Deploy.0 = Debug|x86
{CC2850EF-1451-4D0C-9474-4CBEBB28A2C8}.Release|Any CPU.ActiveCfg = Release|x64
{CC2850EF-1451-4D0C-9474-4CBEBB28A2C8}.Release|Any CPU.Build.0 = Release|x64
{CC2850EF-1451-4D0C-9474-4CBEBB28A2C8}.Release|Any CPU.Deploy.0 = Release|x64
{CC2850EF-1451-4D0C-9474-4CBEBB28A2C8}.Release|ARM.ActiveCfg = Release|ARM
{CC2850EF-1451-4D0C-9474-4CBEBB28A2C8}.Release|ARM.Build.0 = Release|ARM
{CC2850EF-1451-4D0C-9474-4CBEBB28A2C8}.Release|ARM.Deploy.0 = Release|ARM
{CC2850EF-1451-4D0C-9474-4CBEBB28A2C8}.Release|ARM64.ActiveCfg = Release|ARM64
{CC2850EF-1451-4D0C-9474-4CBEBB28A2C8}.Release|ARM64.Build.0 = Release|ARM64
{CC2850EF-1451-4D0C-9474-4CBEBB28A2C8}.Release|ARM64.Deploy.0 = Release|ARM64
{CC2850EF-1451-4D0C-9474-4CBEBB28A2C8}.Release|x64.ActiveCfg = Release|x64
{CC2850EF-1451-4D0C-9474-4CBEBB28A2C8}.Release|x64.Build.0 = Release|x64
{CC2850EF-1451-4D0C-9474-4CBEBB28A2C8}.Release|x64.Deploy.0 = Release|x64
{CC2850EF-1451-4D0C-9474-4CBEBB28A2C8}.Release|x86.ActiveCfg = Release|x86
{CC2850EF-1451-4D0C-9474-4CBEBB28A2C8}.Release|x86.Build.0 = Release|x86
{CC2850EF-1451-4D0C-9474-4CBEBB28A2C8}.Release|x86.Deploy.0 = Release|x86
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE
+3 -1
View File
@@ -8,8 +8,10 @@
<ResourceDictionary.MergedDictionaries> <ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Resources\Strings\StringResources.en.xaml" /> <ResourceDictionary Source="Resources\Strings\StringResources.en.xaml" />
<materialDesign:BundledTheme BaseTheme="Light" PrimaryColor="Grey" SecondaryColor="LightBlue" /> <materialDesign:BundledTheme BaseTheme="Light" PrimaryColor="Grey" SecondaryColor="LightBlue" />
<ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Defaults.xaml" /> <ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesign3.Defaults.xaml" />
<ResourceDictionary Source="pack://application:,,,/BusyIndicator;component/Theme/Default.xaml" /> <ResourceDictionary Source="pack://application:,,,/BusyIndicator;component/Theme/Default.xaml" />
<ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.ObsoleteBrushes.xaml" />
<ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.ObsoleteStyles.xaml" />
<ResourceDictionary Source="Resources\Images\ImageResources.xaml" /> <ResourceDictionary Source="Resources\Images\ImageResources.xaml" />
</ResourceDictionary.MergedDictionaries> </ResourceDictionary.MergedDictionaries>
<Thickness x:Key="DefaultMargin" Top="6" Left="6" Right="6" Bottom ="6"></Thickness> <Thickness x:Key="DefaultMargin" Top="6" Left="6" Right="6" Bottom ="6"></Thickness>
+98 -98
View File
@@ -1,8 +1,4 @@
global using Stone_Red_Utilities.Logging; using CuteUtils.Logging;
using AlwaysUpToDate;
using Stone_Red_C_Sharp_Utilities.Logging;
using System; using System;
using System.IO; using System.IO;
@@ -18,58 +14,107 @@ public partial class App : Application
{ {
public const string AppGuid = "{{61FE5CE9-47C3-4255-A1F4-5BCF4ACA0879}"; public const string AppGuid = "{{61FE5CE9-47C3-4255-A1F4-5BCF4ACA0879}";
public const string AppName = "Desktop Magic"; public const string AppName = "DesktopMagic";
private readonly string logFilePath;
#if DEBUG // This is the previous name of the application, used to migrate the application data folder
private readonly Updater updater = new Updater(TimeSpan.FromDays(1), "https://raw.githubusercontent.com/Stone-Red-Code/DesktopMagic/develop/update/updateInfo.json"); private const string PreviousAppName = "Desktop Magic";
#else
private readonly Updater updater = new Updater(TimeSpan.FromDays(1), "https://raw.githubusercontent.com/Stone-Red-Code/DesktopMagic/main/update/updateInfo.json"); private static readonly string logFilePath = Path.Combine(ApplicationDataPath, $"{AppName}.log");
#endif
private readonly Thread? eventThread; private readonly Thread? eventThread;
private readonly EventWaitHandle eventWaitHandle; private readonly EventWaitHandle eventWaitHandle;
public static string ApplicationDataPath => Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "StoneRed", AppName);
private readonly Logger logger = new Logger(); public static string PluginsPath => Path.Combine(ApplicationDataPath, "Plugins");
public static string ApplicationDataPath { get; } = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "StoneRed", AppName);
public static Logger Logger => ((App)Current).logger; public static Logger Logger { get; } = new Logger()
{
Config = new()
{
FatalConfig = new OutputConfig()
{
ConsoleColor = ConsoleColor.DarkRed,
LogTarget = LogTarget.DebugConsole | LogTarget.File,
FilePath = logFilePath
},
ErrorConfig = new OutputConfig()
{
ConsoleColor = ConsoleColor.Red,
LogTarget = LogTarget.DebugConsole | LogTarget.File,
FilePath = logFilePath
},
WarnConfig = new OutputConfig()
{
ConsoleColor = ConsoleColor.Yellow,
LogTarget = LogTarget.DebugConsole | LogTarget.File,
FilePath = logFilePath
},
InfoConfig = new OutputConfig()
{
ConsoleColor = ConsoleColor.White,
LogTarget = LogTarget.DebugConsole | LogTarget.File,
FilePath = logFilePath
},
DebugConfig = new OutputConfig()
{
ConsoleColor = ConsoleColor.Gray,
LogTarget = LogTarget.DebugConsole,
},
FormatConfig = new FormatConfig()
{
DebugConsoleFormat = $"> {{{LogFormatType.DateTime}:HH:mm:ss}} | {{{LogFormatType.LogSeverity},-5}} | {{{LogFormatType.Message}}}\nat {{{LogFormatType.LineNumber}}} | {{{LogFormatType.FilePath}}}"
}
}
};
public static ResourceDictionary LanguageDictionary
{
get
{
ResourceDictionary dict = [];
string currentCulture = Thread.CurrentThread.CurrentUICulture.ToString();
if (currentCulture.Contains("de"))
{
dict.Source = new Uri("..\\Resources\\Strings\\StringResources.de.xaml", UriKind.Relative);
}
else
{
dict.Source = new Uri("..\\Resources\\Strings\\StringResources.en.xaml", UriKind.Relative);
}
return dict;
}
}
private static string PreviousApplicationDataPath => Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "StoneRed", PreviousAppName);
public App() public App()
{ {
logFilePath = ApplicationDataPath + "\\log.log";
// Setup global event handler // Setup global event handler
eventWaitHandle = new EventWaitHandle(false, EventResetMode.AutoReset, AppGuid, out bool createdNew); eventWaitHandle = new EventWaitHandle(false, EventResetMode.AutoReset, AppGuid, out bool createdNew);
//check if creating new was successful // Check if creating new was successful
if (!createdNew) if (!createdNew)
{ {
Setup(false); Setup(false);
Logger.Log("Shutting down because other instance already running.", "Setup", LogSeverity.Warn); Logger.LogWarn("Shutting down because other instance already running.", source: "Setup");
//Shutdown Application // Shutdown Application
_ = eventWaitHandle.Set(); _ = eventWaitHandle.Set();
Current.Shutdown(); Current.Shutdown();
} }
else else
{ {
eventThread = new Thread( eventThread = new Thread(() =>
() => {
while (eventWaitHandle.WaitOne())
{ {
while (eventWaitHandle.WaitOne()) _ = Current.Dispatcher.BeginInvoke(() => ((MainWindow)Current.MainWindow).RestoreWindow());
{ }
_ = Current.Dispatcher.BeginInvoke( });
() => ((MainWindow)Current.MainWindow).RestoreWindow());
}
});
eventThread.Start(); eventThread.Start();
Setup(true); Setup(true);
Exit += CloseHandler; Exit += CloseHandler;
updater.ProgressChanged += Updater_ProgressChanged;
updater.OnException += Updater_OnException;
updater.NoUpdateAvailible += Updater_NoUpdateAvailible;
updater.UpdateAvailible += Updater_UpdateAvailible;
updater.Start();
} }
} }
@@ -79,78 +124,39 @@ public partial class App : Application
eventThread?.Interrupt(); eventThread?.Interrupt();
} }
private void Updater_UpdateAvailible(string version, string additionalInformation) private static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{ {
updater.Update(); Exception exception = (Exception)e.ExceptionObject;
Logger.LogFatal(exception + (e.IsTerminating ? "\t Process terminating!" : ""), source: exception.Source ?? "Unknown");
} }
private void Updater_NoUpdateAvailible() private static void Setup(bool clearLogFile)
{
Logger.Log("No update available", "Updater");
}
private void Updater_OnException(Exception exception)
{
Logger.Log(exception.ToString(), "Updater");
}
private void Updater_ProgressChanged(long? totalFileSize, long totalBytesDownloaded, double? progressPercentage)
{
Logger.Log($"Downloading: {progressPercentage}% {totalBytesDownloaded}/{totalFileSize}", "Updater");
}
private void Setup(bool clearLogFile)
{ {
AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException; AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
Logger.Config = new LogConfig()
{
FatalConfig = new OutputConfig()
{
Color = ConsoleColor.DarkRed,
LogTarget = LogTarget.DebugConsole | LogTarget.File,
FilePath = logFilePath
},
ErrorConfig = new OutputConfig()
{
Color = ConsoleColor.Red,
LogTarget = LogTarget.DebugConsole | LogTarget.File,
FilePath = logFilePath
},
WarnConfig = new OutputConfig()
{
Color = ConsoleColor.Yellow,
LogTarget = LogTarget.DebugConsole | LogTarget.File,
FilePath = logFilePath
},
InfoConfig = new OutputConfig()
{
Color = ConsoleColor.White,
LogTarget = LogTarget.DebugConsole | LogTarget.File,
FilePath = logFilePath
},
DebugConfig = new OutputConfig()
{
Color = ConsoleColor.Gray,
LogTarget = LogTarget.DebugConsole,
},
FormatConfig = new FormatConfig()
{
DebugConsoleFormat = $"> {{{LogFormatType.DateTime}:HH:mm:ss}} | {{{LogFormatType.LogSeverity},-5}} | {{{LogFormatType.Message}}}\nat {{{LogFormatType.LineNumber}}} | {{{LogFormatType.FilePath}}}"
}
};
try try
{ {
if (Directory.Exists(PreviousApplicationDataPath) && !Directory.Exists(ApplicationDataPath))
{
Directory.Move(PreviousApplicationDataPath, ApplicationDataPath);
Logger.LogInfo("Migrated ApplicationData folder", source: "Setup");
}
if (!Directory.Exists(ApplicationDataPath)) if (!Directory.Exists(ApplicationDataPath))
{ {
_ = Directory.CreateDirectory(ApplicationDataPath); _ = Directory.CreateDirectory(ApplicationDataPath);
Logger.LogInfo("Created ApplicationData folder", source: "Setup");
}
if (!Directory.Exists(PluginsPath))
{
_ = Directory.CreateDirectory(PluginsPath);
Logger.LogInfo("Created Plugins folder", source: "Setup");
} }
Logger.Log("Created ApplicationData Folder", "Main");
} }
catch (Exception ex) catch (Exception ex)
{ {
_ = MessageBox.Show(ex.ToString()); _ = MessageBox.Show(ex.ToString(), AppName, MessageBoxButton.OK, MessageBoxImage.Error);
Logger.Log(ex.Message, "Setup", LogSeverity.Error); Logger.Log(ex.Message, "Setup", LogSeverity.Error);
} }
@@ -159,12 +165,6 @@ public partial class App : Application
Logger.ClearLogFile(LogSeverity.Info); Logger.ClearLogFile(LogSeverity.Info);
} }
Logger.Log("Log setup complete", "Setup"); Logger.LogInfo("Setup complete", source: "Setup");
}
private void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
Exception exception = (Exception)e.ExceptionObject;
Logger.Log(exception + (e.IsTerminating ? "\t Process terminating!" : ""), exception.Source, LogSeverity.Fatal);
} }
} }
@@ -7,7 +7,7 @@ using System.Drawing.Text;
using SettingAttribute = DesktopMagic.Api.Settings.SettingAttribute; using SettingAttribute = DesktopMagic.Api.Settings.SettingAttribute;
namespace DesktopMagic.BuiltInWindowElements; namespace DesktopMagic.BuiltInPlugins;
internal class CpuMonitorPlugin : Plugin internal class CpuMonitorPlugin : Plugin
{ {
@@ -5,22 +5,22 @@ using System;
using System.Drawing; using System.Drawing;
using System.Drawing.Text; using System.Drawing.Text;
namespace DesktopMagic.BuiltInWindowElements; namespace DesktopMagic.BuiltInPlugins;
internal class DatePlugin : Plugin internal class DatePlugin : Plugin
{ {
[Setting("short-date", "Short date")] [Setting("short-date", "Short date")]
private readonly CheckBox shortDatecheckBox = new CheckBox(true); private readonly CheckBox shortDateCheckBox = new CheckBox(true);
private DateTime oldDateTime = DateTime.MinValue; private DateTime oldDateTime = DateTime.MinValue;
private Color oldColor = Color.White; private Color oldColor = Color.White;
private string oldFont = string.Empty; private string oldFont = string.Empty;
private bool oldShortDatecheckBoxValue; private bool oldShortDateCheckBoxValue;
public override int UpdateInterval => 1000; public override int UpdateInterval => 1000;
public override Bitmap? Main() public override Bitmap? Main()
{ {
if (oldDateTime.Date == DateTime.Now.Date && oldColor == Application.Theme.PrimaryColor && oldFont == Application.Theme.Font && oldShortDatecheckBoxValue == shortDatecheckBox.Value) if (oldDateTime.Date == DateTime.Now.Date && oldColor == Application.Theme.PrimaryColor && oldFont == Application.Theme.Font && oldShortDateCheckBoxValue == shortDateCheckBox.Value)
{ {
return null; return null;
} }
@@ -28,9 +28,9 @@ internal class DatePlugin : Plugin
oldDateTime = DateTime.Now; oldDateTime = DateTime.Now;
oldColor = Application.Theme.PrimaryColor; oldColor = Application.Theme.PrimaryColor;
oldFont = Application.Theme.Font; oldFont = Application.Theme.Font;
oldShortDatecheckBoxValue = shortDatecheckBox.Value; oldShortDateCheckBoxValue = shortDateCheckBox.Value;
string date = shortDatecheckBox.Value ? DateTime.Now.ToShortDateString() : DateTime.Now.ToLongDateString(); string date = shortDateCheckBox.Value ? DateTime.Now.ToShortDateString() : DateTime.Now.ToLongDateString();
Font font = new Font(Application.Theme.Font, 200); Font font = new Font(Application.Theme.Font, 200);
@@ -9,7 +9,7 @@ using System.Collections.Generic;
using System.Drawing; using System.Drawing;
using System.Linq; using System.Linq;
namespace DesktopMagic.BuiltInWindowElements; namespace DesktopMagic.BuiltInPlugins;
internal class MusicVisualizerPlugin : Plugin internal class MusicVisualizerPlugin : Plugin
{ {
@@ -272,7 +272,7 @@ internal class MusicVisualizerPlugin : Plugin
} }
catch (Exception ex) catch (Exception ex)
{ {
App.Logger.Log(ex.Message, "Music Visualizer", LogSeverity.Error); App.Logger.LogError(ex.Message, source: "Music Visualizer");
} }
} }
@@ -5,19 +5,33 @@ using System;
using System.Drawing; using System.Drawing;
using System.Drawing.Text; using System.Drawing.Text;
namespace DesktopMagic.BuiltInWindowElements; namespace DesktopMagic.BuiltInPlugins;
internal class TimePlugin : Plugin internal class TimePlugin : Plugin
{ {
[Setting("display-seconds", "Display Seconds")] [Setting("display-seconds", "Show Seconds")]
private readonly CheckBox displaySecondsCheckBox = new CheckBox(true); private readonly CheckBox displaySecondsCheckBox = new CheckBox(true);
private string oldTime = string.Empty;
private Color oldColor = Color.White;
private string oldFont = string.Empty;
private bool oldDisplaySecondsCheckBoxValue;
public override int UpdateInterval => 1000; public override int UpdateInterval => 1000;
public override Bitmap Main() public override Bitmap? Main()
{ {
string time = displaySecondsCheckBox.Value ? DateTime.Now.ToLongTimeString() : DateTime.Now.ToShortTimeString(); string time = displaySecondsCheckBox.Value ? DateTime.Now.ToLongTimeString() : DateTime.Now.ToShortTimeString();
if (oldTime == time && oldColor == Application.Theme.PrimaryColor && oldFont == Application.Theme.Font && oldDisplaySecondsCheckBoxValue == displaySecondsCheckBox.Value)
{
return null;
}
oldTime = time;
oldColor = Application.Theme.PrimaryColor;
oldFont = Application.Theme.Font;
oldDisplaySecondsCheckBoxValue = displaySecondsCheckBox.Value;
Font font = new Font(Application.Theme.Font, 200); Font font = new Font(Application.Theme.Font, 200);
Bitmap bmp = new Bitmap(1, 1); Bitmap bmp = new Bitmap(1, 1);
@@ -1,4 +1,5 @@
using DesktopMagic.Settings; using DesktopMagic.Helpers;
using DesktopMagic.Settings;
using System.ComponentModel; using System.ComponentModel;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
@@ -32,6 +33,23 @@ internal class MainWindowDataContext : INotifyPropertyChanged
} }
} }
public bool IsAutoStartEnabled
{
get => StartupManager.IsAutoStartEnabled();
set
{
if (value)
{
_ = StartupManager.EnableAutoStart();
}
else
{
_ = StartupManager.DisableAutoStart();
}
OnPropertyChanged();
}
}
public static DesktopMagicSettings GetSettings() public static DesktopMagicSettings GetSettings()
{ {
return settings; return settings;
@@ -1,14 +1,18 @@
using DesktopMagic.Plugins; using DesktopMagic.Helpers;
using DesktopMagic.Plugins;
using MaterialDesignThemes.Wpf;
using System; using System;
using System.ComponentModel; using System.ComponentModel;
using System.Diagnostics;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using System.Windows; using System.Windows;
using System.Windows.Input; using System.Windows.Input;
namespace DesktopMagic.DataContexts; namespace DesktopMagic.DataContexts;
internal class PluginEntryDataContext(PluginMetadata pluginMetadata, ICommand command, bool installed = false) : INotifyPropertyChanged internal class PluginEntryDataContext(PluginMetadata pluginMetadata, ICommand command, PluginEntryDataContext.Mode mode, string? path = null) : INotifyPropertyChanged
{ {
public event PropertyChangedEventHandler? PropertyChanged; public event PropertyChangedEventHandler? PropertyChanged;
@@ -18,18 +22,38 @@ internal class PluginEntryDataContext(PluginMetadata pluginMetadata, ICommand co
public string? Description => pluginMetadata.Description; public string? Description => pluginMetadata.Description;
public string Author => pluginMetadata.Author ?? (string)App.LanguageDictionary["unknown"];
public string? Version => pluginMetadata.Version ?? (string)App.LanguageDictionary["unknown"];
public string? Logo => pluginMetadata.IconUri?.ToString(); public string? Logo => pluginMetadata.IconUri?.ToString();
public DateTime? FormattedDateAdded => pluginMetadata.Added; public DateTime? DateAdded => pluginMetadata.Added;
public DateTime? FormattedDateUpdated => pluginMetadata.Updated; public DateTime? DateUpdated => pluginMetadata.Updated;
public uint Id => pluginMetadata.Id; public uint Id => pluginMetadata.Id;
public string? Path => path;
public bool IsLocalPlugin => string.IsNullOrWhiteSpace(pluginMetadata.ProfileUri?.ToString());
public ICommand Command => command; public ICommand Command => command;
public Visibility InstallButtonVisibility => installed ? Visibility.Collapsed : Visibility.Visible; public ButtonData InstallUninstallButtonData => new(mode == Mode.Install ? PackIconKind.Download : PackIconKind.Remove, GetInstallUninstallButtonText(), true, Command);
public Visibility RemoveButtonVisibility => installed ? Visibility.Visible : Visibility.Collapsed; public ButtonData OpenButtonData
{
get
{
if (string.IsNullOrWhiteSpace(pluginMetadata.ProfileUri?.ToString()))
{
return new(PackIconKind.FolderOutline, (string)App.LanguageDictionary["folder"], path is not null, new CommandHandler(() => Process.Start("explorer.exe", path!)));
}
else
{
return new(PackIconKind.ExternalLink, "mod.io", true, new CommandHandler(OpenModIoPage));
}
}
}
public bool IsVisible public bool IsVisible
{ {
@@ -44,8 +68,37 @@ internal class PluginEntryDataContext(PluginMetadata pluginMetadata, ICommand co
public Visibility Visibility => IsVisible ? Visibility.Visible : Visibility.Collapsed; public Visibility Visibility => IsVisible ? Visibility.Visible : Visibility.Collapsed;
private void OpenModIoPage()
{
ProcessStartInfo psi = new ProcessStartInfo
{
UseShellExecute = true,
FileName = pluginMetadata.ProfileUri?.ToString() ?? path
};
_ = Process.Start(psi);
}
private string GetInstallUninstallButtonText()
{
return mode switch
{
Mode.Install => (string)App.LanguageDictionary["install"],
Mode.Uninstall => (string)App.LanguageDictionary["uninstall"],
_ => throw new NotImplementedException()
};
}
private void OnPropertyChanged([CallerMemberName] string? propertyName = null) private void OnPropertyChanged([CallerMemberName] string? propertyName = null)
{ {
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
} }
public record ButtonData(PackIconKind IconKind, string Text, bool IsEnabled, ICommand Command);
public enum Mode
{
Install,
Uninstall
}
} }
@@ -12,6 +12,7 @@ internal class PluginManagerDataContext : INotifyPropertyChanged
private string installedPluginsSearchText = string.Empty; private string installedPluginsSearchText = string.Empty;
private bool isLoading = true; private bool isLoading = true;
private bool isSearching; private bool isSearching;
private bool isAuthenticated = false;
public ObservableCollection<PluginEntryDataContext> AllPlugins { get; } = []; public ObservableCollection<PluginEntryDataContext> AllPlugins { get; } = [];
public ObservableCollection<PluginEntryDataContext> InstalledPlugins { get; } = []; public ObservableCollection<PluginEntryDataContext> InstalledPlugins { get; } = [];
@@ -58,6 +59,19 @@ internal class PluginManagerDataContext : INotifyPropertyChanged
} }
} }
public bool IsAuthenticated
{
get => isAuthenticated;
set
{
isAuthenticated = value;
OnPropertyChanged();
OnPropertyChanged(nameof(LoginButtonText));
}
}
public string LoginButtonText => isAuthenticated ? (string)App.LanguageDictionary["logout"] : (string)App.LanguageDictionary["login"];
protected void OnPropertyChanged([CallerMemberName] string? name = null) protected void OnPropertyChanged([CallerMemberName] string? name = null)
{ {
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name)); PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
+64 -52
View File
@@ -1,61 +1,73 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<OutputType>WinExe</OutputType> <OutputType>WinExe</OutputType>
<UseWPF>true</UseWPF> <UseWPF>true</UseWPF>
<RootNamespace>DesktopMagic</RootNamespace> <RootNamespace>DesktopMagic</RootNamespace>
<ApplicationIcon>icon.ico</ApplicationIcon> <ApplicationIcon>icon.ico</ApplicationIcon>
<RunPostBuildEvent>OnBuildSuccess</RunPostBuildEvent> <RunPostBuildEvent>OnBuildSuccess</RunPostBuildEvent>
<Authors>Stone_Red</Authors> <Authors>Stone_Red</Authors>
<Version>1.0.0.0</Version> <Version>1.1.0.0</Version>
<PackageProjectUrl>https://github.com/Stone-Red-Code/DesktopMagic</PackageProjectUrl> <PackageProjectUrl>https://github.com/Stone-Red-Code/DesktopMagic</PackageProjectUrl>
<RepositoryUrl>https://github.com/Stone-Red-Code/DesktopMagic</RepositoryUrl> <RepositoryUrl>https://github.com/Stone-Red-Code/DesktopMagic</RepositoryUrl>
<AssemblyVersion>1.0.0.0</AssemblyVersion> <AssemblyVersion>1.1.0.0</AssemblyVersion>
<FileVersion>1.0.0.0</FileVersion> <FileVersion>1.1.0.0</FileVersion>
<TargetFramework>net8.0-windows7.0</TargetFramework> <TargetFramework>net8.0-windows7.0</TargetFramework>
<Nullable>enable</Nullable> <RuntimeIdentifier>win-x64</RuntimeIdentifier>
</PropertyGroup> <Nullable>enable</Nullable>
<IncludeSourceRevisionInInformationalVersion>false</IncludeSourceRevisionInInformationalVersion>
<Platforms>AnyCPU;x64</Platforms>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<DefineConstants>DEBUG;TRACE</DefineConstants> <DefineConstants>DEBUG;TRACE</DefineConstants>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<None Remove="icon.ico" /> <DefineConstants>DEBUG;TRACE</DefineConstants>
<None Remove="icons8_volunteering_26_85L_icon.ico" /> </PropertyGroup>
<None Remove="icon_Dark.ico" />
<None Remove="Resources\Images\modio-cog-blue.png" />
<None Remove="Resources\Images\modio-logo-bluedark.png" />
</ItemGroup>
<ItemGroup> <ItemGroup>
<Resource Include="Resources\Images\modio-cog-blue.png"> <None Remove="icon.ico" />
<CopyToOutputDirectory>Never</CopyToOutputDirectory> <None Remove="icons8_volunteering_26_85L_icon.ico" />
</Resource> <None Remove="icon_Dark.ico" />
</ItemGroup> <None Remove="Resources\Images\modio-cog-blue.png" />
<None Remove="Resources\Images\modio-logo-bluedark.png" />
</ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="AlwaysUpToDate" Version="1.0.0.4" /> <Resource Include="Resources\Images\modio-cog-blue.png">
<PackageReference Include="BusyIndicators" Version="2.1.2" /> <CopyToOutputDirectory>Never</CopyToOutputDirectory>
<PackageReference Include="Extended.Wpf.Toolkit" Version="4.5.1" /> </Resource>
<PackageReference Include="MaterialDesignThemes" Version="4.9.0" /> </ItemGroup>
<PackageReference Include="Modio.NET" Version="1.1.1" />
<PackageReference Include="NAudio" Version="2.2.1" />
<PackageReference Include="Stone_Red-C-Sharp-Utilities" Version="1.0.3.2" />
<PackageReference Include="System.Management" Version="8.0.0" />
</ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\DesktopMagicPluginAPI\DesktopMagic.Api.csproj" /> <PackageReference Include="BusyIndicators" Version="2.1.2" />
</ItemGroup> <PackageReference Include="CuteUtils" Version="1.0.0" />
<PackageReference Include="Interop.IWshRuntimeLibrary" Version="1.0.1" />
<PackageReference Include="MaterialDesignThemes" Version="5.1.0" />
<PackageReference Include="Modio" Version="1.0.0" />
<PackageReference Include="NAudio" Version="2.2.1" />
<PackageReference Include="System.Management" Version="8.0.0" />
</ItemGroup>
<ItemGroup> <ItemGroup>
<Resource Include="icon_Dark.ico"> <ProjectReference Include="..\DesktopMagicPluginAPI\DesktopMagic.Api.csproj" />
<CopyToOutputDirectory>Always</CopyToOutputDirectory> </ItemGroup>
</Resource>
<Resource Include="icon.ico"> <ItemGroup>
<CopyToOutputDirectory>Always</CopyToOutputDirectory> <Resource Include="icon_Dark.ico">
</Resource> <CopyToOutputDirectory>Always</CopyToOutputDirectory>
<Resource Include="Resources\Images\modio-logo-bluedark.png" /> </Resource>
</ItemGroup> <Resource Include="icon.ico">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Resource>
<Resource Include="Resources\Images\modio-logo-bluedark.png" />
</ItemGroup>
<ItemGroup>
<None Update="AutoStart.ps1">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project> </Project>
+4 -3
View File
@@ -8,10 +8,11 @@
mc:Ignorable="d" mc:Ignorable="d"
ResizeMode="NoResize" ResizeMode="NoResize"
Title="ColorDialog" Title="ColorDialog"
WindowStartupLocation="CenterOwner"
SizeToContent="WidthAndHeight"> SizeToContent="WidthAndHeight">
<Grid> <Grid>
<StackPanel Margin="15"> <StackPanel Margin="15">
<Label x:Name="label" Content="Label" HorizontalAlignment="Left" VerticalAlignment="Top"/> <Label x:Name="label" Content="Label" HorizontalAlignment="Left" VerticalAlignment="Top" />
<DockPanel> <DockPanel>
<Label Content="A:" Width="20" /> <Label Content="A:" Width="20" />
@@ -41,8 +42,8 @@
</TextBox> </TextBox>
</StackPanel> </StackPanel>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right" Margin="0,10,0,0"> <StackPanel Orientation="Horizontal" HorizontalAlignment="Right" Margin="0,10,0,0">
<Button x:Name="okButton" Content="{DynamicResource ok }" HorizontalAlignment="Left" Margin="0,0,10,0" VerticalAlignment="Top" Width="100" Click="OkButton_Click" Cursor="Hand"/> <Button x:Name="okButton" Content="{DynamicResource ok }" HorizontalAlignment="Left" Margin="0,0,10,0" VerticalAlignment="Top" Width="100" Click="OkButton_Click" Cursor="Hand" />
<Button x:Name="cancelButton" Content="{DynamicResource cancel }" HorizontalAlignment="Left" Margin="0,0,0,0" VerticalAlignment="Top" Width="100" Click="CancelButton_Click"/> <Button x:Name="cancelButton" Content="{DynamicResource cancel }" HorizontalAlignment="Left" Margin="0,0,0,0" VerticalAlignment="Top" Width="100" Click="CancelButton_Click" />
</StackPanel> </StackPanel>
</StackPanel> </StackPanel>
</Grid> </Grid>
+5 -21
View File
@@ -1,7 +1,5 @@
using DesktopMagic.Helpers; using DesktopMagic.Helpers;
using System;
using System.Threading;
using System.Windows; using System.Windows;
using System.Windows.Controls; using System.Windows.Controls;
using System.Windows.Media; using System.Windows.Media;
@@ -17,12 +15,14 @@ public partial class ColorDialog : Window
public Brush ResultBrush { get; private set; } = Brushes.Transparent; public Brush ResultBrush { get; private set; } = Brushes.Transparent;
public ColorDialog(string content, System.Drawing.Color defaultColor, string title = "ColorDialog") public ColorDialog(string content, System.Drawing.Color defaultColor, string title = App.AppName)
{ {
InitializeComponent(); InitializeComponent();
Resources.MergedDictionaries.Add(App.LanguageDictionary);
label.Content = content; label.Content = content;
Title = title; Title = title;
SetLanguageDictionary();
alphaSlider.Value = defaultColor.A; alphaSlider.Value = defaultColor.A;
redSlider.Value = defaultColor.R; redSlider.Value = defaultColor.R;
@@ -97,7 +97,7 @@ public partial class ColorDialog : Window
private void SetColorText() private void SetColorText()
{ {
if (alphaSlider.Value == 255) if ((int)alphaSlider.Value == 255)
{ {
colorHexTextBox.Text = "#"; colorHexTextBox.Text = "#";
} }
@@ -108,20 +108,4 @@ public partial class ColorDialog : Window
colorHexTextBox.Text += ((int)redSlider.Value).ToString("X2") + ((int)greenSlider.Value).ToString("X2") + ((int)blueSlider.Value).ToString("X2"); colorHexTextBox.Text += ((int)redSlider.Value).ToString("X2") + ((int)greenSlider.Value).ToString("X2") + ((int)blueSlider.Value).ToString("X2");
} }
private void SetLanguageDictionary()
{
ResourceDictionary dict = [];
string currentCulture = Thread.CurrentThread.CurrentCulture.ToString();
if (currentCulture.Contains("de"))
{
dict.Source = new Uri("..\\Resources\\Strings\\StringResources.de.xaml", UriKind.Relative);
}
else
{
dict.Source = new Uri("..\\Resources\\Strings\\StringResources.en.xaml", UriKind.Relative);
}
Resources.MergedDictionaries.Add(dict);
}
} }
+5 -4
View File
@@ -7,14 +7,15 @@
mc:Ignorable="d" mc:Ignorable="d"
Title="InputDialog" Title="InputDialog"
ResizeMode="NoResize" ResizeMode="NoResize"
WindowStartupLocation="CenterOwner"
SizeToContent="WidthAndHeight"> SizeToContent="WidthAndHeight">
<Grid> <Grid>
<StackPanel VerticalAlignment="Center" HorizontalAlignment="Center" Margin="15"> <StackPanel VerticalAlignment="Center" HorizontalAlignment="Center" Margin="15">
<Label x:Name="label" Content="Label" HorizontalAlignment="Left" VerticalAlignment="Top"/> <Label x:Name="label" Content="Label" HorizontalAlignment="Left" VerticalAlignment="Top" />
<TextBox x:Name="textBox" HorizontalAlignment="Left" Height="23" TextWrapping="Wrap" VerticalAlignment="Top" Width="280" VerticalContentAlignment="Center"/> <TextBox x:Name="textBox" HorizontalAlignment="Left" Height="23" TextWrapping="Wrap" VerticalAlignment="Top" Width="280" VerticalContentAlignment="Center" />
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right" Margin="0,10,0,0"> <StackPanel Orientation="Horizontal" HorizontalAlignment="Right" Margin="0,10,0,0">
<Button x:Name="okButton" Content="{DynamicResource ok }" HorizontalAlignment="Left" Margin="0,0,10,0" VerticalAlignment="Top" Width="100" Click="OkButton_Click" Cursor="Hand"/> <Button x:Name="okButton" Content="{DynamicResource ok }" HorizontalAlignment="Left" Margin="0,0,10,0" VerticalAlignment="Top" Width="100" Click="OkButton_Click" Cursor="Hand" />
<Button x:Name="cancelButton" Content="{DynamicResource cancel }" HorizontalAlignment="Left" Margin="0,0,0,0" VerticalAlignment="Top" Width="100" Click="CancelButton_Click"/> <Button x:Name="cancelButton" Content="{DynamicResource cancel }" HorizontalAlignment="Left" Margin="0,0,0,0" VerticalAlignment="Top" Width="100" Click="CancelButton_Click" />
</StackPanel> </StackPanel>
</StackPanel> </StackPanel>
</Grid> </Grid>
+5 -21
View File
@@ -1,6 +1,4 @@
using System; using System.Windows;
using System.Threading;
using System.Windows;
namespace DesktopMagic.Dialogs; namespace DesktopMagic.Dialogs;
@@ -12,12 +10,14 @@ public partial class InputDialog : Window
set => textBox.Text = value; set => textBox.Text = value;
} }
public InputDialog(string content, string title = "InputDialog") public InputDialog(string content, string title = App.AppName)
{ {
InitializeComponent(); InitializeComponent();
Resources.MergedDictionaries.Add(App.LanguageDictionary);
label.Content = content; label.Content = content;
Title = title; Title = title;
SetLanguageDictionary();
} }
private void OkButton_Click(object sender, RoutedEventArgs e) private void OkButton_Click(object sender, RoutedEventArgs e)
@@ -29,20 +29,4 @@ public partial class InputDialog : Window
{ {
DialogResult = false; DialogResult = false;
} }
private void SetLanguageDictionary()
{
ResourceDictionary dict = [];
string currentCulture = Thread.CurrentThread.CurrentCulture.ToString();
if (currentCulture.Contains("de"))
{
dict.Source = new Uri("..\\Resources\\Strings\\StringResources.de.xaml", UriKind.Relative);
}
else
{
dict.Source = new Uri("..\\Resources\\Strings\\StringResources.en.xaml", UriKind.Relative);
}
Resources.MergedDictionaries.Add(dict);
}
} }
+4
View File
@@ -8,3 +8,7 @@ using System.Diagnostics.CodeAnalysis;
[assembly: SuppressMessage("Interoperability", "CA1416:Validate platform compatibility", Justification = "Windows only application")] [assembly: SuppressMessage("Interoperability", "CA1416:Validate platform compatibility", Justification = "Windows only application")]
[assembly: SuppressMessage("Performance", "CA1822:Mark members as static", Justification = "No need to")] [assembly: SuppressMessage("Performance", "CA1822:Mark members as static", Justification = "No need to")]
[assembly: SuppressMessage("Minor Code Smell", "S1075:URIs should not be hardcoded", Justification = "<Pending>")] [assembly: SuppressMessage("Minor Code Smell", "S1075:URIs should not be hardcoded", Justification = "<Pending>")]
[assembly: SuppressMessage("Critical Code Smell", "S2696:Instance members should not write to \"static\" fields", Justification = "<Pending>", Scope = "member", Target = "~P:DesktopMagic.DataContexts.MainWindowDataContext.Settings")]
[assembly: SuppressMessage("Major Code Smell", "S3885:\"Assembly.Load\" should be used", Justification = "Assembly.Load does not load dependencies", Scope = "member", Target = "~M:DesktopMagic.PluginWindow.ExecuteSource")]
[assembly: SuppressMessage("Minor Code Smell", "S2325:Methods and properties that don't access instance data should be static", Justification = "<Pending>", Scope = "member", Target = "~M:DesktopMagic.MainWindow.OpenPluginsFolderButton_Click(System.Object,System.Windows.RoutedEventArgs)")]
[assembly: SuppressMessage("Minor Code Smell", "S2325:Methods and properties that don't access instance data should be static", Justification = "<Pending>", Scope = "member", Target = "~M:DesktopMagic.MainWindow.ScrollViewer_PreviewMouseWheel(System.Object,System.Windows.Input.MouseWheelEventArgs)")]
+93
View File
@@ -0,0 +1,93 @@
using System;
using System.IO;
using System.Runtime.InteropServices;
using System.Text;
namespace DesktopMagic.Helpers;
internal static class FileUtilities
{
public static bool ExistsOnPath(string fileName)
{
return GetFullPath(fileName) is not null;
}
public static string? GetFullPath(string fileName)
{
if (File.Exists(fileName))
{
return Path.GetFullPath(fileName);
}
string? values = Environment.GetEnvironmentVariable("PATH");
if (string.IsNullOrEmpty(values))
{
return null;
}
foreach (string path in values.Split(Path.PathSeparator))
{
string fullPath = Path.Combine(path, fileName);
if (File.Exists(fullPath))
{
return fullPath;
}
}
return null;
}
public static bool HasAssociatedProgram(string extension)
{
return GetAssociatedProgram(extension) is not null;
}
public static string? GetAssociatedProgram(string extension)
{
uint pcchOut = 0;
_ = AssocQueryString(AssocF.Verify, AssocStr.Executable, extension, null, null, ref pcchOut);
StringBuilder pszOut = new StringBuilder((int)pcchOut);
_ = AssocQueryString(AssocF.Verify, AssocStr.Executable, extension, null, pszOut, ref pcchOut);
if (File.Exists(pszOut.ToString()))
{
return pszOut.ToString();
}
return null;
}
[DllImport("Shlwapi.dll", SetLastError = true, CharSet = CharSet.Unicode)]
private static extern uint AssocQueryString(AssocF flags, AssocStr str, string pszAssoc, string? pszExtra, [Out] StringBuilder? pszOut, [In][Out] ref uint pcchOut);
[Flags]
public enum AssocF
{
Init_NoRemapCLSID = 0x1,
Init_ByExeName = 0x2,
Open_ByExeName = 0x2,
Init_DefaultToStar = 0x4,
Init_DefaultToFolder = 0x8,
NoUserSettings = 0x10,
NoTruncate = 0x20,
Verify = 0x40,
RemapRunDll = 0x80,
NoFixUps = 0x100,
IgnoreBaseClass = 0x200
}
public enum AssocStr
{
Command = 1,
Executable,
FriendlyDocName,
FriendlyAppName,
NoOpen,
ShellNewValue,
DDECommand,
DDEIfExec,
DDEApplication,
DDETopic
}
}
+1 -1
View File
@@ -47,7 +47,7 @@ internal class SampleAggregator
} }
} }
private bool IsPowerOfTwo(int x) private static bool IsPowerOfTwo(int x)
{ {
return (x & (x - 1)) == 0; return (x & (x - 1)) == 0;
} }
@@ -127,19 +127,22 @@ internal class SettingElementGenerator(ComboBox optionsComboBox)
} }
else if (settingElement.Input is DesktopMagic.Api.Settings.IntegerUpDown eIntegerUpDown) else if (settingElement.Input is DesktopMagic.Api.Settings.IntegerUpDown eIntegerUpDown)
{ {
Xceed.Wpf.Toolkit.IntegerUpDown integerUpDown = new() MaterialDesignThemes.Wpf.NumericUpDown numericUpDown = new()
{ {
Value = eIntegerUpDown.Value, Value = eIntegerUpDown.Value,
Minimum = eIntegerUpDown.Minimum, Minimum = eIntegerUpDown.Minimum,
Maximum = eIntegerUpDown.Maximum, Maximum = eIntegerUpDown.Maximum,
IncreaseContent = new Label() { Content = "+" },
DecreaseContent = new Label() { Content = "" },
VerticalAlignment = VerticalAlignment.Center, VerticalAlignment = VerticalAlignment.Center,
HorizontalAlignment = HorizontalAlignment.Stretch HorizontalAlignment = HorizontalAlignment.Stretch,
AllowChangeOnScroll = true
}; };
integerUpDown.ValueChanged += (_s, _e) => numericUpDown.ValueChanged += (_s, _e) =>
{ {
try try
{ {
eIntegerUpDown.Value = integerUpDown.Value.GetValueOrDefault(); eIntegerUpDown.Value = numericUpDown.Value;
} }
catch (Exception ex) catch (Exception ex)
{ {
@@ -148,12 +151,12 @@ internal class SettingElementGenerator(ComboBox optionsComboBox)
}; };
eIntegerUpDown.OnValueChanged += () => eIntegerUpDown.OnValueChanged += () =>
{ {
integerUpDown.Dispatcher.Invoke(() => numericUpDown.Dispatcher.Invoke(() =>
{ {
integerUpDown.Value = eIntegerUpDown.Value; numericUpDown.Value = eIntegerUpDown.Value;
}); });
}; };
_ = dockPanel.Children.Add(integerUpDown); _ = dockPanel.Children.Add(numericUpDown);
} }
else if (settingElement.Input is DesktopMagic.Api.Settings.Slider eSlider) else if (settingElement.Input is DesktopMagic.Api.Settings.Slider eSlider)
{ {
@@ -222,7 +225,7 @@ internal class SettingElementGenerator(ComboBox optionsComboBox)
private void DisplayException(string message) private void DisplayException(string message)
{ {
App.Logger.Log(message, "PluginInput"); App.Logger.LogInfo(message, source: "PluginInput");
_ = MessageBox.Show("File execution error:\n" + message, "Error", MessageBoxButton.OK, MessageBoxImage.Error); _ = MessageBox.Show("File execution error:\n" + message, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
int index = MainWindow.WindowNames.IndexOf(optionsComboBox.SelectedItem.ToString() ?? string.Empty); int index = MainWindow.WindowNames.IndexOf(optionsComboBox.SelectedItem.ToString() ?? string.Empty);
@@ -0,0 +1,82 @@
using IWshRuntimeLibrary;
using System;
using System.IO;
using System.Reflection;
using System.Windows;
namespace DesktopMagic.Helpers;
public enum AutoStartStatus
{
Success = 0,
InvalidParameters = 1,
AlreadyEnabled = 2,
AlreadyDisabled = 3,
UnexpectedError = 4
}
public static class StartupManager
{
private static readonly string appPath = Path.ChangeExtension(Assembly.GetEntryAssembly()?.Location ?? throw new InvalidOperationException("Failed to get the application path."), ".exe");
private static readonly string startupFolder = Environment.GetFolderPath(Environment.SpecialFolder.Startup);
private static readonly string shortcutPath = Path.Combine(startupFolder, Path.GetFileNameWithoutExtension(appPath) + ".lnk");
public static bool IsAutoStartEnabled()
{
return System.IO.File.Exists(shortcutPath);
}
public static AutoStartStatus EnableAutoStart()
{
if (IsAutoStartEnabled())
{
return AutoStartStatus.AlreadyEnabled;
}
try
{
WshShell shell = new WshShell();
IWshShortcut shortcut = (IWshShortcut)shell.CreateShortcut(shortcutPath);
shortcut.TargetPath = appPath;
shortcut.WorkingDirectory = Path.GetDirectoryName(appPath);
shortcut.Save();
return AutoStartStatus.Success;
}
catch
{
return AutoStartStatus.UnexpectedError;
}
}
public static AutoStartStatus DisableAutoStart()
{
if (!IsAutoStartEnabled())
{
return AutoStartStatus.AlreadyDisabled;
}
try
{
System.IO.File.Delete(shortcutPath);
return AutoStartStatus.Success;
}
catch
{
return AutoStartStatus.UnexpectedError;
}
}
public static void ToggleAutoStart()
{
AutoStartStatus status = IsAutoStartEnabled() ? DisableAutoStart() : EnableAutoStart();
_ = status switch
{
AutoStartStatus.Success => MessageBox.Show("Auto-start setting changed successfully."),
AutoStartStatus.AlreadyEnabled => MessageBox.Show("Auto-start is already enabled."),
AutoStartStatus.AlreadyDisabled => MessageBox.Show("Auto-start is already disabled."),
_ => MessageBox.Show("Failed to change auto-start setting."),
};
}
}
+1 -1
View File
@@ -1,7 +1,7 @@
using System; using System;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Text; using System.Text;
#pragma warning disable
namespace DesktopMagic.Helpers; namespace DesktopMagic.Helpers;
internal class W32 internal class W32
+1 -1
View File
@@ -3,7 +3,7 @@ using System.Runtime.InteropServices;
using System.Windows; using System.Windows;
using System.Windows.Interop; using System.Windows.Interop;
using System.Windows.Shapes; using System.Windows.Shapes;
#pragma warning disable
namespace DesktopMagic namespace DesktopMagic
{ {
using static NativeMethods; using static NativeMethods;
+38 -8
View File
@@ -20,7 +20,6 @@
MinHeight="520" MinHeight="520"
MinWidth="570" MinWidth="570"
WindowState="Minimized" WindowState="Minimized"
StateChanged="Window_StateChanged"
Loaded="Window_Loaded"> Loaded="Window_Loaded">
<busyIndicator:BusyMask x:Name="BusyIndicator" IsBusy="{Binding IsLoading}" IndicatorType="Cogs" BusyContent="Please wait..." BusyContentMargin="0,20,0,0" IsBusyAtStartup="False"> <busyIndicator:BusyMask x:Name="BusyIndicator" IsBusy="{Binding IsLoading}" IndicatorType="Cogs" BusyContent="Please wait..." BusyContentMargin="0,20,0,0" IsBusyAtStartup="False">
@@ -39,7 +38,7 @@
<DockPanel Margin="0,0,2.5,0"> <DockPanel Margin="0,0,2.5,0">
<Grid DockPanel.Dock="Top"> <Grid DockPanel.Dock="Top">
<Rectangle Grid.Row="1" Fill="#FFECECEC" Height="24" /> <Rectangle Grid.Row="1" Fill="#FFECECEC" Height="24" />
<CheckBox x:Name="EditCheckBox" VerticalAlignment="Center" Grid.Row="1" Content="{DynamicResource edit}" Click="EditCheckBox_Click" Foreground="Black" BorderBrush="#FF323232" Style="{StaticResource MaterialDesignDarkCheckBox}" IsChecked="True" /> <CheckBox x:Name="editCheckBox" VerticalAlignment="Center" Grid.Row="1" Content="{DynamicResource edit}" Click="EditCheckBox_Click" Foreground="Black" BorderBrush="#FF323232" Style="{StaticResource MaterialDesignDarkCheckBox}" IsChecked="True" />
</Grid> </Grid>
<ScrollViewer Background="#FFBBBBBB" PreviewMouseWheel="ScrollViewer_PreviewMouseWheel"> <ScrollViewer Background="#FFBBBBBB" PreviewMouseWheel="ScrollViewer_PreviewMouseWheel">
<ItemsControl ItemsSource="{Binding Settings.CurrentLayout.Plugins}"> <ItemsControl ItemsSource="{Binding Settings.CurrentLayout.Plugins}">
@@ -134,16 +133,47 @@
<Rectangle Fill="#FFC5C5C5" Stroke="#FFC5C5C5" Grid.ColumnSpan="3" /> <Rectangle Fill="#FFC5C5C5" Stroke="#FFC5C5C5" Grid.ColumnSpan="3" />
<StackPanel Margin="{StaticResource DefaultMargin}" VerticalAlignment="Bottom"> <StackPanel Margin="{StaticResource DefaultMargin}" VerticalAlignment="Bottom">
<ComboBox x:Name="layoutsComboBox" ItemsSource="{Binding Settings.Layouts}" DisplayMemberPath="Name" SelectedValue="{Binding Settings.CurrentLayoutName}" SelectedValuePath="Name" HorizontalAlignment="Left" Margin="0,0,0,5" Width="170" Height="20" SelectionChanged="LayoutsComboBox_SelectionChanged" /> <ComboBox x:Name="layoutsComboBox" ItemsSource="{Binding Settings.Layouts}" DisplayMemberPath="Name" SelectedValue="{Binding Settings.CurrentLayoutName}" SelectedValuePath="Name" HorizontalAlignment="Left" Margin="0,0,0,5" Width="170" Height="20" SelectionChanged="LayoutsComboBox_SelectionChanged" />
<Button x:Name="newLayoutButton" Content="{DynamicResource newLayout}" Margin="0,0,0,5" HorizontalAlignment="Left" VerticalAlignment="Bottom" Width="170" Click="NewLayoutButton_Click" FontWeight="Regular" /> <Button x:Name="newLayoutButton" Margin="0,0,0,5" HorizontalAlignment="Left" VerticalAlignment="Bottom" Width="170" Click="NewLayoutButton_Click" FontWeight="Regular">
<Button x:Name="removeLayoutButton" Content="{DynamicResource deleteLayout}" HorizontalAlignment="Left" VerticalAlignment="Bottom" Width="170" Click="RemoveLayoutButton_Click" FontWeight="Regular" /> <StackPanel Orientation="Horizontal">
<materialDesign:PackIcon Kind="Add" Margin="0 0 10 0" />
<TextBlock Text="{DynamicResource newLayout}" />
</StackPanel>
</Button>
<Button x:Name="removeLayoutButton" HorizontalAlignment="Left" VerticalAlignment="Bottom" Width="170" Click="RemoveLayoutButton_Click" FontWeight="Regular">
<StackPanel Orientation="Horizontal">
<materialDesign:PackIcon Kind="DeleteOutline" Margin="0 0 10 0" />
<TextBlock Text="{DynamicResource deleteLayout}" />
</StackPanel>
</Button>
</StackPanel> </StackPanel>
<StackPanel Grid.Column="1" Margin="{StaticResource DefaultMargin}" VerticalAlignment="Bottom"> <StackPanel Grid.Column="1" Margin="{StaticResource DefaultMargin}" VerticalAlignment="Bottom">
<Button x:Name="updatePluginsButton" Content="{DynamicResource updatePlugins}" Margin="0,0,0,5" HorizontalAlignment="Center" Width="170" Click="UpdatePluginsButton_Click" FontWeight="Regular" /> <Button x:Name="updatePluginsButton" Margin="0,0,0,5" HorizontalAlignment="Center" Width="170" Click="UpdatePluginsButton_Click" FontWeight="Regular">
<Button x:Name="githubButton" Content="GitHub" HorizontalAlignment="Center" Width="170" Click="GitHubButton_Click" FontWeight="Regular" Cursor="Hand" /> <StackPanel Orientation="Horizontal">
<materialDesign:PackIcon Kind="Reload" Margin="0 0 10 0" />
<TextBlock Text="{DynamicResource updatePlugins}" />
</StackPanel>
</Button>
<Button x:Name="githubButton" HorizontalAlignment="Center" Width="170" Click="GitHubButton_Click" FontWeight="Regular" Cursor="Hand">
<StackPanel Orientation="Horizontal">
<materialDesign:PackIcon Kind="Github" Margin="0 0 10 0" />
<TextBlock Text="GitHub" />
</StackPanel>
</Button>
</StackPanel> </StackPanel>
<StackPanel Grid.Column="2" Margin="{StaticResource DefaultMargin}" VerticalAlignment="Bottom"> <StackPanel Grid.Column="2" Margin="{StaticResource DefaultMargin}" VerticalAlignment="Bottom">
<Button x:Name="downloadPluginsButton" Content="{DynamicResource pluginManager}" Margin="0,0,0,5" HorizontalAlignment="Right" Width="170" Click="PluginManagerButton_Click" FontWeight="Regular" Cursor="Hand" /> <CheckBox x:Name="autoStartCheckBox" Content="{DynamicResource autoStart}" Foreground="Black" BorderBrush="#FF323232" Margin="0,0,0,5" Width="170" Height="20" Style="{StaticResource MaterialDesignDarkCheckBox}" IsChecked="{Binding IsAutoStartEnabled}" />
<Button x:Name="openPluginsFolderButton" Content="{DynamicResource openPluginsFolder}" HorizontalAlignment="Right" Width="170" Click="OpenPluginsFolderButton_Click" FontWeight="Regular" /> <Button x:Name="downloadPluginsButton" Margin="0,0,0,5" HorizontalAlignment="Right" Width="170" Click="PluginManagerButton_Click" FontWeight="Regular" Cursor="Hand">
<StackPanel Orientation="Horizontal">
<materialDesign:PackIcon Kind="ExtensionOutline" Margin="0 0 10 0" />
<TextBlock Text="{DynamicResource pluginManager}" />
</StackPanel>
</Button>
<Button x:Name="openPluginsFolderButton" HorizontalAlignment="Right" Width="170" Click="OpenPluginsFolderButton_Click" FontWeight="Regular">
<StackPanel Orientation="Horizontal">
<materialDesign:PackIcon Kind="FolderOutline" Margin="0 0 10 0" />
<TextBlock Text="{DynamicResource pluginsFolder}" />
</StackPanel>
</Button>
</StackPanel> </StackPanel>
</Grid> </Grid>
</Grid> </Grid>
+111 -107
View File
@@ -1,4 +1,4 @@
using DesktopMagic.BuiltInWindowElements; using DesktopMagic.BuiltInPlugins;
using DesktopMagic.DataContexts; using DesktopMagic.DataContexts;
using DesktopMagic.Dialogs; using DesktopMagic.Dialogs;
using DesktopMagic.Helpers; using DesktopMagic.Helpers;
@@ -10,10 +10,8 @@ using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Reflection;
using System.Text.Json; using System.Text.Json;
using System.Threading; using System.Threading;
using System.Threading.Tasks;
using System.Windows; using System.Windows;
using System.Windows.Controls; using System.Windows.Controls;
using System.Windows.Media; using System.Windows.Media;
@@ -28,17 +26,16 @@ namespace DesktopMagic
private readonly Dictionary<PluginMetadata, Type> builtInPlugins = new() private readonly Dictionary<PluginMetadata, Type> builtInPlugins = new()
{ {
{new("Music Visualizer", 1), typeof(MusicVisualizerPlugin)}, {new((string)App.LanguageDictionary["musicVisualizer"], 1), typeof(MusicVisualizerPlugin)},
{new("Time",2), typeof(TimePlugin)}, {new((string)App.LanguageDictionary["time"],2), typeof(TimePlugin)},
{new("Date",3), typeof(DatePlugin)}, {new((string)App.LanguageDictionary["date"],3), typeof(DatePlugin)},
{new("Cpu Usage", 4), typeof(CpuMonitorPlugin)} {new((string)App.LanguageDictionary["cpuUsage"], 4), typeof(CpuMonitorPlugin)}
}; };
private bool loaded = false; private bool loaded = false;
private bool blockWindowsClosing = true; private bool blockWindowsClosing = true;
public static List<PluginWindow> Windows { get; } = []; public static List<PluginWindow> Windows { get; } = [];
public static List<string> WindowNames { get; } = []; public static List<string> WindowNames { get; } = [];
internal static bool EditMode { get; set; } = false;
private DesktopMagicSettings Settings private DesktopMagicSettings Settings
{ {
@@ -53,24 +50,35 @@ namespace DesktopMagic
try try
{ {
Stream iconStream = Application.GetResourceStream(new Uri("pack://application:,,,/DesktopMagic;component/icon.ico")).Stream; Stream iconStream = Application.GetResourceStream(new Uri("pack://application:,,,/DesktopMagic;component/icon.ico")).Stream;
notifyIcon.Click += TaskbarIcon_TrayLeftClick; notifyIcon.MouseClick += NotifyIcon_MouseClick;
notifyIcon.Visible = true; notifyIcon.Visible = true;
notifyIcon.Text = App.AppName; notifyIcon.Text = App.AppName;
notifyIcon.Icon = new System.Drawing.Icon(iconStream); notifyIcon.Icon = new System.Drawing.Icon(iconStream);
notifyIcon.ContextMenuStrip = new System.Windows.Forms.ContextMenuStrip()
{
Items =
{
new System.Windows.Forms.ToolStripMenuItem((string)App.LanguageDictionary["open"], null, (s, e) => RestoreWindow()),
new System.Windows.Forms.ToolStripMenuItem((string)App.LanguageDictionary["toggleEditMode"], null, (s, e) => { editCheckBox.IsChecked = !editCheckBox.IsChecked; EditCheckBox_Click(null, null); }),
new System.Windows.Forms.ToolStripMenuItem((string)App.LanguageDictionary["pluginManager"], null, (s, e) => PluginManagerButton_Click(null!, null!)),
new System.Windows.Forms.ToolStripMenuItem("GitHub", null, (s, e) => GitHubButton_Click(null!, null!)),
new System.Windows.Forms.ToolStripMenuItem((string)App.LanguageDictionary["quit"], null, (s, e) => Quit()),
}
};
InitializeComponent(); InitializeComponent();
SetLanguageDictionary(); Resources.MergedDictionaries.Add(App.LanguageDictionary);
#if DEBUG #if DEBUG
Title = $"{App.AppName} - Dev {Assembly.GetExecutingAssembly().GetName().Version}"; Title = $"{App.AppName} - Dev {System.Windows.Forms.Application.ProductVersion}";
#else #else
Title = $"{App.AppName} - {Assembly.GetExecutingAssembly().GetName().Version}"; Title = $"{App.AppName} - {System.Windows.Forms.Application.ProductVersion}";
#endif #endif
} }
catch (Exception ex) catch (Exception ex)
{ {
_ = MessageBox.Show(ex.ToString()); _ = MessageBox.Show(ex.ToString(), App.AppName, MessageBoxButton.OK, MessageBoxImage.Error);
} }
} }
@@ -82,28 +90,22 @@ namespace DesktopMagic
{ {
try try
{ {
if (!Directory.Exists(App.ApplicationDataPath + "\\Plugins"))
{
_ = Directory.CreateDirectory(App.ApplicationDataPath + "\\Plugins");
}
App.Logger.Log("Created Plugins Folder", "Main");
//Write To Log File and Load Elements //Write To Log File and Load Elements
App.Logger.Log("Loading Plugin names", "Main"); App.Logger.LogInfo("Loading Plugin names", source: "Main");
LoadPlugins(); LoadPlugins();
App.Logger.Log("Loading Layout names", "Main"); App.Logger.LogInfo("Loading Layout names", source: "Main");
LoadSettings(); LoadSettings();
App.Logger.Log("Loading Layout", "Main"); App.Logger.LogInfo("Loading Layout", source: "Main");
LoadLayout(); LoadLayout();
loaded = true; loaded = true;
App.Logger.Log("Window Loaded", "Main"); App.Logger.LogInfo("Window Loaded", source: "Main");
} }
catch (Exception ex) catch (Exception ex)
{ {
App.Logger.Log(ex.Message, "Main", LogSeverity.Error); App.Logger.LogError(ex.Message, source: "Main");
_ = MessageBox.Show(ex.ToString()); _ = MessageBox.Show(ex.ToString(), App.AppName, MessageBoxButton.OK, MessageBoxImage.Error);
} }
} }
@@ -117,22 +119,20 @@ namespace DesktopMagic
plugins.Add(buildInPlugin.Id, new(buildInPlugin, string.Empty)); plugins.Add(buildInPlugin.Id, new(buildInPlugin, string.Empty));
} }
string pluginsPath = App.ApplicationDataPath + "\\Plugins"; foreach (string directory in Directory.GetDirectories(App.PluginsPath))
foreach (string directory in Directory.GetDirectories(pluginsPath))
{ {
string? pluginDllPath = Directory.GetFiles(directory, "main.dll").FirstOrDefault(); string? pluginDllPath = Directory.GetFiles(directory, "main.dll").FirstOrDefault();
string? pluginMetadataPath = Directory.GetFiles(directory, "metadata.json").FirstOrDefault(); string? pluginMetadataPath = Directory.GetFiles(directory, "metadata.json").FirstOrDefault();
if (pluginDllPath is null) if (pluginDllPath is null)
{ {
App.Logger.Log($"Plugin \"{directory}\" has no \"main.dll\"", "Main", LogSeverity.Error); App.Logger.LogError($"Plugin \"{directory}\" has no \"main.dll\"", source: "Main");
continue; continue;
} }
if (pluginMetadataPath is null) if (pluginMetadataPath is null)
{ {
App.Logger.Log($"Plugin \"{directory}\" has no \"metadata.json\"", "Main", LogSeverity.Warn); App.Logger.LogWarn($"Plugin \"{directory}\" has no \"metadata.json\"", source: "Main");
continue; continue;
} }
@@ -140,13 +140,13 @@ namespace DesktopMagic
if (pluginMetadata is null) if (pluginMetadata is null)
{ {
App.Logger.Log($"Plugin \"{directory}\" has no valid \"metadata.json\"", "Main", LogSeverity.Error); App.Logger.LogError($"Plugin \"{directory}\" has no valid \"metadata.json\"", source: "Main");
continue; continue;
} }
if (plugins.ContainsKey(pluginMetadata.Id)) if (plugins.ContainsKey(pluginMetadata.Id))
{ {
App.Logger.Log($"Plugin \"{directory}\" has the same id as another plugin", "Main", LogSeverity.Error); App.Logger.LogError($"Plugin \"{directory}\" has the same id as another plugin", source: "Main");
continue; continue;
} }
@@ -161,7 +161,11 @@ namespace DesktopMagic
private void EditCheckBox_Click(object? sender, RoutedEventArgs? e) private void EditCheckBox_Click(object? sender, RoutedEventArgs? e)
{ {
EditMode = EditCheckBox.IsChecked == true; foreach (PluginWindow window in Windows)
{
window.SetEditMode(editCheckBox.IsChecked == true);
}
SaveSettings(); SaveSettings();
} }
@@ -204,7 +208,7 @@ namespace DesktopMagic
} }
catch (Exception ex) catch (Exception ex)
{ {
App.Logger.Log(ex.Message, "Main", LogSeverity.Error); App.Logger.LogError(ex.Message, source: "Main");
} }
} }
return; return;
@@ -241,31 +245,26 @@ namespace DesktopMagic
window.PluginLoaded -= onPluginLoaded; window.PluginLoaded -= onPluginLoaded;
}); });
}; };
window.OnExit += () => window.OnExit += () =>
{ {
Windows.Remove(window);
WindowNames.Remove(window.Title);
blockWindowsClosing = false;
window.Close();
blockWindowsClosing = true;
pluginSettings.Enabled = false; pluginSettings.Enabled = false;
}; };
window.PluginLoaded += onPluginLoaded; window.PluginLoaded += onPluginLoaded;
window.ShowInTaskbar = false; window.ShowInTaskbar = false;
window.Show(); window.Show();
window.ContentRendered += DisplayWindow_ContentRendered; window.SetEditMode(editCheckBox.IsChecked == true);
window.Closing += DisplayWindow_Closing; window.Closing += DisplayWindow_Closing;
Windows.Add(window); Windows.Add(window);
WindowNames.Add(window.Title); WindowNames.Add(window.Title);
} }
private void DisplayWindow_ContentRendered(object? sender, EventArgs e)
{
if (sender is not Window window)
{
return;
}
WindowPos.SendWpfWindowBack(window);
WindowPos.SendWpfWindowBack(window);
}
private void DisplayWindow_Closing(object? sender, System.ComponentModel.CancelEventArgs e) private void DisplayWindow_Closing(object? sender, System.ComponentModel.CancelEventArgs e)
{ {
e.Cancel = blockWindowsClosing; e.Cancel = blockWindowsClosing;
@@ -273,9 +272,18 @@ namespace DesktopMagic
private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e) private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{ {
MessageBoxResult msbRes = MessageBox.Show((string)FindResource("wantToCloseProgram"), App.AppName, MessageBoxButton.YesNo);
e.Cancel = msbRes != MessageBoxResult.Yes;
SaveSettings(); SaveSettings();
if (blockWindowsClosing)
{
e.Cancel = true;
editCheckBox.IsChecked = false;
EditCheckBox_Click(null, null);
ShowInTaskbar = false;
WindowState = WindowState.Minimized;
Visibility = Visibility.Collapsed;
}
} }
private void Window_Closed(object sender, EventArgs e) private void Window_Closed(object sender, EventArgs e)
@@ -289,22 +297,6 @@ namespace DesktopMagic
Environment.Exit(0); Environment.Exit(0);
} }
private void Window_StateChanged(object? sender, EventArgs? e)
{
if (WindowState == WindowState.Minimized)
{
EditCheckBox.IsChecked = false;
EditCheckBox_Click(null, null);
ShowInTaskbar = false;
Visibility = Visibility.Collapsed;
foreach (Window item in Windows)
{
WindowPos.SendWpfWindowBack(item);
WindowPos.SendWpfWindowBack(item);
}
}
}
#endregion Windows #endregion Windows
#region Options #region Options
@@ -371,6 +363,24 @@ namespace DesktopMagic
} }
} }
private void Quit()
{
blockWindowsClosing = false;
Close();
}
private void OpenPluginsFolderButton_Click(object sender, RoutedEventArgs e)
{
_ = Process.Start("explorer.exe", App.PluginsPath);
}
private void ScrollViewer_PreviewMouseWheel(object sender, System.Windows.Input.MouseWheelEventArgs e)
{
ScrollViewer scv = (ScrollViewer)sender;
scv.ScrollToVerticalOffset(scv.VerticalOffset - e.Delta);
e.Handled = true;
}
private void TextBlock_Loaded(object sender, RoutedEventArgs e) private void TextBlock_Loaded(object sender, RoutedEventArgs e)
{ {
int index = 0; int index = 0;
@@ -397,7 +407,11 @@ namespace DesktopMagic
private void ChangePrimaryColorButton_Click(object sender, RoutedEventArgs e) private void ChangePrimaryColorButton_Click(object sender, RoutedEventArgs e)
{ {
ColorDialog colorDialog = new ColorDialog("Set Primary Color", Settings.CurrentLayout.Theme.PrimaryColor); ColorDialog colorDialog = new ColorDialog("Set Primary Color", Settings.CurrentLayout.Theme.PrimaryColor)
{
Owner = this
};
if (colorDialog.ShowDialog() == true) if (colorDialog.ShowDialog() == true)
{ {
Settings.CurrentLayout.Theme.PrimaryColor = colorDialog.ResultColor; Settings.CurrentLayout.Theme.PrimaryColor = colorDialog.ResultColor;
@@ -407,7 +421,11 @@ namespace DesktopMagic
private void ChangeSecondaryColorButton_Click(object sender, RoutedEventArgs e) private void ChangeSecondaryColorButton_Click(object sender, RoutedEventArgs e)
{ {
ColorDialog colorDialog = new ColorDialog("Set Secondary Color", Settings.CurrentLayout.Theme.SecondaryColor); ColorDialog colorDialog = new ColorDialog("Set Secondary Color", Settings.CurrentLayout.Theme.SecondaryColor)
{
Owner = this
};
if (colorDialog.ShowDialog() == true) if (colorDialog.ShowDialog() == true)
{ {
Settings.CurrentLayout.Theme.SecondaryColor = colorDialog.ResultColor; Settings.CurrentLayout.Theme.SecondaryColor = colorDialog.ResultColor;
@@ -417,7 +435,11 @@ namespace DesktopMagic
private void ChangeBackgroundColorButton_Click(object sender, RoutedEventArgs e) private void ChangeBackgroundColorButton_Click(object sender, RoutedEventArgs e)
{ {
ColorDialog colorDialog = new ColorDialog("Set Background Color", Settings.CurrentLayout.Theme.BackgroundColor); ColorDialog colorDialog = new ColorDialog("Set Background Color", Settings.CurrentLayout.Theme.BackgroundColor)
{
Owner = this
};
if (colorDialog.ShowDialog() == true) if (colorDialog.ShowDialog() == true)
{ {
Settings.CurrentLayout.Theme.BackgroundColor = colorDialog.ResultColor; Settings.CurrentLayout.Theme.BackgroundColor = colorDialog.ResultColor;
@@ -474,12 +496,16 @@ namespace DesktopMagic
private void NewLayoutButton_Click(object sender, RoutedEventArgs e) private void NewLayoutButton_Click(object sender, RoutedEventArgs e)
{ {
InputDialog inputDialog = new((string)FindResource("enterLayoutName")); InputDialog inputDialog = new((string)FindResource("enterLayoutName"))
{
Owner = this
};
if (inputDialog.ShowDialog() == true) if (inputDialog.ShowDialog() == true)
{ {
if (Settings.Layouts.Any(l => l.Name.Trim() == inputDialog.ResponseText.Trim())) if (Settings.Layouts.Any(l => l.Name.Trim() == inputDialog.ResponseText.Trim()))
{ {
_ = MessageBox.Show((string)FindResource("layoutAlreadyExists")); _ = MessageBox.Show((string)FindResource("layoutAlreadyExists"), App.AppName, MessageBoxButton.OK, MessageBoxImage.Warning);
return; return;
} }
@@ -551,8 +577,8 @@ namespace DesktopMagic
window.Close(); window.Close();
} }
EditCheckBox.IsChecked = false; editCheckBox.IsChecked = false;
EditMode = false; EditCheckBox_Click(null, null);
blockWindowsClosing = true; blockWindowsClosing = true;
Windows.Clear(); Windows.Clear();
WindowNames.Clear(); WindowNames.Clear();
@@ -599,14 +625,13 @@ namespace DesktopMagic
if (!showWindow && minimize) if (!showWindow && minimize)
{ {
WindowState = WindowState.Minimized; Close();
Window_StateChanged(null, null);
} }
else else
{ {
WindowState = WindowState.Normal; RestoreWindow();
Window_StateChanged(null, null);
} }
mainWindowDataContext.IsLoading = false; mainWindowDataContext.IsLoading = false;
} }
@@ -618,21 +643,12 @@ namespace DesktopMagic
LoadLayout(false); LoadLayout(false);
} }
private void OpenPluginsFolderButton_Click(object sender, RoutedEventArgs e) private void NotifyIcon_MouseClick(object? sender, System.Windows.Forms.MouseEventArgs e)
{ {
_ = Process.Start("explorer.exe", App.ApplicationDataPath + "\\Plugins"); if (e.Button == System.Windows.Forms.MouseButtons.Left)
} {
RestoreWindow();
private void ScrollViewer_PreviewMouseWheel(object sender, System.Windows.Input.MouseWheelEventArgs e) }
{
ScrollViewer scv = (ScrollViewer)sender;
scv.ScrollToVerticalOffset(scv.VerticalOffset - e.Delta);
e.Handled = true;
}
private void TaskbarIcon_TrayLeftClick(object? sender, EventArgs e)
{
RestoreWindow();
} }
private void GitHubButton_Click(object sender, RoutedEventArgs e) private void GitHubButton_Click(object sender, RoutedEventArgs e)
@@ -648,26 +664,14 @@ namespace DesktopMagic
private void PluginManagerButton_Click(object sender, RoutedEventArgs e) private void PluginManagerButton_Click(object sender, RoutedEventArgs e)
{ {
PluginManager pluginManager = new PluginManager(); PluginManager pluginManager = new PluginManager
{
Owner = this
};
pluginManager.ShowDialog(); pluginManager.ShowDialog();
LoadPlugins(); LoadPlugins();
LoadLayout(false); LoadLayout(Visibility != Visibility.Visible);
}
private void SetLanguageDictionary()
{
ResourceDictionary dict = [];
string currentCulture = Thread.CurrentThread.CurrentUICulture.ToString();
if (currentCulture.Contains("de"))
{
dict.Source = new Uri("..\\Resources\\Strings\\StringResources.de.xaml", UriKind.Relative);
}
else
{
dict.Source = new Uri("..\\Resources\\Strings\\StringResources.en.xaml", UriKind.Relative);
}
Resources.MergedDictionaries.Add(dict);
} }
} }
-43
View File
@@ -1,43 +0,0 @@
<UserControl x:Class="DesktopMagic.Plugins.ModEntry"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
xmlns:local="clr-namespace:DesktopMagic.Plugins"
xmlns:dataContext="clr-namespace:DesktopMagic.DataContexts"
d:DataContext="{d:DesignInstance Type=dataContext:PluginEntryDataContext}"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800"
Background="{DynamicResource MaterialDesignPaper}"
FontFamily="{DynamicResource MaterialDesignFont}"
Visibility="{Binding Visibility}">
<Grid Background="White" Margin="10">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Border HorizontalAlignment="Left" Width="100" Height="100" BorderThickness="1" BorderBrush="LightGray">
<Image Source="{Binding Logo, FallbackValue={StaticResource ModioCogBlue}, TargetNullValue={StaticResource ModioCogBlue}}" Width="100" Height="100" />
</Border>
<StackPanel Grid.Column="1" HorizontalAlignment="Stretch">
<Label Content="{Binding FormattedDateAdded}" HorizontalAlignment="Center" ContentStringFormat="Added: {0}" />
<Label Content="{Binding FormattedDateUpdated}" HorizontalAlignment="Center" ContentStringFormat="Updated: {0}" />
<Button Command="{Binding Command}" Visibility="{Binding InstallButtonVisibility}" HorizontalAlignment="Stretch" Margin="10" Content="Install" />
<Button Command="{Binding Command}" Visibility="{Binding RemoveButtonVisibility}" HorizontalAlignment="Stretch" Margin="10" Content="Remove" />
</StackPanel>
<StackPanel Grid.Row="1" Grid.ColumnSpan="2">
<Label Content="{Binding Name}" FontSize="20" />
<TextBlock Text="{Binding Description}" TextWrapping="Wrap" />
</StackPanel>
</Grid>
</UserControl>
+63
View File
@@ -0,0 +1,63 @@
<UserControl x:Class="DesktopMagic.Plugins.ModEntry"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
xmlns:local="clr-namespace:DesktopMagic.Plugins"
xmlns:dataContext="clr-namespace:DesktopMagic.DataContexts"
d:DataContext="{d:DesignInstance Type=dataContext:PluginEntryDataContext}"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800"
Background="{DynamicResource MaterialDesignPaper}"
FontFamily="{DynamicResource MaterialDesignFont}"
Visibility="{Binding Visibility}">
<Grid Background="White" Margin="10">
<Grid.RowDefinitions>
<RowDefinition Height="2*" />
<RowDefinition Height="auto" />
<RowDefinition Height="3*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Border HorizontalAlignment="Center" Margin="10" Width="100" Height="100" BorderThickness="1" BorderBrush="LightGray">
<Image Source="{Binding Logo, FallbackValue={StaticResource ModioCogBlue}, TargetNullValue={StaticResource ModioCogBlue}}" Width="100" Height="100" />
</Border>
<StackPanel Grid.Column="1" VerticalAlignment="Center">
<Label Content="{Binding Author}" HorizontalAlignment="Center" ContentStringFormat="{DynamicResource authorFormat}" />
<Label Content="{Binding DateAdded}" HorizontalAlignment="Center" ContentStringFormat="{DynamicResource addedFormat}" />
<Label Content="{Binding DateUpdated}" HorizontalAlignment="Center" ContentStringFormat="{DynamicResource updatedFormat}" />
<Label Content="{Binding Version}" HorizontalAlignment="Center" ContentStringFormat="{DynamicResource versionFormat}" />
</StackPanel>
<Grid Grid.Row="1" Grid.ColumnSpan="2">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Button Grid.Column="0" Command="{Binding InstallUninstallButtonData.Command}" IsEnabled="{Binding InstallUninstallButtonData.IsEnabled}" VerticalAlignment="Bottom" HorizontalAlignment="Stretch" Margin="10 5 5 0">
<StackPanel Orientation="Horizontal">
<materialDesign:PackIcon Kind="{Binding InstallUninstallButtonData.IconKind}" Margin="0 0 10 0" />
<TextBlock Text="{Binding InstallUninstallButtonData.Text}" />
</StackPanel>
</Button>
<Button Grid.Column="1" Command="{Binding OpenButtonData.Command}" IsEnabled="{Binding OpenButtonData.IsEnabled}" VerticalAlignment="Bottom" HorizontalAlignment="Stretch" Margin="5 5 10 0">
<StackPanel Orientation="Horizontal">
<materialDesign:PackIcon Kind="{Binding OpenButtonData.IconKind}" Margin="0 0 10 0" />
<TextBlock Text="{Binding OpenButtonData.Text}" />
</StackPanel>
</Button>
</Grid>
<StackPanel Grid.Row="2" Grid.ColumnSpan="2" Margin="10">
<Label Content="{Binding Name}" FontSize="20" Padding="0" />
<TextBlock Text="{Binding Description}" TextWrapping="Wrap" />
</StackPanel>
</Grid>
</UserControl>
@@ -1,6 +1,7 @@
using System.Windows.Controls; using System.Windows.Controls;
namespace DesktopMagic.Plugins; namespace DesktopMagic.Plugins;
/// <summary> /// <summary>
/// Interaction logic for ModEntry.xaml /// Interaction logic for ModEntry.xaml
/// </summary> /// </summary>
+45 -29
View File
@@ -9,7 +9,7 @@
xmlns:dataContexts="clr-namespace:DesktopMagic.DataContexts" xmlns:dataContexts="clr-namespace:DesktopMagic.DataContexts"
mc:Ignorable="d" mc:Ignorable="d"
d:DataContext="{d:DesignInstance Type=dataContexts:PluginManagerDataContext}" d:DataContext="{d:DesignInstance Type=dataContexts:PluginManagerDataContext}"
Title="PluginManager" Title="{DynamicResource pluginManager}"
Height="450" Height="450"
Width="800" Width="800"
MinHeight="520" MinHeight="520"
@@ -31,7 +31,7 @@
<ColumnDefinition /> <ColumnDefinition />
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<Label Content="All plugins" FontSize="20" /> <Label Content="{DynamicResource allPlugins}" FontSize="20" />
<TextBox Grid.Row="1" Text="{Binding AllPluginsSearchText, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" TextChanged="AllPluginsSearchTextBox_TextChanged" materialDesign:HintAssist.Hint="Search..." materialDesign:TextFieldAssist.HasLeadingIcon="True" materialDesign:TextFieldAssist.LeadingIcon="Search" /> <TextBox Grid.Row="1" Text="{Binding AllPluginsSearchText, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" TextChanged="AllPluginsSearchTextBox_TextChanged" materialDesign:HintAssist.Hint="Search..." materialDesign:TextFieldAssist.HasLeadingIcon="True" materialDesign:TextFieldAssist.LeadingIcon="Search" />
@@ -52,7 +52,7 @@
<Setter Property="Template"> <Setter Property="Template">
<Setter.Value> <Setter.Value>
<ControlTemplate> <ControlTemplate>
<TextBlock Text="No plugins found!" FontSize="20" VerticalAlignment="Center" HorizontalAlignment="Center"/> <TextBlock Text="No plugins found!" FontSize="20" VerticalAlignment="Center" HorizontalAlignment="Center" />
</ControlTemplate> </ControlTemplate>
</Setter.Value> </Setter.Value>
</Setter> </Setter>
@@ -64,37 +64,53 @@
</ScrollViewer> </ScrollViewer>
</busyIndicator:BusyMask> </busyIndicator:BusyMask>
<Label Grid.Column="1" Content="Installed plugins" FontSize="20" /> <Label Grid.Column="1" Content="{DynamicResource installedPlugins}" FontSize="20" />
<TextBox Grid.Row="1" Grid.Column="1" Text="{Binding InstalledPluginsSearchText, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" TextChanged="InstalledPluginsSearchTextBox_TextChanged" materialDesign:HintAssist.Hint="Search..." materialDesign:TextFieldAssist.HasLeadingIcon="True" materialDesign:TextFieldAssist.LeadingIcon="Search" /> <TextBox Grid.Row="1" Grid.Column="1" Text="{Binding InstalledPluginsSearchText, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" TextChanged="InstalledPluginsSearchTextBox_TextChanged" materialDesign:HintAssist.Hint="Search..." materialDesign:TextFieldAssist.HasLeadingIcon="True" materialDesign:TextFieldAssist.LeadingIcon="Search" />
<ItemsControl Grid.Row="2" Grid.Column="1" ItemsSource="{Binding InstalledPlugins}"> <ScrollViewer Grid.Row="2" Grid.Column="1" VerticalScrollBarVisibility="Auto">
<ItemsControl.ItemTemplate> <ItemsControl ItemsSource="{Binding InstalledPlugins}">
<DataTemplate> <ItemsControl.ItemTemplate>
<Border BorderBrush="LightGray" BorderThickness="1"> <DataTemplate>
<local:ModEntry /> <Border BorderBrush="LightGray" BorderThickness="1">
</Border> <local:ModEntry />
</DataTemplate> </Border>
</ItemsControl.ItemTemplate> </DataTemplate>
<ItemsControl.Style> </ItemsControl.ItemTemplate>
<Style TargetType="ItemsControl"> <ItemsControl.Style>
<Style.Triggers> <Style TargetType="ItemsControl">
<Trigger Property="HasItems" Value="false"> <Style.Triggers>
<Setter Property="Template"> <Trigger Property="HasItems" Value="false">
<Setter.Value> <Setter Property="Template">
<ControlTemplate> <Setter.Value>
<TextBlock Text="No plugins found!" FontSize="20" VerticalAlignment="Center" HorizontalAlignment="Center"/> <ControlTemplate>
</ControlTemplate> <TextBlock Text="No plugins found!" FontSize="20" VerticalAlignment="Center" HorizontalAlignment="Center" />
</Setter.Value> </ControlTemplate>
</Setter> </Setter.Value>
</Trigger> </Setter>
</Style.Triggers> </Trigger>
</Style> </Style.Triggers>
</ItemsControl.Style> </Style>
</ItemsControl> </ItemsControl.Style>
</ItemsControl>
</ScrollViewer>
<Border Grid.Row="3" Grid.ColumnSpan="2" Padding="0 5 0 0" BorderThickness="0 2 0 0" BorderBrush="DarkGray"> <Border Grid.Row="3" Grid.ColumnSpan="2" Padding="0 5 0 0" BorderThickness="0 2 0 0" BorderBrush="DarkGray">
<Image Source="{StaticResource ModioLogoBlueDark}" Cursor="Hand" Height="30" MouseUp="Image_MouseUp" HorizontalAlignment="Left" /> <DockPanel>
<Image Source="{StaticResource ModioLogoBlueDark}" Cursor="Hand" Height="30" MouseUp="Image_MouseUp" HorizontalAlignment="Left" />
<Button DockPanel.Dock="Right" HorizontalAlignment="Right" Click="LogInButton_Click">
<StackPanel Orientation="Horizontal">
<materialDesign:PackIcon Kind="Login" Margin="0 0 10 0" />
<TextBlock Text="{Binding LoginButtonText}" />
</StackPanel>
</Button>
<Button DockPanel.Dock="Right" HorizontalAlignment="Right" Margin="0 0 10 0" Click="CreatePluginButton_Click">
<StackPanel Orientation="Horizontal">
<materialDesign:PackIcon Kind="Add" Margin="0 0 10 0" />
<TextBlock Text="{DynamicResource createNewPlugin}" />
</StackPanel>
</Button>
</DockPanel>
</Border> </Border>
</Grid> </Grid>
</busyIndicator:BusyMask> </busyIndicator:BusyMask>
+338 -18
View File
@@ -1,22 +1,26 @@
using DesktopMagic.DataContexts; using DesktopMagic.DataContexts;
using DesktopMagic.Dialogs;
using DesktopMagic.Helpers; using DesktopMagic.Helpers;
using Modio.NET; using Modio;
using Modio.NET.Filters; using Modio.Filters;
using Modio.NET.Models; using Modio.Models;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel; using System.ComponentModel;
using System.Diagnostics; using System.Diagnostics;
using System.Globalization;
using System.IO; using System.IO;
using System.IO.Compression; using System.IO.Compression;
using System.Linq; using System.Linq;
using System.Net.Http; using System.Net.Http;
using System.Text.Json; using System.Text.Json;
using System.Text.RegularExpressions;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Windows; using System.Windows;
using System.Windows.Threading; using System.Windows.Threading;
using System.Xml.Linq;
using File = System.IO.File; using File = System.IO.File;
using Path = System.IO.Path; using Path = System.IO.Path;
@@ -28,20 +32,36 @@ namespace DesktopMagic.Plugins;
/// </summary> /// </summary>
public partial class PluginManager : Window public partial class PluginManager : Window
{ {
private const int modIoGameId = 5665; private const int ModIoGameId = 5665;
private readonly Client client = new Client(new Credentials("88e6ea774c3a502b06114e7fee0829ac")); private const string ModIoApiKey = "88e6ea774c3a502b06114e7fee0829ac";
private readonly HttpClient httpClient = new(); private readonly HttpClient httpClient = new();
private readonly PluginManagerDataContext pluginManagerDataContext = new(); private readonly PluginManagerDataContext pluginManagerDataContext = new();
private readonly string pluginsPath = Path.Combine(App.ApplicationDataPath, "Plugins"); private readonly string pluginsPath = Path.Combine(App.ApplicationDataPath, "Plugins");
private readonly string pluginDevelopmentPath = Path.Combine(App.ApplicationDataPath, "PluginDevelopment");
private readonly DispatcherTimer searchTimer = new() private readonly DispatcherTimer searchTimer = new()
{ {
Interval = TimeSpan.FromMilliseconds(300), Interval = TimeSpan.FromMilliseconds(300),
}; };
private Client modIoClient;
public PluginManager() public PluginManager()
{ {
Resources.MergedDictionaries.Add(App.LanguageDictionary);
string? modIoAccessToken = MainWindowDataContext.GetSettings().ModIoAccessToken;
if (modIoAccessToken is null)
{
modIoClient = new Client(new Credentials(ModIoApiKey));
}
else
{
modIoClient = new Client(new Credentials(ModIoApiKey, modIoAccessToken));
pluginManagerDataContext.IsAuthenticated = true;
}
InitializeComponent(); InitializeComponent();
DataContext = pluginManagerDataContext; DataContext = pluginManagerDataContext;
@@ -52,20 +72,33 @@ public partial class PluginManager : Window
}; };
} }
public void Remove(string pluginPath, uint? id) public async Task Remove(string pluginPath, uint id)
{ {
pluginManagerDataContext.IsLoading = true; pluginManagerDataContext.IsLoading = true;
PluginEntryDataContext? pluginEntryDataContext = pluginManagerDataContext.InstalledPlugins.FirstOrDefault(p => p.Id == id); PluginEntryDataContext? pluginEntryDataContext = pluginManagerDataContext.InstalledPlugins.FirstOrDefault(p => p.Id == id);
if (Directory.Exists(pluginPath))
{
try
{
Directory.Delete(pluginPath, true);
}
catch (Exception ex)
{
_ = MessageBox.Show(ex.Message, "Plugin Manager", MessageBoxButton.OK, MessageBoxImage.Error);
App.Logger.LogError(ex.Message, source: "PluginManager");
}
}
if (pluginEntryDataContext is not null) if (pluginEntryDataContext is not null)
{ {
_ = pluginManagerDataContext.InstalledPlugins.Remove(pluginEntryDataContext); _ = pluginManagerDataContext.InstalledPlugins.Remove(pluginEntryDataContext);
} }
if (Directory.Exists(pluginPath)) if (pluginManagerDataContext.IsAuthenticated)
{ {
Directory.Delete(pluginPath, true); await modIoClient.Games[ModIoGameId].Mods.Unsubscribe(id);
} }
pluginManagerDataContext.IsLoading = false; pluginManagerDataContext.IsLoading = false;
@@ -85,18 +118,18 @@ public partial class PluginManager : Window
continue; continue;
} }
PluginMetadata? pluginMetadata = JsonSerializer.Deserialize<PluginMetadata>(File.ReadAllText(pluginMetadataPath)); PluginMetadata? pluginMetadata = JsonSerializer.Deserialize<PluginMetadata>(await File.ReadAllTextAsync(pluginMetadataPath));
if (pluginMetadata is not null) if (pluginMetadata is not null)
{ {
pluginManagerDataContext.InstalledPlugins.Add(new PluginEntryDataContext(pluginMetadata, new CommandHandler(() => Remove(pluginPath, pluginMetadata.Id)), true)); pluginManagerDataContext.InstalledPlugins.Add(new PluginEntryDataContext(pluginMetadata, new CommandHandler(async () => await Remove(pluginPath, pluginMetadata.Id)), PluginEntryDataContext.Mode.Uninstall, pluginPath));
_ = pluginIds.Add(pluginMetadata.Id); _ = pluginIds.Add(pluginMetadata.Id);
} }
} }
Filter filter = ModFilter.Popular.Desc().Limit(100); Filter filter = ModFilter.Popular.Desc().Limit(100);
IAsyncEnumerable<Mod> mods = client.Games[modIoGameId].Mods.Search(filter).ToEnumerableAsync(); IAsyncEnumerable<Mod> mods = modIoClient.Games[ModIoGameId].Mods.Search(filter).ToEnumerable();
await foreach (Mod mod in mods) await foreach (Mod mod in mods)
{ {
if (pluginIds.Contains(mod.Id)) if (pluginIds.Contains(mod.Id))
@@ -104,9 +137,11 @@ public partial class PluginManager : Window
continue; continue;
} }
pluginManagerDataContext.AllPlugins.Add(new PluginEntryDataContext(new(mod), new CommandHandler(async () => await Install(mod)))); pluginManagerDataContext.AllPlugins.Add(new PluginEntryDataContext(new(mod), new CommandHandler(async () => await Install(mod)), PluginEntryDataContext.Mode.Install));
} }
await SyncPlugins();
pluginManagerDataContext.IsLoading = false; pluginManagerDataContext.IsLoading = false;
} }
@@ -115,6 +150,9 @@ public partial class PluginManager : Window
e.Cancel = pluginManagerDataContext.IsLoading; e.Cancel = pluginManagerDataContext.IsLoading;
} }
[GeneratedRegex(@"[^a-zA-Z0-9]")]
private static partial Regex IdentifierNameRegex();
private async Task Install(Mod mod) private async Task Install(Mod mod)
{ {
pluginManagerDataContext.IsLoading = true; pluginManagerDataContext.IsLoading = true;
@@ -141,13 +179,13 @@ public partial class PluginManager : Window
} }
string pluginMetadataPath = Path.Combine(pluginPath, "metadata.json"); string pluginMetadataPath = Path.Combine(pluginPath, "metadata.json");
File.WriteAllText(pluginMetadataPath, JsonSerializer.Serialize(new PluginMetadata(mod))); await File.WriteAllTextAsync(pluginMetadataPath, JsonSerializer.Serialize(new PluginMetadata(mod)));
File.Delete(zipFilePath); File.Delete(zipFilePath);
if (!File.Exists(Path.Combine(pluginPath, "main.dll"))) if (!File.Exists(Path.Combine(pluginPath, "main.dll")))
{ {
Remove(pluginPath, mod.Id); _ = Remove(pluginPath, mod.Id);
pluginManagerDataContext.IsLoading = false; pluginManagerDataContext.IsLoading = false;
_ = MessageBox.Show("The plugin you are trying to install does not contain a \"main.dll\" file. Please contact the plugin author.", "Plugin Manager", MessageBoxButton.OK, MessageBoxImage.Error); _ = MessageBox.Show("The plugin you are trying to install does not contain a \"main.dll\" file. Please contact the plugin author.", "Plugin Manager", MessageBoxButton.OK, MessageBoxImage.Error);
return; return;
@@ -160,7 +198,12 @@ public partial class PluginManager : Window
_ = pluginManagerDataContext.AllPlugins.Remove(pluginEntryDataContext); _ = pluginManagerDataContext.AllPlugins.Remove(pluginEntryDataContext);
} }
pluginManagerDataContext.InstalledPlugins.Add(new PluginEntryDataContext(new PluginMetadata(mod), new CommandHandler(() => Remove(pluginPath, mod.Id)), true)); if (pluginManagerDataContext.IsAuthenticated)
{
await modIoClient.Games[ModIoGameId].Mods.Subscribe(mod.Id);
}
pluginManagerDataContext.InstalledPlugins.Add(new PluginEntryDataContext(new PluginMetadata(mod), new CommandHandler(async () => await Remove(pluginPath, mod.Id)), PluginEntryDataContext.Mode.Uninstall, pluginPath));
pluginManagerDataContext.IsLoading = false; pluginManagerDataContext.IsLoading = false;
} }
@@ -212,7 +255,7 @@ public partial class PluginManager : Window
Filter filter = ModFilter.Name.Like($"{searchString}").And(ModFilter.Popular.Desc()).Limit(100); Filter filter = ModFilter.Name.Like($"{searchString}").And(ModFilter.Popular.Desc()).Limit(100);
IAsyncEnumerable<Mod> mods = client.Games[modIoGameId].Mods.Search(filter).ToEnumerableAsync(); IAsyncEnumerable<Mod> mods = modIoClient.Games[ModIoGameId].Mods.Search(filter).ToEnumerable();
await foreach (Mod mod in mods) await foreach (Mod mod in mods)
{ {
if (pluginManagerDataContext.InstalledPlugins.Any(p => p.Id == mod.Id)) if (pluginManagerDataContext.InstalledPlugins.Any(p => p.Id == mod.Id))
@@ -220,9 +263,286 @@ public partial class PluginManager : Window
continue; continue;
} }
pluginManagerDataContext.AllPlugins.Add(new PluginEntryDataContext(new(mod), new CommandHandler(async () => await Install(mod)))); pluginManagerDataContext.AllPlugins.Add(new PluginEntryDataContext(new(mod), new CommandHandler(async () => await Install(mod)), PluginEntryDataContext.Mode.Install));
} }
pluginManagerDataContext.IsSearching = false; pluginManagerDataContext.IsSearching = false;
} }
private void CreatePluginButton_Click(object sender, RoutedEventArgs e)
{
try
{
CreateNewPlugin();
}
catch (Exception ex)
{
App.Logger.LogError(ex.Message, source: "PluginManager");
_ = MessageBox.Show(ex.Message, "Plugin Manager", MessageBoxButton.OK, MessageBoxImage.Error);
}
}
private void CreateNewPlugin()
{
if (!FileUtilities.ExistsOnPath("dotnet.exe"))
{
_ = MessageBox.Show("The .NET SDK is required to create a plugin. Please install it and try again.", "Plugin Manager", MessageBoxButton.OK, MessageBoxImage.Error);
return;
}
string pluginGuid = Guid.NewGuid().ToString();
string pluginPath = Path.Combine(pluginsPath, pluginGuid);
uint pluginId = (uint)Random.Shared.Next(1000, 9999);
InputDialog inputDialog = new((string)FindResource("enterPluginName"), "Plugin Manager")
{
Owner = this,
};
if (inputDialog.ShowDialog() != true)
{
return;
}
string pluginName = inputDialog.ResponseText;
string pluginSafeName = pluginName.ToLower().Replace("_", " ");
TextInfo info = CultureInfo.CurrentCulture.TextInfo;
pluginSafeName = info.ToTitleCase(pluginSafeName);
pluginSafeName = IdentifierNameRegex().Replace(pluginSafeName, "");
if (!Directory.Exists(pluginDevelopmentPath))
{
_ = Directory.CreateDirectory(pluginDevelopmentPath);
}
string pluginProjectPath = Path.Combine(pluginDevelopmentPath, pluginSafeName);
if (Directory.Exists(pluginProjectPath))
{
_ = MessageBox.Show("A plugin with the same name already exists. Please choose a different name.", "Plugin Manager", MessageBoxButton.OK, MessageBoxImage.Error);
return;
}
PluginMetadata pluginMetadata = new(pluginName, pluginId);
_ = Directory.CreateDirectory(pluginPath);
_ = Directory.CreateDirectory(pluginProjectPath);
string pluginMetadataPath = Path.Combine(pluginPath, "metadata.json");
File.WriteAllText(pluginMetadataPath, JsonSerializer.Serialize(pluginMetadata));
string cmd = $"new classlib -n {pluginSafeName} -o {pluginProjectPath} -f net8.0 --target-framework-override net8.0-windows7";
Process process = Process.Start("dotnet", cmd);
process.WaitForExit();
// Install the required NuGet packages
process = Process.Start("dotnet", $"add {pluginProjectPath} package DesktopMagic.Api");
process.WaitForExit();
File.Move(Path.Combine(pluginProjectPath, "Class1.cs"), Path.Combine(pluginProjectPath, $"{pluginSafeName}.cs"));
string code = $@"using DesktopMagic.Api;
using System.Drawing;
namespace {pluginSafeName};
public class {pluginSafeName}Plugin : Plugin
{{
public override Bitmap Main()
{{
Bitmap bmp = new Bitmap(2000, 1000);
using (Graphics g = Graphics.FromImage(bmp))
{{
g.Clear(Application.Theme.PrimaryColor); // Set the background color to the color specified in the DesktopMagic application.
g.DrawString(""Hello World"", new Font(Application.Theme.Font, 100), Brushes.Black, new PointF(0, 0)); // Draw ""Hello World"" to the image.
}}
bmp.SetResolution(300, 300); // Set DPI to avoid scaling issues.
return bmp; // Return the image.
}}
}}
";
// Update the .csproj file
string csprojPath = Path.Combine(pluginProjectPath, $"{pluginSafeName}.csproj");
File.WriteAllText(Path.Combine(pluginProjectPath, $"{pluginSafeName}.cs"), code);
XDocument doc = XDocument.Load(csprojPath);
XElement? propertyGroup = doc.Root?.Element("PropertyGroup");
if (propertyGroup is not null)
{
XElement? outputPathElement = propertyGroup.Element("OutputPath");
if (outputPathElement is not null)
{
outputPathElement.Value = pluginPath;
}
else
{
propertyGroup.Add(new XElement("OutputPath", pluginPath));
}
XElement? appendTargetFrameworkToOutputPathElement = propertyGroup.Element("AppendTargetFrameworkToOutputPath");
if (appendTargetFrameworkToOutputPathElement is not null)
{
appendTargetFrameworkToOutputPathElement.Value = "false";
}
else
{
propertyGroup.Add(new XElement("AppendTargetFrameworkToOutputPath", "false"));
}
XElement? targetNameElement = propertyGroup.Element("TargetName");
if (targetNameElement is not null)
{
targetNameElement.Value = "main";
}
else
{
propertyGroup.Add(new XElement("TargetName", "main"));
}
doc.Save(csprojPath);
}
else
{
_ = MessageBox.Show("PropertyGroup element not found in .csproj", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
return;
}
// Open the project in the default IDE
string? associatedProgram = FileUtilities.GetAssociatedProgram(".csproj");
if (associatedProgram is null)
{
_ = Process.Start("explorer.exe", pluginProjectPath);
return;
}
ProcessStartInfo psi = new ProcessStartInfo
{
FileName = associatedProgram,
Arguments = csprojPath,
};
_ = Process.Start(psi);
}
private async void LogInButton_Click(object sender, RoutedEventArgs e)
{
if (pluginManagerDataContext.IsAuthenticated)
{
MainWindowDataContext.GetSettings().ModIoAccessToken = null;
pluginManagerDataContext.IsAuthenticated = false;
return;
}
try
{
InputDialog inputDialog = new((string)FindResource("enterModIoEmail"), "Plugin Manager")
{
Owner = this,
};
if (inputDialog.ShowDialog() != true)
{
return;
}
await modIoClient.Auth.RequestCode(ModIoApiKey, inputDialog.ResponseText);
inputDialog = new((string)FindResource("enterModIoAccessToken"), "Plugin Manager")
{
Owner = this,
};
if (inputDialog.ShowDialog() != true)
{
return;
}
pluginManagerDataContext.IsLoading = true;
AccessToken accessToken = await modIoClient.Auth.SecurityCode(ModIoApiKey, inputDialog.ResponseText);
if (accessToken.Value is not null)
{
modIoClient = new Client(new Credentials(ModIoApiKey, accessToken.Value));
}
MainWindowDataContext.GetSettings().ModIoAccessToken = accessToken.Value;
pluginManagerDataContext.IsAuthenticated = true;
foreach (PluginEntryDataContext plugin in pluginManagerDataContext.InstalledPlugins)
{
if (!plugin.IsLocalPlugin)
{
try
{
await modIoClient.Games[ModIoGameId].Mods.Subscribe(plugin.Id);
}
catch (Exception ex)
{
App.Logger.LogError(ex.Message, source: "PluginManager");
}
}
}
await SyncPlugins();
}
catch (Exception ex)
{
App.Logger.LogError(ex.Message, source: "PluginManager");
_ = MessageBox.Show(ex.Message, "Plugin Manager", MessageBoxButton.OK, MessageBoxImage.Error);
}
pluginManagerDataContext.IsLoading = false;
}
private async Task SyncPlugins()
{
if (!pluginManagerDataContext.IsAuthenticated)
{
return;
}
IReadOnlyList<Mod> mods = await modIoClient.User.GetSubscriptions(ModFilter.GameId.Eq(ModIoGameId)).ToList();
List<PluginEntryDataContext> pluginsToRemove = [];
foreach (PluginEntryDataContext plugin in pluginManagerDataContext.InstalledPlugins)
{
if (!plugin.IsLocalPlugin && !mods.Any(m => m.Id == plugin.Id))
{
pluginsToRemove.Add(plugin);
}
}
foreach (PluginEntryDataContext plugin in pluginsToRemove)
{
if (plugin.Path is null)
{
continue;
}
await Remove(plugin.Path, plugin.Id);
}
IEnumerable<Mod> notInstalledMods = mods.Where(m => !pluginManagerDataContext.InstalledPlugins.Any(p => p.Id == m.Id));
foreach (Mod mod in notInstalledMods)
{
await Install(mod);
}
}
} }
+8 -2
View File
@@ -1,4 +1,4 @@
using Modio.NET.Models; using Modio.Models;
using System; using System;
using System.Text.Json.Serialization; using System.Text.Json.Serialization;
@@ -7,7 +7,7 @@ namespace DesktopMagic.Plugins;
public class PluginMetadata public class PluginMetadata
{ {
public string Name { get; set; } public string Name { get; set; } = string.Empty;
public uint Id { get; set; } public uint Id { get; set; }
@@ -15,12 +15,16 @@ public class PluginMetadata
public Uri? IconUri { get; set; } public Uri? IconUri { get; set; }
public Uri? ProfileUri { get; set; }
public DateTime? Added { get; set; } public DateTime? Added { get; set; }
public DateTime? Updated { get; set; } public DateTime? Updated { get; set; }
public string? Description { get; set; } public string? Description { get; set; }
public string? Summary { get; set; }
public string? Version { get; set; } public string? Version { get; set; }
public PluginMetadata(Mod mod) public PluginMetadata(Mod mod)
@@ -29,9 +33,11 @@ public class PluginMetadata
Id = mod.Id; Id = mod.Id;
Author = mod.SubmittedBy?.Username; Author = mod.SubmittedBy?.Username;
IconUri = mod.Logo?.Thumb320x180; IconUri = mod.Logo?.Thumb320x180;
ProfileUri = mod.ProfileUrl;
Added = DateTimeOffset.FromUnixTimeSeconds(mod.DateAdded).DateTime; Added = DateTimeOffset.FromUnixTimeSeconds(mod.DateAdded).DateTime;
Updated = DateTimeOffset.FromUnixTimeSeconds(mod.DateUpdated).DateTime; Updated = DateTimeOffset.FromUnixTimeSeconds(mod.DateUpdated).DateTime;
Description = mod.DescriptionPlaintext; Description = mod.DescriptionPlaintext;
Summary = mod.Summary;
Version = mod.Modfile?.Version; Version = mod.Modfile?.Version;
} }
+2 -2
View File
@@ -17,8 +17,8 @@
<Grid> <Grid>
<Rectangle x:Name="panel" Fill="#4CBAFFEF" Stroke="White" Margin="0,0,0,0" Visibility="Collapsed" /> <Rectangle x:Name="panel" Fill="#4CBAFFEF" Stroke="White" Margin="0,0,0,0" Visibility="Collapsed" />
<Border x:Name="border" /> <Border SizeChanged="Border_SizeChanged" x:Name="border" />
<Viewbox x:Name="viewBox" StretchDirection="Both" Stretch="Uniform"> <Viewbox SizeChanged="ViewBox_SizeChanged" x:Name="viewBox" StretchDirection="Both" Stretch="Uniform">
<Viewbox.Clip> <Viewbox.Clip>
<RectangleGeometry x:Name="rectangleGeometry" RadiusX="{Binding ElementName=border, Path=CornerRadius.TopLeft}" RadiusY="{Binding ElementName=border, Path=CornerRadius.TopLeft}" /> <RectangleGeometry x:Name="rectangleGeometry" RadiusX="{Binding ElementName=border, Path=CornerRadius.TopLeft}" RadiusY="{Binding ElementName=border, Path=CornerRadius.TopLeft}" />
</Viewbox.Clip> </Viewbox.Clip>
+78 -76
View File
@@ -28,14 +28,13 @@ public partial class PluginWindow : Window
public event Action? OnExit; public event Action? OnExit;
private readonly PluginSettings settings; private readonly PluginSettings settings;
private readonly System.Timers.Timer? updateTimer;
private Thread? pluginThread; private Thread? pluginThread;
private System.Timers.Timer? valueTimer; private System.Timers.Timer? updateTimer;
private Plugin? pluginClassInstance; private Plugin? pluginClassInstance;
public bool IsRunning { get; private set; } = true; public bool IsRunning { get; private set; } = true;
public PluginMetadata PluginMetadata { get; private set; } public PluginMetadata PluginMetadata { get; private set; }
public string? PluginFolderPath { get; private set; } public string PluginFolderPath { get; private set; }
public PluginWindow(PluginMetadata pluginMetadata, PluginSettings settings, string pluginFolderPath) public PluginWindow(PluginMetadata pluginMetadata, PluginSettings settings, string pluginFolderPath)
{ {
@@ -51,16 +50,13 @@ public partial class PluginWindow : Window
WindowStyle = WindowStyle.ToolWindow, WindowStyle = WindowStyle.ToolWindow,
ShowInTaskbar = false ShowInTaskbar = false
}; };
w.Show();
Owner = w;
w.Hide();
updateTimer = new System.Timers.Timer WindowInteropHelper helper = new WindowInteropHelper(w);
{ _ = helper.EnsureHandle();
Interval = 100
}; Owner = w;
updateTimer.Elapsed += UpdateTimer_Elapsed;
updateTimer.Start(); settings.Theme.PropertyChanged += (e, s) => ThemeChanged();
PluginMetadata = pluginMetadata; PluginMetadata = pluginMetadata;
this.settings = settings; this.settings = settings;
@@ -80,7 +76,8 @@ public partial class PluginWindow : Window
public void UpdatePluginWindow() public void UpdatePluginWindow()
{ {
ValueTimer_Elapsed(valueTimer, null); Dispatcher.Invoke(ThemeChanged);
UpdateTimer_Elapsed(updateTimer, null);
} }
public void Exit() public void Exit()
@@ -93,6 +90,32 @@ public partial class PluginWindow : Window
}); });
} }
public void SetEditMode(bool enabled)
{
if (enabled)
{
Topmost = true;
panel.Visibility = Visibility.Visible;
imageBorder.BorderThickness = new Thickness(3);
image.Margin = new(-3);
WindowPos.SetIsLocked(this, false);
tileBar.CaptionHeight = tileBar.CaptionHeight = ActualHeight - 10 < 0 ? 0 : ActualHeight - 10;
ResizeMode = ResizeMode.CanResize;
}
else
{
Topmost = false;
panel.Visibility = Visibility.Collapsed;
imageBorder.BorderThickness = new Thickness(0);
image.Margin = new Thickness(0);
WindowPos.SendWpfWindowBack(this);
WindowPos.SendWpfWindowBack(this);
WindowPos.SetIsLocked(this, true);
tileBar.CaptionHeight = 0;
ResizeMode = ResizeMode.NoResize;
}
}
protected override void OnSourceInitialized(EventArgs e) protected override void OnSourceInitialized(EventArgs e)
{ {
base.OnSourceInitialized(e); base.OnSourceInitialized(e);
@@ -121,62 +144,25 @@ public partial class PluginWindow : Window
private void Window_ContentRendered(object? sender, EventArgs e) private void Window_ContentRendered(object? sender, EventArgs e)
{ {
App.Logger.Log($"\"{PluginMetadata.Name}\" - Starting plugin thread", "Plugin"); App.Logger.LogInfo($"\"{PluginMetadata.Name}\" - Starting plugin thread", source: "Plugin");
pluginThread = new Thread(LoadPlugin); pluginThread = new Thread(LoadPlugin);
pluginThread.Start(); pluginThread.Start();
} }
private void UpdateTimer_Elapsed(object? sender, ElapsedEventArgs e) private void ThemeChanged()
{ {
Dispatcher.Invoke(() => viewBox.Margin = new Thickness(settings.Theme.Margin);
{ border.Background = new SolidColorBrush(MultiColorConverter.ConvertToMediaColor(settings.Theme.BackgroundColor));
if (MainWindow.EditMode) border.CornerRadius = new CornerRadius(settings.Theme.CornerRadius);
{
panel.Visibility = Visibility.Visible;
imageBorder.BorderThickness = new Thickness(3);
image.Margin = new(-3);
WindowPos.SetIsLocked(this, false);
tileBar.CaptionHeight = tileBar.CaptionHeight = ActualHeight - 10 < 0 ? 0 : ActualHeight - 10;
ResizeMode = ResizeMode.CanResize;
}
else
{
panel.Visibility = Visibility.Collapsed;
imageBorder.BorderThickness = new Thickness(0);
image.Margin = new Thickness(0);
WindowPos.SetIsLocked(this, true);
tileBar.CaptionHeight = 0;
ResizeMode = ResizeMode.NoResize;
}
if (!IsRunning)
{
(sender as System.Timers.Timer)?.Stop();
}
else
{
viewBox.Margin = new Thickness(settings.Theme.Margin);
border.Width = viewBox.ActualWidth + (settings.Theme.Margin * 2);
border.Height = viewBox.ActualHeight + (settings.Theme.Margin * 2);
rectangleGeometry.Rect = new Rect(-settings.Theme.Margin, -settings.Theme.Margin, border.ActualWidth, border.ActualHeight);
border.Background = new SolidColorBrush(MultiColorConverter.ConvertToMediaColor(settings.Theme.BackgroundColor));
border.CornerRadius = new CornerRadius(settings.Theme.CornerRadius);
}
});
if (!IsRunning)
{
updateTimer?.Stop();
}
} }
private void LoadPlugin() private void LoadPlugin()
{ {
App.Logger.Log($"\"{PluginMetadata.Name}\" - Loading plugin", "Plugin"); App.Logger.LogInfo($"\"{PluginMetadata.Name}\" - Loading plugin", source: "Plugin");
if (pluginClassInstance is null && !File.Exists($"{PluginFolderPath}\\main.dll")) if (pluginClassInstance is null && !File.Exists($"{PluginFolderPath}\\main.dll"))
{ {
App.Logger.Log($"\"{PluginMetadata.Name}\" - File \"main.dll\" does not exist", "Plugin", LogSeverity.Error); App.Logger.LogError($"\"{PluginMetadata.Name}\" - File \"main.dll\" does not exist", source: "Plugin");
_ = MessageBox.Show("File \"main.dll\" does not exist!", $"Error \"{PluginMetadata.Name}\"", MessageBoxButton.OK, MessageBoxImage.Error); _ = MessageBox.Show("File \"main.dll\" does not exist!", $"Error \"{PluginMetadata.Name}\"", MessageBoxButton.OK, MessageBoxImage.Error);
Exit(); Exit();
@@ -189,7 +175,7 @@ public partial class PluginWindow : Window
} }
catch (Exception ex) catch (Exception ex)
{ {
App.Logger.Log($"\"{PluginMetadata.Name}\" - {ex}", "Plugin", LogSeverity.Error); App.Logger.LogError($"\"{PluginMetadata.Name}\" - {ex}", source: "Plugin");
_ = MessageBox.Show("File execution error:\n" + ex, $"Error \"{PluginMetadata.Name}\"", MessageBoxButton.OK, MessageBoxImage.Error); _ = MessageBox.Show("File execution error:\n" + ex, $"Error \"{PluginMetadata.Name}\"", MessageBoxButton.OK, MessageBoxImage.Error);
Exit(); Exit();
return; return;
@@ -202,13 +188,12 @@ public partial class PluginWindow : Window
object? instance = pluginClassInstance; object? instance = pluginClassInstance;
if (instance is null) if (instance is null)
{ {
byte[] assemblyBytes = File.ReadAllBytes($"{PluginFolderPath}\\main.dll"); Assembly dll = Assembly.LoadFrom($"{PluginFolderPath}\\main.dll");
Assembly dll = Assembly.Load(assemblyBytes);
Type? instanceType = Array.Find(dll.GetTypes(), type => type.GetTypeInfo().BaseType == typeof(Plugin)); Type? instanceType = Array.Find(dll.GetTypes(), type => type.GetTypeInfo().BaseType == typeof(Plugin));
if (instanceType is null) if (instanceType is null)
{ {
App.Logger.Log($"\"{PluginMetadata.Name}\" - The \"Plugin\" class could not be found! It has to inherit from \"{typeof(Plugin).FullName}\"", "Plugin", LogSeverity.Error); App.Logger.LogError($"\"{PluginMetadata.Name}\" - The \"Plugin\" class could not be found! It has to inherit from \"{typeof(Plugin).FullName}\"", source: "Plugin");
_ = MessageBox.Show($"The \"Plugin\" class could not be found! It has to inherit from \"{typeof(Plugin).FullName}\"", $"Error \"{PluginMetadata.Name}\"", MessageBoxButton.OK, MessageBoxImage.Error); _ = MessageBox.Show($"The \"Plugin\" class could not be found! It has to inherit from \"{typeof(Plugin).FullName}\"", $"Error \"{PluginMetadata.Name}\"", MessageBoxButton.OK, MessageBoxImage.Error);
Exit(); Exit();
@@ -224,7 +209,7 @@ public partial class PluginWindow : Window
} }
else else
{ {
App.Logger.Log($"\"{PluginMetadata.Name}\" - The \"Plugin\" class could not be found! It has to inherit from \"{typeof(Plugin).FullName}\"", "Plugin", LogSeverity.Error); App.Logger.LogError($"\"{PluginMetadata.Name}\" - The \"Plugin\" class could not be found! It has to inherit from \"{typeof(Plugin).FullName}\"", source: "Plugin");
_ = MessageBox.Show($"The \"Plugin\" class has to inherit from \"{typeof(Plugin).FullName}\"", $"Error \"{PluginMetadata.Name}\"", MessageBoxButton.OK, MessageBoxImage.Error); _ = MessageBox.Show($"The \"Plugin\" class has to inherit from \"{typeof(Plugin).FullName}\"", $"Error \"{PluginMetadata.Name}\"", MessageBoxButton.OK, MessageBoxImage.Error);
Exit(); Exit();
return; return;
@@ -233,19 +218,19 @@ public partial class PluginWindow : Window
LoadOptions(pluginClassInstance); LoadOptions(pluginClassInstance);
BindDefaultSettings(pluginClassInstance); BindDefaultSettings(pluginClassInstance);
valueTimer = new System.Timers.Timer updateTimer = new System.Timers.Timer
{ {
Interval = 1000 Interval = 1000
}; };
valueTimer.Elapsed += ValueTimer_Elapsed; updateTimer.Elapsed += UpdateTimer_Elapsed;
pluginClassInstance.Start(); pluginClassInstance.Start();
UpdatePluginWindow(); UpdatePluginWindow();
if (pluginClassInstance.UpdateInterval > 0) if (pluginClassInstance.UpdateInterval > 0)
{ {
valueTimer.Interval = pluginClassInstance.UpdateInterval; updateTimer.Interval = pluginClassInstance.UpdateInterval;
valueTimer.Start(); updateTimer.Start();
} }
} }
@@ -262,30 +247,36 @@ public partial class PluginWindow : Window
void SetVerticalAlignment() void SetVerticalAlignment()
{ {
viewBox.VerticalAlignment = pluginClassInstance.verticalAlignment.Value switch VerticalAlignment verticalAlignment = pluginClassInstance.verticalAlignment.Value switch
{ {
"Top" => VerticalAlignment.Top, "Top" => VerticalAlignment.Top,
"Center" => VerticalAlignment.Center, "Center" => VerticalAlignment.Center,
"Bottom" => VerticalAlignment.Bottom, "Bottom" => VerticalAlignment.Bottom,
_ => VerticalAlignment.Center _ => VerticalAlignment.Center
}; };
viewBox.VerticalAlignment = verticalAlignment;
border.VerticalAlignment = verticalAlignment;
} }
void SetHorizontalAlignment() void SetHorizontalAlignment()
{ {
viewBox.HorizontalAlignment = pluginClassInstance.horizontalAlignment.Value switch HorizontalAlignment horizontalAlignment = pluginClassInstance.horizontalAlignment.Value switch
{ {
"Left" => HorizontalAlignment.Left, "Left" => HorizontalAlignment.Left,
"Center" => HorizontalAlignment.Center, "Center" => HorizontalAlignment.Center,
"Right" => HorizontalAlignment.Right, "Right" => HorizontalAlignment.Right,
_ => HorizontalAlignment.Center _ => HorizontalAlignment.Center
}; };
viewBox.HorizontalAlignment = horizontalAlignment;
border.HorizontalAlignment = horizontalAlignment;
} }
} }
private void LoadOptions(object instance) private void LoadOptions(object instance)
{ {
App.Logger.Log($"\"{PluginMetadata.Name}\" - Loading plugin options", "Plugin"); App.Logger.LogInfo($"\"{PluginMetadata.Name}\" - Loading plugin options", source: "Plugin");
try try
{ {
@@ -323,13 +314,13 @@ public partial class PluginWindow : Window
catch (Exception ex) catch (Exception ex)
{ {
IsRunning = false; IsRunning = false;
App.Logger.Log($"\"{PluginMetadata.Name}\" - {ex}", "Plugin", LogSeverity.Error); App.Logger.LogError($"\"{PluginMetadata.Name}\" - {ex}", source: "Plugin");
_ = MessageBox.Show("File execution error:\n" + ex, $"Error \"{PluginMetadata.Name}\"", MessageBoxButton.OK, MessageBoxImage.Error); _ = MessageBox.Show("File execution error:\n" + ex, $"Error \"{PluginMetadata.Name}\"", MessageBoxButton.OK, MessageBoxImage.Error);
Exit(); Exit();
} }
} }
private void ValueTimer_Elapsed(object? sender, ElapsedEventArgs? e) private void UpdateTimer_Elapsed(object? sender, ElapsedEventArgs? e)
{ {
try try
{ {
@@ -339,11 +330,11 @@ public partial class PluginWindow : Window
if (pluginClassInstance.UpdateInterval > 0) if (pluginClassInstance.UpdateInterval > 0)
{ {
valueTimer!.Interval = pluginClassInstance.UpdateInterval; updateTimer!.Interval = pluginClassInstance.UpdateInterval;
} }
else else
{ {
valueTimer!.Stop(); updateTimer!.Stop();
} }
if (result is not null) if (result is not null)
@@ -368,7 +359,7 @@ public partial class PluginWindow : Window
catch (Exception ex) catch (Exception ex)
{ {
IsRunning = false; IsRunning = false;
App.Logger.Log($"\"{PluginMetadata.Name}\" - {ex}", "Plugin", LogSeverity.Error); App.Logger.LogError($"\"{PluginMetadata.Name}\" - {ex}", source: "Plugin");
_ = MessageBox.Show("File execution error:\n" + ex, $"Error \"{PluginMetadata.Name}\"", MessageBoxButton.OK, MessageBoxImage.Error); _ = MessageBox.Show("File execution error:\n" + ex, $"Error \"{PluginMetadata.Name}\"", MessageBoxButton.OK, MessageBoxImage.Error);
Exit(); Exit();
return; return;
@@ -376,13 +367,24 @@ public partial class PluginWindow : Window
if (!IsRunning) if (!IsRunning)
{ {
valueTimer!.Stop(); updateTimer!.Stop();
} }
} }
private void Border_SizeChanged(object sender, SizeChangedEventArgs e)
{
rectangleGeometry.Rect = new Rect(-settings.Theme.Margin, -settings.Theme.Margin, e.NewSize.Width, e.NewSize.Height);
}
private void ViewBox_SizeChanged(object sender, SizeChangedEventArgs e)
{
border.Width = e.NewSize.Width + (settings.Theme.Margin * 2);
border.Height = e.NewSize.Height + (settings.Theme.Margin * 2);
}
private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e) private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{ {
App.Logger.Log($"\"{PluginMetadata.Name}\" - Stopping plugin", "Plugin"); App.Logger.LogInfo($"\"{PluginMetadata.Name}\" - Stopping plugin", source: "Plugin");
IsRunning = false; IsRunning = false;
pluginClassInstance?.Stop(); pluginClassInstance?.Stop();
} }
@@ -5,9 +5,23 @@
<system:String x:Key="lineMode">Linie</system:String> <system:String x:Key="lineMode">Linie</system:String>
<system:String x:Key="mirrorMode">Spiegeln</system:String> <system:String x:Key="mirrorMode">Spiegeln</system:String>
<system:String x:Key="folder">Ordner</system:String>
<system:String x:Key="autoStart">Starten beim Hochfahren</system:String>
<system:String x:Key="unknown">Unbekannt</system:String>
<system:String x:Key="open">Öffnen</system:String>
<system:String x:Key="quit">Schließen</system:String>
<system:String x:Key="login">Einloggen</system:String>
<system:String x:Key="logout">Ausloggen</system:String>
<system:String x:Key="enterModIoEmail">Mod.io Account E-Mail eingeben</system:String>
<system:String x:Key="enterModIoAccessToken">Geben Sie Ihren mod.io Sicherheitscode ein</system:String>
<system:String x:Key="toggleEditMode">Bearbeitungsmodus umschalten</system:String>
<system:String x:Key="allPlugins">Alle Plugins</system:String>
<system:String x:Key="installedPlugins">Installierte Plugins</system:String>
<system:String x:Key="updatePlugins">Neu Laden</system:String> <system:String x:Key="updatePlugins">Neu Laden</system:String>
<system:String x:Key="openPluginsFolder">Plugins Ordner Öffnen</system:String> <system:String x:Key="pluginsFolder">Plugins Ordner</system:String>
<system:String x:Key="pluginManager">Plugin Manager</system:String> <system:String x:Key="pluginManager">Plugins Manager</system:String>
<system:String x:Key="createNewPlugin">Neues Plugin erstellen</system:String>
<system:String x:Key="enterPluginName">Pluginnamen eingeben</system:String>
<system:String x:Key="color">Farbe:</system:String> <system:String x:Key="color">Farbe:</system:String>
<system:String x:Key="default">Standard</system:String> <system:String x:Key="default">Standard</system:String>
<system:String x:Key="wantToCloseProgram">Wollen sie das Programm wirklich schließen?</system:String> <system:String x:Key="wantToCloseProgram">Wollen sie das Programm wirklich schließen?</system:String>
@@ -16,9 +30,7 @@
<system:String x:Key="time">Uhrzeit</system:String> <system:String x:Key="time">Uhrzeit</system:String>
<system:String x:Key="date">Datum</system:String> <system:String x:Key="date">Datum</system:String>
<system:String x:Key="cpuUsage">CPU Auslastung</system:String> <system:String x:Key="cpuUsage">CPU Auslastung</system:String>
<system:String x:Key="googleCalendar">Google Kalender</system:String> <system:String x:Key="musicVisualizer">Musik Visualisierer</system:String>
<system:String x:Key="musicVisualizer">Musik Visualizer</system:String>
<system:String x:Key="musicVisualizerOptions">Musik Visualizer Einstellungen:</system:String>
<system:String x:Key="amplifier">Signalverstärkung:</system:String> <system:String x:Key="amplifier">Signalverstärkung:</system:String>
<system:String x:Key="newLayout">Neues Layout</system:String> <system:String x:Key="newLayout">Neues Layout</system:String>
<system:String x:Key="deleteLayout">Layout Löschen</system:String> <system:String x:Key="deleteLayout">Layout Löschen</system:String>
@@ -27,7 +39,12 @@
<system:String x:Key="enterLayoutName">Layoutnamen eingeben:</system:String> <system:String x:Key="enterLayoutName">Layoutnamen eingeben:</system:String>
<system:String x:Key="layoutAlreadyExists">Layout existiert bereits!</system:String> <system:String x:Key="layoutAlreadyExists">Layout existiert bereits!</system:String>
<system:String x:Key="install">Installieren</system:String> <system:String x:Key="install">Installieren</system:String>
<system:String x:Key="uninstall">Deinstallieren</system:String>
<system:String x:Key="remove">Entfernen</system:String> <system:String x:Key="remove">Entfernen</system:String>
<system:String x:Key="authorFormat">Author: {0}</system:String>
<system:String x:Key="addedFormat">Erstellt: {0}</system:String>
<system:String x:Key="updatedFormat">Aktualisiert: {0}</system:String>
<system:String x:Key="versionFormat">Version: {0}</system:String>
<col:ArrayList x:Key="musicVisualizerOptionsComboboxItems"> <col:ArrayList x:Key="musicVisualizerOptionsComboboxItems">
<system:String>Unten</system:String> <system:String>Unten</system:String>
<system:String>Mitte</system:String> <system:String>Mitte</system:String>
@@ -5,9 +5,23 @@
<system:String x:Key="lineMode">Line</system:String> <system:String x:Key="lineMode">Line</system:String>
<system:String x:Key="mirrorMode">Mirror</system:String> <system:String x:Key="mirrorMode">Mirror</system:String>
<system:String x:Key="folder">Folder</system:String>
<system:String x:Key="autoStart">Launch on startup</system:String>
<system:String x:Key="unknown">Unknown</system:String>
<system:String x:Key="open">Open</system:String>
<system:String x:Key="quit">Quit</system:String>
<system:String x:Key="login">Log In</system:String>
<system:String x:Key="logout">Log Out</system:String>
<system:String x:Key="enterModIoEmail">Enter your mod.io account E-mail</system:String>
<system:String x:Key="enterModIoAccessToken">Enter your mod.io security code</system:String>
<system:String x:Key="toggleEditMode">Toggle Edit Mode</system:String>
<system:String x:Key="allPlugins">All Plugins</system:String>
<system:String x:Key="installedPlugins">Installed Plugins</system:String>
<system:String x:Key="updatePlugins">Reload</system:String> <system:String x:Key="updatePlugins">Reload</system:String>
<system:String x:Key="openPluginsFolder">Open Plugins Folder</system:String> <system:String x:Key="pluginsFolder">Plugins Folder</system:String>
<system:String x:Key="pluginManager">Plugin Manager</system:String> <system:String x:Key="pluginManager">Plugins Manager</system:String>
<system:String x:Key="createNewPlugin">Create New Plugin</system:String>
<system:String x:Key="enterPluginName">Enter plugin name</system:String>
<system:String x:Key="color">Color:</system:String> <system:String x:Key="color">Color:</system:String>
<system:String x:Key="default">Default</system:String> <system:String x:Key="default">Default</system:String>
<system:String x:Key="wantToCloseProgram">Do you really want to close the program?</system:String> <system:String x:Key="wantToCloseProgram">Do you really want to close the program?</system:String>
@@ -16,9 +30,7 @@
<system:String x:Key="time">Time</system:String> <system:String x:Key="time">Time</system:String>
<system:String x:Key="date">Date</system:String> <system:String x:Key="date">Date</system:String>
<system:String x:Key="cpuUsage">CPU Usage</system:String> <system:String x:Key="cpuUsage">CPU Usage</system:String>
<system:String x:Key="googleCalendar">Google Calendar</system:String>
<system:String x:Key="musicVisualizer">Music Visualizer</system:String> <system:String x:Key="musicVisualizer">Music Visualizer</system:String>
<system:String x:Key="musicVisualizerOptions">Music Visualizer Options:</system:String>
<system:String x:Key="amplifier">Signal Amplification:</system:String> <system:String x:Key="amplifier">Signal Amplification:</system:String>
<system:String x:Key="newLayout">New Layout</system:String> <system:String x:Key="newLayout">New Layout</system:String>
<system:String x:Key="deleteLayout">Delete Layout</system:String> <system:String x:Key="deleteLayout">Delete Layout</system:String>
@@ -27,7 +39,12 @@
<system:String x:Key="enterLayoutName">Enter layout name</system:String> <system:String x:Key="enterLayoutName">Enter layout name</system:String>
<system:String x:Key="layoutAlreadyExists">Layout already exists!</system:String> <system:String x:Key="layoutAlreadyExists">Layout already exists!</system:String>
<system:String x:Key="install">Install</system:String> <system:String x:Key="install">Install</system:String>
<system:String x:Key="uninstall">Uninstall</system:String>
<system:String x:Key="remove">Remove</system:String> <system:String x:Key="remove">Remove</system:String>
<system:String x:Key="authorFormat">Author: {0}</system:String>
<system:String x:Key="addedFormat">Added: {0}</system:String>
<system:String x:Key="updatedFormat">Updated: {0}</system:String>
<system:String x:Key="versionFormat">Version: {0}</system:String>
<col:ArrayList x:Key="musicVisualizerOptionsComboboxItems"> <col:ArrayList x:Key="musicVisualizerOptionsComboboxItems">
<system:String>Bottom</system:String> <system:String>Bottom</system:String>
<system:String>Middle</system:String> <system:String>Middle</system:String>
@@ -37,6 +37,8 @@ internal class DesktopMagicSettings : INotifyPropertyChanged
} }
} }
public string? ModIoAccessToken { get; set; }
protected void OnPropertyChanged([CallerMemberName] string? name = null) protected void OnPropertyChanged([CallerMemberName] string? name = null)
{ {
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name)); PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
@@ -3,6 +3,7 @@
<PropertyGroup> <PropertyGroup>
<TargetFramework>net8.0-windows</TargetFramework> <TargetFramework>net8.0-windows</TargetFramework>
<OutputType>Library</OutputType> <OutputType>Library</OutputType>
<Platforms>AnyCPU;x64</Platforms>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<TargetFramework>net8.0-windows</TargetFramework> <TargetFramework>net8.0-windows</TargetFramework>
@@ -12,25 +12,34 @@
<PackageProjectUrl></PackageProjectUrl> <PackageProjectUrl></PackageProjectUrl>
<FileVersion>0.0.0.5</FileVersion> <FileVersion>0.0.0.5</FileVersion>
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
<Platforms>AnyCPU;x64</Platforms>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<DocumentationFile>C:\Users\David\Programmieren\DesktopMagic\src\DesktopMagicPluginAPI\DesktopMagicPluginAPI.xml</DocumentationFile> <DocumentationFile>$([System.IO.Path]::Combine($(MSBuildProjectDirectory), "DesktopMagicPluginAPI.xml"))</DocumentationFile>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<DocumentationFile>$([System.IO.Path]::Combine($(MSBuildProjectDirectory), "DesktopMagicPluginAPI.xml"))</DocumentationFile>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
<DocumentationFile>C:\Users\David\Programmieren\DesktopMagic\src\DesktopMagicPluginAPI\DesktopMagicPluginAPI.xml</DocumentationFile> <DocumentationFile>$([System.IO.Path]::Combine($(MSBuildProjectDirectory), "DesktopMagicPluginAPI.xml"))</DocumentationFile>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<DocumentationFile>$([System.IO.Path]::Combine($(MSBuildProjectDirectory), "DesktopMagicPluginAPI.xml"))</DocumentationFile>
</PropertyGroup>
<ItemGroup>
<None Include="..\..\LICENSE">
<Pack>True</Pack>
<PackagePath>\</PackagePath>
</None>
</ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="System.Drawing.Common" Version="8.0.0" /> <PackageReference Include="System.Drawing.Common" Version="8.0.0" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<None Include="..\..\LICENSE">
<Pack>True</Pack>
<PackagePath></PackagePath>
</None>
</ItemGroup>
</Project> </Project>
@@ -1,4 +1,5 @@
using System.Collections.Generic; using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis; using System.Diagnostics.CodeAnalysis;
using System.Drawing; using System.Drawing;
@@ -6,14 +7,21 @@ namespace DesktopMagic.Api.Drawing;
internal class FontComparer : IEqualityComparer<Font> internal class FontComparer : IEqualityComparer<Font>
{ {
public bool Equals(Font font1, Font font2) private const float Tolerance = 0.01f;
public bool Equals(Font? font1, Font? font2)
{ {
if (font1 is null || font2 is null)
{
return false;
}
if (font1.Name != font2.Name) if (font1.Name != font2.Name)
{ {
return false; return false;
} }
if (font1.SizeInPoints != font2.SizeInPoints) if (Math.Abs(font1.SizeInPoints - font2.SizeInPoints) > Tolerance)
{ {
return false; return false;
} }
-21
View File
@@ -1,21 +0,0 @@
MIT License
Copyright (c) 2021 Stone_Red
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+3 -3
View File
@@ -11,16 +11,16 @@ namespace DesktopMagic.Api;
/// </summary> /// </summary>
public abstract class Plugin public abstract class Plugin
{ {
[Setting("horizontalAlignment", "Horizontal Alignment", -999)] [Setting("desktopmagic-horizontal-alignment", "Horizontal Alignment", -999)]
internal ComboBox horizontalAlignment = new ComboBox("Center", "Left", "Right"); internal ComboBox horizontalAlignment = new ComboBox("Center", "Left", "Right");
[Setting("verticalAlignment", "Vertical Alignment", -998)] [Setting("desktopmagic-vertical-alignment", "Vertical Alignment", -998)]
internal ComboBox verticalAlignment = new ComboBox("Center", "Top", "Bottom"); internal ComboBox verticalAlignment = new ComboBox("Center", "Top", "Bottom");
private IPluginData application = null!; private IPluginData application = null!;
/// <summary> /// <summary>
/// Informations about the main application. /// Information about the main application.
/// </summary> /// </summary>
public IPluginData Application public IPluginData Application
{ {
+2 -2
View File
@@ -10,9 +10,9 @@ public class Button : Setting
/// <summary> /// <summary>
/// Occurs when the button gets clicked. /// Occurs when the button gets clicked.
/// </summary> /// </summary>
public event Action OnClick; public event Action? OnClick;
private string _value; private string _value = string.Empty;
/// <summary> /// <summary>
/// Gets or sets the text caption displayed in the <see cref="Button"/> element. /// Gets or sets the text caption displayed in the <see cref="Button"/> element.
+1 -1
View File
@@ -5,7 +5,7 @@
/// </summary> /// </summary>
public class Label : Setting public class Label : Setting
{ {
private string _value; private string _value = string.Empty;
/// <summary> /// <summary>
/// Gets or sets the text associated with this <see cref="Label"/>. /// Gets or sets the text associated with this <see cref="Label"/>.
@@ -1,4 +1,5 @@
using System; using System;
using System.Diagnostics.CodeAnalysis;
namespace DesktopMagic.Api.Settings; namespace DesktopMagic.Api.Settings;
@@ -22,6 +23,7 @@ public sealed class Slider : Setting
/// <summary> /// <summary>
/// Gets or sets the value assigned to the <see cref="Slider"/> element. /// Gets or sets the value assigned to the <see cref="Slider"/> element.
/// </summary> /// </summary>
[SuppressMessage("Major Bug", "S1244:Floating point numbers should not be tested for equality", Justification = "Not applicable here since we want to detect changes in the value.")]
public double Value public double Value
{ {
get => _value; get => _value;
@@ -5,7 +5,7 @@
/// </summary> /// </summary>
public class TextBox : Setting public class TextBox : Setting
{ {
private string _value; private string _value = string.Empty;
/// <summary> /// <summary>
/// Gets or sets the text associated with this <see cref="TextBox"/>. /// Gets or sets the text associated with this <see cref="TextBox"/>.
-20
View File
@@ -1,20 +0,0 @@
{"message":"No project detected for extracting metadata.","source":"MetadataCommand.ExtractMetadata","date_time":"2022-03-23T17:27:09.2932822Z","message_severity":"warning","correlation_id":"05F9403E-48D7-4391-A021-24959EE7708C.1.1.3"}
{"message":"System.IO.DirectoryNotFoundException: Could not find a part of the path 'C:\\Users\\David\\Programmieren\\DesktopMagic\\src\\DesktopMagicPluginAPI\\obj\\.cache\\build\\dwcg0axe.jl4\\ukjrz4sg.zci'.\r\n at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)\r\n at System.IO.File.InternalCopy(String sourceFileName, String destFileName, Boolean overwrite, Boolean checkHost)\r\n at Microsoft.DocAsCode.Common.RealFileWriter.Copy(PathMapping sourceFileName, RelativePath destFileName)\r\n at Microsoft.DocAsCode.Common.FileAbstractLayer.Copy(RelativePath sourceFileName, RelativePath destFileName)\r\n at Microsoft.DocAsCode.Common.ManifestFileHelper.<>c__DisplayClass8_0.<Dereference>b__4(OutputFileInfo ofi)\r\n at System.Threading.Tasks.Parallel.<>c__DisplayClass42_0`2.<PartitionerForEachWorker>b__1()\r\n at System.Threading.Tasks.Task.InnerInvokeWithArg(Task childTask)\r\n at System.Threading.Tasks.Task.<>c__DisplayClass176_0.<ExecuteSelfReplicating>b__0(Object <p0>)","date_time":"2022-03-23T17:27:10.803282Z","message_severity":"error","code":"FatalError","correlation_id":"05F9403E-48D7-4391-A021-24959EE7708C.3"}
{"message":"System.IO.DirectoryNotFoundException: Could not find a part of the path 'C:\\Users\\David\\Programmieren\\DesktopMagic\\src\\DesktopMagicPluginAPI\\obj\\.cache\\build\\dwcg0axe.jl4\\dwwldwwa.bzu'.\r\n at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)\r\n at System.IO.File.InternalCopy(String sourceFileName, String destFileName, Boolean overwrite, Boolean checkHost)\r\n at Microsoft.DocAsCode.Common.RealFileWriter.Copy(PathMapping sourceFileName, RelativePath destFileName)\r\n at Microsoft.DocAsCode.Common.FileAbstractLayer.Copy(RelativePath sourceFileName, RelativePath destFileName)\r\n at Microsoft.DocAsCode.Common.ManifestFileHelper.<>c__DisplayClass8_0.<Dereference>b__4(OutputFileInfo ofi)\r\n at System.Threading.Tasks.Parallel.<>c__DisplayClass42_0`2.<PartitionerForEachWorker>b__1()\r\n at System.Threading.Tasks.Task.InnerInvokeWithArg(Task childTask)\r\n at System.Threading.Tasks.Task.<>c__DisplayClass176_0.<ExecuteSelfReplicating>b__0(Object <p0>)","date_time":"2022-03-23T17:27:10.803282Z","message_severity":"error","code":"FatalError","correlation_id":"05F9403E-48D7-4391-A021-24959EE7708C.4"}
{"message":"System.IO.DirectoryNotFoundException: Could not find a part of the path 'C:\\Users\\David\\Programmieren\\DesktopMagic\\src\\DesktopMagicPluginAPI\\obj\\.cache\\build\\dwcg0axe.jl4\\t3fz202q.zli'.\r\n at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)\r\n at System.IO.File.InternalCopy(String sourceFileName, String destFileName, Boolean overwrite, Boolean checkHost)\r\n at Microsoft.DocAsCode.Common.RealFileWriter.Copy(PathMapping sourceFileName, RelativePath destFileName)\r\n at Microsoft.DocAsCode.Common.FileAbstractLayer.Copy(RelativePath sourceFileName, RelativePath destFileName)\r\n at Microsoft.DocAsCode.Common.ManifestFileHelper.<>c__DisplayClass8_0.<Dereference>b__4(OutputFileInfo ofi)\r\n at System.Threading.Tasks.Parallel.<>c__DisplayClass42_0`2.<PartitionerForEachWorker>b__1()\r\n at System.Threading.Tasks.Task.InnerInvokeWithArg(Task childTask)\r\n at System.Threading.Tasks.Task.<>c__DisplayClass176_0.<ExecuteSelfReplicating>b__0(Object <p0>)","date_time":"2022-03-23T17:27:10.803282Z","message_severity":"error","code":"FatalError","correlation_id":"05F9403E-48D7-4391-A021-24959EE7708C.5"}
{"message":"System.IO.DirectoryNotFoundException: Could not find a part of the path 'C:\\Users\\David\\Programmieren\\DesktopMagic\\src\\DesktopMagicPluginAPI\\obj\\.cache\\build\\dwcg0axe.jl4\\i2420sau.kem'.\r\n at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)\r\n at System.IO.File.InternalCopy(String sourceFileName, String destFileName, Boolean overwrite, Boolean checkHost)\r\n at Microsoft.DocAsCode.Common.RealFileWriter.Copy(PathMapping sourceFileName, RelativePath destFileName)\r\n at Microsoft.DocAsCode.Common.FileAbstractLayer.Copy(RelativePath sourceFileName, RelativePath destFileName)\r\n at Microsoft.DocAsCode.Common.ManifestFileHelper.<>c__DisplayClass8_0.<Dereference>b__4(OutputFileInfo ofi)\r\n at System.Threading.Tasks.Parallel.<>c__DisplayClass42_0`2.<PartitionerForEachWorker>b__1()\r\n at System.Threading.Tasks.Task.InnerInvokeWithArg(Task childTask)\r\n at System.Threading.Tasks.Task.<>c__DisplayClass176_0.<ExecuteSelfReplicating>b__0(Object <p0>)","date_time":"2022-03-23T17:27:10.803282Z","message_severity":"error","code":"FatalError","correlation_id":"05F9403E-48D7-4391-A021-24959EE7708C.6"}
{"message":"System.IO.DirectoryNotFoundException: Could not find a part of the path 'C:\\Users\\David\\Programmieren\\DesktopMagic\\src\\DesktopMagicPluginAPI\\obj\\.cache\\build\\dwcg0axe.jl4\\cb1eimph.z3j'.\r\n at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)\r\n at System.IO.File.InternalCopy(String sourceFileName, String destFileName, Boolean overwrite, Boolean checkHost)\r\n at Microsoft.DocAsCode.Common.RealFileWriter.Copy(PathMapping sourceFileName, RelativePath destFileName)\r\n at Microsoft.DocAsCode.Common.FileAbstractLayer.Copy(RelativePath sourceFileName, RelativePath destFileName)\r\n at Microsoft.DocAsCode.Common.ManifestFileHelper.<>c__DisplayClass8_0.<Dereference>b__4(OutputFileInfo ofi)\r\n at System.Threading.Tasks.Parallel.<>c__DisplayClass42_0`2.<PartitionerForEachWorker>b__1()\r\n at System.Threading.Tasks.Task.InnerInvokeWithArg(Task childTask)\r\n at System.Threading.Tasks.Task.<>c__DisplayClass176_0.<ExecuteSelfReplicating>b__0(Object <p0>)","date_time":"2022-03-23T17:27:10.803282Z","message_severity":"error","code":"FatalError","correlation_id":"05F9403E-48D7-4391-A021-24959EE7708C.7"}
{"message":"System.IO.DirectoryNotFoundException: Could not find a part of the path 'C:\\Users\\David\\Programmieren\\DesktopMagic\\src\\DesktopMagicPluginAPI\\obj\\.cache\\build\\dwcg0axe.jl4\\1055nvuh.cur'.\r\n at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)\r\n at System.IO.File.InternalCopy(String sourceFileName, String destFileName, Boolean overwrite, Boolean checkHost)\r\n at Microsoft.DocAsCode.Common.RealFileWriter.Copy(PathMapping sourceFileName, RelativePath destFileName)\r\n at Microsoft.DocAsCode.Common.FileAbstractLayer.Copy(RelativePath sourceFileName, RelativePath destFileName)\r\n at Microsoft.DocAsCode.Common.ManifestFileHelper.<>c__DisplayClass8_0.<Dereference>b__4(OutputFileInfo ofi)\r\n at System.Threading.Tasks.Parallel.<>c__DisplayClass42_0`2.<PartitionerForEachWorker>b__1()\r\n at System.Threading.Tasks.Task.InnerInvokeWithArg(Task childTask)\r\n at System.Threading.Tasks.Task.<>c__DisplayClass176_0.<ExecuteSelfReplicating>b__0(Object <p0>)","date_time":"2022-03-23T17:27:10.803282Z","message_severity":"error","code":"FatalError","correlation_id":"05F9403E-48D7-4391-A021-24959EE7708C.8"}
{"message":"System.IO.DirectoryNotFoundException: Could not find a part of the path 'C:\\Users\\David\\Programmieren\\DesktopMagic\\src\\DesktopMagicPluginAPI\\obj\\.cache\\build\\dwcg0axe.jl4\\1dkzedxu.fnm'.\r\n at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)\r\n at System.IO.File.InternalCopy(String sourceFileName, String destFileName, Boolean overwrite, Boolean checkHost)\r\n at Microsoft.DocAsCode.Common.RealFileWriter.Copy(PathMapping sourceFileName, RelativePath destFileName)\r\n at Microsoft.DocAsCode.Common.FileAbstractLayer.Copy(RelativePath sourceFileName, RelativePath destFileName)\r\n at Microsoft.DocAsCode.Common.ManifestFileHelper.<>c__DisplayClass8_0.<Dereference>b__4(OutputFileInfo ofi)\r\n at System.Threading.Tasks.Parallel.<>c__DisplayClass42_0`2.<PartitionerForEachWorker>b__1()\r\n at System.Threading.Tasks.Task.InnerInvokeWithArg(Task childTask)\r\n at System.Threading.Tasks.Task.<>c__DisplayClass176_0.<ExecuteSelfReplicating>b__0(Object <p0>)","date_time":"2022-03-23T17:27:10.803282Z","message_severity":"error","code":"FatalError","correlation_id":"05F9403E-48D7-4391-A021-24959EE7708C.9"}
{"message":"System.IO.DirectoryNotFoundException: Could not find a part of the path 'C:\\Users\\David\\Programmieren\\DesktopMagic\\src\\DesktopMagicPluginAPI\\obj\\.cache\\build\\dwcg0axe.jl4\\nkzrssns.lck'.\r\n at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)\r\n at System.IO.File.InternalCopy(String sourceFileName, String destFileName, Boolean overwrite, Boolean checkHost)\r\n at Microsoft.DocAsCode.Common.RealFileWriter.Copy(PathMapping sourceFileName, RelativePath destFileName)\r\n at Microsoft.DocAsCode.Common.FileAbstractLayer.Copy(RelativePath sourceFileName, RelativePath destFileName)\r\n at Microsoft.DocAsCode.Common.ManifestFileHelper.<>c__DisplayClass8_0.<Dereference>b__4(OutputFileInfo ofi)\r\n at System.Threading.Tasks.Parallel.<>c__DisplayClass42_0`2.<PartitionerForEachWorker>b__1()\r\n at System.Threading.Tasks.Task.InnerInvokeWithArg(Task childTask)\r\n at System.Threading.Tasks.Task.<>c__DisplayClass176_0.<ExecuteSelfReplicating>b__0(Object <p0>)","date_time":"2022-03-23T17:27:10.8042823Z","message_severity":"error","code":"FatalError","correlation_id":"05F9403E-48D7-4391-A021-24959EE7708C.10"}
{"message":"System.IO.DirectoryNotFoundException: Could not find a part of the path 'C:\\Users\\David\\Programmieren\\DesktopMagic\\src\\DesktopMagicPluginAPI\\obj\\.cache\\build\\dwcg0axe.jl4\\lwogcavo.5da'.\r\n at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)\r\n at System.IO.File.InternalCopy(String sourceFileName, String destFileName, Boolean overwrite, Boolean checkHost)\r\n at Microsoft.DocAsCode.Common.RealFileWriter.Copy(PathMapping sourceFileName, RelativePath destFileName)\r\n at Microsoft.DocAsCode.Common.FileAbstractLayer.Copy(RelativePath sourceFileName, RelativePath destFileName)\r\n at Microsoft.DocAsCode.Common.ManifestFileHelper.<>c__DisplayClass8_0.<Dereference>b__4(OutputFileInfo ofi)\r\n at System.Threading.Tasks.Parallel.<>c__DisplayClass42_0`2.<PartitionerForEachWorker>b__1()\r\n at System.Threading.Tasks.Task.InnerInvokeWithArg(Task childTask)\r\n at System.Threading.Tasks.Task.<>c__DisplayClass176_0.<ExecuteSelfReplicating>b__0(Object <p0>)","date_time":"2022-03-23T17:27:10.8042823Z","message_severity":"error","code":"FatalError","correlation_id":"05F9403E-48D7-4391-A021-24959EE7708C.11"}
{"message":"System.IO.DirectoryNotFoundException: Could not find a part of the path 'C:\\Users\\David\\Programmieren\\DesktopMagic\\src\\DesktopMagicPluginAPI\\obj\\.cache\\build\\dwcg0axe.jl4\\puc5uwdx.h5d'.\r\n at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)\r\n at System.IO.File.InternalCopy(String sourceFileName, String destFileName, Boolean overwrite, Boolean checkHost)\r\n at Microsoft.DocAsCode.Common.RealFileWriter.Copy(PathMapping sourceFileName, RelativePath destFileName)\r\n at Microsoft.DocAsCode.Common.FileAbstractLayer.Copy(RelativePath sourceFileName, RelativePath destFileName)\r\n at Microsoft.DocAsCode.Common.ManifestFileHelper.<>c__DisplayClass8_0.<Dereference>b__4(OutputFileInfo ofi)\r\n at System.Threading.Tasks.Parallel.<>c__DisplayClass42_0`2.<PartitionerForEachWorker>b__1()\r\n at System.Threading.Tasks.Task.InnerInvokeWithArg(Task childTask)\r\n at System.Threading.Tasks.Task.<>c__DisplayClass176_0.<ExecuteSelfReplicating>b__0(Object <p0>)","date_time":"2022-03-23T17:27:10.8042823Z","message_severity":"error","code":"FatalError","correlation_id":"05F9403E-48D7-4391-A021-24959EE7708C.12"}
{"message":"System.IO.DirectoryNotFoundException: Could not find a part of the path 'C:\\Users\\David\\Programmieren\\DesktopMagic\\src\\DesktopMagicPluginAPI\\obj\\.cache\\build\\dwcg0axe.jl4\\v12lrk4s.ngm'.\r\n at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)\r\n at System.IO.File.InternalCopy(String sourceFileName, String destFileName, Boolean overwrite, Boolean checkHost)\r\n at Microsoft.DocAsCode.Common.RealFileWriter.Copy(PathMapping sourceFileName, RelativePath destFileName)\r\n at Microsoft.DocAsCode.Common.FileAbstractLayer.Copy(RelativePath sourceFileName, RelativePath destFileName)\r\n at Microsoft.DocAsCode.Common.ManifestFileHelper.<>c__DisplayClass8_0.<Dereference>b__4(OutputFileInfo ofi)\r\n at System.Threading.Tasks.Parallel.<>c__DisplayClass42_0`2.<PartitionerForEachWorker>b__1()\r\n at System.Threading.Tasks.Task.InnerInvokeWithArg(Task childTask)\r\n at System.Threading.Tasks.Task.<>c__DisplayClass176_0.<ExecuteSelfReplicating>b__0(Object <p0>)","date_time":"2022-03-23T17:27:10.805282Z","message_severity":"error","code":"FatalError","correlation_id":"05F9403E-48D7-4391-A021-24959EE7708C.13"}
{"message":"System.IO.DirectoryNotFoundException: Could not find a part of the path 'C:\\Users\\David\\Programmieren\\DesktopMagic\\src\\DesktopMagicPluginAPI\\obj\\.cache\\build\\dwcg0axe.jl4\\0hscybzu.ob2'.\r\n at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)\r\n at System.IO.File.InternalCopy(String sourceFileName, String destFileName, Boolean overwrite, Boolean checkHost)\r\n at Microsoft.DocAsCode.Common.RealFileWriter.Copy(PathMapping sourceFileName, RelativePath destFileName)\r\n at Microsoft.DocAsCode.Common.FileAbstractLayer.Copy(RelativePath sourceFileName, RelativePath destFileName)\r\n at Microsoft.DocAsCode.Common.ManifestFileHelper.<>c__DisplayClass8_0.<Dereference>b__4(OutputFileInfo ofi)\r\n at System.Threading.Tasks.Parallel.<>c__DisplayClass42_0`2.<PartitionerForEachWorker>b__1()\r\n at System.Threading.Tasks.Task.InnerInvokeWithArg(Task childTask)\r\n at System.Threading.Tasks.Task.<>c__DisplayClass176_0.<ExecuteSelfReplicating>b__0(Object <p0>)","date_time":"2022-03-23T17:27:10.805282Z","message_severity":"error","code":"FatalError","correlation_id":"05F9403E-48D7-4391-A021-24959EE7708C.14"}
{"message":"System.IO.DirectoryNotFoundException: Could not find a part of the path 'C:\\Users\\David\\Programmieren\\DesktopMagic\\src\\DesktopMagicPluginAPI\\obj\\.cache\\build\\dwcg0axe.jl4\\rphd3j2r.zjr'.\r\n at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)\r\n at System.IO.File.InternalCopy(String sourceFileName, String destFileName, Boolean overwrite, Boolean checkHost)\r\n at Microsoft.DocAsCode.Common.RealFileWriter.Copy(PathMapping sourceFileName, RelativePath destFileName)\r\n at Microsoft.DocAsCode.Common.FileAbstractLayer.Copy(RelativePath sourceFileName, RelativePath destFileName)\r\n at Microsoft.DocAsCode.Common.ManifestFileHelper.<>c__DisplayClass8_0.<Dereference>b__4(OutputFileInfo ofi)\r\n at System.Threading.Tasks.Parallel.<>c__DisplayClass42_0`2.<PartitionerForEachWorker>b__1()\r\n at System.Threading.Tasks.Task.InnerInvokeWithArg(Task childTask)\r\n at System.Threading.Tasks.Task.<>c__DisplayClass176_0.<ExecuteSelfReplicating>b__0(Object <p0>)","date_time":"2022-03-23T17:27:10.805282Z","message_severity":"error","code":"FatalError","correlation_id":"05F9403E-48D7-4391-A021-24959EE7708C.15"}
{"message":"No project detected for extracting metadata.","source":"MetadataCommand.ExtractMetadata","date_time":"2022-03-24T12:36:07.32842Z","message_severity":"warning","correlation_id":"831032FA-9498-4B91-8F87-6478A11BD9B2.1.1.3"}
{"message":"System.IO.DirectoryNotFoundException: Could not find a part of the path 'C:\\Users\\David\\Programmieren\\DesktopMagic\\src\\DesktopMagicPluginAPI\\obj\\.cache\\build\\dwcg0axe.jl4\\puc5uwdx.h5d'.\r\n at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)\r\n at System.IO.File.InternalCopy(String sourceFileName, String destFileName, Boolean overwrite, Boolean checkHost)\r\n at Microsoft.DocAsCode.Common.RealFileWriter.Copy(PathMapping sourceFileName, RelativePath destFileName)\r\n at Microsoft.DocAsCode.Common.FileAbstractLayer.Copy(RelativePath sourceFileName, RelativePath destFileName)\r\n at Microsoft.DocAsCode.Common.ManifestFileHelper.<>c__DisplayClass8_0.<Dereference>b__4(OutputFileInfo ofi)\r\n at System.Threading.Tasks.Parallel.<>c__DisplayClass42_0`2.<PartitionerForEachWorker>b__1()\r\n at System.Threading.Tasks.Task.InnerInvokeWithArg(Task childTask)\r\n at System.Threading.Tasks.Task.<>c__DisplayClass176_0.<ExecuteSelfReplicating>b__0(Object <p0>)","date_time":"2022-03-24T12:36:18.2594668Z","message_severity":"error","code":"FatalError","correlation_id":"831032FA-9498-4B91-8F87-6478A11BD9B2.3"}
{"message":"System.IO.DirectoryNotFoundException: Could not find a part of the path 'C:\\Users\\David\\Programmieren\\DesktopMagic\\src\\DesktopMagicPluginAPI\\obj\\.cache\\build\\dwcg0axe.jl4\\lwogcavo.5da'.\r\n at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)\r\n at System.IO.File.InternalCopy(String sourceFileName, String destFileName, Boolean overwrite, Boolean checkHost)\r\n at Microsoft.DocAsCode.Common.RealFileWriter.Copy(PathMapping sourceFileName, RelativePath destFileName)\r\n at Microsoft.DocAsCode.Common.FileAbstractLayer.Copy(RelativePath sourceFileName, RelativePath destFileName)\r\n at Microsoft.DocAsCode.Common.ManifestFileHelper.<>c__DisplayClass8_0.<Dereference>b__4(OutputFileInfo ofi)\r\n at System.Threading.Tasks.Parallel.<>c__DisplayClass42_0`2.<PartitionerForEachWorker>b__1()\r\n at System.Threading.Tasks.Task.InnerInvokeWithArg(Task childTask)\r\n at System.Threading.Tasks.Task.<>c__DisplayClass176_0.<ExecuteSelfReplicating>b__0(Object <p0>)","date_time":"2022-03-24T12:36:18.2604591Z","message_severity":"error","code":"FatalError","correlation_id":"831032FA-9498-4B91-8F87-6478A11BD9B2.4"}
{"message":"System.IO.DirectoryNotFoundException: Could not find a part of the path 'C:\\Users\\David\\Programmieren\\DesktopMagic\\src\\DesktopMagicPluginAPI\\obj\\.cache\\build\\dwcg0axe.jl4\\v12lrk4s.ngm'.\r\n at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)\r\n at System.IO.File.InternalCopy(String sourceFileName, String destFileName, Boolean overwrite, Boolean checkHost)\r\n at Microsoft.DocAsCode.Common.RealFileWriter.Copy(PathMapping sourceFileName, RelativePath destFileName)\r\n at Microsoft.DocAsCode.Common.FileAbstractLayer.Copy(RelativePath sourceFileName, RelativePath destFileName)\r\n at Microsoft.DocAsCode.Common.ManifestFileHelper.<>c__DisplayClass8_0.<Dereference>b__4(OutputFileInfo ofi)\r\n at System.Threading.Tasks.Parallel.<>c__DisplayClass42_0`2.<PartitionerForEachWorker>b__1()\r\n at System.Threading.Tasks.Task.InnerInvokeWithArg(Task childTask)\r\n at System.Threading.Tasks.Task.<>c__DisplayClass176_0.<ExecuteSelfReplicating>b__0(Object <p0>)","date_time":"2022-03-24T12:36:18.2604591Z","message_severity":"error","code":"FatalError","correlation_id":"831032FA-9498-4B91-8F87-6478A11BD9B2.5"}
{"message":"System.IO.DirectoryNotFoundException: Could not find a part of the path 'C:\\Users\\David\\Programmieren\\DesktopMagic\\src\\DesktopMagicPluginAPI\\obj\\.cache\\build\\dwcg0axe.jl4\\t3fz202q.zli'.\r\n at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)\r\n at System.IO.File.InternalCopy(String sourceFileName, String destFileName, Boolean overwrite, Boolean checkHost)\r\n at Microsoft.DocAsCode.Common.RealFileWriter.Copy(PathMapping sourceFileName, RelativePath destFileName)\r\n at Microsoft.DocAsCode.Common.FileAbstractLayer.Copy(RelativePath sourceFileName, RelativePath destFileName)\r\n at Microsoft.DocAsCode.Common.ManifestFileHelper.<>c__DisplayClass8_0.<Dereference>b__4(OutputFileInfo ofi)\r\n at System.Threading.Tasks.Parallel.<>c__DisplayClass42_0`2.<PartitionerForEachWorker>b__1()\r\n at System.Threading.Tasks.Task.InnerInvokeWithArg(Task childTask)\r\n at System.Threading.Tasks.Task.<>c__DisplayClass176_0.<ExecuteSelfReplicating>b__0(Object <p0>)","date_time":"2022-03-24T12:36:18.2604591Z","message_severity":"error","code":"FatalError","correlation_id":"831032FA-9498-4B91-8F87-6478A11BD9B2.6"}
{"message":"System.IO.DirectoryNotFoundException: Could not find a part of the path 'C:\\Users\\David\\Programmieren\\DesktopMagic\\src\\DesktopMagicPluginAPI\\obj\\.cache\\build\\dwcg0axe.jl4\\0hscybzu.ob2'.\r\n at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)\r\n at System.IO.File.InternalCopy(String sourceFileName, String destFileName, Boolean overwrite, Boolean checkHost)\r\n at Microsoft.DocAsCode.Common.RealFileWriter.Copy(PathMapping sourceFileName, RelativePath destFileName)\r\n at Microsoft.DocAsCode.Common.FileAbstractLayer.Copy(RelativePath sourceFileName, RelativePath destFileName)\r\n at Microsoft.DocAsCode.Common.ManifestFileHelper.<>c__DisplayClass8_0.<Dereference>b__4(OutputFileInfo ofi)\r\n at System.Threading.Tasks.Parallel.<>c__DisplayClass42_0`2.<PartitionerForEachWorker>b__1()\r\n at System.Threading.Tasks.Task.InnerInvokeWithArg(Task childTask)\r\n at System.Threading.Tasks.Task.<>c__DisplayClass176_0.<ExecuteSelfReplicating>b__0(Object <p0>)","date_time":"2022-03-24T12:36:18.2604591Z","message_severity":"error","code":"FatalError","correlation_id":"831032FA-9498-4B91-8F87-6478A11BD9B2.7"}
Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 864 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 864 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 606 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Some files were not shown because too many files have changed in this diff Show More