mirror of
https://github.com/Stone-Red-Code/DesktopMagic.git
synced 2026-09-04 00:46:12 +02:00
Add create new plugin button to plugin manager
This commit is contained in:
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -96,7 +96,15 @@
|
||||
</ScrollViewer>
|
||||
|
||||
<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 HorizontalAlignment="Right" Click="CreatePluginButton_Click">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<materialDesign:PackIcon Kind="Add" Margin="0 0 10 0" />
|
||||
<TextBlock Text="{DynamicResource createNewPlugin}" />
|
||||
</StackPanel>
|
||||
</Button>
|
||||
</DockPanel>
|
||||
</Border>
|
||||
</Grid>
|
||||
</busyIndicator:BusyMask>
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using DesktopMagic.DataContexts;
|
||||
using DesktopMagic.Dialogs;
|
||||
using DesktopMagic.Helpers;
|
||||
|
||||
using Modio;
|
||||
@@ -9,11 +10,13 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.IO.Compression;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Text.Json;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Threading;
|
||||
@@ -34,6 +37,7 @@ public partial class PluginManager : Window
|
||||
|
||||
private readonly PluginManagerDataContext pluginManagerDataContext = new();
|
||||
private readonly string pluginsPath = Path.Combine(App.ApplicationDataPath, "Plugins");
|
||||
private readonly string pluginDevelopmentPath = Path.Combine(App.ApplicationDataPath, "PluginDevelopment");
|
||||
|
||||
private readonly DispatcherTimer searchTimer = new()
|
||||
{
|
||||
@@ -125,6 +129,9 @@ public partial class PluginManager : Window
|
||||
e.Cancel = pluginManagerDataContext.IsLoading;
|
||||
}
|
||||
|
||||
[GeneratedRegex(@"[^a-zA-Z0-9]")]
|
||||
private static partial Regex IdentifierNameRegex();
|
||||
|
||||
private async Task Install(Mod mod)
|
||||
{
|
||||
pluginManagerDataContext.IsLoading = true;
|
||||
@@ -235,4 +242,123 @@ public partial class PluginManager : Window
|
||||
|
||||
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() is not 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(1000, 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.
|
||||
}}
|
||||
}}
|
||||
";
|
||||
|
||||
File.WriteAllText(Path.Combine(pluginProjectPath, $"{pluginSafeName}.cs"), code);
|
||||
|
||||
// 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 = Path.Combine(pluginProjectPath, $"{pluginSafeName}.csproj"),
|
||||
};
|
||||
|
||||
_ = Process.Start(psi);
|
||||
}
|
||||
}
|
||||
@@ -15,6 +15,8 @@
|
||||
<system:String x:Key="updatePlugins">Neu Laden</system:String>
|
||||
<system:String x:Key="pluginsFolder">Plugins Ordner</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="default">Standard</system:String>
|
||||
<system:String x:Key="wantToCloseProgram">Wollen sie das Programm wirklich schließen?</system:String>
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
<system:String x:Key="updatePlugins">Reload</system:String>
|
||||
<system:String x:Key="pluginsFolder">Plugins Folder</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="default">Default</system:String>
|
||||
<system:String x:Key="wantToCloseProgram">Do you really want to close the program?</system:String>
|
||||
|
||||
Reference in New Issue
Block a user