Skip to content

Commit

Permalink
(GH-785) Add assembly resolver to CLI and GUI
Browse files Browse the repository at this point in the history
This will be responsible for ensuring that a version of the
ChocolateyGui.Common and ChocolateyGui.Common.Windows assemblies
are loaded into the current process.  As long as the Public Key of the
requested assembly matching what the host process has been compiled
with, then it will be returned.  The compiled version number does not
need to match.  This will mean that the Chocolatey GUI Extension will
work with multiple versions of Chocolatey GUI, in the same was as the
Chocolatey Extension works with multiple versions of Chocolatey.
  • Loading branch information
gep13 committed Jul 13, 2020
1 parent 0701d71 commit b5d7a72
Show file tree
Hide file tree
Showing 2 changed files with 93 additions and 2 deletions.
43 changes: 43 additions & 0 deletions Source/ChocolateyGui/App.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,11 @@
// --------------------------------------------------------------------------------------------------------------------

using System;
using System.Reflection;
using System.Windows;
using Autofac;
using chocolatey;
using chocolatey.infrastructure.registration;
using ChocolateyGui.Common.Services;
using ChocolateyGui.Common.Windows;

Expand All @@ -22,6 +25,46 @@ public partial class App

public App()
{
AppDomain.CurrentDomain.AssemblyResolve += (sender, args) =>
{
var requestedAssembly = new AssemblyName(args.Name);

#if FORCE_CHOCOLATEY_OFFICIAL_KEY
var chocolateyGuiPublicKey = Bootstrapper.OfficialChocolateyPublicKey;
#else
var chocolateyGuiPublicKey = Bootstrapper.UnofficialChocolateyPublicKey;
#endif

try
{
if (requestedAssembly.get_public_key_token().is_equal_to(chocolateyGuiPublicKey)
&& requestedAssembly.Name.is_equal_to(Bootstrapper.ChocolateyGuiCommonAssemblySimpleName))
{
return AssemblyResolution.resolve_or_load_assembly(
Bootstrapper.ChocolateyGuiCommonAssemblySimpleName,
requestedAssembly.get_public_key_token(),
Bootstrapper.ChocolateyGuiCommonAssemblyLocation).UnderlyingType;
}

if (requestedAssembly.get_public_key_token().is_equal_to(chocolateyGuiPublicKey)
&& requestedAssembly.Name.is_equal_to(Bootstrapper.ChocolateyGuiCommonWindowsAssemblySimpleName))
{
return AssemblyResolution.resolve_or_load_assembly(
Bootstrapper.ChocolateyGuiCommonWindowsAssemblySimpleName,
requestedAssembly.get_public_key_token(),
Bootstrapper.ChocolateyGuiCommonWindowsAssemblyLocation).UnderlyingType;
}
}
catch (Exception ex)
{
var errorMessage = string.Format("Unable to load Chocolatey GUI assembly. {0}", ex.Message);
MessageBox.Show(errorMessage);
throw new ApplicationException(errorMessage);
}

return null;
};

InitializeComponent();
}

Expand Down
52 changes: 50 additions & 2 deletions Source/ChocolateyGuiCli/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,24 +8,27 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;
using Autofac;
using chocolatey;
using chocolatey.infrastructure.adapters;
using chocolatey.infrastructure.commandline;
using chocolatey.infrastructure.information;
using ChocolateyGui.Common;
using chocolatey.infrastructure.registration;
using ChocolateyGui.Common.Attributes;
using ChocolateyGui.Common.Commands;
using ChocolateyGui.Common.Models;
using Assembly = chocolatey.infrastructure.adapters.Assembly;
using Console = System.Console;
using GenericRunner = ChocolateyGui.Common.Commands.GenericRunner;

namespace ChocolateyGuiCli
{
public class Program
{
private static readonly OptionSet _optionSet = new OptionSet();
private static ResolveEventHandler _handler = null;

public static OptionSet OptionSet
{
Expand All @@ -34,6 +37,8 @@ public static OptionSet OptionSet

public static void Main(string[] args)
{
AddAssemblyResolver();

Bootstrapper.Configure();

var commandName = string.Empty;
Expand Down Expand Up @@ -90,6 +95,49 @@ public static void Main(string[] args)
});
}

private static void AddAssemblyResolver()
{
_handler = (sender, args) =>
{
var requestedAssembly = new AssemblyName(args.Name);

#if FORCE_CHOCOLATEY_OFFICIAL_KEY
var chocolateyGuiPublicKey = Bootstrapper.OfficialChocolateyPublicKey;
#else
var chocolateyGuiPublicKey = Bootstrapper.UnofficialChocolateyPublicKey;
#endif

try
{
if (requestedAssembly.get_public_key_token().is_equal_to(chocolateyGuiPublicKey)
&& requestedAssembly.Name.is_equal_to(Bootstrapper.ChocolateyGuiCommonAssemblySimpleName))
{
return AssemblyResolution.resolve_or_load_assembly(
Bootstrapper.ChocolateyGuiCommonAssemblySimpleName,
requestedAssembly.get_public_key_token(),
Bootstrapper.ChocolateyGuiCommonAssemblyLocation).UnderlyingType;
}

if (requestedAssembly.get_public_key_token().is_equal_to(chocolateyGuiPublicKey)
&& requestedAssembly.Name.is_equal_to(Bootstrapper.ChocolateyGuiCommonWindowsAssemblySimpleName))
{
return AssemblyResolution.resolve_or_load_assembly(
Bootstrapper.ChocolateyGuiCommonWindowsAssemblySimpleName,
requestedAssembly.get_public_key_token(),
Bootstrapper.ChocolateyGuiCommonWindowsAssemblyLocation).UnderlyingType;
}
}
catch (Exception ex)
{
Bootstrapper.Logger.Warning("Unable to load Chocolatey GUI assembly. {0}".format_with(ex.Message));
}

return null;
};

AppDomain.CurrentDomain.AssemblyResolve += _handler;
}

private static void SetUpGlobalOptions(IList<string> args, ChocolateyGuiConfiguration configuration, IContainer container)
{
ParseArgumentsAndUpdateConfiguration(
Expand Down

0 comments on commit b5d7a72

Please sign in to comment.