forked from microsoft/winget-cli
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Enable cmdlets for Windows PowerShell (microsoft#3951)
- Enable the following cmdlets for Windows PowerShell on user context. - Find-WinGetPackage - Get-WinGetPackage - Install-WinGetPackage - Uninstall-WinGetPackage - Update-WinGetPackage - Get-WinGetSource - Move WinGetAssemblyLoadContext.cs as common code between the modules. - Implement AppDomain handler for the current AppDomain for module's dependencies. However, dependency conflicts can still occur. In order to fix it, one should implement a custom app domain and deal with the serialization boundaries. - WinRTHelpers is a static class to handle all native calls. Since AppDomain doesn't have something similar to LoadUnmanagedDll, a call to `SetDllDirectoryW` is needed before calling the native method. ###### Microsoft Reviewers: [Open in CodeFlow](https://microsoft.github.io/open-pr/?codeflow=https://github.com/microsoft/winget-cli/pull/3951)
- Loading branch information
1 parent
1ff0b28
commit e70c3f8
Showing
15 changed files
with
316 additions
and
258 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
58 changes: 58 additions & 0 deletions
58
src/PowerShell/Microsoft.WinGet.Client.Cmdlets/Resolver/ModuleInit.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
// ----------------------------------------------------------------------------- | ||
// <copyright file="ModuleInit.cs" company="Microsoft Corporation"> | ||
// Copyright (c) Microsoft Corporation. Licensed under the MIT License. | ||
// </copyright> | ||
// ----------------------------------------------------------------------------- | ||
|
||
namespace Microsoft.WinGet.Resolver | ||
{ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Management.Automation; | ||
using System.Runtime.InteropServices; | ||
|
||
#if !POWERSHELL_WINDOWS | ||
using System.Runtime.Loader; | ||
#else | ||
using Microsoft.WinGet.Client.Cmdlets.Resolver; | ||
#endif | ||
|
||
/// <summary> | ||
/// Initialization class for this module. | ||
/// </summary> | ||
public class ModuleInit : IModuleAssemblyInitializer, IModuleAssemblyCleanup | ||
{ | ||
private static readonly IEnumerable<Architecture> ValidArchs = new Architecture[] { Architecture.X86, Architecture.X64 }; | ||
|
||
/// <inheritdoc/> | ||
public void OnImport() | ||
{ | ||
var arch = RuntimeInformation.ProcessArchitecture; | ||
if (!ValidArchs.Contains(arch)) | ||
{ | ||
throw new NotSupportedException(arch.ToString()); | ||
} | ||
|
||
#if !POWERSHELL_WINDOWS | ||
AssemblyLoadContext.Default.Resolving += WinGetAssemblyLoadContext.ResolvingHandler; | ||
#else | ||
// If we really need to avoid dependency conflicts, we could create a custom domain and handle the serialization boundaries. | ||
// PowerShell doesn't recommended because its complications. | ||
AppDomain currentDomain = AppDomain.CurrentDomain; | ||
currentDomain.AssemblyResolve += WinGetAppDomain.Handler; | ||
#endif | ||
} | ||
|
||
/// <inheritdoc/> | ||
public void OnRemove(PSModuleInfo module) | ||
{ | ||
#if !POWERSHELL_WINDOWS | ||
AssemblyLoadContext.Default.Resolving -= WinGetAssemblyLoadContext.ResolvingHandler; | ||
#else | ||
AppDomain currentDomain = AppDomain.CurrentDomain; | ||
currentDomain.AssemblyResolve -= WinGetAppDomain.Handler; | ||
#endif | ||
} | ||
} | ||
} |
69 changes: 69 additions & 0 deletions
69
src/PowerShell/Microsoft.WinGet.Client.Cmdlets/Resolver/WinGetAppDomain.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
// ----------------------------------------------------------------------------- | ||
// <copyright file="WinGetAppDomain.cs" company="Microsoft Corporation"> | ||
// Copyright (c) Microsoft Corporation. Licensed under the MIT License. | ||
// </copyright> | ||
// ----------------------------------------------------------------------------- | ||
#if POWERSHELL_WINDOWS | ||
|
||
namespace Microsoft.WinGet.Client.Cmdlets.Resolver | ||
{ | ||
using System; | ||
using System.IO; | ||
using System.Reflection; | ||
using System.Runtime.InteropServices; | ||
|
||
/// <summary> | ||
/// Resolver for assemblies. | ||
/// </summary> | ||
internal static class WinGetAppDomain | ||
{ | ||
private static readonly string SharedDependencyPath; | ||
private static readonly string SharedArchDependencyPath; | ||
private static readonly string DirectDependencyPath; | ||
|
||
static WinGetAppDomain() | ||
{ | ||
var self = typeof(WinGetAppDomain).Assembly; | ||
SharedDependencyPath = Path.Combine( | ||
Path.GetDirectoryName(self.Location), | ||
"SharedDependencies"); | ||
SharedArchDependencyPath = Path.Combine( | ||
SharedDependencyPath, | ||
RuntimeInformation.ProcessArchitecture.ToString().ToLower()); | ||
DirectDependencyPath = Path.Combine( | ||
Path.GetDirectoryName(self.Location), | ||
"DirectDependencies"); | ||
} | ||
|
||
/// <summary> | ||
/// Handler to register in the AppDomain. | ||
/// </summary> | ||
/// <param name="source">Source.</param> | ||
/// <param name="args">Event args.</param> | ||
/// <returns>The assembly if found.</returns> | ||
public static Assembly Handler(object source, ResolveEventArgs args) | ||
{ | ||
string name = $"{new AssemblyName(args.Name).Name}.dll"; | ||
string path = Path.Combine(SharedDependencyPath, name); | ||
if (File.Exists(path)) | ||
{ | ||
return Assembly.LoadFile(path); | ||
} | ||
|
||
path = Path.Combine(SharedArchDependencyPath, name); | ||
if (File.Exists(path)) | ||
{ | ||
return Assembly.LoadFile(path); | ||
} | ||
|
||
path = Path.Combine(DirectDependencyPath, name); | ||
if (File.Exists(path)) | ||
{ | ||
return Assembly.LoadFile(path); | ||
} | ||
|
||
return null; | ||
} | ||
} | ||
} | ||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.