Skip to content

Commit

Permalink
Merge branch 'hotfix/0.18.2' into develop
Browse files Browse the repository at this point in the history
* hotfix/0.18.2:
  (maint) Update to use correct URL
  (#880) Use PNG for Nuspec IconUrl
  (#857) Load Chocolatey executable assembly
  • Loading branch information
gep13 committed Sep 2, 2021
2 parents 0256e2f + 230a811 commit 0c626b4
Show file tree
Hide file tree
Showing 12 changed files with 472 additions and 288 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@
</Reference>
<Reference Include="chocolatey, Version=0.10.15.0, Culture=neutral, PublicKeyToken=79d02ea9cad655eb, processorArchitecture=MSIL">
<HintPath>..\packages\chocolatey.lib.0.10.15\lib\chocolatey.dll</HintPath>
<SpecificVersion>False</SpecificVersion>
<Private>False</Private>
</Reference>
<Reference Include="ControlzEx, Version=4.0.0.0, Culture=neutral, PublicKeyToken=69f1c32f803d307e, processorArchitecture=MSIL">
<HintPath>..\packages\ControlzEx.4.4.0\lib\net462\ControlzEx.dll</HintPath>
Expand Down
5 changes: 5 additions & 0 deletions Source/ChocolateyGui.Common/ChocolateyGui.Common.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@
</Reference>
<Reference Include="chocolatey, Version=0.10.15.0, Culture=neutral, PublicKeyToken=79d02ea9cad655eb, processorArchitecture=MSIL">
<HintPath>..\packages\chocolatey.lib.0.10.15\lib\chocolatey.dll</HintPath>
<SpecificVersion>False</SpecificVersion>
<Private>False</Private>
</Reference>
<Reference Include="LiteDB, Version=5.0.5.0, Culture=neutral, PublicKeyToken=4ee40123013c9f27, processorArchitecture=MSIL">
<HintPath>..\packages\LiteDB.5.0.5\lib\net45\LiteDB.dll</HintPath>
Expand Down Expand Up @@ -187,6 +189,7 @@
<Compile Include="Services\IVersionService.cs" />
<Compile Include="Services\LiteDBFileStorageService.cs" />
<Compile Include="Services\VersionService.cs" />
<Compile Include="Startup\AssemblyResolver.cs" />
<Compile Include="Startup\AutoFacConfiguration.cs" />
<Compile Include="Utilities\DefaultsExtensions.cs" />
<Compile Include="Utilities\LogSetup.cs" />
Expand Down Expand Up @@ -221,6 +224,8 @@
<ItemGroup>
<Analyzer Include="..\packages\StyleCop.Analyzers.1.0.2\analyzers\dotnet\cs\StyleCop.Analyzers.CodeFixes.dll" />
<Analyzer Include="..\packages\StyleCop.Analyzers.1.0.2\analyzers\dotnet\cs\StyleCop.Analyzers.dll" />
<SourceRoot Include="$(MSBuildThisFileDirectory)/../" />
<Folder Include="Startup\Adapters\" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>
106 changes: 106 additions & 0 deletions Source/ChocolateyGui.Common/Startup/AssemblyResolver.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
// <copyright file="AssemblyResolver.cs" company="Chocolatey">
// Copyright 2017 - Present Chocolatey Software, LLC
// Copyright 2014 - 2017 Rob Reynolds, the maintainers of Chocolatey, and RealDimensions Software, LLC
// </copyright>

using System;
using System.Linq;
using System.Reflection;
using System.Threading;
using Serilog;

namespace ChocolateyGui.Common.Startup
{
public class AssemblyResolver
{
private const int LOCKRESOLUTIONTIMEOUTSECONDS = 5;
private static readonly object _lockObject = new object();

/// <summary>
/// Resolves or loads an assembly. If an assembly is already loaded, no need to reload it.
/// </summary>
/// <param name="assemblySimpleName">Simple Name of the assembly, such as "chocolatey"</param>
/// <param name="publicKeyToken">The public key token.</param>
/// <param name="assemblyFileLocation">The assembly file location. Typically the path to the DLL on disk.</param>
/// <returns>An assembly</returns>
/// <exception cref="Exception">Unable to enter synchronized code to determine assembly loading</exception>
public static Assembly ResolveOrLoadAssembly(string assemblySimpleName, string publicKeyToken, string assemblyFileLocation)
{
return ResolveOrLoadAssemblyInternal(
assemblySimpleName,
publicKeyToken,
assemblyFileLocation,
(assembly) => string.Equals(assembly.GetName().Name, assemblySimpleName, StringComparison.OrdinalIgnoreCase));
}

public static bool DoesPublicKeyTokenMatch(AssemblyName assemblyName, string expectedKeyToken)
{
var publicKey = GetPublicKeyToken(assemblyName);

return string.Equals(publicKey, expectedKeyToken, StringComparison.OrdinalIgnoreCase);
}

public static string GetPublicKeyToken(AssemblyName assemblyName)
{
if (assemblyName == null)
{
return string.Empty;
}

var publicKeyToken = assemblyName.GetPublicKeyToken();

if (publicKeyToken == null || publicKeyToken.Length == 0)
{
return string.Empty;
}

return publicKeyToken.Select(x => x.ToString("x2")).Aggregate((x, y) => x + y);
}

private static Assembly ResolveOrLoadAssemblyInternal(string assemblySimpleName, string publicKeyToken, string assemblyFileLocation, Func<Assembly, bool> assemblyPredicate)
{
var lockTaken = false;
try
{
Monitor.TryEnter(_lockObject, TimeSpan.FromSeconds(LOCKRESOLUTIONTIMEOUTSECONDS), ref lockTaken);
}
catch (Exception)
{
throw new Exception("Unable to enter synchronized code to determine assembly loading");
}

Assembly resolvedAssembly = null;
if (lockTaken)
{
try
{
foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies().Where(assemblyPredicate))
{
if (string.IsNullOrWhiteSpace(publicKeyToken) || string.Equals(GetPublicKeyToken(assembly.GetName()), publicKeyToken, StringComparison.OrdinalIgnoreCase))
{
Log.Debug("Returning loaded assembly type for '{0}'", assemblySimpleName);

resolvedAssembly = assembly;
break;
}
}

if (resolvedAssembly == null)
{
Log.Debug("Loading up '{0}' assembly type from '{1}'", assemblySimpleName, assemblyFileLocation);

// Reading the raw bytes and calling 'Load' causes an exception, as such we use LoadFrom instead.
resolvedAssembly = Assembly.LoadFrom(assemblyFileLocation);
}
}
finally
{
Monitor.Pulse(_lockObject);
Monitor.Exit(_lockObject);
}
}

return resolvedAssembly;
}
}
}
51 changes: 35 additions & 16 deletions Source/ChocolateyGui/App.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@
// --------------------------------------------------------------------------------------------------------------------

using System;
using System.IO;
using System.Reflection;
using System.Windows;
using Autofac;
using chocolatey;
using chocolatey.infrastructure.registration;
using ChocolateyGui.Common.Enums;
using ChocolateyGui.Common.Services;
using ChocolateyGui.Common.Startup;
using ChocolateyGui.Common.Windows;
using ChocolateyGui.Common.Windows.Theming;

Expand All @@ -32,30 +32,49 @@ public App()
{
var requestedAssembly = new AssemblyName(args.Name);
try
{
if (string.Equals(requestedAssembly.Name, "chocolatey", StringComparison.OrdinalIgnoreCase))
{
var installDir = Environment.GetEnvironmentVariable("ChocolateyInstall");
if (string.IsNullOrEmpty(installDir))
{
var rootDrive = Path.GetPathRoot(Assembly.GetExecutingAssembly().Location);
if (string.IsNullOrEmpty(rootDrive))
{
return null; // TODO: Maybe return the chocolatey.dll file instead?
}
installDir = Path.Combine(rootDrive, "ProgramData", "chocolatey");
}
var assemblyLocation = Path.Combine(installDir, "choco.exe");
return AssemblyResolver.ResolveOrLoadAssembly("choco", string.Empty, assemblyLocation);
}
#if FORCE_CHOCOLATEY_OFFICIAL_KEY
var chocolateyGuiPublicKey = Bootstrapper.OfficialChocolateyPublicKey;
var chocolateyGuiPublicKey = Bootstrapper.OfficialChocolateyPublicKey;
#else
var chocolateyGuiPublicKey = Bootstrapper.UnofficialChocolateyPublicKey;
var chocolateyGuiPublicKey = Bootstrapper.UnofficialChocolateyPublicKey;
#endif
try
{
if (requestedAssembly.get_public_key_token().is_equal_to(chocolateyGuiPublicKey)
&& requestedAssembly.Name.is_equal_to(Bootstrapper.ChocolateyGuiCommonAssemblySimpleName))
if (AssemblyResolver.DoesPublicKeyTokenMatch(requestedAssembly, chocolateyGuiPublicKey)
&& string.Equals(requestedAssembly.Name, Bootstrapper.ChocolateyGuiCommonAssemblySimpleName, StringComparison.OrdinalIgnoreCase))
{
return AssemblyResolution.resolve_or_load_assembly(
return AssemblyResolver.ResolveOrLoadAssembly(
Bootstrapper.ChocolateyGuiCommonAssemblySimpleName,
requestedAssembly.get_public_key_token(),
Bootstrapper.ChocolateyGuiCommonAssemblyLocation).UnderlyingType;
AssemblyResolver.GetPublicKeyToken(requestedAssembly),
Bootstrapper.ChocolateyGuiCommonAssemblyLocation);
}
if (requestedAssembly.get_public_key_token().is_equal_to(chocolateyGuiPublicKey)
&& requestedAssembly.Name.is_equal_to(Bootstrapper.ChocolateyGuiCommonWindowsAssemblySimpleName))
if (AssemblyResolver.DoesPublicKeyTokenMatch(requestedAssembly, chocolateyGuiPublicKey)
&& string.Equals(requestedAssembly.Name, Bootstrapper.ChocolateyGuiCommonWindowsAssemblySimpleName, StringComparison.OrdinalIgnoreCase))
{
return AssemblyResolution.resolve_or_load_assembly(
return AssemblyResolver.ResolveOrLoadAssembly(
Bootstrapper.ChocolateyGuiCommonWindowsAssemblySimpleName,
requestedAssembly.get_public_key_token(),
Bootstrapper.ChocolateyGuiCommonWindowsAssemblyLocation).UnderlyingType;
AssemblyResolver.GetPublicKeyToken(requestedAssembly),
Bootstrapper.ChocolateyGuiCommonWindowsAssemblyLocation);
}
}
catch (Exception ex)
Expand Down
5 changes: 5 additions & 0 deletions Source/ChocolateyGui/ChocolateyGui.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,9 @@
<CodeAnalysisRuleSet>..\ChocolateyGuiRules.ruleset</CodeAnalysisRuleSet>
<Prefer32Bit>true</Prefer32Bit>
</PropertyGroup>
<PropertyGroup>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
</PropertyGroup>
<ItemGroup>
<Reference Include="Autofac, Version=4.6.1.0, Culture=neutral, PublicKeyToken=17863af14b0044da, processorArchitecture=MSIL">
<HintPath>..\packages\Autofac.4.6.1\lib\net45\Autofac.dll</HintPath>
Expand All @@ -117,6 +120,8 @@
</Reference>
<Reference Include="chocolatey, Version=0.10.15.0, Culture=neutral, PublicKeyToken=79d02ea9cad655eb, processorArchitecture=MSIL">
<HintPath>..\packages\chocolatey.lib.0.10.15\lib\chocolatey.dll</HintPath>
<SpecificVersion>False</SpecificVersion>
<Private>False</Private>
</Reference>
<Reference Include="ControlzEx, Version=4.0.0.0, Culture=neutral, PublicKeyToken=69f1c32f803d307e, processorArchitecture=MSIL">
<HintPath>..\packages\ControlzEx.4.4.0\lib\net462\ControlzEx.dll</HintPath>
Expand Down
6 changes: 5 additions & 1 deletion Source/ChocolateyGuiCli/Bootstrapper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
// --------------------------------------------------------------------------------------------------------------------

using System.IO;
using System.Reflection;
using Autofac;
using chocolatey.infrastructure.filesystem;
using ChocolateyGui.Common;
Expand All @@ -21,7 +22,10 @@ public static class Bootstrapper
private static readonly IFileSystem _fileSystem = new DotNetFileSystem();

#pragma warning disable SA1202
public static readonly string ChocolateyGuiInstallLocation = _fileSystem.get_directory_name(_fileSystem.get_current_assembly_path());

// Due to an unknown reason, we can not use chocolateys own get_current_assembly() function here,
// as it will be returning the path to the choco.exe executable instead.
public static readonly string ChocolateyGuiInstallLocation = _fileSystem.get_directory_name(Assembly.GetExecutingAssembly().CodeBase.Replace("file:///", string.Empty));
public static readonly string ChocolateyInstallEnvironmentVariableName = "ChocolateyInstall";
public static readonly string ChocolateyInstallLocation = System.Environment.GetEnvironmentVariable(ChocolateyInstallEnvironmentVariableName) ?? _fileSystem.get_directory_name(_fileSystem.get_current_assembly_path());
public static readonly string LicensedGuiAssemblyLocation = _fileSystem.combine_paths(ChocolateyInstallLocation, "extensions", "chocolateygui", "chocolateygui.licensed.dll");
Expand Down
5 changes: 4 additions & 1 deletion Source/ChocolateyGuiCli/ChocolateyGuiCli.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@
</Reference>
<Reference Include="chocolatey, Version=0.10.15.0, Culture=neutral, PublicKeyToken=79d02ea9cad655eb, processorArchitecture=MSIL">
<HintPath>..\packages\chocolatey.lib.0.10.15\lib\chocolatey.dll</HintPath>
<SpecificVersion>False</SpecificVersion>
<Private>False</Private>
</Reference>
<Reference Include="LiteDB, Version=5.0.5.0, Culture=neutral, PublicKeyToken=4ee40123013c9f27, processorArchitecture=MSIL">
<HintPath>..\packages\LiteDB.5.0.5\lib\net45\LiteDB.dll</HintPath>
Expand Down Expand Up @@ -91,8 +93,9 @@
<Link>Properties\SolutionInfo.cs</Link>
</Compile>
<Compile Include="Bootstrapper.cs" />
<Compile Include="Startup\ChocolateyGuiCliModule.cs" />
<Compile Include="Program.cs" />
<Compile Include="Startup\ChocolateyGuiCliModule.cs" />
<Compile Include="Runner.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
Expand Down
Loading

0 comments on commit 0c626b4

Please sign in to comment.