diff --git a/AffinityHook/AffinityHook.csproj b/AffinityHook/AffinityHook.csproj
index 624cd91..10b0508 100644
--- a/AffinityHook/AffinityHook.csproj
+++ b/AffinityHook/AffinityHook.csproj
@@ -8,9 +8,11 @@
x64
- AffinityHook
+ AffinityHook
Launch wrapper to hook Affinity and inject AffinityBootstrap
0.2.0
- Noah Curoe & AffinityHook Contributors
+ Noah Curoe & AffinityHook Contributors
+
+ false
diff --git a/AffinityPluginLoader/AffinityPluginLoader.csproj b/AffinityPluginLoader/AffinityPluginLoader.csproj
index 508f206..cf19e69 100644
--- a/AffinityPluginLoader/AffinityPluginLoader.csproj
+++ b/AffinityPluginLoader/AffinityPluginLoader.csproj
@@ -7,10 +7,12 @@
x64
- AffinityHook
- Plugin loader for Affinity by Canva.
+ Affinity Plugin Loader
+ Plugin loader for 'Affinity by Canva'.
0.2.0
- Noah Curoe & AffinityPluginLoader Contributors
+ Noah Curoe & APL Contributors
+
+ false
diff --git a/AffinityPluginLoader/Core/Logger.cs b/AffinityPluginLoader/Core/Logger.cs
new file mode 100644
index 0000000..1e442f7
--- /dev/null
+++ b/AffinityPluginLoader/Core/Logger.cs
@@ -0,0 +1,350 @@
+using System;
+using System.IO;
+using System.Reflection;
+using System.Runtime.InteropServices;
+using System.Text;
+using HarmonyLib;
+
+namespace AffinityPluginLoader.Core
+{
+ ///
+ /// Logging API for APL and plugins.
+ /// Supports console and file output with log levels and rotation.
+ ///
+ public static class Logger
+ {
+ public enum LogLevel
+ {
+ DEBUG = 0,
+ INFO = 1,
+ WARNING = 2,
+ ERROR = 3,
+ NONE = 4 // Disables all logging
+ }
+
+ private static LogLevel _minimumLevel = LogLevel.INFO;
+ private static bool _fileLoggingEnabled = false;
+ private static string _logFilePath = null;
+ private static readonly object _lockObj = new object();
+ private static bool _initialized = false;
+ private static StreamWriter _fileWriter = null;
+ private static bool _hasConsole = false;
+
+ // P/Invoke for console attachment
+ [DllImport("kernel32.dll", SetLastError = true)]
+ private static extern bool AttachConsole(int dwProcessId);
+
+ [DllImport("kernel32.dll", SetLastError = true)]
+ private static extern bool AllocConsole();
+
+ [DllImport("kernel32.dll", SetLastError = true)]
+ private static extern IntPtr GetConsoleWindow();
+
+ private const int ATTACH_PARENT_PROCESS = -1;
+
+ ///
+ /// Initialize the logger. Call this once at startup.
+ ///
+ public static void Initialize()
+ {
+ lock (_lockObj)
+ {
+ if (_initialized)
+ return;
+
+ // Try to attach to parent console for output visibility
+ AttachToConsole();
+
+ // Parse APL_LOGGING environment variable
+ string aplLogging = Environment.GetEnvironmentVariable("APL_LOGGING");
+ if (!string.IsNullOrEmpty(aplLogging))
+ {
+ // Parse log level
+ if (Enum.TryParse(aplLogging.ToUpperInvariant(), out LogLevel level))
+ {
+ _minimumLevel = level;
+ _fileLoggingEnabled = true;
+ }
+ else
+ {
+ // Invalid log level, default to DEBUG and warn
+ _minimumLevel = LogLevel.DEBUG;
+ _fileLoggingEnabled = true;
+ Console.WriteLine($"[WARNING] Invalid APL_LOGGING value '{aplLogging}'. Using DEBUG. Valid values: DEBUG, INFO, WARNING, ERROR, NONE");
+ }
+ }
+
+ // Setup file logging if enabled
+ if (_fileLoggingEnabled)
+ {
+ SetupFileLogging();
+ }
+
+ _initialized = true;
+
+ // Log startup message with timezone info
+ var now = DateTime.Now;
+ var timezone = TimeZoneInfo.Local;
+ Info($"APL logging initialized");
+ Info($"Local timezone: {timezone.DisplayName} (UTC{(timezone.BaseUtcOffset.TotalHours >= 0 ? "+" : "")}{timezone.BaseUtcOffset.TotalHours:0.##})");
+ Info($"Log level: {_minimumLevel}");
+ if (_fileLoggingEnabled)
+ {
+ Info($"File logging enabled: {_logFilePath}");
+ }
+ }
+ }
+
+ private static void AttachToConsole()
+ {
+ try
+ {
+ // Check if we already have a console
+ if (GetConsoleWindow() != IntPtr.Zero)
+ {
+ _hasConsole = true;
+ return;
+ }
+
+ // Try to attach to parent process console (AffinityHook)
+ if (AttachConsole(ATTACH_PARENT_PROCESS))
+ {
+ _hasConsole = true;
+ // Reopen standard output to the console
+ try
+ {
+ var stdOut = Console.OpenStandardOutput();
+ Console.SetOut(new StreamWriter(stdOut, Console.OutputEncoding) { AutoFlush = true });
+ var stdErr = Console.OpenStandardError();
+ Console.SetError(new StreamWriter(stdErr, Console.OutputEncoding) { AutoFlush = true });
+ }
+ catch
+ {
+ // If reopening fails, we still have the console attached
+ }
+ return;
+ }
+
+ // If attaching to parent failed, we won't allocate a new console
+ // (Affinity is a GUI app and allocating a new console creates a popup window)
+ _hasConsole = false;
+ }
+ catch
+ {
+ _hasConsole = false;
+ }
+ }
+
+ private static void SetupFileLogging()
+ {
+ try
+ {
+ // Determine log file path (plugins/logs/apl.latest.log)
+ string assemblyDir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
+ string pluginsDir = Path.Combine(assemblyDir, "plugins");
+ string logsDir = Path.Combine(pluginsDir, "logs");
+
+ // Create plugins/logs directory if it doesn't exist
+ if (!Directory.Exists(logsDir))
+ {
+ Directory.CreateDirectory(logsDir);
+ }
+
+ _logFilePath = Path.Combine(logsDir, "apl.latest.log");
+
+ // Rotate existing log files
+ RotateLogFiles(_logFilePath);
+
+ // Open log file for writing
+ _fileWriter = new StreamWriter(_logFilePath, append: false, Encoding.UTF8)
+ {
+ AutoFlush = true
+ };
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine($"[ERROR] Failed to setup file logging: {ex.Message}");
+ _fileLoggingEnabled = false;
+ }
+ }
+
+ private static void RotateLogFiles(string logFilePath)
+ {
+ try
+ {
+ // If current log file doesn't exist, nothing to rotate
+ if (!File.Exists(logFilePath))
+ return;
+
+ // Get directory and base name (e.g., "apl.latest.log" -> "apl", ".log")
+ string logDir = Path.GetDirectoryName(logFilePath);
+
+ // Delete apl.5.log if it exists
+ string log5 = Path.Combine(logDir, "apl.5.log");
+ if (File.Exists(log5))
+ {
+ File.Delete(log5);
+ }
+
+ // Cycle logs: apl.4.log -> apl.5.log, apl.3.log -> apl.4.log, etc.
+ for (int i = 4; i >= 1; i--)
+ {
+ string oldLog = Path.Combine(logDir, $"apl.{i}.log");
+ string newLog = Path.Combine(logDir, $"apl.{i + 1}.log");
+ if (File.Exists(oldLog))
+ {
+ File.Move(oldLog, newLog);
+ }
+ }
+
+ // Move current log to apl.1.log
+ File.Move(logFilePath, Path.Combine(logDir, "apl.1.log"));
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine($"[ERROR] Failed to rotate log files: {ex.Message}");
+ }
+ }
+
+ private static void Log(LogLevel level, string message)
+ {
+ if (!_initialized)
+ {
+ // Auto-initialize on first log call
+ Initialize();
+ }
+
+ // Filter by minimum level
+ if (level < _minimumLevel)
+ return;
+
+ // Get the plugin name from the calling assembly
+ string pluginName = GetCallingPluginName();
+
+ string timestamp = DateTime.Now.ToString("HH:mm:ss");
+ string levelStr = level.ToString();
+ string logLine = $"[{timestamp}] [{levelStr}] [APL/{pluginName}] {message}";
+
+ lock (_lockObj)
+ {
+ // Write to console if we have one attached
+ if (_hasConsole)
+ {
+ try
+ {
+ Console.WriteLine(logLine);
+ }
+ catch
+ {
+ // Console write failed, disable it
+ _hasConsole = false;
+ }
+ }
+
+ // Write to file if enabled
+ if (_fileLoggingEnabled && _fileWriter != null)
+ {
+ try
+ {
+ _fileWriter.WriteLine(logLine);
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine($"[ERROR] Failed to write to log file: {ex.Message}");
+ }
+ }
+ }
+ }
+
+ public static void Debug(string message)
+ {
+ Log(LogLevel.DEBUG, message);
+ }
+
+ public static void Info(string message)
+ {
+ Log(LogLevel.INFO, message);
+ }
+
+ public static void Warning(string message)
+ {
+ Log(LogLevel.WARNING, message);
+ }
+
+ public static void Error(string message)
+ {
+ Log(LogLevel.ERROR, message);
+ }
+
+ public static void Error(string message, Exception ex)
+ {
+ Error($"{message}: {ex.Message}");
+ if (ex.StackTrace != null)
+ {
+ Error($"Stack trace:\n{ex.StackTrace}");
+ }
+ }
+
+ ///
+ /// Get the name of the plugin/assembly that called the logger
+ ///
+ private static string GetCallingPluginName()
+ {
+ try
+ {
+ // Walk up the stack to find the first assembly that isn't this one
+ var stackTrace = new System.Diagnostics.StackTrace();
+ var frames = stackTrace.GetFrames();
+
+ if (frames != null)
+ {
+ var loggerAssembly = typeof(Logger).Assembly;
+
+ foreach (var frame in frames)
+ {
+ var method = frame.GetMethod();
+ if (method != null)
+ {
+ var declaringType = method.DeclaringType;
+ if (declaringType != null)
+ {
+ var assembly = declaringType.Assembly;
+
+ // Skip our own assembly
+ if (assembly != loggerAssembly)
+ {
+ // Get the plugin name using the same approach as PluginManager
+ var nameAttr = assembly.GetCustomAttribute();
+ return nameAttr?.Title ?? assembly.GetName().Name;
+ }
+ }
+ }
+ }
+ }
+
+ // Fallback to "APL" if we can't determine the caller
+ return "Core";
+ }
+ catch
+ {
+ return "Core";
+ }
+ }
+
+ ///
+ /// Cleanup resources. Call this on shutdown if needed.
+ ///
+ public static void Shutdown()
+ {
+ lock (_lockObj)
+ {
+ if (_fileWriter != null)
+ {
+ _fileWriter.Flush();
+ _fileWriter.Close();
+ _fileWriter = null;
+ }
+ }
+ }
+ }
+}
diff --git a/AffinityPluginLoader/Core/PluginManager.cs b/AffinityPluginLoader/Core/PluginManager.cs
index bf4fbc0..d0fc765 100644
--- a/AffinityPluginLoader/Core/PluginManager.cs
+++ b/AffinityPluginLoader/Core/PluginManager.cs
@@ -22,34 +22,34 @@ public static void Initialize(Harmony harmony)
if (_initialized)
return;
- FileLog.Log($"PluginManager initializing...\n");
+ Logger.Info($"PluginManager initializing...");
- // Add AffinityPluginLoader itself as the first plugin
+ // Add APL itself as the first plugin
var loaderAssembly = Assembly.GetExecutingAssembly();
- var loaderNameAttr = loaderAssembly.GetCustomAttribute();
- var loaderVersionAttr = loaderAssembly.GetCustomAttribute();
+ var loaderProductAttr = loaderAssembly.GetCustomAttribute();
+ var loaderVersionAttr = loaderAssembly.GetCustomAttribute();
var loaderCompanyAttr = loaderAssembly.GetCustomAttribute();
var loaderDescAttr = loaderAssembly.GetCustomAttribute();
-
+
var loaderInfo = new PluginInfo
{
- Name = loaderNameAttr?.Title ?? "AffinityPluginLoader",
- Version = loaderVersionAttr?.Version ?? loaderAssembly.GetName().Version?.ToString() ?? "0.1.0.1",
- Author = loaderCompanyAttr?.Company ?? "AffinityPluginLoader",
+ Name = loaderProductAttr?.Product ?? loaderAssembly.GetName().Name,
+ Version = FormatVersion(loaderVersionAttr?.InformationalVersion, loaderAssembly.GetName().Version),
+ Author = loaderCompanyAttr?.Company ?? "Unknown",
AssemblyName = loaderAssembly.FullName,
- Description = loaderDescAttr.Description
+ Description = loaderDescAttr?.Description ?? ""
};
_loadedPlugins.Add(loaderInfo);
- FileLog.Log($"Added AffinityPluginLoader to plugin list: {loaderInfo.Name} v{loaderInfo.Version}\n");
+ Logger.Info($"Added APL to plugin list: {loaderInfo.Name} v{loaderInfo.Version}");
// Apply loader's own patches (version strings, preferences tab)
- Patches.LoaderPatches.ApplyPatches(harmony);
+ Patches.LoaderPatches.ApplyPatches(harmony, loaderInfo);
// Load plugins from ./plugins/ directory
LoadPlugins(harmony);
_initialized = true;
- FileLog.Log($"PluginManager initialized with {_loadedPlugins.Count} plugins\n");
+ Logger.Info($"PluginManager initialized with {_loadedPlugins.Count} plugins");
}
private static void LoadPlugins(Harmony harmony)
@@ -61,18 +61,18 @@ private static void LoadPlugins(Harmony harmony)
string loaderDir = Path.GetDirectoryName(loaderPath);
string pluginsDir = Path.Combine(loaderDir, "plugins");
- FileLog.Log($"Looking for plugins in: {pluginsDir}\n");
+ Logger.Debug($"Looking for plugins in: {pluginsDir}");
if (!Directory.Exists(pluginsDir))
{
- FileLog.Log($"Plugins directory not found, creating it...\n");
+ Logger.Info($"Plugins directory not found, creating it...");
Directory.CreateDirectory(pluginsDir);
return;
}
// Load all DLLs in the plugins directory
var pluginFiles = Directory.GetFiles(pluginsDir, "*.dll");
- FileLog.Log($"Found {pluginFiles.Length} DLL files in plugins directory\n");
+ Logger.Debug($"Found {pluginFiles.Length} DLL files in plugins directory");
foreach (var pluginFile in pluginFiles)
{
@@ -82,36 +82,34 @@ private static void LoadPlugins(Harmony harmony)
}
catch (Exception ex)
{
- FileLog.Log($"Failed to load plugin {Path.GetFileName(pluginFile)}: {ex.Message}\n");
+ Logger.Error($"Failed to load plugin {Path.GetFileName(pluginFile)}: {ex.Message}");
}
}
}
catch (Exception ex)
{
- FileLog.Log($"Error loading plugins: {ex.Message}\n{ex.StackTrace}\n");
+ Logger.Error("Error loading plugins", ex);
}
}
private static void LoadPlugin(string pluginPath, Harmony harmony)
{
- FileLog.Log($"Loading plugin: {Path.GetFileName(pluginPath)}\n");
+ Logger.Debug($"Loading plugin: {Path.GetFileName(pluginPath)}");
// Load the assembly
var assembly = Assembly.LoadFrom(pluginPath);
-
- // Get plugin metadata from assembly attributes
- var nameAttr = assembly.GetCustomAttribute();
- var versionAttr = assembly.GetCustomAttribute();
+ var productAttr = assembly.GetCustomAttribute();
+ var versionAttr = assembly.GetCustomAttribute();
var companyAttr = assembly.GetCustomAttribute();
var descAttr = assembly.GetCustomAttribute();
var pluginInfo = new PluginInfo
{
- Name = nameAttr?.Title ?? assembly.GetName().Name,
- Version = versionAttr?.Version ?? assembly.GetName().Version?.ToString() ?? "1.0.0",
+ Name = productAttr?.Product ?? assembly.GetName().Name,
+ Version = FormatVersion(versionAttr?.InformationalVersion, assembly.GetName().Version),
Author = companyAttr?.Company ?? "Unknown",
AssemblyName = assembly.FullName,
- Description = descAttr.Description ?? ""
+ Description = descAttr?.Description ?? ""
};
// Look for IAffinityPlugin interface implementation
@@ -127,21 +125,53 @@ private static void LoadPlugin(string pluginPath, Harmony harmony)
{
var plugin = Activator.CreateInstance(pluginType) as IAffinityPlugin;
plugin?.Initialize(harmony);
- FileLog.Log($" Initialized plugin: {pluginType.Name}\n");
+ Logger.Info($"Initialized plugin: {pluginType.Name}");
}
catch (Exception ex)
{
- FileLog.Log($" Failed to initialize {pluginType.Name}: {ex.Message}\n");
+ Logger.Error($"Failed to initialize {pluginType.Name}: {ex.Message}");
}
}
}
else
{
- FileLog.Log($" No IAffinityPlugin implementation found, plugin loaded but not initialized\n");
+ Logger.Info($"No IAffinityPlugin implementation found, plugin loaded but not initialized");
}
_loadedPlugins.Add(pluginInfo);
- FileLog.Log($" Plugin loaded: {pluginInfo.Name} v{pluginInfo.Version} by {pluginInfo.Author}\n");
+ Logger.Info($"Plugin loaded: {pluginInfo.Name} v{pluginInfo.Version} by {pluginInfo.Author}");
+ }
+
+ ///
+ /// Format version string, truncating git hash to 8 chars if present
+ ///
+ private static string FormatVersion(string informationalVersion, Version assemblyVersion)
+ {
+ // If we have an informational version, process it
+ if (!string.IsNullOrEmpty(informationalVersion))
+ {
+ // Check if it contains a git hash (format: "version+hash")
+ int plusIndex = informationalVersion.IndexOf('+');
+ if (plusIndex > 0 && plusIndex < informationalVersion.Length - 1)
+ {
+ string version = informationalVersion.Substring(0, plusIndex);
+ string hash = informationalVersion.Substring(plusIndex + 1);
+
+ // Truncate hash to 8 chars if longer
+ if (hash.Length > 8)
+ {
+ hash = hash.Substring(0, 8);
+ }
+
+ return $"{version}+{hash}";
+ }
+
+ // No git hash, return as-is
+ return informationalVersion;
+ }
+
+ // Fallback to assembly version
+ return assemblyVersion?.ToString() ?? "0.0.0";
}
}
diff --git a/AffinityPluginLoader/EntryPoint.cs b/AffinityPluginLoader/EntryPoint.cs
index ef49cc1..bc541ac 100644
--- a/AffinityPluginLoader/EntryPoint.cs
+++ b/AffinityPluginLoader/EntryPoint.cs
@@ -2,6 +2,7 @@
using System.IO;
using System.Reflection;
using HarmonyLib;
+using AffinityPluginLoader.Core;
namespace AffinityPluginLoader
{
@@ -24,7 +25,7 @@ public static int Initialize(string args)
}
catch (Exception ex)
{
- FileLog.Log($"Static Initialize error: {ex.Message}\n{ex.StackTrace}\n");
+ Logger.Error("Static Initialize error", ex);
return 1;
}
}
@@ -39,12 +40,15 @@ private void InitializeInternal()
{
if (_initialized)
return;
-
+
_initialized = true;
}
-
- FileLog.Log($"AffinityPluginLoader initializing... {DateTime.UtcNow}\n");
- FileLog.Log($"Current AppDomain: {AppDomain.CurrentDomain.FriendlyName}\n");
+
+ // Initialize logger first
+ Logger.Initialize();
+
+ Logger.Info($"APL initializing... {DateTime.UtcNow}");
+ Logger.Debug($"Current AppDomain: {AppDomain.CurrentDomain.FriendlyName}");
try
{
@@ -53,29 +57,29 @@ private void InitializeInternal()
if (defaultDomain != null && defaultDomain != AppDomain.CurrentDomain)
{
- FileLog.Log($"Switching to default AppDomain: {defaultDomain.FriendlyName}\n");
-
+ Logger.Info($"Switching to default AppDomain: {defaultDomain.FriendlyName}");
+
// Since AffinityPluginLoader.dll is now in Affinity's folder,
// the default domain can find it naturally
var patcherType = typeof(DefaultDomainPatcher);
var patcher = (DefaultDomainPatcher)defaultDomain.CreateInstanceAndUnwrap(
patcherType.Assembly.FullName,
patcherType.FullName);
-
+
patcher.Initialize();
- FileLog.Log($"AffinityPluginLoader initialized in default AppDomain\n");
+ Logger.Info($"APL initialized in default AppDomain");
}
else
{
// Fallback: run in current domain
- FileLog.Log($"Running in current AppDomain\n");
+ Logger.Info($"Running in current AppDomain");
var harmony = new Harmony("dev.ncuroe.affinitypluginloader");
Core.PluginManager.Initialize(harmony);
}
}
catch (Exception ex)
{
- FileLog.Log($"Error: {ex.Message}\n{ex.StackTrace}\n");
+ Logger.Error("Error during initialization", ex);
}
}
@@ -92,7 +96,7 @@ private AppDomain GetDefaultAppDomain()
}
catch (Exception ex)
{
- FileLog.Log($"Error getting default AppDomain: {ex.Message}\n");
+ Logger.Error($"Error getting default AppDomain: {ex.Message}");
}
return null;
@@ -106,14 +110,14 @@ public void Initialize()
{
try
{
- HarmonyLib.FileLog.Log($"DefaultDomainPatcher running in AppDomain: {AppDomain.CurrentDomain.FriendlyName}\n");
-
+ Logger.Debug($"DefaultDomainPatcher running in AppDomain: {AppDomain.CurrentDomain.FriendlyName}");
+
var harmony = new Harmony("dev.ncuroe.affinitypluginloader");
Core.PluginManager.Initialize(harmony);
}
catch (Exception ex)
{
- HarmonyLib.FileLog.Log($"Error in DefaultDomainPatcher: {ex.Message}\n{ex.StackTrace}\n");
+ Logger.Error("Error in DefaultDomainPatcher", ex);
}
}
}
diff --git a/AffinityPluginLoader/Patches/LoaderPatches.cs b/AffinityPluginLoader/Patches/LoaderPatches.cs
index a51b074..0443e93 100644
--- a/AffinityPluginLoader/Patches/LoaderPatches.cs
+++ b/AffinityPluginLoader/Patches/LoaderPatches.cs
@@ -2,6 +2,7 @@
using System.Linq;
using System.Reflection;
using HarmonyLib;
+using AffinityPluginLoader.Core;
namespace AffinityPluginLoader.Patches
{
@@ -12,16 +13,19 @@ public static class LoaderPatches
{
private static Harmony _harmony;
private static bool _patchesApplied = false;
+ private static string _assemblyVersion = "";
- public static void ApplyPatches(Harmony harmony)
+ public static void ApplyPatches(Harmony harmony, PluginInfo plugin)
{
_harmony = harmony;
-
- FileLog.Log($"Applying AffinityPluginLoader patches...\n");
-
+
+ Logger.Info($"Applying Affinity Plugin Loader patches...");
+
+ _assemblyVersion = plugin.Version ?? "not found";
+
// Apply version string patches
ApplyVersionPatches();
-
+
// Apply preferences dialog patches
PreferencesPatches.ApplyPatches(harmony);
}
@@ -36,20 +40,20 @@ private static void ApplyVersionPatches()
// Find the Serif.Affinity assembly
var serifAssembly = AppDomain.CurrentDomain.GetAssemblies()
.FirstOrDefault(a => a.GetName().Name == "Serif.Affinity");
-
+
if (serifAssembly == null)
{
- FileLog.Log($"ERROR: Serif.Affinity assembly not found\n");
+ Logger.Error($"ERROR: Serif.Affinity assembly not found");
return;
}
-
- FileLog.Log($"Found Serif.Affinity assembly: {serifAssembly.GetName().Version}\n");
-
+
+ Logger.Info($"Found Serif.Affinity assembly: {serifAssembly.GetName().Version}");
+
// Get the Application type
var applicationType = serifAssembly.GetType("Serif.Affinity.Application");
if (applicationType == null)
{
- FileLog.Log($"ERROR: Application type not found\n");
+ Logger.Error($"ERROR: Application type not found");
return;
}
@@ -59,23 +63,22 @@ private static void ApplyVersionPatches()
{
var postfix = typeof(LoaderPatches).GetMethod(nameof(GetVerboseVersionString_Postfix), BindingFlags.Static | BindingFlags.Public);
_harmony.Patch(getVerboseVersionString, postfix: new HarmonyMethod(postfix));
- FileLog.Log($"Patched GetCurrentVerboseVersionString\n");
+ Logger.Info($"Patched GetCurrentVerboseVersionString");
}
-
+
_patchesApplied = true;
- FileLog.Log($"Version patches applied successfully!\n");
+ Logger.Info($"Version patches applied successfully!");
}
catch (Exception ex)
{
- FileLog.Log($"Failed to apply version patches: {ex.Message}\n{ex.StackTrace}\n");
+ Logger.Error("Failed to apply version patches", ex);
}
}
// Postfix for GetCurrentVerboseVersionString (splash screen)
public static void GetVerboseVersionString_Postfix(ref string __result)
{
- var version = Assembly.GetExecutingAssembly().GetName().Version;
- __result = __result + $" (AffinityPluginLoader {version})";
+ __result = __result + $" (APL {_assemblyVersion})";
}
}
}
diff --git a/AffinityPluginLoader/Patches/PreferencesPatches.cs b/AffinityPluginLoader/Patches/PreferencesPatches.cs
index 31024c6..2c5daa0 100644
--- a/AffinityPluginLoader/Patches/PreferencesPatches.cs
+++ b/AffinityPluginLoader/Patches/PreferencesPatches.cs
@@ -2,6 +2,7 @@
using System.Linq;
using System.Reflection;
using HarmonyLib;
+using AffinityPluginLoader.Core;
using AffinityPluginLoader.UI;
namespace AffinityPluginLoader.Patches
@@ -15,23 +16,23 @@ public static void ApplyPatches(Harmony harmony)
{
try
{
- FileLog.Log($"Applying PreferencesDialog patches\n");
-
+ Logger.Info($"Applying PreferencesDialog patches");
+
// Find the Serif.Affinity assembly
var serifAssembly = AppDomain.CurrentDomain.GetAssemblies()
.FirstOrDefault(a => a.GetName().Name == "Serif.Affinity");
-
+
if (serifAssembly == null)
{
- FileLog.Log($"ERROR: Serif.Affinity assembly not found for preferences patch\n");
+ Logger.Error($"ERROR: Serif.Affinity assembly not found for preferences patch");
return;
}
-
+
// Get the PreferencesDialog type
var preferencesDialogType = serifAssembly.GetType("Serif.Affinity.UI.Dialogs.Preferences.PreferencesDialog");
if (preferencesDialogType == null)
{
- FileLog.Log($"ERROR: PreferencesDialog type not found\n");
+ Logger.Error($"ERROR: PreferencesDialog type not found");
return;
}
@@ -44,19 +45,19 @@ public static void ApplyPatches(Harmony harmony)
if (constructor != null)
{
- FileLog.Log($"Found PreferencesDialog constructor\n");
+ Logger.Info($"Found PreferencesDialog constructor");
var postfix = typeof(PreferencesPatches).GetMethod(nameof(PreferencesDialog_Constructor_Postfix), BindingFlags.Static | BindingFlags.Public);
harmony.Patch(constructor, postfix: new HarmonyMethod(postfix));
- FileLog.Log($"Patched PreferencesDialog constructor\n");
+ Logger.Info($"Patched PreferencesDialog constructor");
}
else
{
- FileLog.Log($"ERROR: PreferencesDialog constructor not found\n");
+ Logger.Error($"ERROR: PreferencesDialog constructor not found");
}
}
catch (Exception ex)
{
- FileLog.Log($"Failed to apply preferences patches: {ex.Message}\n{ex.StackTrace}\n");
+ Logger.Error("Failed to apply preferences patches", ex);
}
}
@@ -65,22 +66,22 @@ public static void PreferencesDialog_Constructor_Postfix(object __instance)
{
try
{
- FileLog.Log($"PreferencesDialog constructor postfix called\n");
-
+ Logger.Debug($"PreferencesDialog constructor postfix called");
+
// Get the type of the dialog
var dialogType = __instance.GetType();
-
+
// Find the property that holds the pages (it's called "Pages")
var pagesProperty = dialogType.GetProperty("Pages", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
-
+
if (pagesProperty != null)
{
var pages = pagesProperty.GetValue(__instance);
if (pages is System.Collections.IList pageList)
{
- FileLog.Log($"Found Pages property with {pageList.Count} existing pages\n");
+ Logger.Debug($"Found Pages property with {pageList.Count} existing pages");
- // Add a separator before the AffinityPluginLoader tab
+ // Add a separator before the Affinity Plugin Loader tab
var serifAssembly = AppDomain.CurrentDomain.GetAssemblies()
.FirstOrDefault(a => a.GetName().Name == "Serif.Affinity");
@@ -97,13 +98,13 @@ public static void PreferencesDialog_Constructor_Postfix(object __instance)
{
indexProperty.SetValue(separator, pageList.Count);
}
-
+
pageList.Add(separator);
- FileLog.Log($"Added separator to preferences dialog\n");
+ Logger.Debug($"Added separator to preferences dialog");
}
else
{
- FileLog.Log($"PreferencesPageSeparator type not found, skipping separator\n");
+ Logger.Debug($"PreferencesPageSeparator type not found, skipping separator");
}
}
@@ -118,24 +119,24 @@ public static void PreferencesDialog_Constructor_Postfix(object __instance)
{
indexProperty.SetValue(pluginsPage, pageList.Count);
}
-
+
pageList.Add(pluginsPage);
- FileLog.Log($"Added AffinityPluginLoader tab to preferences dialog\n");
+ Logger.Info($"Added Affinity Plugin Loader tab to preferences dialog");
}
}
else
{
- FileLog.Log($"Pages property is not IList: {pages?.GetType()?.FullName}\n");
+ Logger.Debug($"Pages property is not IList: {pages?.GetType()?.FullName}");
}
}
else
{
- FileLog.Log($"Could not find Pages property in PreferencesDialog\n");
+ Logger.Debug($"Could not find Pages property in PreferencesDialog");
}
}
catch (Exception ex)
{
- FileLog.Log($"Error in PreferencesDialog postfix: {ex.Message}\n{ex.StackTrace}\n");
+ Logger.Error("Error in PreferencesDialog postfix", ex);
}
}
}
diff --git a/AffinityPluginLoader/UI/PluginsPreferencesPage.cs b/AffinityPluginLoader/UI/PluginsPreferencesPage.cs
index 75d7cd5..e3fadb2 100644
--- a/AffinityPluginLoader/UI/PluginsPreferencesPage.cs
+++ b/AffinityPluginLoader/UI/PluginsPreferencesPage.cs
@@ -5,6 +5,7 @@
using System.Windows;
using System.Windows.Controls;
using System.Windows.Markup;
+using AffinityPluginLoader.Core;
namespace AffinityPluginLoader.UI
{
@@ -28,23 +29,23 @@ public static object CreatePage()
{
try
{
- HarmonyLib.FileLog.Log($"Creating PluginsPreferencesPage\n");
-
+ Logger.Debug($"Creating PluginsPreferencesPage");
+
// Find Serif.Affinity assembly (it's already loaded in the Affinity process)
var serifAssembly = AppDomain.CurrentDomain.GetAssemblies()
.FirstOrDefault(a => a.GetName().Name == "Serif.Affinity");
-
+
if (serifAssembly == null)
{
- HarmonyLib.FileLog.Log($"ERROR: Serif.Affinity not found\n");
+ Logger.Error($"ERROR: Serif.Affinity not found");
return null;
}
-
+
// Get PreferencesPage base type
var preferencesPageType = serifAssembly.GetType("Serif.Affinity.UI.Dialogs.Preferences.PreferencesPage");
if (preferencesPageType == null)
{
- HarmonyLib.FileLog.Log($"ERROR: PreferencesPage type not found\n");
+ Logger.Error($"ERROR: PreferencesPage type not found");
return null;
}
@@ -67,7 +68,7 @@ public static object CreatePage()
if (content == null)
{
- HarmonyLib.FileLog.Log($"ERROR: Could not load XAML\n");
+ Logger.Error($"ERROR: Could not load XAML");
return null;
}
@@ -102,15 +103,15 @@ public static object CreatePage()
var pageNameProperty = preferencesPageType.GetProperty("PageName");
if (pageNameProperty != null)
{
- pageNameProperty.SetValue(grid, "AffinityPluginLoader");
+ pageNameProperty.SetValue(grid, "Affinity Plugin Loader");
}
-
- HarmonyLib.FileLog.Log($"PluginsPreferencesPage created successfully\n");
+
+ Logger.Debug($"PluginsPreferencesPage created successfully");
return grid;
}
catch (Exception ex)
{
- HarmonyLib.FileLog.Log($"Error creating PluginsPreferencesPage: {ex.Message}\n{ex.StackTrace}\n");
+ Logger.Error("Error creating PluginsPreferencesPage", ex);
return null;
}
}
diff --git a/WineFix/Patches/MainWindowLoadedPatch.cs b/WineFix/Patches/MainWindowLoadedPatch.cs
index 1a27d8f..c4f0326 100644
--- a/WineFix/Patches/MainWindowLoadedPatch.cs
+++ b/WineFix/Patches/MainWindowLoadedPatch.cs
@@ -4,6 +4,7 @@
using System.Reflection;
using System.Reflection.Emit;
using HarmonyLib;
+using AffinityPluginLoader.Core;
namespace WineFix.Patches
{
@@ -18,23 +19,23 @@ public static void ApplyPatches(Harmony harmony)
{
try
{
- HarmonyLib.FileLog.Log($"Applying MainWindowLoaded patch (Wine fix)...\n");
-
+ Logger.Info($"Applying MainWindowLoaded patch (Wine fix)...");
+
// Find the Serif.Affinity assembly
var serifAssembly = AppDomain.CurrentDomain.GetAssemblies()
.FirstOrDefault(a => a.GetName().Name == "Serif.Affinity");
-
+
if (serifAssembly == null)
{
- HarmonyLib.FileLog.Log($"ERROR: Serif.Affinity assembly not found\n");
+ Logger.Error($"ERROR: Serif.Affinity assembly not found");
return;
}
-
+
// Get the Application type
var applicationType = serifAssembly.GetType("Serif.Affinity.Application");
if (applicationType == null)
{
- HarmonyLib.FileLog.Log($"ERROR: Application type not found\n");
+ Logger.Error($"ERROR: Application type not found");
return;
}
@@ -45,19 +46,19 @@ public static void ApplyPatches(Harmony harmony)
if (onMainWindowLoaded != null)
{
// Use transpiler to modify the IL
- var transpiler = typeof(MainWindowLoadedPatch).GetMethod(nameof(OnMainWindowLoaded_Transpiler),
+ var transpiler = typeof(MainWindowLoadedPatch).GetMethod(nameof(OnMainWindowLoaded_Transpiler),
BindingFlags.Static | BindingFlags.Public);
harmony.Patch(onMainWindowLoaded, transpiler: new HarmonyMethod(transpiler));
- HarmonyLib.FileLog.Log($"Patched OnMainWindowLoaded to skip HasPreviousPackageInstalled call\n");
+ Logger.Info($"Patched OnMainWindowLoaded to skip HasPreviousPackageInstalled call");
}
else
{
- HarmonyLib.FileLog.Log($"ERROR: OnMainWindowLoaded method not found\n");
+ Logger.Error($"ERROR: OnMainWindowLoaded method not found");
}
}
catch (Exception ex)
{
- HarmonyLib.FileLog.Log($"Failed to apply MainWindowLoaded patch: {ex.Message}\n{ex.StackTrace}\n");
+ Logger.Error("Failed to apply MainWindowLoaded patch", ex);
}
}
@@ -75,13 +76,13 @@ public static IEnumerable OnMainWindowLoaded_Transpiler(IEnumer
// Look for: call instance bool Serif.Affinity.Application::HasPreviousPackageInstalled()
// (Index 1 in the IL - this is a non-virtual call, not callvirt!)
- if (!patchedPackageCheck &&
+ if (!patchedPackageCheck &&
(instruction.opcode == OpCodes.Call || instruction.opcode == OpCodes.Callvirt) &&
instruction.operand is MethodInfo method &&
method.Name == "HasPreviousPackageInstalled")
{
- HarmonyLib.FileLog.Log($"Found HasPreviousPackageInstalled call at instruction {i}\n");
-
+ Logger.Debug($"Found HasPreviousPackageInstalled call at instruction {i}");
+
// Replace: ldarg.0 + call HasPreviousPackageInstalled
// With: ldc.i4.0 (just load false, skip the ldarg.0 before it)
// Check if previous instruction is ldarg.0
@@ -91,19 +92,19 @@ instruction.operand is MethodInfo method &&
var newLoadFalse = new CodeInstruction(OpCodes.Ldc_I4_0);
newLoadFalse.labels.AddRange(codes[i - 1].labels); // Transfer labels!
codes[i - 1] = newLoadFalse;
-
+
var newNop = new CodeInstruction(OpCodes.Nop);
newNop.labels.AddRange(codes[i].labels); // Transfer labels!
codes[i] = newNop;
-
- HarmonyLib.FileLog.Log($"Replaced ldarg.0 + HasPreviousPackageInstalled with 'ldc.i4.0' (false)\n");
+
+ Logger.Debug($"Replaced ldarg.0 + HasPreviousPackageInstalled with 'ldc.i4.0' (false)");
}
else
{
// Fallback: just replace the call
codes[i] = new CodeInstruction(OpCodes.Pop);
codes.Insert(i + 1, new CodeInstruction(OpCodes.Ldc_I4_0));
- HarmonyLib.FileLog.Log($"Replaced HasPreviousPackageInstalled call with 'false' (fallback)\n");
+ Logger.Debug($"Replaced HasPreviousPackageInstalled call with 'false' (fallback)");
}
patchedPackageCheck = true;
@@ -120,36 +121,36 @@ instruction.operand is MethodInfo baseMethod &&
(baseMethod.DeclaringType.FullName == "Serif.Interop.Persona.Application" ||
baseMethod.DeclaringType.FullName == "System.Windows.Application"))
{
- HarmonyLib.FileLog.Log($"Found base.OnMainWindowLoaded call at instruction {i}\n");
-
+ Logger.Debug($"Found base.OnMainWindowLoaded call at instruction {i}");
+
// The IL sequence is (indices 20-22):
// ldarg.0 ; load 'this'
// ldarg.1 ; load 'mainWindow'
// call base.OnMainWindowLoaded
// Replace all three with NOPs, preserving labels
- if (i >= 2 &&
- codes[i - 2].opcode == OpCodes.Ldarg_0 &&
+ if (i >= 2 &&
+ codes[i - 2].opcode == OpCodes.Ldarg_0 &&
codes[i - 1].opcode == OpCodes.Ldarg_1)
{
// Create NOPs but preserve labels
var nop1 = new CodeInstruction(OpCodes.Nop);
nop1.labels.AddRange(codes[i - 2].labels);
codes[i - 2] = nop1;
-
+
var nop2 = new CodeInstruction(OpCodes.Nop);
nop2.labels.AddRange(codes[i - 1].labels);
codes[i - 1] = nop2;
-
+
var nop3 = new CodeInstruction(OpCodes.Nop);
nop3.labels.AddRange(codes[i].labels);
codes[i] = nop3;
-
- HarmonyLib.FileLog.Log($"Removed base.OnMainWindowLoaded call (indices {i-2} to {i})\n");
+
+ Logger.Debug($"Removed base.OnMainWindowLoaded call (indices {i-2} to {i})");
patchedBaseCall = true;
}
else
{
- HarmonyLib.FileLog.Log($"WARNING: Found base.OnMainWindowLoaded but preceding instructions don't match expected pattern\n");
+ Logger.Warning($"WARNING: Found base.OnMainWindowLoaded but preceding instructions don't match expected pattern");
var nop = new CodeInstruction(OpCodes.Nop);
nop.labels.AddRange(codes[i].labels);
codes[i] = nop;
@@ -161,12 +162,12 @@ instruction.operand is MethodInfo baseMethod &&
if (!patchedPackageCheck)
{
- HarmonyLib.FileLog.Log($"WARNING: Could not find HasPreviousPackageInstalled call to patch\n");
+ Logger.Warning($"WARNING: Could not find HasPreviousPackageInstalled call to patch");
}
-
+
if (!patchedBaseCall)
{
- HarmonyLib.FileLog.Log($"WARNING: Could not find base.OnMainWindowLoaded call to patch\n");
+ Logger.Warning($"WARNING: Could not find base.OnMainWindowLoaded call to patch");
}
return codes.AsEnumerable();
diff --git a/WineFix/WineFix.csproj b/WineFix/WineFix.csproj
index 4a702c4..c64b1c6 100644
--- a/WineFix/WineFix.csproj
+++ b/WineFix/WineFix.csproj
@@ -7,10 +7,12 @@
x64
- WineFix
+ WineFix
Plugin to fix Wine compatibility issues in Affinity applications
0.2.0
- Noah Curoe & WineFix Contributors
+ Noah Curoe & WineFix Contributors
+
+ false
diff --git a/WineFix/WineFixPlugin.cs b/WineFix/WineFixPlugin.cs
index a0a1c6d..8ece872 100644
--- a/WineFix/WineFixPlugin.cs
+++ b/WineFix/WineFixPlugin.cs
@@ -1,5 +1,6 @@
using System;
using HarmonyLib;
+using AffinityPluginLoader.Core;
namespace WineFix
{
@@ -12,16 +13,16 @@ public void Initialize(Harmony harmony)
{
try
{
- FileLog.Log($"WineFix plugin initializing...\n");
-
+ Logger.Info($"WineFix plugin initializing...");
+
// Apply Wine compatibility patches
Patches.MainWindowLoadedPatch.ApplyPatches(harmony);
-
- FileLog.Log($"WineFix plugin initialized successfully\n");
+
+ Logger.Info($"WineFix plugin initialized successfully");
}
catch (Exception ex)
{
- FileLog.Log($"Error initializing WineFix: {ex.Message}\n{ex.StackTrace}\n");
+ Logger.Error("Error initializing WineFix", ex);
}
}
}
diff --git a/build.bat b/build.bat
index d39593a..b1f3f05 100644
--- a/build.bat
+++ b/build.bat
@@ -4,6 +4,9 @@ REM Builds both .NET assemblies and native AffinityBootstrap.dll
setlocal enabledelayedexpansion
+set CONFIGURATION=%1
+if "%CONFIGURATION%"=="" set CONFIGURATION=Release
+
echo ========================================
echo Building AffinityPluginLoader
echo ========================================
@@ -11,7 +14,7 @@ echo.
REM Build .NET projects
echo [1/2] Building .NET projects...
-dotnet build -c Release
+dotnet build -c %CONFIGURATION%
if %errorlevel% neq 0 (
echo Error: .NET build failed
exit /b 1
diff --git a/build.sh b/build.sh
index 86323c3..c0f720a 100755
--- a/build.sh
+++ b/build.sh
@@ -3,6 +3,8 @@
# Builds both .NET assemblies and native AffinityBootstrap.dll
set -e
+CONFIGURATION="${1:-Release}"
+
ROOTDIR=$(dirname "$(readlink -f "$0")")
pushd "$ROOTDIR"
@@ -14,7 +16,7 @@ echo
# Build .NET projects
echo "[1/2] Building .NET projects..."
-dotnet build -c Release
+dotnet build -c "$CONFIGURATION"
echo
# Build AffinityBootstrap
diff --git a/package-release.ps1 b/package-release.ps1
index d02c6f2..bb35fc6 100644
--- a/package-release.ps1
+++ b/package-release.ps1
@@ -3,14 +3,18 @@
# Creates release archives for distribution
param(
- [switch]$SkipBuild
+ [switch]$SkipBuild,
+ [switch]$Debug
)
$ErrorActionPreference = "Stop"
+$Configuration = if ($Debug) { "Debug" } else { "Release" }
+
Write-Host "========================================" -ForegroundColor Cyan
Write-Host "AffinityPluginLoader Release Packaging" -ForegroundColor Cyan
Write-Host "========================================" -ForegroundColor Cyan
+Write-Host "Configuration: $Configuration" -ForegroundColor Green
Write-Host
# Function to parse version from .csproj file
@@ -30,7 +34,11 @@ function Get-ProjectVersion {
# Build everything if not skipping
if (-not $SkipBuild) {
Write-Host "[1/4] Building all projects..." -ForegroundColor Yellow
- & .\build.bat
+ if ($Debug) {
+ & .\build.bat Debug
+ } else {
+ & .\build.bat
+ }
if ($LASTEXITCODE -ne 0) {
throw "Build failed"
}
@@ -61,10 +69,10 @@ $apl_temp = "releases\apl_temp"
New-Item -ItemType Directory -Path $apl_temp | Out-Null
# Copy files for AffinityPluginLoader package
-Copy-Item "AffinityPluginLoader\bin\Release\net48\win-x64\0Harmony.dll" $apl_temp
+Copy-Item "AffinityPluginLoader\bin\$Configuration\net48\win-x64\0Harmony.dll" $apl_temp
Copy-Item "AffinityBootstrap\build\AffinityBootstrap.dll" $apl_temp
-Copy-Item "AffinityHook\bin\Release\net48\win-x64\AffinityHook.exe" $apl_temp
-Copy-Item "AffinityPluginLoader\bin\Release\net48\win-x64\AffinityPluginLoader.dll" $apl_temp
+Copy-Item "AffinityHook\bin\$Configuration\net48\win-x64\AffinityHook.exe" $apl_temp
+Copy-Item "AffinityPluginLoader\bin\$Configuration\net48\win-x64\AffinityPluginLoader.dll" $apl_temp
Copy-Item "README.md" $apl_temp
Copy-Item "AffinityPluginLoader\LICENSE" $apl_temp
@@ -83,7 +91,7 @@ New-Item -ItemType Directory -Path "$winefix_temp\plugins" | Out-Null
# Copy files for WineFix package
Copy-Item "README.md" $winefix_temp
Copy-Item "WineFix\LICENSE" $winefix_temp
-Copy-Item "WineFix\bin\Release\net48\win-x64\WineFix.dll" "$winefix_temp\plugins\"
+Copy-Item "WineFix\bin\$Configuration\net48\win-x64\WineFix.dll" "$winefix_temp\plugins\"
# Create zip
Compress-Archive -Path "$winefix_temp\*" -DestinationPath "releases\winefix-v$winefix_version.zip" -Force
@@ -98,11 +106,11 @@ New-Item -ItemType Directory -Path $combined_temp | Out-Null
New-Item -ItemType Directory -Path "$combined_temp\plugins" | Out-Null
# Copy files for combined package
-Copy-Item "AffinityPluginLoader\bin\Release\net48\win-x64\0Harmony.dll" $combined_temp
+Copy-Item "AffinityPluginLoader\bin\$Configuration\net48\win-x64\0Harmony.dll" $combined_temp
Copy-Item "AffinityBootstrap\build\AffinityBootstrap.dll" $combined_temp
-Copy-Item "AffinityHook\bin\Release\net48\win-x64\AffinityHook.exe" $combined_temp
-Copy-Item "AffinityPluginLoader\bin\Release\net48\win-x64\AffinityPluginLoader.dll" $combined_temp
-Copy-Item "WineFix\bin\Release\net48\win-x64\WineFix.dll" "$combined_temp\plugins\"
+Copy-Item "AffinityHook\bin\$Configuration\net48\win-x64\AffinityHook.exe" $combined_temp
+Copy-Item "AffinityPluginLoader\bin\$Configuration\net48\win-x64\AffinityPluginLoader.dll" $combined_temp
+Copy-Item "WineFix\bin\$Configuration\net48\win-x64\WineFix.dll" "$combined_temp\plugins\"
# Create tar.xz (requires tar command, available in Windows 10+)
$tar_path = "releases\affinitypluginloader-plus-winefix.tar"
diff --git a/package-release.sh b/package-release.sh
index 311f9e6..3570295 100755
--- a/package-release.sh
+++ b/package-release.sh
@@ -5,13 +5,29 @@
set -e
SKIP_BUILD=false
-if [ "$1" = "--skip-build" ]; then
- SKIP_BUILD=true
-fi
+CONFIGURATION="Release"
+
+# Parse arguments
+for arg in "$@"; do
+ case $arg in
+ --skip-build)
+ SKIP_BUILD=true
+ ;;
+ --debug)
+ CONFIGURATION="Debug"
+ ;;
+ *)
+ echo "Unknown argument: $arg"
+ echo "Usage: $0 [--skip-build] [--debug]"
+ exit 1
+ ;;
+ esac
+done
echo "========================================"
echo "AffinityPluginLoader Release Packaging"
echo "========================================"
+echo "Configuration: $CONFIGURATION"
echo
# Function to parse version from .csproj file
@@ -30,7 +46,11 @@ get_project_version() {
# Build everything if not skipping
if [ "$SKIP_BUILD" = false ]; then
echo "[1/4] Building all projects..."
- bash build.sh
+ if [ "$CONFIGURATION" = "Debug" ]; then
+ bash build.sh Debug
+ else
+ bash build.sh
+ fi
echo
else
echo "[1/4] Skipping build (using existing binaries)..."
@@ -58,10 +78,10 @@ APL_TEMP="$OUTPUT_DIR/apl_temp"
mkdir -p "$APL_TEMP"
# Copy files for AffinityPluginLoader package
-cp "AffinityPluginLoader/bin/x64/Release/net48/win-x64/0Harmony.dll" "$APL_TEMP/"
+cp "AffinityPluginLoader/bin/x64/$CONFIGURATION/net48/win-x64/0Harmony.dll" "$APL_TEMP/"
cp "AffinityBootstrap/build/AffinityBootstrap.dll" "$APL_TEMP/"
-cp "AffinityHook/bin/x64/Release/net48/win-x64/AffinityHook.exe" "$APL_TEMP/"
-cp "AffinityPluginLoader/bin/x64/Release/net48/win-x64/AffinityPluginLoader.dll" "$APL_TEMP/"
+cp "AffinityHook/bin/x64/$CONFIGURATION/net48/win-x64/AffinityHook.exe" "$APL_TEMP/"
+cp "AffinityPluginLoader/bin/x64/$CONFIGURATION/net48/win-x64/AffinityPluginLoader.dll" "$APL_TEMP/"
cp "README.md" "$APL_TEMP/"
cp "AffinityPluginLoader/LICENSE" "$APL_TEMP/"
@@ -79,7 +99,7 @@ mkdir -p "$WINEFIX_TEMP/plugins"
# Copy files for WineFix package
cp "README.md" "$WINEFIX_TEMP/"
cp "WineFix/LICENSE" "$WINEFIX_TEMP/"
-cp "WineFix/bin/x64/Release/net48/win-x64/WineFix.dll" "$WINEFIX_TEMP/plugins/"
+cp "WineFix/bin/x64/$CONFIGURATION/net48/win-x64/WineFix.dll" "$WINEFIX_TEMP/plugins/"
# Create zip
(cd "$WINEFIX_TEMP" && zip -q -r "../winefix-v$WINEFIX_VERSION.zip" *)
@@ -93,11 +113,11 @@ COMBINED_TEMP="$OUTPUT_DIR/combined_temp"
mkdir -p "$COMBINED_TEMP/plugins"
# Copy files for combined package
-cp "AffinityPluginLoader/bin/x64/Release/net48/win-x64/0Harmony.dll" "$COMBINED_TEMP/"
+cp "AffinityPluginLoader/bin/x64/$CONFIGURATION/net48/win-x64/0Harmony.dll" "$COMBINED_TEMP/"
cp "AffinityBootstrap/build/AffinityBootstrap.dll" "$COMBINED_TEMP/"
-cp "AffinityHook/bin/x64/Release/net48/win-x64/AffinityHook.exe" "$COMBINED_TEMP/"
-cp "AffinityPluginLoader/bin/x64/Release/net48/win-x64/AffinityPluginLoader.dll" "$COMBINED_TEMP/"
-cp "WineFix/bin/x64/Release/net48/win-x64/WineFix.dll" "$COMBINED_TEMP/plugins/"
+cp "AffinityHook/bin/x64/$CONFIGURATION/net48/win-x64/AffinityHook.exe" "$COMBINED_TEMP/"
+cp "AffinityPluginLoader/bin/x64/$CONFIGURATION/net48/win-x64/AffinityPluginLoader.dll" "$COMBINED_TEMP/"
+cp "WineFix/bin/x64/$CONFIGURATION/net48/win-x64/WineFix.dll" "$COMBINED_TEMP/plugins/"
# Create tar.xz
tar -C "$COMBINED_TEMP" -cJf "$OUTPUT_DIR/affinitypluginloader-plus-winefix.tar.xz" .