import Application stuff from .NET Classic MBS.Framework

This commit is contained in:
Michael Becker 2024-06-15 23:08:46 -04:00
parent a24ae26d57
commit ccfb7410c1
14 changed files with 793 additions and 21 deletions

View File

@ -4,11 +4,27 @@ public class Application
{ {
public static Application? Instance { get; private set; } public static Application? Instance { get; private set; }
public CommandLine CommandLine { get; } = new CommandLine();
protected virtual void OnStartup(EventArgs e)
{
}
protected virtual void OnActivated(ApplicationActivatedEventArgs e)
{
}
protected virtual int StartInternal() protected virtual int StartInternal()
{ {
return 0; OnStartup(EventArgs.Empty);
CommandLine cline = new CommandLine();
cline.Arguments = System.Environment.GetCommandLineArgs();
ApplicationActivatedEventArgs e = new ApplicationActivatedEventArgs(true, ApplicationActivationType.CommandLineLaunch, cline);
OnActivated(e);
return e.ExitCode;
} }
public int Start() public int Start()
{ {
Instance = this; Instance = this;

View File

@ -0,0 +1,43 @@
//
// ApplicationActivatedEvent.cs
//
// Author:
// Michael Becker <alcexhim@gmail.com>
//
// Copyright (c) 20192024 Michael Becker
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
using System;
using System.Collections.Generic;
namespace MBS.Core
{
public class ApplicationActivatedEventArgs : EventArgs
{
public bool Success { get; set; } = true;
public bool FirstRun { get; } = true;
public CommandLine CommandLine { get; } = null;
public int ExitCode { get; set; } = 0;
public ApplicationActivationType ActivationType { get; } = ApplicationActivationType.Launch;
public ApplicationActivatedEventArgs(bool firstRun, ApplicationActivationType activationType, CommandLine commandLine)
{
FirstRun = firstRun;
ActivationType = activationType;
CommandLine = commandLine;
}
}
public delegate void ApplicationActivatedEventHandler(object sender, ApplicationActivatedEventArgs e);
}

View File

@ -0,0 +1,275 @@
//
// ActivationType.cs
//
// Author:
// Michael Becker <alcexhim@gmail.com>
//
// Copyright (c) 2022 Mike Becker's Software
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
using System;
namespace MBS.Core;
/// <summary>
/// Specifies the type of activation when the application is started
/// from layout on a layout-aware operating system.
/// </summary>
/// <remarks>
/// <para>
/// Values are mutually exclusive and cannot be combined. Each one
/// relates to a different type of activation, and an app instance can
/// be activated in only one way at a time.
/// </para>
/// <para>
/// The activation types are based on those supported by Windows 11,
/// however the enum values are operating system agnostic. Translation
/// (e.g. by an Engine) must be done before calls to operating system
/// specific methods are made.
/// </para>
/// <para>
/// On non-layout-aware operating systems, such as Linux, a wrapper
/// executable (bootstrapper) must be used to invoke the app activation
/// with the desired <see cref="ApplicationActivationType" />.
/// </para>
/// </remarks>
public enum ApplicationActivationType
{
/// <summary>
/// The activation type was not specified.
/// </summary>
Unspecified = -1,
/// <summary>
/// The user wants to manage appointments that are provided by the
/// app.
/// </summary>
AppointmentsProvider,
/// <summary>
/// The app was activated as a barcode scanner provider.
/// </summary>
BarcodeScannerProvider,
/// <summary>
/// The user wants to save a file for which the app provides content
/// management.
/// </summary>
CachedFileUpdater,
/// <summary>
/// The app captures photos or video from an attached camera.
/// </summary>
CameraSettings,
/// <summary>
/// The app was launched from the command line.
/// </summary>
CommandLineLaunch,
/// <summary>
/// Reserved for system use. Introduced in Windows 10, version 1507
/// (10.0.10240).
/// </summary>
ComponentUI,
/// <summary>
/// The user wants to handle calls or messages for the phone number
/// of a contact that is provided by the app.
/// </summary>
Contact,
/// <summary>
/// The app was launched from the My People UI. Note: introduced in
/// Windows 10, version 1703 (10.0.15063), but not used. Now used
/// starting with Windows 10, version 1709 (10.0.16299).
/// </summary>
ContactPanel,
/// <summary>
/// The user wants to pick contacts.
/// </summary>
ContactPicker,
/// <summary>
/// The app handles AutoPlay.
/// </summary>
Device,
/// <summary>
/// This app was activated as a result of pairing a device.
/// </summary>
DevicePairing,
/// <summary>
/// This app was launched by another app on a different device by
/// using the DIAL protocol.Introduced in Windows 10, version 1507
/// (10.0.10240).
/// </summary>
DialReceiver,
/// <summary>
/// An app launched a file whose file type this app is registered to
/// handle.
/// </summary>
File,
/// <summary>
/// The user wants to pick files that are provided by the app.
/// </summary>
FileOpenPicker,
/// <summary>
/// Reserved for system use. Introduced in Windows 10, version 1607
/// (10.0.14393).
/// </summary>
FilePickerExperience,
/// <summary>
/// The user wants to save a file and selected the app as the
/// location.
/// </summary>
FileSavePicker,
/// <summary>
/// The app was activated because it was launched by the OS due to a
/// game's request for Xbox-specific UI. Introduced in Windows 10,
/// version 1703 (10.0.15063).
/// </summary>
GameUIProvider,
/// <summary>
/// The user launched the app or tapped a content tile.
/// </summary>
Launch,
/// <summary>
/// The app was activated as the lock screen. Introduced in Windows
/// 10, version 1507 (10.0.10240).
/// </summary>
LockScreen,
/// <summary>
/// Windows Store only. The app launches a call from the lock screen.
/// If the user wants to accept the call, the app displays its call
/// UI directly on the lock screen without requiring the user to
/// unlock. A lock-screen call is a special type of launch
/// activation.
/// </summary>
LockScreenCall,
/// <summary>
/// Reserved for system use. Introduced in Windows 10, version 1703
/// (10.0.15063).
/// </summary>
LockScreenComponent,
/// <summary>
/// The app was activated in response to a phone call.
/// </summary>
PhoneCallActivation,
/// <summary>
/// Windows Phone only. The app was activated after the completion of
/// a picker.
/// </summary>
PickerReturned,
/// <summary>
/// Windows Phone only. The app was activated after the app was
/// suspended for a file picker operation.
/// </summary>
PickFileContinuation,
/// <summary>
/// Windows Phone only. The app was activated after the app was
/// suspended for a folder picker operation.
/// </summary>
PickFolderContinuation,
/// <summary>
/// Windows Phone only. The app was activated after the app was
/// suspended for a file save picker operation.
/// </summary>
PickSaveFileContinuation,
/// <summary>
/// This app was launched by another app to provide a customized
/// printing experience for a 3D printer. Introduced in Windows 10,
/// version 1507 (10.0.10240).
/// </summary>
Print3DWorkflow,
/// <summary>
/// The app was activated as a print workflow job UI extension.
/// </summary>
PrintSupportJobUI,
/// <summary>
/// The app was activated as a print support settings UI extension.
/// </summary>
PrintSupportSettingsUI,
/// <summary>
/// The app handles print tasks.
/// </summary>
PrintTaskSettings,
/// <summary>
/// The app was activated because the user is printing to a printer
/// that has a Print Workflow Application associated with it which
/// has requested user input.
/// </summary>
PrintWorkflowForegroundTask,
/// <summary>
/// An app launched a URI whose scheme name this app is registered to
/// handle.
/// </summary>
Protocol,
/// <summary>
/// The app was launched by another app with the expectation that it
/// will return a result back to the caller. Introduced in Windows
/// 10, version 1507 (10.0.10240).
/// </summary>
ProtocolForResults,
/// <summary>
/// Windows Store only. The user launched the restricted app.
/// </summary>
RestrictedLaunch,
/// <summary>
/// The user wants to search with the app.
/// </summary>
Search,
/// <summary>
/// The app is activated as a target for share operations.
/// </summary>
ShareTarget,
/// <summary>
/// The app was activated because the app is specified to launch at
/// system startup or user log-in. Introduced in Windows 10, version
/// 1703 (10.0.15063).
/// </summary>
StartupTask,
/// <summary>
/// The app was activated when a user tapped on the body of a toast
/// notification or performed an action inside a toast notification.
/// Introduced in Windows 10, version 1507 (10.0.10240).
/// </summary>
ToastNotification,
/// <summary>
/// The app was launched to handle the user interface for account
/// management. In circumstances where the system would have shown
/// the default system user interface, it instead has invoked your
/// app with the UserDataAccountProvider contract. The activation
/// payload contains information about the type of operation being
/// requested and all the information necessary to replicate the
/// system-provided user interface. This activation kind is limited
/// to 1st party apps. To use this field, you must add the
/// userDataAccountsProvider capability in your app's package
/// manifest. For more info see App capability declarations.
/// Introduced in Windows 10, version 1607 (10.0.14393).
/// </summary>
UserDataAccountsProvider,
/// <summary>
/// The app was activated as the result of a voice command.
/// </summary>
VoiceCommand,
/// <summary>
/// The app is a VPN foreground app that was activated by the plugin.
/// For more details, see VpnChannel.ActivateForeground.
/// </summary>
VpnForeground,
/// <summary>
/// The app was activated to perform a Wallet operation.
/// </summary>
WalletAction,
/// <summary>
/// The app was activated by a web account provider.
/// </summary>
WebAccountProvider,
/// <summary>
/// The app was activated after the app was suspended for a web
/// authentication broker operation.
/// </summary>
WebAuthenticationBrokerContinuation
}

View File

@ -0,0 +1,70 @@
//
// CommandLine.cs
//
// Author:
// Mike Becker <alcexhim@gmail.com>
//
// Copyright (c) 2019 Mike Becker
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
using System;
using System.Collections.Generic;
namespace MBS.Core;
public class CommandLine
{
/// <summary>
/// Gets the original <see cref="String" /> array of arguments.
/// </summary>
/// <value>The arguments.</value>
public string[] Arguments { get; internal set; }
/// <summary>
/// Gets the list of file names passed on the command line.
/// </summary>
/// <value>The file names.</value>
public List<string> FileNames { get; } = new List<string>();
public CommandLineParser Parser { get; set; } = null;
public string HelpTextPrefix { get; set; } = null;
public string HelpTextSuffix { get; set; } = null;
public CommandLineOption.CommandLineOptionCollection Options { get; } = new CommandLineOption.CommandLineOptionCollection();
public CommandLineCommand.CommandLineCommandCollection Commands { get; } = new CommandLineCommand.CommandLineCommandCollection();
public CommandLineCommand Command { get; internal set; } = null;
public string ShortOptionPrefix { get; set; } = null;
public string LongOptionPrefix { get; set; } = null;
public CommandLine(string[] arguments = null)
{
string[] args = arguments;
if (args == null)
{
args = Environment.GetCommandLineArgs();
}
string[] args2 = new string[args.Length - 1];
Array.Copy(args, 1, args2, 0, args2.Length);
Arguments = args2;
Options.Add(new CommandLineOption() { Abbreviation = 'A', Name = "activation-type", Description = "The type of activation for this app", Type = CommandLineOptionValueType.Single, Optional = true });
Options.Add(new CommandLineOption() { Name = "help", Description = "Displays help", Type = CommandLineOptionValueType.None, Optional = true });
}
public override string ToString()
{
return String.Join(" ", Arguments);
}
}

View File

@ -0,0 +1,61 @@
//
// CommandLineCommand.cs
//
// Author:
// Michael Becker <alcexhim@gmail.com>
//
// Copyright (c) 2022 Mike Becker's Software
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
using System;
using MBS.Core.Collections.Generic;
namespace MBS.Core;
public class CommandLineCommand
{
public class CommandLineCommandCollection
: System.Collections.ObjectModel.Collection<CommandLineCommand>
{
public CommandLineCommand this[string name]
{
get
{
foreach (CommandLineCommand item in this)
{
if (item.Name == name)
return item;
}
return null;
}
}
}
public string Name { get; set; } = null;
public string Description { get; set; } = null;
public CommandLineOption.CommandLineOptionCollection Options { get; } = new CommandLineOption.CommandLineOptionCollection();
public Action<ApplicationActivatedEventArgs> ActivationDelegate { get; } = null;
public CommandLineCommand(string command, CommandLineOption[] options = null, Action<ApplicationActivatedEventArgs> activationDelegate = null)
{
Name = command;
if (options != null)
{
Options.AddRange(options);
}
ActivationDelegate = activationDelegate;
}
}

View File

@ -0,0 +1,138 @@
//
// CommandLineOption.cs
//
// Author:
// Mike Becker <alcexhim@gmail.com>
//
// Copyright (c) 2019 Mike Becker
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
using System;
using System.Collections.Generic;
namespace MBS.Core;
public class CommandLineOption
{
public class CommandLineOptionCollection
: System.Collections.ObjectModel.Collection<CommandLineOption>
{
private Dictionary<char, CommandLineOption> _byAbbreviation = new Dictionary<char, CommandLineOption>();
private Dictionary<string, CommandLineOption> _byName = new Dictionary<string, CommandLineOption>();
public bool Contains(char abbreviation)
{
return _byAbbreviation.ContainsKey(abbreviation);
}
public bool Contains(string name)
{
return _byName.ContainsKey(name);
}
public CommandLineOption this[char abbreviation]
{
get
{
if (_byAbbreviation.ContainsKey(abbreviation))
return _byAbbreviation[abbreviation];
return null;
}
}
public CommandLineOption this[string name]
{
get
{
if (_byName.ContainsKey(name))
return _byName[name];
return null;
}
}
protected override void ClearItems()
{
base.ClearItems();
_byName.Clear();
_byAbbreviation.Clear();
}
protected override void InsertItem(int index, CommandLineOption item)
{
base.InsertItem(index, item);
if (item.Name != null)
_byName[item.Name] = item;
if (item.Abbreviation != '\0')
_byAbbreviation[item.Abbreviation] = item;
}
public CommandLineOption Add(string name, CommandLineOptionValueType type = CommandLineOptionValueType.None, object defaultValue = null, char abbreviation = '\0', string description = null)
{
return Add(name, abbreviation, defaultValue, type, description);
}
public CommandLineOption Add(string name, char abbreviation = '\0', object defaultValue = null, CommandLineOptionValueType type = CommandLineOptionValueType.None, string description = null)
{
CommandLineOption option = new CommandLineOption();
option.Name = name;
option.Abbreviation = abbreviation;
option.DefaultValue = defaultValue;
option.Type = type;
option.Description = description;
Add(option);
return option;
}
protected override void RemoveItem(int index)
{
_byName.Remove(this[index].Name);
_byAbbreviation.Remove(this[index].Abbreviation);
base.RemoveItem(index);
}
public T GetValueOrDefault<T>(string name, T defaultValue = default(T))
{
if (_byName.ContainsKey(name))
{
return (T) _byName[name].Value;
}
return defaultValue;
}
}
public string Name { get; set; } = null;
public char Abbreviation { get; set; } = '\0';
public object DefaultValue { get; set; } = null;
/// <summary>
/// Gets or sets a value indicating whether this <see cref="T:MBS.Framework.CommandLineOption"/> is optional.
/// </summary>
/// <value><c>true</c> if optional; otherwise, <c>false</c>.</value>
public bool Optional { get; set; } = false;
/// <summary>
/// The description displayed in the help text.
/// </summary>
/// <value>The description.</value>
public string Description { get; set; } = null;
public object Value { get; set; } = null;
/// <summary>
/// Gets or sets a value indicating whether this <see cref="T:MBS.Framework.UserInterface.CommandLineOption"/> expects a value to be passed in after this option.
/// </summary>
/// <value><c>true</c> if a value is expected to be passed in after this option; otherwise, <c>false</c>.</value>
public CommandLineOptionValueType Type { get; set; } = CommandLineOptionValueType.None;
}

View File

@ -0,0 +1,38 @@
//
// CommandLineOptionValueType.cs
//
// Author:
// Mike Becker <alcexhim@gmail.com>
//
// Copyright (c) 2019 Mike Becker
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
using System;
namespace MBS.Core;
public enum CommandLineOptionValueType
{
/// <summary>
/// The option accepts no values.
/// </summary>
None = 0,
/// <summary>
/// The option accepts a single value.
/// </summary>
Single = 1,
/// <summary>
/// The option accepts multiple values.
/// </summary>
Multiple = 2
}

View File

@ -0,0 +1,38 @@
//
// CommandLineParser.cs
//
// Author:
// Michael Becker <alcexhim@gmail.com>
//
// Copyright (c) 2022 Mike Becker's Software
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
using System;
namespace MBS.Core;
public class CommandLineParser
{
protected virtual void ParseInternal(string[] arguments)
{
string[] ary1 = Environment.GetCommandLineArgs();
string[] ary2 = new string[ary1.Length - 1];
Array.Copy(ary1, 1, ary2, 0, ary1.Length - 1);
Application.Instance.CommandLine.Arguments = ary2;
}
public void Parse(string[] arguments)
{
ParseInternal(arguments);
}
}

View File

@ -0,0 +1,29 @@
using System.Runtime.InteropServices;
namespace MBS.Core.Interop;
public static class InteropServices
{
[StructLayout(LayoutKind.Sequential)]
private struct PtrToStringArrayStruct
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)]
public IntPtr[] listOfStrings;
}
public static string[] PtrToStringArray(IntPtr hptr, int size)
{
// eww.. gross. thanks https://stackoverflow.com/questions/1323797/marshaling-pointer-to-an-array-of-strings
PtrToStringArrayStruct hwss = (PtrToStringArrayStruct)Marshal.PtrToStructure(hptr, typeof(PtrToStringArrayStruct));
string[] argv = new string[size];
for (int i = 0; i < size; i++)
{
IntPtr hstr = hwss.listOfStrings[i];
string p = Marshal.PtrToStringAuto(hstr);
argv[i] = p;
}
return argv;
}
}

View File

@ -0,0 +1,7 @@
namespace MBS.Core;
public enum Orientation
{
Horizontal,
Vertical
}

View File

@ -0,0 +1,43 @@
namespace MBS.Core.Reflection;
public class Invoker
{
public static void Invoke(object obj, string meth, params object[] parms)
{
if (obj == null)
{
Console.WriteLine("Invoker::Invoke: obj is null");
return;
}
Type t = obj.GetType();
System.Reflection.MethodInfo mi = t.GetMethod(meth, System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance);
if (mi != null)
{
mi.Invoke(obj, parms);
}
else
{
Console.WriteLine("Invoker::Invoke: instance method not found '" + meth + "' on '" + t.FullName + "'");
}
}
public static void InvokeStatic(Type type, string meth, params object[] parms)
{
if (type == null)
{
Console.WriteLine("Invoker::InvokeStatic: type is null");
return;
}
Type t = type;
System.Reflection.MethodInfo mi = t.GetMethod(meth, System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static);
if (mi != null)
{
mi.Invoke(null, parms);
}
else
{
Console.WriteLine("Invoker::InvokeStatic: static method not found '" + meth + "' on '" + t.FullName + "'");
}
}
}

View File

@ -76,7 +76,13 @@ public class TypeLoader
List<string> asmdirs = new List<string>(); List<string> asmdirs = new List<string>();
string dir = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetCallingAssembly().Location); string dir = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetCallingAssembly().Location);
asmdirs.Add(dir); asmdirs.Add(dir);
asmdirs.Add(dir + System.IO.Path.DirectorySeparatorChar.ToString() + "plugins");
string[] subdirs = System.IO.Directory.GetDirectories(dir);
foreach (string subdir in subdirs)
{
asmdirs.Add(subdir);
}
// asmdirs.Add(dir + System.IO.Path.DirectorySeparatorChar.ToString() + "plugins");
if (searchPaths != null) if (searchPaths != null)
{ {
for (int i = 0; i < searchPaths.Length; i++) for (int i = 0; i < searchPaths.Length; i++)
@ -123,6 +129,33 @@ public class TypeLoader
} }
private static Type[] mvarAvailableTypes = null; private static Type[] mvarAvailableTypes = null;
public static T[] GetAvailableTypes<T>(Assembly[] additionalAssemblies = null) where T : class
{
Type[] ts = null;
try
{
ts = GetAvailableTypes(new Type[] { typeof(T) }, additionalAssemblies);
}
catch (ReflectionTypeLoadException ex)
{
ts = ex.Types;
}
List<T> list = new List<T>();
foreach (Type t in ts)
{
if (t == null)
continue;
if (t.IsAbstract)
continue;
T obj = t.Assembly.CreateInstance(t.FullName) as T;
if (obj != null)
list.Add(obj);
}
return list.ToArray();
}
public static Type[] GetAvailableTypes(Type[] inheritsFrom = null, Assembly[] additionalAssemblies = null) public static Type[] GetAvailableTypes(Type[] inheritsFrom = null, Assembly[] additionalAssemblies = null)
{ {
if (mvarAvailableTypes == null) if (mvarAvailableTypes == null)

View File

@ -1,6 +0,0 @@
namespace MBS.Desktop;
public class DesktopApplication : MBS.Core.Application
{
}

View File

@ -1,13 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<ItemGroup>
<ProjectReference Include="..\MBS.Core\MBS.Core.csproj" />
</ItemGroup>
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
</Project>