commit bd08499f5e711134a6257be9a572ffc108d1b3af parent 25243766d1bf6b34955909c6d4066b9478dc03f8 Author: Jonathan Abbott <jtabbott2001@gmail.com> Date: Tue, 26 Jul 2022 13:24:36 -0700 Add Microsoft.WinGet.Client PowerShell Module files (#2314) Diffstat:
| M | .github/actions/spelling/expect.txt | | | 12 | +++++++++++- |
| M | azure-pipelines.yml | | | 40 | ++++++++++++++++++++++++++++++++++++++++ |
| M | src/AppInstallerCLI.sln | | | 54 | +++++++++++++++++++++++++++++++++++++++++++++--------- |
| A | src/PowerShell/Microsoft.WinGet.Client/Commands/FindPackageCommand.cs | | | 33 | +++++++++++++++++++++++++++++++++ |
| A | src/PowerShell/Microsoft.WinGet.Client/Commands/GetPackageCommand.cs | | | 33 | +++++++++++++++++++++++++++++++++ |
| A | src/PowerShell/Microsoft.WinGet.Client/Commands/GetSourceCommand.cs | | | 43 | +++++++++++++++++++++++++++++++++++++++++++ |
| A | src/PowerShell/Microsoft.WinGet.Client/Commands/InstallPackageCommand.cs | | | 98 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | src/PowerShell/Microsoft.WinGet.Client/Commands/UninstallPackageCommand.cs | | | 95 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | src/PowerShell/Microsoft.WinGet.Client/Commands/UpdatePackageCommand.cs | | | 62 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | src/PowerShell/Microsoft.WinGet.Client/Common/BaseClientCommand.cs | | | 75 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | src/PowerShell/Microsoft.WinGet.Client/Common/BaseFinderCommand.cs | | | 212 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | src/PowerShell/Microsoft.WinGet.Client/Common/BaseFinderExtendedCommand.cs | | | 58 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | src/PowerShell/Microsoft.WinGet.Client/Common/BaseInstallCommand.cs | | | 149 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | src/PowerShell/Microsoft.WinGet.Client/Common/BasePackageCommand.cs | | | 133 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | src/PowerShell/Microsoft.WinGet.Client/Common/Constants.cs | | | 47 | +++++++++++++++++++++++++++++++++++++++++++++++ |
| A | src/PowerShell/Microsoft.WinGet.Client/Common/Utilities.cs | | | 41 | +++++++++++++++++++++++++++++++++++++++++ |
| A | src/PowerShell/Microsoft.WinGet.Client/Copy-ModuleFiles.ps1 | | | 24 | ++++++++++++++++++++++++ |
| A | src/PowerShell/Microsoft.WinGet.Client/Copy-PlatformBinaries.ps1 | | | 48 | ++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | src/PowerShell/Microsoft.WinGet.Client/Crescendo.json | | | 148 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | src/PowerShell/Microsoft.WinGet.Client/Errors/FindPackagesException.cs | | | 36 | ++++++++++++++++++++++++++++++++++++ |
| A | src/PowerShell/Microsoft.WinGet.Client/Errors/VagueCriteriaException.cs | | | 39 | +++++++++++++++++++++++++++++++++++++++ |
| A | src/PowerShell/Microsoft.WinGet.Client/Format.ps1xml | | | 136 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | src/PowerShell/Microsoft.WinGet.Client/Helpers/CatalogPackageExtensions.cs | | | 38 | ++++++++++++++++++++++++++++++++++++++ |
| A | src/PowerShell/Microsoft.WinGet.Client/Helpers/ComObjectFactory.cs | | | 104 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | src/PowerShell/Microsoft.WinGet.Client/Helpers/FilterAttribute.cs | | | 25 | +++++++++++++++++++++++++ |
| A | src/PowerShell/Microsoft.WinGet.Client/Helpers/WriteProgressAdapter.cs | | | 90 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | src/PowerShell/Microsoft.WinGet.Client/Microsoft.WinGet.Client.csproj | | | 81 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | src/PowerShell/Microsoft.WinGet.Client/Microsoft.WinGet.Client.psd1 | | | 164 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | src/PowerShell/Microsoft.WinGet.Client/Microsoft.WinGet.Client.psm1 | | | 789 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | src/PowerShell/Microsoft.WinGet.Client/Properties/Resources.Designer.cs | | | 153 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | src/PowerShell/Microsoft.WinGet.Client/Properties/Resources.resx | | | 158 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | src/PowerShell/Microsoft.WinGet.Client/stylecop.json | | | 10 | ++++++++++ |
32 files changed, 3218 insertions(+), 10 deletions(-)
diff --git a/.github/actions/spelling/expect.txt b/.github/actions/spelling/expect.txt @@ -54,7 +54,9 @@ bomgar BOMs boundparms brk +Browsable Buf +buildtransitive BUILTINS cancelledbyuser casemap @@ -82,6 +84,7 @@ COMGLB commandline Concat contactsupport +contentfiles contoso contractversion count'th @@ -225,6 +228,7 @@ learnxinyminutes lhs libsolv libyaml +Lifecycle Linq liv liwpx @@ -234,6 +238,7 @@ localizationpriority LPBYTE LPDWORD lpitemidlist +LPITEMIDLIST LPWCH LPWSTR LSTATUS @@ -293,8 +298,9 @@ objidl ofile Outptr packageinuse -PACL PARAMETERMAP +paramref +PACL pathparts Patil pb @@ -317,6 +323,7 @@ pri processthreads productcode pscustomobject +psd pseudocode psm psobject @@ -379,6 +386,7 @@ startswith streambuf STRRET strtoull +stylecop subdir subkey superstring @@ -456,6 +464,7 @@ winerror wingetcreate wingetdev winreg +winrtact withstarts wn Workflows @@ -464,6 +473,7 @@ wsv wto wwinmain WZDNCRFJ +XFile XPLATSTR xsi yamlcreateps diff --git a/azure-pipelines.yml b/azure-pipelines.yml @@ -306,6 +306,12 @@ jobs: TargetFolder: '$(artifactsDir)' condition: succeededOrFailed() + - task: PowerShell@2 + displayName: 'Copy PowerShell Module Binaries to Output' + inputs: + filePath: 'src\PowerShell\Microsoft.WinGet.Client\Copy-PlatformBinaries.ps1' + arguments: '-Platform $(buildPlatform) -Configuration $(buildConfiguration) -OutDir $(artifactsDir)\PowerShell' + - task: PublishPipelineArtifact@1 displayName: Publish Pipeline Artifacts inputs: @@ -327,3 +333,37 @@ jobs: - task: securedevelopmentteam.vss-secure-development-tools.build-task-publishsecurityanalysislogs.PublishSecurityAnalysisLogs@2 displayName: 'Publish Security Analysis Logs' + +- job: 'BuildPowerShellModule' + timeoutInMinutes: 120 + dependsOn: 'Build' + condition: always() + + steps: + - task: DownloadPipelineArtifact@2 + displayName: 'Download Build Artifacts' + + - task: CopyFiles@2 + displayName: 'Copy x64 PowerShell Binaries to Output' + inputs: + SourceFolder: '$(Pipeline.Workspace)\Build.x64release\PowerShell' + Contents: '**\*' + TargetFolder: '$(Build.ArtifactStagingDirectory)' + + - task: CopyFiles@2 + displayName: 'Copy x86 PowerShell Binaries to Output' + inputs: + SourceFolder: '$(Pipeline.Workspace)\Build.x86release\PowerShell' + Contents: '**\*' + TargetFolder: '$(Build.ArtifactStagingDirectory)' + + - task: PowerShell@2 + displayName: 'Copy PowerShell Module Files to Output' + inputs: + filePath: 'src\PowerShell\Microsoft.WinGet.Client\Copy-ModuleFiles.ps1' + arguments: '-OutDir $(Build.ArtifactStagingDirectory)' + + - task: PublishPipelineArtifact@1 + displayName: Publish PowerShell Module Artifacts + inputs: + targetPath: '$(Build.ArtifactStagingDirectory)' diff --git a/src/AppInstallerCLI.sln b/src/AppInstallerCLI.sln @@ -136,7 +136,11 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "COMServer", "COMServer\COMS EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Microsoft.Management.Deployment.InProc", "Microsoft.Management.Deployment.InProc\Microsoft.Management.Deployment.InProc.vcxproj", "{9AC3C6A4-1875-4D3E-BF9C-C31E81EFF6B4}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.Management.Deployment.Projection", "Microsoft.Management.Deployment.Projection\Microsoft.Management.Deployment.Projection.csproj", "{0B104762-5CD8-47EE-A904-71C1C3F84DCD}" +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "PowerShell", "PowerShell", "{7C218A3E-9BC8-48FF-B91B-BCACD828C0C9}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.WinGet.Client", "PowerShell\Microsoft.WinGet.Client\Microsoft.WinGet.Client.csproj", "{463C0EF3-DF38-4C3D-8E7E-D4901E0CDC6C}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Management.Deployment.Projection", "Microsoft.Management.Deployment.Projection\Microsoft.Management.Deployment.Projection.csproj", "{0B104762-5CD8-47EE-A904-71C1C3F84DCD}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "UndockedRegFreeWinRT", "UndockedRegFreeWinRT\UndockedRegFreeWinRT\UndockedRegFreeWinRT.vcxproj", "{31ED69A8-5310-45A9-953F-56C351D2C3E1}" EndProject @@ -1032,6 +1036,37 @@ Global {9AC3C6A4-1875-4D3E-BF9C-C31E81EFF6B4}.TestRelease|x64.Build.0 = Release|x64 {9AC3C6A4-1875-4D3E-BF9C-C31E81EFF6B4}.TestRelease|x86.ActiveCfg = Release|Win32 {9AC3C6A4-1875-4D3E-BF9C-C31E81EFF6B4}.TestRelease|x86.Build.0 = Release|Win32 + {463C0EF3-DF38-4C3D-8E7E-D4901E0CDC6C}.Debug|Any CPU.ActiveCfg = Debug|ARM64 + {463C0EF3-DF38-4C3D-8E7E-D4901E0CDC6C}.Debug|ARM.ActiveCfg = Debug|ARM64 + {463C0EF3-DF38-4C3D-8E7E-D4901E0CDC6C}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {463C0EF3-DF38-4C3D-8E7E-D4901E0CDC6C}.Debug|ARM64.Build.0 = Debug|ARM64 + {463C0EF3-DF38-4C3D-8E7E-D4901E0CDC6C}.Debug|x64.ActiveCfg = Debug|x64 + {463C0EF3-DF38-4C3D-8E7E-D4901E0CDC6C}.Debug|x64.Build.0 = Debug|x64 + {463C0EF3-DF38-4C3D-8E7E-D4901E0CDC6C}.Debug|x86.ActiveCfg = Debug|x86 + {463C0EF3-DF38-4C3D-8E7E-D4901E0CDC6C}.Debug|x86.Build.0 = Debug|x86 + {463C0EF3-DF38-4C3D-8E7E-D4901E0CDC6C}.Fuzzing|Any CPU.ActiveCfg = Debug|ARM64 + {463C0EF3-DF38-4C3D-8E7E-D4901E0CDC6C}.Fuzzing|ARM.ActiveCfg = Debug|ARM64 + {463C0EF3-DF38-4C3D-8E7E-D4901E0CDC6C}.Fuzzing|ARM64.ActiveCfg = Debug|ARM64 + {463C0EF3-DF38-4C3D-8E7E-D4901E0CDC6C}.Fuzzing|ARM64.Build.0 = Debug|ARM64 + {463C0EF3-DF38-4C3D-8E7E-D4901E0CDC6C}.Fuzzing|x64.ActiveCfg = Debug|x64 + {463C0EF3-DF38-4C3D-8E7E-D4901E0CDC6C}.Fuzzing|x86.ActiveCfg = Debug|x86 + {463C0EF3-DF38-4C3D-8E7E-D4901E0CDC6C}.Fuzzing|x86.Build.0 = Debug|x86 + {463C0EF3-DF38-4C3D-8E7E-D4901E0CDC6C}.Release|Any CPU.ActiveCfg = Release|ARM64 + {463C0EF3-DF38-4C3D-8E7E-D4901E0CDC6C}.Release|ARM.ActiveCfg = Release|ARM64 + {463C0EF3-DF38-4C3D-8E7E-D4901E0CDC6C}.Release|ARM64.ActiveCfg = Release|ARM64 + {463C0EF3-DF38-4C3D-8E7E-D4901E0CDC6C}.Release|ARM64.Build.0 = Release|ARM64 + {463C0EF3-DF38-4C3D-8E7E-D4901E0CDC6C}.Release|x64.ActiveCfg = Release|x64 + {463C0EF3-DF38-4C3D-8E7E-D4901E0CDC6C}.Release|x64.Build.0 = Release|x64 + {463C0EF3-DF38-4C3D-8E7E-D4901E0CDC6C}.Release|x86.ActiveCfg = Release|x86 + {463C0EF3-DF38-4C3D-8E7E-D4901E0CDC6C}.Release|x86.Build.0 = Release|x86 + {463C0EF3-DF38-4C3D-8E7E-D4901E0CDC6C}.TestRelease|Any CPU.ActiveCfg = Debug|ARM64 + {463C0EF3-DF38-4C3D-8E7E-D4901E0CDC6C}.TestRelease|ARM.ActiveCfg = Debug|ARM64 + {463C0EF3-DF38-4C3D-8E7E-D4901E0CDC6C}.TestRelease|ARM64.ActiveCfg = Debug|ARM64 + {463C0EF3-DF38-4C3D-8E7E-D4901E0CDC6C}.TestRelease|ARM64.Build.0 = Debug|ARM64 + {463C0EF3-DF38-4C3D-8E7E-D4901E0CDC6C}.TestRelease|x64.ActiveCfg = Release|x64 + {463C0EF3-DF38-4C3D-8E7E-D4901E0CDC6C}.TestRelease|x64.Build.0 = Release|x64 + {463C0EF3-DF38-4C3D-8E7E-D4901E0CDC6C}.TestRelease|x86.ActiveCfg = Debug|x86 + {463C0EF3-DF38-4C3D-8E7E-D4901E0CDC6C}.TestRelease|x86.Build.0 = Debug|x86 {0B104762-5CD8-47EE-A904-71C1C3F84DCD}.Debug|Any CPU.ActiveCfg = Debug|x86 {0B104762-5CD8-47EE-A904-71C1C3F84DCD}.Debug|ARM.ActiveCfg = Debug|x86 {0B104762-5CD8-47EE-A904-71C1C3F84DCD}.Debug|ARM64.ActiveCfg = Debug|x86 @@ -1074,16 +1109,16 @@ Global {31ED69A8-5310-45A9-953F-56C351D2C3E1}.Release|Any CPU.ActiveCfg = Debug|Win32 {31ED69A8-5310-45A9-953F-56C351D2C3E1}.Release|ARM.ActiveCfg = Debug|Win32 {31ED69A8-5310-45A9-953F-56C351D2C3E1}.Release|ARM64.ActiveCfg = Debug|Win32 - {31ED69A8-5310-45A9-953F-56C351D2C3E1}.Release|x64.ActiveCfg = Debug|x64 - {31ED69A8-5310-45A9-953F-56C351D2C3E1}.Release|x64.Build.0 = Debug|x64 + {31ED69A8-5310-45A9-953F-56C351D2C3E1}.Release|x64.ActiveCfg = Release|x64 + {31ED69A8-5310-45A9-953F-56C351D2C3E1}.Release|x64.Build.0 = Release|x64 {31ED69A8-5310-45A9-953F-56C351D2C3E1}.Release|x86.ActiveCfg = Debug|Win32 {31ED69A8-5310-45A9-953F-56C351D2C3E1}.Release|x86.Build.0 = Debug|Win32 {31ED69A8-5310-45A9-953F-56C351D2C3E1}.TestRelease|Any CPU.ActiveCfg = Debug|Win32 {31ED69A8-5310-45A9-953F-56C351D2C3E1}.TestRelease|Any CPU.Build.0 = Debug|Win32 {31ED69A8-5310-45A9-953F-56C351D2C3E1}.TestRelease|ARM.ActiveCfg = Debug|Win32 {31ED69A8-5310-45A9-953F-56C351D2C3E1}.TestRelease|ARM64.ActiveCfg = Debug|Win32 - {31ED69A8-5310-45A9-953F-56C351D2C3E1}.TestRelease|x64.ActiveCfg = Debug|x64 - {31ED69A8-5310-45A9-953F-56C351D2C3E1}.TestRelease|x64.Build.0 = Debug|x64 + {31ED69A8-5310-45A9-953F-56C351D2C3E1}.TestRelease|x64.ActiveCfg = Release|x64 + {31ED69A8-5310-45A9-953F-56C351D2C3E1}.TestRelease|x64.Build.0 = Release|x64 {31ED69A8-5310-45A9-953F-56C351D2C3E1}.TestRelease|x86.ActiveCfg = Debug|Win32 {31ED69A8-5310-45A9-953F-56C351D2C3E1}.TestRelease|x86.Build.0 = Debug|Win32 {787EC629-C0FB-4BA9-9746-4A82CD06B73E}.Debug|Any CPU.ActiveCfg = Debug|Win32 @@ -1102,16 +1137,16 @@ Global {787EC629-C0FB-4BA9-9746-4A82CD06B73E}.Release|Any CPU.ActiveCfg = Debug|Win32 {787EC629-C0FB-4BA9-9746-4A82CD06B73E}.Release|ARM.ActiveCfg = Debug|Win32 {787EC629-C0FB-4BA9-9746-4A82CD06B73E}.Release|ARM64.ActiveCfg = Debug|Win32 - {787EC629-C0FB-4BA9-9746-4A82CD06B73E}.Release|x64.ActiveCfg = Debug|x64 - {787EC629-C0FB-4BA9-9746-4A82CD06B73E}.Release|x64.Build.0 = Debug|x64 + {787EC629-C0FB-4BA9-9746-4A82CD06B73E}.Release|x64.ActiveCfg = Release|x64 + {787EC629-C0FB-4BA9-9746-4A82CD06B73E}.Release|x64.Build.0 = Release|x64 {787EC629-C0FB-4BA9-9746-4A82CD06B73E}.Release|x86.ActiveCfg = Debug|Win32 {787EC629-C0FB-4BA9-9746-4A82CD06B73E}.Release|x86.Build.0 = Debug|Win32 {787EC629-C0FB-4BA9-9746-4A82CD06B73E}.TestRelease|Any CPU.ActiveCfg = Debug|Win32 {787EC629-C0FB-4BA9-9746-4A82CD06B73E}.TestRelease|Any CPU.Build.0 = Debug|Win32 {787EC629-C0FB-4BA9-9746-4A82CD06B73E}.TestRelease|ARM.ActiveCfg = Debug|Win32 {787EC629-C0FB-4BA9-9746-4A82CD06B73E}.TestRelease|ARM64.ActiveCfg = Debug|Win32 - {787EC629-C0FB-4BA9-9746-4A82CD06B73E}.TestRelease|x64.ActiveCfg = Debug|x64 - {787EC629-C0FB-4BA9-9746-4A82CD06B73E}.TestRelease|x64.Build.0 = Debug|x64 + {787EC629-C0FB-4BA9-9746-4A82CD06B73E}.TestRelease|x64.ActiveCfg = Release|x64 + {787EC629-C0FB-4BA9-9746-4A82CD06B73E}.TestRelease|x64.Build.0 = Release|x64 {787EC629-C0FB-4BA9-9746-4A82CD06B73E}.TestRelease|x86.ActiveCfg = Debug|Win32 {787EC629-C0FB-4BA9-9746-4A82CD06B73E}.TestRelease|x86.Build.0 = Debug|Win32 EndGlobalSection @@ -1133,6 +1168,7 @@ Global {866C3F06-636F-4BE8-BC24-5F86ECC606A1} = {60618CAC-2995-4DF9-9914-45C6FC02C995} {1A47951F-5C7A-4D6D-BB5F-D77484437940} = {8D53D749-D51C-46F8-A162-9371AAA6C2E7} {409CD681-22A4-469D-88AE-CB5E4836E07A} = {8D53D749-D51C-46F8-A162-9371AAA6C2E7} + {463C0EF3-DF38-4C3D-8E7E-D4901E0CDC6C} = {7C218A3E-9BC8-48FF-B91B-BCACD828C0C9} {31ED69A8-5310-45A9-953F-56C351D2C3E1} = {60618CAC-2995-4DF9-9914-45C6FC02C995} {787EC629-C0FB-4BA9-9746-4A82CD06B73E} = {60618CAC-2995-4DF9-9914-45C6FC02C995} EndGlobalSection diff --git a/src/PowerShell/Microsoft.WinGet.Client/Commands/FindPackageCommand.cs b/src/PowerShell/Microsoft.WinGet.Client/Commands/FindPackageCommand.cs @@ -0,0 +1,33 @@ +// ----------------------------------------------------------------------------- +// <copyright file="FindPackageCommand.cs" company="Microsoft Corporation"> +// Copyright (c) Microsoft Corporation. Licensed under the MIT License. +// </copyright> +// ----------------------------------------------------------------------------- + +namespace Microsoft.WinGet.Client.Commands +{ + using System.Management.Automation; + using Microsoft.Management.Deployment; + using Microsoft.WinGet.Client.Common; + + /// <summary> + /// Searches configured sources for packages. + /// </summary> + [Cmdlet(VerbsCommon.Find, Constants.PackageNoun)] + [OutputType(typeof(MatchResult))] + public sealed class FindPackageCommand : BaseFinderExtendedCommand + { + /// <summary> + /// Searches for configured sources for packages. + /// </summary> + protected override void ProcessRecord() + { + base.ProcessRecord(); + var results = this.FindPackages(CompositeSearchBehavior.RemotePackagesFromRemoteCatalogs); + for (var i = 0; i < results.Count; i++) + { + this.WriteObject(results[i]); + } + } + } +} diff --git a/src/PowerShell/Microsoft.WinGet.Client/Commands/GetPackageCommand.cs b/src/PowerShell/Microsoft.WinGet.Client/Commands/GetPackageCommand.cs @@ -0,0 +1,33 @@ +// ----------------------------------------------------------------------------- +// <copyright file="GetPackageCommand.cs" company="Microsoft Corporation"> +// Copyright (c) Microsoft Corporation. Licensed under the MIT License. +// </copyright> +// ----------------------------------------------------------------------------- + +namespace Microsoft.WinGet.Client.Commands +{ + using System.Management.Automation; + using Microsoft.Management.Deployment; + using Microsoft.WinGet.Client.Common; + + /// <summary> + /// Searches configured sources for packages. + /// </summary> + [Cmdlet(VerbsCommon.Get, Constants.PackageNoun)] + [OutputType(typeof(CatalogPackage))] + public sealed class GetPackageCommand : BaseFinderExtendedCommand + { + /// <summary> + /// Searches for configured sources for packages. + /// </summary> + protected override void ProcessRecord() + { + base.ProcessRecord(); + var results = this.FindPackages(CompositeSearchBehavior.LocalCatalogs); + for (var i = 0; i < results.Count; i++) + { + this.WriteObject(results[i].CatalogPackage); + } + } + } +} diff --git a/src/PowerShell/Microsoft.WinGet.Client/Commands/GetSourceCommand.cs b/src/PowerShell/Microsoft.WinGet.Client/Commands/GetSourceCommand.cs @@ -0,0 +1,43 @@ +// ----------------------------------------------------------------------------- +// <copyright file="GetSourceCommand.cs" company="Microsoft Corporation"> +// Copyright (c) Microsoft Corporation. Licensed under the MIT License. +// </copyright> +// ----------------------------------------------------------------------------- + +namespace Microsoft.WinGet.Client.Commands +{ + using System; + using System.Management.Automation; + using Microsoft.Management.Deployment; + using Microsoft.WinGet.Client.Common; + + /// <summary> + /// Retrieves the list of configured sources. + /// </summary> + [Cmdlet(VerbsCommon.Get, Constants.SourceNoun)] + [OutputType(typeof(PackageCatalogReference))] + public sealed class GetSourceCommand : BaseClientCommand + { + /// <summary> + /// Gets or sets the name of the source to retrieve. + /// </summary> + [Parameter( + Position = 0, + ValueFromPipeline = true, + ValueFromPipelineByPropertyName = true)] + public string Name { get; set; } + + /// <summary> + /// Returns the list of configured sources. + /// </summary> + protected override void ProcessRecord() + { + base.ProcessRecord(); + var results = GetPackageCatalogReferences(this.Name); + for (var i = 0; i < results.Count; i++) + { + this.WriteObject(results[i]); + } + } + } +} diff --git a/src/PowerShell/Microsoft.WinGet.Client/Commands/InstallPackageCommand.cs b/src/PowerShell/Microsoft.WinGet.Client/Commands/InstallPackageCommand.cs @@ -0,0 +1,98 @@ +// ----------------------------------------------------------------------------- +// <copyright file="InstallPackageCommand.cs" company="Microsoft Corporation"> +// Copyright (c) Microsoft Corporation. Licensed under the MIT License. +// </copyright> +// ----------------------------------------------------------------------------- + +#pragma warning disable SA1200 // Using directives should be placed correctly +using Windows.System; +#pragma warning restore SA1200 // Using directives should be placed correctly + +namespace Microsoft.WinGet.Client.Commands +{ + using System.Management.Automation; + using Microsoft.Management.Deployment; + using Microsoft.WinGet.Client.Common; + + /// <summary> + /// Installs a package from the pipeline or from a configured source. + /// </summary> + [Cmdlet( + VerbsLifecycle.Install, + Constants.PackageNoun, + DefaultParameterSetName = Constants.FoundSet, + SupportsShouldProcess = true)] + [OutputType(typeof(InstallResult))] + public sealed class InstallPackageCommand : BaseInstallCommand + { + private ProcessorArchitecture architecture; + private bool architectureGiven; + + /// <summary> + /// Gets or sets the scope to install the application under. + /// </summary> + [Parameter(ValueFromPipelineByPropertyName = true)] + public PackageInstallScope Scope { get; set; } + + /// <summary> + /// Gets or sets the architecture of the application to be installed. + /// </summary> + [Parameter(ValueFromPipelineByPropertyName = true)] + public ProcessorArchitecture Architecture + { + get => this.architecture; + set + { + this.architectureGiven = true; + this.architecture = value; + } + } + + /// <summary> + /// Prepares the command to install a package. + /// </summary> + protected override void BeginProcessing() + { + base.BeginProcessing(); + this.architectureGiven = false; + } + + /// <summary> + /// Installs a package from the pipeline or from a configured source. + /// </summary> + protected override void ProcessRecord() + { + base.ProcessRecord(); + this.GetPackageAndExecute(CompositeSearchBehavior.RemotePackagesFromRemoteCatalogs, (package, version) => + { + InstallOptions options = this.GetInstallOptions(version); + InstallResult result = this.InstallPackage(package, options); + this.WriteObject(result); + }); + } + + /// <inheritdoc /> + protected override InstallOptions GetInstallOptions(PackageVersionId version) + { + InstallOptions options = base.GetInstallOptions(version); + if (this.architectureGiven) + { + options.AllowedArchitectures.Clear(); + options.AllowedArchitectures.Add(this.architecture); + } + + options.PackageInstallScope = this.Scope; + return options; + } + + private InstallResult InstallPackage( + CatalogPackage package, + InstallOptions options) + { + var operation = PackageManager.Value.InstallPackageAsync(package, options); + return this.RegisterCallbacksAndWait(operation, string.Format( + Utilities.ResourceManager.GetString("ProgressRecordActivityInstalling"), + package.Name)); + } + } +} diff --git a/src/PowerShell/Microsoft.WinGet.Client/Commands/UninstallPackageCommand.cs b/src/PowerShell/Microsoft.WinGet.Client/Commands/UninstallPackageCommand.cs @@ -0,0 +1,95 @@ +// ----------------------------------------------------------------------------- +// <copyright file="UninstallPackageCommand.cs" company="Microsoft Corporation"> +// Copyright (c) Microsoft Corporation. Licensed under the MIT License. +// </copyright> +// ----------------------------------------------------------------------------- + +namespace Microsoft.WinGet.Client.Commands +{ + using System; + using System.Management.Automation; + using Microsoft.Management.Deployment; + using Microsoft.WinGet.Client.Common; + using Microsoft.WinGet.Client.Helpers; + + /// <summary> + /// Uninstalls a package from the local system. + /// </summary> + [Cmdlet( + VerbsLifecycle.Uninstall, + Constants.PackageNoun, + DefaultParameterSetName = Constants.FoundSet, + SupportsShouldProcess = true)] + [OutputType(typeof(UninstallResult))] + public sealed class UninstallPackageCommand : BasePackageCommand + { + /// <summary> + /// Gets or sets the desired mode for the uninstallation process. + /// </summary> + [Parameter(ValueFromPipelineByPropertyName = true)] + public PackageUninstallMode Mode { get; set; } = PackageUninstallMode.Default; + + /// <summary> + /// Uninstalls a package from the local system. + /// </summary> + protected override void ProcessRecord() + { + this.GetPackageAndExecute(CompositeSearchBehavior.LocalCatalogs, (package, version) => + { + UninstallOptions options = this.GetUninstallOptions(version); + UninstallResult result = this.UninstallPackage(package, options); + this.WriteObject(result); + }); + } + + private UninstallOptions GetUninstallOptions(PackageVersionId version) + { + var options = ComObjectFactory.Value.CreateUninstallOptions(); + if (this.Log != null) + { + options.LogOutputPath = this.Log; + } + + options.PackageUninstallMode = this.Mode; + if (version != null) + { + options.PackageVersionId = version; + } + + return options; + } + + private UninstallResult UninstallPackage( + CatalogPackage package, + UninstallOptions options) + { + string activity = string.Format( + Utilities.ResourceManager.GetString("ProgressRecordActivityUninstalling"), + package.Name); + + var operation = PackageManager.Value.UninstallPackageAsync(package, options); + WriteProgressAdapter adapter = new (this); + operation.Progress = (context, progress) => + { + adapter.WriteProgress(new ProgressRecord(1, activity, progress.State.ToString()) + { + RecordType = ProgressRecordType.Processing, + }); + }; + operation.Completed = (context, status) => + { + adapter.WriteProgress(new ProgressRecord(1, activity, status.ToString()) + { + RecordType = ProgressRecordType.Completed, + }); + adapter.Completed = true; + }; + Console.CancelKeyPress += (sender, e) => + { + operation.Cancel(); + }; + adapter.Wait(); + return operation.GetResults(); + } + } +} diff --git a/src/PowerShell/Microsoft.WinGet.Client/Commands/UpdatePackageCommand.cs b/src/PowerShell/Microsoft.WinGet.Client/Commands/UpdatePackageCommand.cs @@ -0,0 +1,62 @@ +// ----------------------------------------------------------------------------- +// <copyright file="UpdatePackageCommand.cs" company="Microsoft Corporation"> +// Copyright (c) Microsoft Corporation. Licensed under the MIT License. +// </copyright> +// ----------------------------------------------------------------------------- + +namespace Microsoft.WinGet.Client.Commands +{ + using System.Management.Automation; + using Microsoft.Management.Deployment; + using Microsoft.WinGet.Client.Common; + + /// <summary> + /// This commands updates a package from the pipeline or from the local system. + /// </summary> + [Cmdlet( + VerbsData.Update, + Constants.PackageNoun, + DefaultParameterSetName = Constants.FoundSet, + SupportsShouldProcess = true)] + [OutputType(typeof(InstallResult))] + public sealed class UpdatePackageCommand : BaseInstallCommand + { + /// <summary> + /// Gets or sets a value indicating whether updating to an unknown version is allowed. + /// </summary> + [Parameter(ValueFromPipelineByPropertyName = true)] + public SwitchParameter IncludeUnknown { get; set; } + + /// <summary> + /// Updates a package from the pipeline or from the local system. + /// </summary> + protected override void ProcessRecord() + { + base.ProcessRecord(); + this.GetPackageAndExecute(CompositeSearchBehavior.LocalCatalogs, (package, version) => + { + InstallOptions options = this.GetInstallOptions(version); + InstallResult result = this.UpgradePackage(package, options); + this.WriteObject(result); + }); + } + + /// <inheritdoc /> + protected override InstallOptions GetInstallOptions(PackageVersionId version) + { + InstallOptions options = base.GetInstallOptions(version); + options.AllowUpgradeToUnknownVersion = this.IncludeUnknown.ToBool(); + return options; + } + + private InstallResult UpgradePackage( + CatalogPackage package, + InstallOptions options) + { + var operation = PackageManager.Value.UpgradePackageAsync(package, options); + return this.RegisterCallbacksAndWait(operation, string.Format( + Utilities.ResourceManager.GetString("ProgressRecordActivityUpdating"), + package.Name)); + } + } +} diff --git a/src/PowerShell/Microsoft.WinGet.Client/Common/BaseClientCommand.cs b/src/PowerShell/Microsoft.WinGet.Client/Common/BaseClientCommand.cs @@ -0,0 +1,75 @@ +// ----------------------------------------------------------------------------- +// <copyright file="BaseClientCommand.cs" company="Microsoft Corporation"> +// Copyright (c) Microsoft Corporation. Licensed under the MIT License. +// </copyright> +// ----------------------------------------------------------------------------- + +namespace Microsoft.WinGet.Client.Common +{ + using System; + using System.Collections.Generic; + using System.Management.Automation; + using System.Runtime.InteropServices; + using Microsoft.Management.Deployment; + using Microsoft.WinGet.Client.Factories; + + /// <summary> + /// This is the base class for all of the commands in this module. + /// </summary> + public class BaseClientCommand : PSCmdlet + { + static BaseClientCommand() + { + InitializeUndockedRegFreeWinRT(); + } + + /// <summary> + /// Initializes a new instance of the <see cref="BaseClientCommand"/> class. + /// </summary> + public BaseClientCommand() + : base() + { + if (Utilities.ExecutingAsAdministrator) + { + throw new Exception(Utilities.ResourceManager.GetString("ExceptionAdministratorDisabled")); + } + } + + /// <summary> + /// Gets the instance of the <see cref="ComObjectFactory" /> class. + /// </summary> + protected static Lazy<ComObjectFactory> ComObjectFactory { get; } = new (); + + /// <summary> + /// Gets the instance of the <see cref="PackageManager" /> class. + /// </summary> + protected static Lazy<PackageManager> PackageManager { get; } = new (() => ComObjectFactory.Value.CreatePackageManager()); + + /// <summary> + /// Retrieves the specified source or all sources if <paramref name="source" /> is null. + /// </summary> + /// <returns>A list of <see cref="PackageCatalogReference" /> instances.</returns> + /// <param name="source">The name of the source to retrieve. If null, then all sources are returned.</param> + /// <exception cref="ArgumentException">The source does not exist.</exception> + protected static IReadOnlyList<PackageCatalogReference> GetPackageCatalogReferences(string source) + { + if (source is null) + { + return PackageManager.Value.GetPackageCatalogs(); + } + else + { + return new List<PackageCatalogReference>() + { + PackageManager.Value.GetPackageCatalogByName(source) + ?? throw new ArgumentException(string.Format( + Utilities.ResourceManager.GetString("ArgumentExceptionInvalidSource"), + source)), + }; + } + } + + [DllImport("winrtact.dll", EntryPoint = "winrtact_Initialize", ExactSpelling = true, PreserveSig = false)] + private static extern void InitializeUndockedRegFreeWinRT(); + } +} diff --git a/src/PowerShell/Microsoft.WinGet.Client/Common/BaseFinderCommand.cs b/src/PowerShell/Microsoft.WinGet.Client/Common/BaseFinderCommand.cs @@ -0,0 +1,212 @@ +// ----------------------------------------------------------------------------- +// <copyright file="BaseFinderCommand.cs" company="Microsoft Corporation"> +// Copyright (c) Microsoft Corporation. Licensed under the MIT License. +// </copyright> +// ----------------------------------------------------------------------------- + +namespace Microsoft.WinGet.Client.Common +{ + using System; + using System.Collections.Generic; + using System.Linq; + using System.Management.Automation; + using System.Reflection; + using Microsoft.Management.Deployment; + using Microsoft.WinGet.Client.Attributes; + using Microsoft.WinGet.Client.Errors; + + /// <summary> + /// This is the base class for all commands that might need to search for a package. It contains an initial + /// set of parameters that corresponds to the intersection of i.e., the "install" and "search" commands. + /// </summary> + public class BaseFinderCommand : BaseClientCommand + { + /// <summary> + /// Gets or sets the field that is matched against the identifier of a package. + /// </summary> + [Filter(Field = PackageMatchField.Id)] + [Parameter( + ParameterSetName = Constants.FoundSet, + ValueFromPipelineByPropertyName = true)] + public string Id { get; set; } + + /// <summary> + /// Gets or sets the field that is matched against the name of a package. + /// </summary> + [Filter(Field = PackageMatchField.Name)] + [Parameter( + ParameterSetName = Constants.FoundSet, + ValueFromPipelineByPropertyName = true)] + public string Name { get; set; } + + /// <summary> + /// Gets or sets the field that is matched against the name of a package. + /// </summary> + [Filter(Field = PackageMatchField.Moniker)] + [Parameter( + ParameterSetName = Constants.FoundSet, + ValueFromPipelineByPropertyName = true)] + public string Moniker { get; set; } + + /// <summary> + /// Gets or sets the name of the source to search for packages. If null, then all sources are searched. + /// </summary> + [Parameter( + ParameterSetName = Constants.FoundSet, + ValueFromPipelineByPropertyName = true)] + public string Source { get; set; } + + /// <summary> + /// Gets or sets the strings that match against every field of a package. + /// </summary> + [Parameter( + ParameterSetName = Constants.FoundSet, + Position = 0, + ValueFromPipelineByPropertyName = true, + ValueFromRemainingArguments = true)] + public string[] Query { get; set; } + + /// <summary> + /// Gets or sets a value indicating whether to match exactly against package fields. + /// </summary> + [Parameter( + ParameterSetName = Constants.FoundSet, + ValueFromPipelineByPropertyName = true)] + public SwitchParameter Exact { get; set; } + + private string QueryAsJoinedString + { + get + { + return (this.Query is null) + ? null + : string.Join(" ", this.Query); + } + } + + /// <summary> + /// Returns a <see cref="PackageFieldMatchOption" /> based on a parameter. + /// </summary> + /// <returns>A <see cref="PackageFieldMatchOption" /> value.</returns> + protected virtual PackageFieldMatchOption GetExactAsMatchOption() + { + return this.Exact.ToBool() + ? PackageFieldMatchOption.Equals + : PackageFieldMatchOption.ContainsCaseInsensitive; + } + + /// <summary> + /// Searches for packages based on the configured parameters. + /// </summary> + /// <param name="behavior">The <see cref="CompositeSearchBehavior" /> value.</param> + /// <param name="limit">The limit on the number of matches returned.</param> + /// <returns>A list of <see cref="MatchResult" /> objects.</returns> + protected IReadOnlyList<MatchResult> FindPackages( + CompositeSearchBehavior behavior, + uint limit) + { + PackageCatalog catalog = this.GetPackageCatalog(behavior); + FindPackagesOptions options = this.GetFindPackagesOptions(limit); + return GetMatchResults(catalog, options); + } + + private static void SetQueryInFindPackagesOptions( + ref FindPackagesOptions options, + PackageFieldMatchOption match, + string value) + { + var selector = ComObjectFactory.Value.CreatePackageMatchFilter(); + selector.Field = PackageMatchField.CatalogDefault; + selector.Value = value ?? string.Empty; + selector.Option = match; + options.Selectors.Add(selector); + } + + private static void AddFilterToFindPackagesOptionsIfNotNull( + ref FindPackagesOptions options, + PackageMatchField field, + PackageFieldMatchOption match, + string value) + { + if (value != null) + { + var filter = ComObjectFactory.Value.CreatePackageMatchFilter(); + filter.Field = field; + filter.Value = value; + filter.Option = match; + options.Filters.Add(filter); + } + } + + private static IReadOnlyList<MatchResult> GetMatchResults( + PackageCatalog catalog, + FindPackagesOptions options) + { + FindPackagesResult result = catalog.FindPackages(options); + if (result.Status == FindPackagesResultStatus.Ok) + { + return result.Matches; + } + else + { + throw new FindPackagesException(result.Status); + } + } + + private PackageCatalog GetPackageCatalog(CompositeSearchBehavior behavior) + { + PackageCatalogReference reference = this.GetPackageCatalogReference(behavior); + ConnectResult result = reference.Connect(); + if (result.Status == ConnectResultStatus.Ok) + { + return result.PackageCatalog; + } + else + { + throw new RuntimeException(Utilities.ResourceManager.GetString("RuntimeExceptionCatalogError")); + } + } + + private PackageCatalogReference GetPackageCatalogReference(CompositeSearchBehavior behavior) + { + CreateCompositePackageCatalogOptions options = ComObjectFactory.Value.CreateCreateCompositePackageCatalogOptions(); + IReadOnlyList<PackageCatalogReference> references = GetPackageCatalogReferences(this.Source); + for (var i = 0; i < references.Count; i++) + { + options.Catalogs.Add(references[i]); + } + + options.CompositeSearchBehavior = behavior; + return PackageManager.Value.CreateCompositePackageCatalog(options); + } + + private FindPackagesOptions GetFindPackagesOptions(uint limit) + { + var options = ComObjectFactory.Value.CreateFindPackagesOptions(); + SetQueryInFindPackagesOptions(ref options, this.GetExactAsMatchOption(), this.QueryAsJoinedString); + this.AddAttributedFiltersToFindPackagesOptions(ref options, this.GetExactAsMatchOption()); + options.ResultLimit = limit; + return options; + } + + private void AddAttributedFiltersToFindPackagesOptions( + ref FindPackagesOptions options, + PackageFieldMatchOption match) + { + IEnumerable<PropertyInfo> properties = this + .GetType() + .GetProperties() + .Where(property => Attribute.IsDefined(property, typeof(FilterAttribute))); + + foreach (PropertyInfo info in properties) + { + if (info.GetCustomAttribute(typeof(FilterAttribute), true) is FilterAttribute attribute) + { + PackageMatchField field = attribute.Field; + string value = info.GetValue(this, null) as string; + AddFilterToFindPackagesOptionsIfNotNull(ref options, field, match, value); + } + } + } + } +} diff --git a/src/PowerShell/Microsoft.WinGet.Client/Common/BaseFinderExtendedCommand.cs b/src/PowerShell/Microsoft.WinGet.Client/Common/BaseFinderExtendedCommand.cs @@ -0,0 +1,58 @@ +// ----------------------------------------------------------------------------- +// <copyright file="BaseFinderExtendedCommand.cs" company="Microsoft Corporation"> +// Copyright (c) Microsoft Corporation. Licensed under the MIT License. +// </copyright> +// ----------------------------------------------------------------------------- + +namespace Microsoft.WinGet.Client.Common +{ + using System.Collections.Generic; + using System.Management.Automation; + using Microsoft.Management.Deployment; + using Microsoft.WinGet.Client.Attributes; + + /// <summary> + /// This is the base class for the commands whose sole purpose is to filter a list of packages i.e., + /// the "search" and "list" commands. This class contains an extended set of parameters suited for + /// that purpose. + /// </summary> + public class BaseFinderExtendedCommand : BaseFinderCommand + { + /// <summary> + /// Gets or sets the filter that is matched against the tags of the package. + /// </summary> + [Filter(Field = PackageMatchField.Tag)] + [Parameter( + ParameterSetName = Constants.FoundSet, + ValueFromPipelineByPropertyName = true)] + public string Tag { get; set; } + + /// <summary> + /// Gets or sets the filter that is matched against the commands of the package. + /// </summary> + [Filter(Field = PackageMatchField.Command)] + [Parameter( + ParameterSetName = Constants.FoundSet, + ValueFromPipelineByPropertyName = true)] + public string Command { get; set; } + + /// <summary> + /// Gets or sets the maximum number of results returned. + /// </summary> + [ValidateRange(Constants.CountLowerBound, Constants.CountUpperBound)] + [Parameter( + ParameterSetName = Constants.FoundSet, + ValueFromPipelineByPropertyName = true)] + public uint Count { get; set; } + + /// <summary> + /// Searches for packages from configured sources. + /// </summary> + /// <param name="behavior">A <see cref="CompositeSearchBehavior" /> value.</param> + /// <returns>A list of <see cref="MatchResult" /> objects.</returns> + protected IReadOnlyList<MatchResult> FindPackages(CompositeSearchBehavior behavior) + { + return this.FindPackages(behavior, this.Count); + } + } +} diff --git a/src/PowerShell/Microsoft.WinGet.Client/Common/BaseInstallCommand.cs b/src/PowerShell/Microsoft.WinGet.Client/Common/BaseInstallCommand.cs @@ -0,0 +1,149 @@ +// ----------------------------------------------------------------------------- +// <copyright file="BaseInstallCommand.cs" company="Microsoft Corporation"> +// Copyright (c) Microsoft Corporation. Licensed under the MIT License. +// </copyright> +// ----------------------------------------------------------------------------- + +#pragma warning disable SA1200 // Using directives should be placed correctly +using Windows.Foundation; +#pragma warning restore SA1200 // Using directives should be placed correctly + +namespace Microsoft.WinGet.Client.Common +{ + using System.IO; + using System.Management.Automation; + using Microsoft.Management.Deployment; + using Microsoft.WinGet.Client.Helpers; + + /// <summary> + /// This is the base class for all commands that parse a <see cref="FindPackagesOptions" /> result + /// from the provided parameters i.e., the "install" and "upgrade" commands. + /// </summary> + public class BaseInstallCommand : BasePackageCommand + { + private string location; + + /// <summary> + /// Gets or sets the mode to manipulate the package with. + /// </summary> + [Parameter(ValueFromPipelineByPropertyName = true)] + public PackageInstallMode Mode { get; set; } = PackageInstallMode.Default; + + /// <summary> + /// Gets or sets the override arguments to be passed on to the installer. + /// </summary> + [Parameter(ValueFromPipelineByPropertyName = true)] + public string Override { get; set; } + + /// <summary> + /// Gets or sets the installation location. + /// </summary> + [Parameter(ValueFromPipelineByPropertyName = true)] + public string Location + { + get => this.location; + set + { + this.location = Path.IsPathRooted(value) + ? value + : this.SessionState.Path.CurrentFileSystemLocation + @"\" + value; + } + } + + /// <summary> + /// Gets or sets a value indicating whether to skip the installer hash validation check. + /// </summary> + [Parameter(ValueFromPipelineByPropertyName = true)] + public SwitchParameter Force { get; set; } + + /// <summary> + /// Gets or sets the optional HTTP Header to pass on to the REST Source. + /// </summary> + [Parameter(ValueFromPipelineByPropertyName = true)] + public string Header { get; set; } + + /// <summary> + /// Gets the install options from the configured parameters. + /// </summary> + /// <param name="version">The <see cref="PackageVersionId" /> to install.</param> + /// <returns>An <see cref="InstallOptions" /> instance.</returns> + protected virtual InstallOptions GetInstallOptions(PackageVersionId version) + { + InstallOptions options = ComObjectFactory.Value.CreateInstallOptions(); + options.AllowHashMismatch = this.Force.ToBool(); + options.PackageInstallMode = this.Mode; + if (version != null) + { + options.PackageVersionId = version; + } + + if (this.Log != null) + { + options.LogOutputPath = this.Log; + } + + if (this.Override != null) + { + options.ReplacementInstallerArguments = this.Override; + } + + if (this.Location != null) + { + options.PreferredInstallLocation = this.Location; + } + + if (this.Header != null) + { + options.AdditionalPackageCatalogArguments = this.Header; + } + + return options; + } + + /// <summary> + /// Registers callbacks on an asynchronous operation and waits for the results. + /// </summary> + /// <param name="operation">The asynchronous operation.</param> + /// <param name="activity">A <see cref="string" /> instance.</param> + /// <returns>A <see cref="InstallResult" /> instance.</returns> + protected InstallResult RegisterCallbacksAndWait( + IAsyncOperationWithProgress<InstallResult, InstallProgress> operation, + string activity) + { + WriteProgressAdapter adapter = new (this); + operation.Progress = (context, progress) => + { + ProgressRecord record = new (1, activity, progress.State.ToString()) + { + RecordType = ProgressRecordType.Processing, + }; + + if ((progress.State == PackageInstallProgressState.Downloading) && (progress.BytesRequired != 0)) + { + record.StatusDescription = $"{progress.BytesDownloaded / 1000000.0f:0.0} MB / {progress.BytesRequired / 1000000.0f:0.0} MB"; + record.PercentComplete = (int)(progress.DownloadProgress * 100); + } + else if (progress.State == PackageInstallProgressState.Installing) + { + record.PercentComplete = (int)(progress.InstallationProgress * 100); + } + + adapter.WriteProgress(record); + }; + operation.Completed = (context, status) => + { + adapter.WriteProgress(new ProgressRecord(1, activity, status.ToString()) + { + RecordType = ProgressRecordType.Completed, + }); + adapter.Completed = true; + }; + System.Console.CancelKeyPress += (sender, e) => + { + operation.Cancel(); + }; + adapter.Wait(); + return operation.GetResults(); + } + } +} diff --git a/src/PowerShell/Microsoft.WinGet.Client/Common/BasePackageCommand.cs b/src/PowerShell/Microsoft.WinGet.Client/Common/BasePackageCommand.cs @@ -0,0 +1,133 @@ +// ----------------------------------------------------------------------------- +// <copyright file="BasePackageCommand.cs" company="Microsoft Corporation"> +// Copyright (c) Microsoft Corporation. Licensed under the MIT License. +// </copyright> +// ----------------------------------------------------------------------------- + +namespace Microsoft.WinGet.Client.Common +{ + using System; + using System.Collections.Generic; + using System.IO; + using System.Management.Automation; + using Microsoft.Management.Deployment; + using Microsoft.WinGet.Client.Errors; + + /// <summary> + /// This is the base class for commands which operate on a specific package & version i.e., + /// the "install", "uninstall", and "upgrade" commands. + /// </summary> + public class BasePackageCommand : BaseFinderCommand + { + private string log; + + /// <summary> + /// Gets or sets the package to directly install. + /// </summary> + /// <remarks> + /// Must match the name of the <see cref="Deployment.CatalogPackage" /> field on the <see cref="MatchResult" /> class. + /// </remarks> + [Alias("InputObject")] + [ValidateNotNull] + [Parameter( + ParameterSetName = Constants.GivenSet, + Position = 0, + ValueFromPipeline = true, + ValueFromPipelineByPropertyName = true)] + public CatalogPackage CatalogPackage { get; set; } + + /// <summary> + /// Gets or sets the version to install. + /// </summary> + [Parameter(ValueFromPipelineByPropertyName = true)] + public string Version { get; set; } + + /// <summary> + /// Gets or sets the path to the logging file. + /// </summary> + [Parameter(ValueFromPipelineByPropertyName = true)] + public string Log + { + get => this.log; + set + { + this.log = Path.IsPathRooted(value) + ? value + : this.SessionState.Path.CurrentFileSystemLocation + @"\" + value; + } + } + + /// <inheritdoc /> + protected override PackageFieldMatchOption GetExactAsMatchOption() + { + return this.Exact.ToBool() + ? PackageFieldMatchOption.Equals + : PackageFieldMatchOption.EqualsCaseInsensitive; + } + + /// <summary> + /// Executes a command targeting a specific package version. + /// </summary> + /// <param name="behavior">The <see cref="CompositeSearchBehavior" /> value.</param> + /// <param name="callback">The method to call after retrieving the package and version to operate upon.</param> + protected void GetPackageAndExecute( + CompositeSearchBehavior behavior, + Action<CatalogPackage, PackageVersionId> callback) + { + CatalogPackage package = this.GetCatalogPackage(behavior); + PackageVersionId version = this.GetPackageVersionId(package); + if (this.ShouldProcess(package.ToString(version))) + { + callback(package, version); + } + } + + private CatalogPackage GetCatalogPackage(CompositeSearchBehavior behavior) + { + if (this.ParameterSetName == Constants.GivenSet) + { + // The package was already provided via a parameter or the pipeline. + return this.CatalogPackage; + } + else + { + IReadOnlyList<MatchResult> results = this.FindPackages(behavior, 0); + if (results.Count == 1) + { + // Exactly one package matched, so we can just return it. + return results[0].CatalogPackage; + } + else if (results.Count == 0) + { + // No packages matched, we need to throw an error. + throw new RuntimeException(Utilities.ResourceManager.GetString("RuntimeExceptionNoPackagesFound")); + } + else + { + // Too many packages matched! The user needs to refine their input. + throw new VagueCriteriaException(results); + } + } + } + + private PackageVersionId GetPackageVersionId(CatalogPackage package) + { + if (this.Version != null) + { + for (var i = 0; i < package.AvailableVersions.Count; i++) + { + if (package.AvailableVersions[i].Version.CompareTo(this.Version) == 0) + { + return package.AvailableVersions[i]; + } + } + + throw new ArgumentException(Utilities.ResourceManager.GetString("RuntimeExceptionInvalidVersion")); + } + else + { + return null; + } + } + } +} diff --git a/src/PowerShell/Microsoft.WinGet.Client/Common/Constants.cs b/src/PowerShell/Microsoft.WinGet.Client/Common/Constants.cs @@ -0,0 +1,47 @@ +// ----------------------------------------------------------------------------- +// <copyright file="Constants.cs" company="Microsoft Corporation"> +// Copyright (c) Microsoft Corporation. Licensed under the MIT License. +// </copyright> +// ----------------------------------------------------------------------------- + +namespace Microsoft.WinGet.Client.Common +{ + using Microsoft.Management.Deployment; + + /// <summary> + /// This class contains all of the configurable constants for this project. + /// </summary> + public static class Constants + { + /// <summary> + /// The noun analogue of the <see cref="CatalogPackage" /> class. Changing this will alter the names of the related commands. + /// </summary> + public const string PackageNoun = "WinGetPackage"; + + /// <summary> + /// The noun analogue of the <see cref="PackageCatalogReference" /> class. Changing this will alter the names of the related commands. + /// </summary> + public const string SourceNoun = "WinGetSource"; + + /// <summary> + /// If a command allows the specification of the maximum number of results to return, this is the lower bound for that value. + /// </summary> + public const uint CountLowerBound = 1; + + /// <summary> + /// If a command allows the specification of the maximum number of results to return, this is the upper bound for that value. + /// </summary> + public const uint CountUpperBound = 1000; + + /// <summary> + /// This parameter set indicates that a package was provided via a parameter or the pipeline and it can be acted on directly. + /// </summary> + public const string GivenSet = "GivenSet"; + + /// <summary> + /// This parameter set indicates that a package was not provided via a parameter or the pipeline and it + /// needs to be found by searching a package source. + /// </summary> + public const string FoundSet = "FoundSet"; + } +} diff --git a/src/PowerShell/Microsoft.WinGet.Client/Common/Utilities.cs b/src/PowerShell/Microsoft.WinGet.Client/Common/Utilities.cs @@ -0,0 +1,41 @@ +// ----------------------------------------------------------------------------- +// <copyright file="Utilities.cs" company="Microsoft Corporation"> +// Copyright (c) Microsoft Corporation. Licensed under the MIT License. +// </copyright> +// ----------------------------------------------------------------------------- + +namespace Microsoft.WinGet.Client.Common +{ + using System.Resources; + using System.Security.Principal; + + /// <summary> + /// This class contains various helper methods for this project. + /// </summary> + public static class Utilities + { + /// <summary> + /// Gets the <see cref="ResourceManager" /> instance for the executing assembly. + /// </summary> + public static ResourceManager ResourceManager + { + get + { + return new ResourceManager(typeof(Properties.Resources)); + } + } + + /// <summary> + /// Gets a value indicating whether the current assembly is executing in an administrative context. + /// </summary> + public static bool ExecutingAsAdministrator + { + get + { + WindowsIdentity identity = WindowsIdentity.GetCurrent(); + WindowsPrincipal principal = new (identity); + return principal.IsInRole(WindowsBuiltInRole.Administrator); + } + } + } +} diff --git a/src/PowerShell/Microsoft.WinGet.Client/Copy-ModuleFiles.ps1 b/src/PowerShell/Microsoft.WinGet.Client/Copy-ModuleFiles.ps1 @@ -0,0 +1,24 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + +<# + .SYNOPSIS + Copies everything but the binary files to an output directory. + + .PARAMETER OutDir + The output directory where the module manifest will live. +#> + +[CmdletBinding()] +param ( + [Parameter(Mandatory)] + [string] + $OutDir +) + +New-Item $OutDir -ItemType Directory -Force -ErrorAction Stop +Copy-Item "$PSScriptRoot\Microsoft.WinGet.Client.psd1" $OutDir -Force -ErrorAction Stop +Copy-Item "$PSScriptRoot\Microsoft.WinGet.Client.psm1" $OutDir -Force -ErrorAction Stop +Copy-Item "$PSScriptRoot\Format.ps1xml" $OutDir -Force -ErrorAction Stop + +Write-Host 'Done!' -ForegroundColor Green diff --git a/src/PowerShell/Microsoft.WinGet.Client/Copy-PlatformBinaries.ps1 b/src/PowerShell/Microsoft.WinGet.Client/Copy-PlatformBinaries.ps1 @@ -0,0 +1,48 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + +<# + .SYNOPSIS + Copies built binaries for a specific platform to an output directory. + + .PARAMETER Platform + The platform we are building for. + + .PARAMETER Configuration + The configuration we are building in. + + .PARAMETER OutDir + The base output directory where the module manifest will be. +#> + +[CmdletBinding()] +param ( + [Parameter(Mandatory)] + [string] + $Platform, + + [Parameter(Mandatory)] + [string] + $Configuration, + + [Parameter(Mandatory)] + [string] + $OutDir +) + +# src\x64\Release\Project\net461\Library.Desktop.dll +# src\x64\Release\Project\net5.0-windows10.0.22000.0\Library.Core.dll + +# build\Module\x64\Desktop\Library.Desktop.dll +# build\Module\x64\Core\Library.Core.dll + +$CoreFramework = 'net5.0-windows10.0.22000.0' +$CoreFolderName = 'Core' +$DesktopFramework = 'net461' +$DesktopFolderName = 'Desktop' +$ProjectName = 'Microsoft.WinGet.Client' + +Copy-Item "$PSScriptRoot\..\..\$Platform\$Configuration\$ProjectName\$CoreFramework" "$OutDir\$Platform\$CoreFolderName" -Force -Recurse -ErrorAction Stop +Copy-Item "$PSScriptRoot\..\..\$Platform\$Configuration\$ProjectName\$DesktopFramework" "$OutDir\$Platform\$DesktopFolderName" -Force -Recurse -ErrorAction Stop + +Write-Host 'Done!' -ForegroundColor Green diff --git a/src/PowerShell/Microsoft.WinGet.Client/Crescendo.json b/src/PowerShell/Microsoft.WinGet.Client/Crescendo.json @@ -0,0 +1,147 @@ +{ + "$schema": "https://aka.ms/PowerShell/Crescendo/Schemas/2021-11", + "Commands": [ + { + "Verb": "Get", + "Noun": "WinGetVersion", + "Platform": [ + "Windows" + ], + "OriginalName": "winget.exe", + "OriginalCommandElements": [ + "--version" + ] + }, + { + "Verb": "Enable", + "Noun": "WinGetSetting", + "Platform": [ + "Windows" + ], + "OriginalName": "winget.exe", + "OriginalCommandElements": [ + "settings", + "--enable" + ], + "Parameters": [ + { + "Mandatory": true, + "Name": "Name", + "OriginalPosition": 0, + "Position": 0, + "ValueFromPipeline": true, + "ValueFromPipelineByPropertyName": true, + "ParameterType": "string" + } + ] + }, + { + "Verb": "Disable", + "Noun": "WinGetSetting", + "Platform": [ + "Windows" + ], + "OriginalName": "winget.exe", + "OriginalCommandElements": [ + "settings", + "--disable" + ], + "Parameters": [ + { + "Mandatory": true, + "Name": "Name", + "OriginalPosition": 0, + "Position": 0, + "ValueFromPipeline": true, + "ValueFromPipelineByPropertyName": true, + "ParameterType": "string" + } + ] + }, + { + "Verb": "Add", + "Noun": "WinGetSource", + "Platform": [ + "Windows" + ], + "OriginalName": "winget.exe", + "OriginalCommandElements": [ + "source", + "add" + ], + "Parameters": [ + { + "Name": "Name", + "OriginalName": "--name", + "Mandatory": true, + "ParameterType": "string", + "ValueFromPipelineByPropertyName": true, + "Position": 0 + }, + { + "Name": "Argument", + "OriginalName": "--arg", + "Mandatory": true, + "ParameterType": "string", + "ValueFromPipelineByPropertyName": true, + "Position": 1 + }, + { + "Name": "Type", + "OriginalName": "--type", + "Mandatory": false, + "ParameterType": "string", + "ValueFromPipelineByPropertyName": true, + "Position": 2 + } + ] + }, + { + "Verb": "Remove", + "Noun": "WinGetSource", + "Platform": [ + "Windows" + ], + "OriginalName": "winget.exe", + "OriginalCommandElements": [ + "source", + "remove" + ], + "Parameters": [ + { + "Name": "Name", + "OriginalName": "--name", + "Mandatory": true, + "ParameterType": "string", + "ValueFromPipeline": true, + "ValueFromPipelineByPropertyName": true, + "Position": 0 + } + ] + }, + { + "Verb": "Reset", + "Noun": "WinGetSource", + "Platform": [ + "Windows" + ], + "OriginalName": "winget.exe", + "OriginalCommandElements": [ + "source", + "reset", + "--force" + ], + "Parameters": [ + { + "Name": "Name", + "OriginalName": "--name", + "Mandatory": false, + "ParameterType": "string", + "ValueFromPipeline": true, + "ValueFromPipelineByPropertyName": true, + "Position": 0 + } + ] + } + ] +}+ \ No newline at end of file diff --git a/src/PowerShell/Microsoft.WinGet.Client/Errors/FindPackagesException.cs b/src/PowerShell/Microsoft.WinGet.Client/Errors/FindPackagesException.cs @@ -0,0 +1,36 @@ +// ----------------------------------------------------------------------------- +// <copyright file="FindPackagesException.cs" company="Microsoft Corporation"> +// Copyright (c) Microsoft Corporation. Licensed under the MIT License. +// </copyright> +// ----------------------------------------------------------------------------- + +namespace Microsoft.WinGet.Client.Errors +{ + using System; + using Microsoft.Management.Deployment; + using Microsoft.WinGet.Client.Common; + + /// <summary> + /// Raised when there is an error searching for packages. + /// </summary> + [Serializable] + public class FindPackagesException : Exception + { + /// <summary> + /// Initializes a new instance of the <see cref="FindPackagesException"/> class. + /// </summary> + /// <param name="status">A <see cref="FindPackagesResultStatus" /> value.</param> + public FindPackagesException(FindPackagesResultStatus status) + : base(string.Format( + Utilities.ResourceManager.GetString("FindPackagesExceptionMessage"), + status.ToString())) + { + this.Status = status; + } + + /// <summary> + /// Gets or sets the error status. + /// </summary> + public FindPackagesResultStatus Status { get; set; } + } +} diff --git a/src/PowerShell/Microsoft.WinGet.Client/Errors/VagueCriteriaException.cs b/src/PowerShell/Microsoft.WinGet.Client/Errors/VagueCriteriaException.cs @@ -0,0 +1,39 @@ +// ----------------------------------------------------------------------------- +// <copyright file="VagueCriteriaException.cs" company="Microsoft Corporation"> +// Copyright (c) Microsoft Corporation. Licensed under the MIT License. +// </copyright> +// ----------------------------------------------------------------------------- + +namespace Microsoft.WinGet.Client.Errors +{ + using System; + using System.Collections.Generic; + using Microsoft.Management.Deployment; + using Microsoft.WinGet.Client.Common; + + /// <summary> + /// Raised when search criteria for installing or updating a package is too vague. + /// </summary> + [Serializable] + public class VagueCriteriaException : Exception + { + /// <summary> + /// Initializes a new instance of the <see cref="VagueCriteriaException"/> class. + /// </summary> + /// <param name="results">The list of conflicting packages of length at least two.</param> + public VagueCriteriaException(IReadOnlyList<MatchResult> results) + : base(string.Format( + Utilities.ResourceManager.GetString("VagueCriteriaExceptionMessage"), + results[0].CatalogPackage.ToString(null), + results[1].CatalogPackage.ToString(null), + results.Count - 2)) + { + this.MatchResults = results; + } + + /// <summary> + /// Gets or sets the list of conflicting packages. + /// </summary> + public IReadOnlyList<MatchResult> MatchResults { get; set; } + } +} diff --git a/src/PowerShell/Microsoft.WinGet.Client/Format.ps1xml b/src/PowerShell/Microsoft.WinGet.Client/Format.ps1xml @@ -0,0 +1,135 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<Configuration> + <ViewDefinitions> + <View> + <Name>Microsoft.Management.Deployment.MatchResult</Name> + <ViewSelectedBy> + <TypeName>Microsoft.Management.Deployment.MatchResult</TypeName> + </ViewSelectedBy> + <TableControl> + <TableHeaders> + <TableColumnHeader> + <Width>32</Width> + <Label>Name</Label> + </TableColumnHeader> + <TableColumnHeader> + <Width>32</Width> + <Label>Id</Label> + </TableColumnHeader> + <TableColumnHeader> + <Label>Version</Label> + </TableColumnHeader> + <TableColumnHeader> + <Label>Match</Label> + </TableColumnHeader> + <TableColumnHeader> + <Label>Source</Label> + </TableColumnHeader> + </TableHeaders> + <TableRowEntries> + <TableRowEntry> + <TableColumnItems> + <TableColumnItem> + <ScriptBlock>$_.CatalogPackage.Name</ScriptBlock> + </TableColumnItem> + <TableColumnItem> + <ScriptBlock>$_.CatalogPackage.Id</ScriptBlock> + </TableColumnItem> + <TableColumnItem> + <ScriptBlock>$_.CatalogPackage.DefaultInstallVersion.Version</ScriptBlock> + </TableColumnItem> + <TableColumnItem> + <ScriptBlock>'{0}: {1}' -f $_.MatchCriteria.Field,$_.MatchCriteria.Value</ScriptBlock> + </TableColumnItem> + <TableColumnItem> + <ScriptBlock>$_.CatalogPackage.DefaultInstallVersion.PackageCatalog.Info.Name</ScriptBlock> + </TableColumnItem> + </TableColumnItems> + </TableRowEntry> + </TableRowEntries> + </TableControl> + </View> + <View> + <Name>Microsoft.Management.Deployment.PackageCatalogReference</Name> + <ViewSelectedBy> + <TypeName>Microsoft.Management.Deployment.PackageCatalogReference</TypeName> + </ViewSelectedBy> + <TableControl> + <TableHeaders> + <TableColumnHeader> + <Width>32</Width> + <Label>Name</Label> + </TableColumnHeader> + <TableColumnHeader> + <Label>Argument</Label> + </TableColumnHeader> + <TableColumnHeader> + <Label>Type</Label> + </TableColumnHeader> + </TableHeaders> + <TableRowEntries> + <TableRowEntry> + <TableColumnItems> + <TableColumnItem> + <ScriptBlock>$_.Info.Name</ScriptBlock> + </TableColumnItem> + <TableColumnItem> + <ScriptBlock>$_.Info.Type</ScriptBlock> + </TableColumnItem> + <TableColumnItem> + <ScriptBlock>$_.Info.Argument</ScriptBlock> + </TableColumnItem> + </TableColumnItems> + </TableRowEntry> + </TableRowEntries> + </TableControl> + </View> + <View> + <Name>Microsoft.Management.Deployment.CatalogPackage</Name> + <ViewSelectedBy> + <TypeName>Microsoft.Management.Deployment.CatalogPackage</TypeName> + </ViewSelectedBy> + <TableControl> + <TableHeaders> + <TableColumnHeader> + <Width>32</Width> + <Label>Name</Label> + </TableColumnHeader> + <TableColumnHeader> + <Label>Id</Label> + </TableColumnHeader> + <TableColumnHeader> + <Label>Version</Label> + </TableColumnHeader> + <TableColumnHeader> + <Label>Available</Label> + </TableColumnHeader> + <TableColumnHeader> + <Label>Source</Label> + </TableColumnHeader> + </TableHeaders> + <TableRowEntries> + <TableRowEntry> + <TableColumnItems> + <TableColumnItem> + <ScriptBlock>$_.Name</ScriptBlock> + </TableColumnItem> + <TableColumnItem> + <ScriptBlock>$_.Id</ScriptBlock> + </TableColumnItem> + <TableColumnItem> + <ScriptBlock>$_.InstalledVersion.Version</ScriptBlock> + </TableColumnItem> + <TableColumnItem> + <ScriptBlock>if ($_.IsUpdateAvailable) { $_.AvailableVersions[0].Version }</ScriptBlock> + </TableColumnItem> + <TableColumnItem> + <ScriptBlock>$_.DefaultInstallVersion.PackageCatalog.Info.Name</ScriptBlock> + </TableColumnItem> + </TableColumnItems> + </TableRowEntry> + </TableRowEntries> + </TableControl> + </View> + </ViewDefinitions> +</Configuration>+ \ No newline at end of file diff --git a/src/PowerShell/Microsoft.WinGet.Client/Helpers/CatalogPackageExtensions.cs b/src/PowerShell/Microsoft.WinGet.Client/Helpers/CatalogPackageExtensions.cs @@ -0,0 +1,38 @@ +// ----------------------------------------------------------------------------- +// <copyright file="CatalogPackageExtensions.cs" company="Microsoft Corporation"> +// Copyright (c) Microsoft Corporation. Licensed under the MIT License. +// </copyright> +// ----------------------------------------------------------------------------- + +namespace Microsoft.Management.Deployment +{ + /// <summary> + /// Extensions for the <see cref="CatalogPackage" /> class. + /// </summary> + public static class CatalogPackageExtensions + { + /// <summary> + /// Converts a <see cref="CatalogPackage" /> to a string previewing the specified version. + /// </summary> + /// <param name="package">A <see cref="CatalogPackage" /> instance.</param> + /// <param name="version">A <see cref="PackageVersionId" /> instance. If null, the latest available version is used.</param> + /// <returns>A <see cref="string" /> instance.</returns> + public static string ToString( + this CatalogPackage package, + PackageVersionId version) + { + if ((version != null) || (package.AvailableVersions.Count > 0)) + { + string versionString = (version is null) + ? package.AvailableVersions[0].Version + : version.Version; + return $"{package.Name} [{package.Id}] Version {versionString}"; + } + else + { + // There were no available versions! + return $"{package.Name} [{package.Id}]"; + } + } + } +} diff --git a/src/PowerShell/Microsoft.WinGet.Client/Helpers/ComObjectFactory.cs b/src/PowerShell/Microsoft.WinGet.Client/Helpers/ComObjectFactory.cs @@ -0,0 +1,104 @@ +// ----------------------------------------------------------------------------- +// <copyright file="ComObjectFactory.cs" company="Microsoft Corporation"> +// Copyright (c) Microsoft Corporation. Licensed under the MIT License. +// </copyright> +// ----------------------------------------------------------------------------- + +namespace Microsoft.WinGet.Client.Factories +{ + using System; + using Microsoft.Management.Deployment; + +#if NET + using System.Runtime.InteropServices; + using WinRT; +#endif + + /// <summary> + /// Constructs instances of classes from the <see cref="Management.Deployment" /> namespace. + /// </summary> + public class ComObjectFactory + { +#if USE_TEST_CLSIDS +#else + private static readonly Guid PackageManagerClsid = Guid.Parse("C53A4F16-787E-42A4-B304-29EFFB4BF597"); + private static readonly Guid FindPackagesOptionsClsid = Guid.Parse("572DED96-9C60-4526-8F92-EE7D91D38C1A"); + private static readonly Guid CreateCompositePackageCatalogOptionsClsid = Guid.Parse("526534B8-7E46-47C8-8416-B1685C327D37"); + private static readonly Guid InstallOptionsClsid = Guid.Parse("1095F097-EB96-453B-B4E6-1613637F3B14"); + private static readonly Guid UninstallOptionsClsid = Guid.Parse("E1D9A11E-9F85-4D87-9C17-2B93143ADB8D"); + private static readonly Guid PackageMatchFilterClsid = Guid.Parse("D02C9DAF-99DC-429C-B503-4E504E4AB000"); +#endif + + private static readonly Type PackageManagerType = Type.GetTypeFromCLSID(PackageManagerClsid); + private static readonly Type FindPackagesOptionsType = Type.GetTypeFromCLSID(FindPackagesOptionsClsid); + private static readonly Type CreateCompositePackageCatalogOptionsType = Type.GetTypeFromCLSID(CreateCompositePackageCatalogOptionsClsid); + private static readonly Type InstallOptionsType = Type.GetTypeFromCLSID(InstallOptionsClsid); + private static readonly Type UninstallOptionsType = Type.GetTypeFromCLSID(UninstallOptionsClsid); + private static readonly Type PackageMatchFilterType = Type.GetTypeFromCLSID(PackageMatchFilterClsid); + + /// <summary> + /// Creates an instance of the <see cref="PackageManager" /> class. + /// </summary> + /// <returns>A <see cref="PackageManager" /> instance.</returns> + public virtual PackageManager CreatePackageManager() + { + return Create<PackageManager>(PackageManagerType); + } + + /// <summary> + /// Creates an instance of the <see cref="FindPackagesOptions" /> class. + /// </summary> + /// <returns>A <see cref="FindPackagesOptions" /> instance.</returns> + public virtual FindPackagesOptions CreateFindPackagesOptions() + { + return Create<FindPackagesOptions>(FindPackagesOptionsType); + } + + /// <summary> + /// Creates an instance of the <see cref="CreateCompositePackageCatalogOptions" /> class. + /// </summary> + /// <returns>A <see cref="CreateCompositePackageCatalogOptions" /> instance.</returns> + public virtual CreateCompositePackageCatalogOptions CreateCreateCompositePackageCatalogOptions() + { + return Create<CreateCompositePackageCatalogOptions>(CreateCompositePackageCatalogOptionsType); + } + + /// <summary> + /// Creates an instance of the <see cref="InstallOptions" /> class. + /// </summary> + /// <returns>An <see cref="InstallOptions" /> instance.</returns> + public virtual InstallOptions CreateInstallOptions() + { + return Create<InstallOptions>(InstallOptionsType); + } + + /// <summary> + /// Creates an instance of the <see cref="UninstallOptions" /> class. + /// </summary> + /// <returns>A <see cref="UninstallOptions" /> instance.</returns> + public virtual UninstallOptions CreateUninstallOptions() + { + return Create<UninstallOptions>(UninstallOptionsType); + } + + /// <summary> + /// Creates an instance of the <see cref="PackageMatchFilter" /> class. + /// </summary> + /// <returns>A <see cref="PackageMatchFilter" /> instance.</returns> + public virtual PackageMatchFilter CreatePackageMatchFilter() + { + return Create<PackageMatchFilter>(PackageMatchFilterType); + } + + private static T Create<T>(Type type) + { + object instance = Activator.CreateInstance(type); +#if NET + IntPtr pointer = Marshal.GetIUnknownForObject(instance); + return MarshalInterface<T>.FromAbi(pointer); +#else + return (T)instance; +#endif + } + } +} diff --git a/src/PowerShell/Microsoft.WinGet.Client/Helpers/FilterAttribute.cs b/src/PowerShell/Microsoft.WinGet.Client/Helpers/FilterAttribute.cs @@ -0,0 +1,25 @@ +// ----------------------------------------------------------------------------- +// <copyright file="FilterAttribute.cs" company="Microsoft Corporation"> +// Copyright (c) Microsoft Corporation. Licensed under the MIT License. +// </copyright> +// ----------------------------------------------------------------------------- + +namespace Microsoft.WinGet.Client.Attributes +{ + using System; + using Microsoft.Management.Deployment; + + /// <summary> + /// A <see cref="FindPackagesOptions" /> is constructed by introspecting on the inheritance tree and + /// looking for parameters that are marked with this attribute. Properties that are marked with this + /// attribute are added to the <see cref="FindPackagesOptions" /> object. + /// </summary> + [AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = true)] + public class FilterAttribute : Attribute + { + /// <summary> + /// Gets or sets the field that the filter will be matching against. + /// </summary> + public PackageMatchField Field { get; set; } + } +} diff --git a/src/PowerShell/Microsoft.WinGet.Client/Helpers/WriteProgressAdapter.cs b/src/PowerShell/Microsoft.WinGet.Client/Helpers/WriteProgressAdapter.cs @@ -0,0 +1,90 @@ +// ----------------------------------------------------------------------------- +// <copyright file="WriteProgressAdapter.cs" company="Microsoft Corporation"> +// Copyright (c) Microsoft Corporation. Licensed under the MIT License. +// </copyright> +// ----------------------------------------------------------------------------- + +namespace Microsoft.WinGet.Client.Helpers +{ + using System.Collections.Generic; + using System.Management.Automation; + using System.Threading; + + /// <summary> + /// Marshals calls to <see cref="Cmdlet.WriteProgress(ProgressRecord)" /> back to the main thread. + /// </summary> + public class WriteProgressAdapter + { + private readonly AutoResetEvent resetEvent = new (false); + private readonly Queue<ProgressRecord> records = new (); + private readonly Cmdlet cmdlet; + private volatile bool completed = false; + + /// <summary> + /// Initializes a new instance of the <see cref="WriteProgressAdapter" /> class. + /// </summary> + /// <param name="cmdlet">A <see cref="Cmdlet" /> instance.</param> + public WriteProgressAdapter(Cmdlet cmdlet) + { + this.cmdlet = cmdlet; + } + + /// <summary> + /// Sets a value indicating whether the asynchronous operation is finished and the main thread can continue. + /// </summary> + public bool Completed + { + set + { + this.completed = value; + if (value) + { + this.resetEvent.Set(); + } + } + } + + /// <summary> + /// This should be called on the main thread to wait for the asynchronous operation to complete. + /// </summary> + public void Wait() + { + while (!this.completed) + { + lock (this.records) + { + this.Flush(); + } + + this.resetEvent.WaitOne(); + } + + this.Flush(); + } + + /// <summary> + /// This is an analogue of the <see cref="Cmdlet.WriteProgress(ProgressRecord)" /> function. + /// </summary> + /// <param name="record">A <see cref="ProgressRecord" /> instance.</param> + public void WriteProgress(ProgressRecord record) + { + if (record != null) + { + lock (this.records) + { + this.records.Enqueue(record); + } + + this.resetEvent.Set(); + } + } + + private void Flush() + { + while (this.records.Count > 0) + { + this.cmdlet.WriteProgress(this.records.Dequeue()); + } + } + } +} diff --git a/src/PowerShell/Microsoft.WinGet.Client/Microsoft.WinGet.Client.csproj b/src/PowerShell/Microsoft.WinGet.Client/Microsoft.WinGet.Client.csproj @@ -0,0 +1,80 @@ +<Project Sdk="Microsoft.NET.Sdk"> + + <PropertyGroup> + <TargetWindowsVersion>10.0.22000.0</TargetWindowsVersion> + <CoreFramework>net5.0-windows$(TargetWindowsVersion)</CoreFramework> + <DesktopFramework>net461</DesktopFramework> + </PropertyGroup> + + <PropertyGroup> + <CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies> + <LangVersion>9</LangVersion> + <OutputPath>$(SolutionDir)$(Platform)\$(Configuration)\$(MSBuildProjectName)\</OutputPath> + <Platforms>x64;x86</Platforms> + <TargetFrameworks>$(CoreFramework);$(DesktopFramework)</TargetFrameworks> + </PropertyGroup> + + <ItemGroup> + <AdditionalFiles Include="stylecop.json" /> + </ItemGroup> + + <ItemGroup> + <PackageReference Include="PowerShellStandard.Library" Version="5.1.1" PrivateAssets="all" /> + <PackageReference Include="StyleCop.Analyzers" Version="1.1.118"> + <PrivateAssets>all</PrivateAssets> + <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> + </PackageReference> + <PackageReference Include="System.Security.Principal.Windows" Version="5.0.0" /> + </ItemGroup> + + <ItemGroup> + <ProjectReference Include="..\..\Microsoft.Management.Deployment\Microsoft.Management.Deployment.vcxproj"> + <OutputItemType>Content</OutputItemType> + <CopyToOutputDirectory>Always</CopyToOutputDirectory> + </ProjectReference> + <ProjectReference Include="..\..\UndockedRegFreeWinRT\UndockedRegFreeWinRT\UndockedRegFreeWinRT.vcxproj"> + <OutputItemType>Content</OutputItemType> + <CopyToOutputDirectory>Always</CopyToOutputDirectory> + </ProjectReference> + </ItemGroup> + + <ItemGroup Condition="'$(TargetFramework)' == '$(CoreFramework)'"> + <PackageReference Include="Microsoft.Windows.CsWinRT" Version="1.6.4" /> + </ItemGroup> + + <ItemGroup Condition="'$(TargetFramework)' == '$(DesktopFramework)'"> + <PackageReference Include="Microsoft.Windows.SDK.Contracts" Version="10.0.22000.196" PrivateAssets="all" /> + </ItemGroup> + + <ItemGroup> + <Compile Update="Properties\Resources.Designer.cs"> + <DesignTime>True</DesignTime> + <AutoGen>True</AutoGen> + <DependentUpon>Resources.resx</DependentUpon> + </Compile> + </ItemGroup> + + <ItemGroup> + <EmbeddedResource Update="Properties\Resources.resx"> + <Generator>ResXFileCodeGenerator</Generator> + <LastGenOutput>Resources.Designer.cs</LastGenOutput> + </EmbeddedResource> + </ItemGroup> + + <PropertyGroup Condition="'$(TargetFramework)' == '$(CoreFramework)'"> + <CsWinRTIncludes>Microsoft.Management.Deployment</CsWinRTIncludes> + <CsWinRTWindowsMetadata>$(TargetWindowsVersion)</CsWinRTWindowsMetadata> + <!-- Ensure Support for Windows 10, Version 1809 --> + <TargetPlatformMinVersion>10.0.17763.0</TargetPlatformMinVersion> + </PropertyGroup> + + <Target Name="CopyWinRTAct" AfterTargets="Build" Condition="'$(TargetFramework)' != ''"> + <ItemGroup> + <!-- Ensure Referenced Project Output is in Output Directory --> + <WinRTActDll Include="$(SolutionDir)**\$(Platform)\$(Configuration)\**\winrtact.dll" /> + </ItemGroup> + <Message Importance="high" Text="Copying '@(WinRTActDll)' to '$(OutputPath)'" /> + <Copy SourceFiles="@(WinRTActDll)" DestinationFolder="$(OutputPath)" /> + </Target> + +</Project>+ \ No newline at end of file diff --git a/src/PowerShell/Microsoft.WinGet.Client/Microsoft.WinGet.Client.psd1 b/src/PowerShell/Microsoft.WinGet.Client/Microsoft.WinGet.Client.psd1 @@ -0,0 +1,164 @@ +# +# Module manifest for module 'Microsoft.WinGet.Client' +# +# Generated by: Microsoft Corporation +# +# Generated on: 7/7/2022 +# + +@{ + +# Script module or binary module file associated with this manifest. +RootModule = 'Microsoft.WinGet.Client.psm1' + +# Version number of this module. +ModuleVersion = '0.0.1' + +# Supported PSEditions +CompatiblePSEditions = 'Core' + +# ID used to uniquely identify this module +GUID = 'e11157e2-cd24-4250-83b8-c6654ea4926a' + +# Author of this module +Author = 'Microsoft Corporation' + +# Company or vendor of this module +CompanyName = 'Microsoft Corporation' + +# Copyright statement for this module +Copyright = '(c) Microsoft Corporation. All rights reserved.' + +# Description of the functionality provided by this module +Description = 'PowerShell Module for the Windows Package Manager Client.' + +# Minimum version of the PowerShell engine required by this module +PowerShellVersion = '5.1.0' + +# Name of the PowerShell host required by this module +# PowerShellHostName = '' + +# Minimum version of the PowerShell host required by this module +# PowerShellHostVersion = '' + +# Minimum version of Microsoft .NET Framework required by this module. This prerequisite is valid for the PowerShell Desktop edition only. +# DotNetFrameworkVersion = '' + +# Minimum version of the common language runtime (CLR) required by this module. This prerequisite is valid for the PowerShell Desktop edition only. +# ClrVersion = '' + +# Processor architecture (None, X86, Amd64) required by this module +# ProcessorArchitecture = '' + +# Modules that must be imported into the global environment prior to importing this module +# RequiredModules = @() + +# Assemblies that must be loaded prior to importing this module +# RequiredAssemblies = @() + +# Script files (.ps1) that are run in the caller's environment prior to importing this module. +# ScriptsToProcess = @() + +# Type files (.ps1xml) to be loaded when importing this module +# TypesToProcess = @() + +# Format files (.ps1xml) to be loaded when importing this module +FormatsToProcess = 'Format.ps1xml' + +# Modules to import as nested modules of the module specified in RootModule/ModuleToProcess +NestedModules = if ($env:PROCESSOR_ARCHITECTURE -like 'amd64') { + "x64\$PSEdition\Microsoft.WinGet.Client.dll" +} +else { + "x86\$PSEdition\Microsoft.WinGet.Client.dll" +} + +# Functions to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no functions to export. +FunctionsToExport = @( + 'Get-WinGetVersion' + 'Get-WinGetVersion', + 'Enable-WinGetSetting', + 'Disable-WinGetSetting', + 'Add-WinGetSource', + 'Remove-WinGetSource', + 'Reset-WinGetSource' +) + +# Cmdlets to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no cmdlets to export. +CmdletsToExport = @( + 'Find-WinGetPackage', + 'Get-WinGetPackage', + 'Get-WinGetSource', + 'Install-WinGetPackage', + 'Uninstall-WinGetPackage', + 'Update-WinGetPackage' +) + +# Variables to export from this module +# VariablesToExport = @() + +# Aliases to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no aliases to export. +AliasesToExport = @() + +# DSC resources to export from this module +# DscResourcesToExport = @() + +# List of all modules packaged with this module +# ModuleList = @() + +# List of all files packaged with this module +# FileList = @() + +# Private data to pass to the module specified in RootModule/ModuleToProcess. This may also contain a PSData hashtable with additional module metadata used by PowerShell. +PrivateData = @{ + + PSData = @{ + + # Tags applied to this module. These help with module discovery in online galleries. + Tags = @( + 'CrescendoBuilt', + 'PSEdition_Desktop', + 'PSEdition_Core', + 'Windows', + 'WindowsPackageManager' + ) + + # A URL to the license for this module. + # LicenseUri = '' + + # A URL to the main website for this project. + ProjectUri = 'https://github.com/microsoft/winget-cli' + + # A URL to an icon representing this module. + # IconUri = '' + + # ReleaseNotes of this module + # ReleaseNotes = '' + + # Prerelease string of this module + Prerelease = 'alpha' + + # Flag to indicate whether the module requires explicit user acceptance for install/update/save + # RequireLicenseAcceptance = $false + + # External dependent modules of this module + # ExternalModuleDependencies = @() + + } # End of PSData hashtable + + + # CrescendoVersion + CrescendoVersion = '1.0.0' + + # CrescendoGenerated + CrescendoGenerated = '07/07/2022 00:00:00' + +} # End of PrivateData hashtable + +# HelpInfo URI of this module +# HelpInfoURI = '' + +# Default prefix for commands exported from this module. Override the default prefix using Import-Module -Prefix. +# DefaultCommandPrefix = '' + +} diff --git a/src/PowerShell/Microsoft.WinGet.Client/Microsoft.WinGet.Client.psm1 b/src/PowerShell/Microsoft.WinGet.Client/Microsoft.WinGet.Client.psm1 @@ -0,0 +1,789 @@ +# Module created by Microsoft.PowerShell.Crescendo +class PowerShellCustomFunctionAttribute : System.Attribute { + [bool]$RequiresElevation + [string]$Source + PowerShellCustomFunctionAttribute() { $this.RequiresElevation = $false; $this.Source = "Microsoft.PowerShell.Crescendo" } + PowerShellCustomFunctionAttribute([bool]$rElevation) { + $this.RequiresElevation = $rElevation + $this.Source = "Microsoft.PowerShell.Crescendo" + } +} + + + +function Get-WinGetVersion +{ +[PowerShellCustomFunctionAttribute(RequiresElevation=$False)] +[CmdletBinding()] + +param( ) + +BEGIN { + $__PARAMETERMAP = @{} + $__outputHandlers = @{ Default = @{ StreamOutput = $true; Handler = { $input } } } +} + +PROCESS { + $__boundParameters = $PSBoundParameters + $__defaultValueParameters = $PSCmdlet.MyInvocation.MyCommand.Parameters.Values.Where({$_.Attributes.Where({$_.TypeId.Name -eq "PSDefaultValueAttribute"})}).Name + $__defaultValueParameters.Where({ !$__boundParameters["$_"] }).ForEach({$__boundParameters["$_"] = get-variable -value $_}) + $__commandArgs = @() + $MyInvocation.MyCommand.Parameters.Values.Where({$_.SwitchParameter -and $_.Name -notmatch "Debug|Whatif|Confirm|Verbose" -and ! $__boundParameters[$_.Name]}).ForEach({$__boundParameters[$_.Name] = [switch]::new($false)}) + if ($__boundParameters["Debug"]){wait-debugger} + $__commandArgs += '--version' + foreach ($paramName in $__boundParameters.Keys| + Where-Object {!$__PARAMETERMAP[$_].ApplyToExecutable}| + Sort-Object {$__PARAMETERMAP[$_].OriginalPosition}) { + $value = $__boundParameters[$paramName] + $param = $__PARAMETERMAP[$paramName] + if ($param) { + if ($value -is [switch]) { + if ($value.IsPresent) { + if ($param.OriginalName) { $__commandArgs += $param.OriginalName } + } + elseif ($param.DefaultMissingValue) { $__commandArgs += $param.DefaultMissingValue } + } + elseif ( $param.NoGap ) { + $pFmt = "{0}{1}" + if($value -match "\s") { $pFmt = "{0}""{1}""" } + $__commandArgs += $pFmt -f $param.OriginalName, $value + } + else { + if($param.OriginalName) { $__commandArgs += $param.OriginalName } + $__commandArgs += $value | Foreach-Object {$_} + } + } + } + $__commandArgs = $__commandArgs | Where-Object {$_ -ne $null} + if ($__boundParameters["Debug"]){wait-debugger} + if ( $__boundParameters["Verbose"]) { + Write-Verbose -Verbose -Message winget.exe + $__commandArgs | Write-Verbose -Verbose + } + $__handlerInfo = $__outputHandlers[$PSCmdlet.ParameterSetName] + if (! $__handlerInfo ) { + $__handlerInfo = $__outputHandlers["Default"] # Guaranteed to be present + } + $__handler = $__handlerInfo.Handler + if ( $PSCmdlet.ShouldProcess("winget.exe $__commandArgs")) { + # check for the application and throw if it cannot be found + if ( -not (Get-Command -ErrorAction Ignore "winget.exe")) { + throw "Cannot find executable 'winget.exe'" + } + if ( $__handlerInfo.StreamOutput ) { + & "winget.exe" $__commandArgs | & $__handler + } + else { + $result = & "winget.exe" $__commandArgs + & $__handler $result + } + } + } # end PROCESS + +<# +.SYNOPSIS +Windows Package Manager (Preview) v1.3.1391-preview +Copyright (c) Microsoft Corporation. All rights reserved. + +The winget command line utility enables installing applications and other packages from the command line. + +usage: winget [<command>] [<options>] + +The following commands are available: + install Installs the given package + show Shows information about a package + source Manage sources of packages + search Find and show basic info of packages + list Display installed packages + upgrade Shows and performs available upgrades + uninstall Uninstalls the given package + hash Helper to hash installer files + validate Validates a manifest file + settings Open settings or set administrator settings + features Shows the status of experimental features + export Exports a list of the installed packages + import Installs all the packages in a file + +For more details on a specific command, pass it the help argument. [-?] + +The following options are available: + -v,--version Display the version of the tool + --info Display general info of the tool + +More help can be found at: https://aka.ms/winget-command-help + +.DESCRIPTION See help for winget.exe + +#> +} + + + + +function Enable-WinGetSetting +{ +[PowerShellCustomFunctionAttribute(RequiresElevation=$False)] +[CmdletBinding()] + +param( +[Parameter(Position=0,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true,Mandatory=$true)] +[string]$Name + ) + +BEGIN { + $__PARAMETERMAP = @{ + Name = @{ + OriginalName = '' + OriginalPosition = '0' + Position = '0' + ParameterType = 'string' + ApplyToExecutable = $False + NoGap = $False + } + } + + $__outputHandlers = @{ Default = @{ StreamOutput = $true; Handler = { $input } } } +} + +PROCESS { + $__boundParameters = $PSBoundParameters + $__defaultValueParameters = $PSCmdlet.MyInvocation.MyCommand.Parameters.Values.Where({$_.Attributes.Where({$_.TypeId.Name -eq "PSDefaultValueAttribute"})}).Name + $__defaultValueParameters.Where({ !$__boundParameters["$_"] }).ForEach({$__boundParameters["$_"] = get-variable -value $_}) + $__commandArgs = @() + $MyInvocation.MyCommand.Parameters.Values.Where({$_.SwitchParameter -and $_.Name -notmatch "Debug|Whatif|Confirm|Verbose" -and ! $__boundParameters[$_.Name]}).ForEach({$__boundParameters[$_.Name] = [switch]::new($false)}) + if ($__boundParameters["Debug"]){wait-debugger} + $__commandArgs += 'settings' + $__commandArgs += '--enable' + foreach ($paramName in $__boundParameters.Keys| + Where-Object {!$__PARAMETERMAP[$_].ApplyToExecutable}| + Sort-Object {$__PARAMETERMAP[$_].OriginalPosition}) { + $value = $__boundParameters[$paramName] + $param = $__PARAMETERMAP[$paramName] + if ($param) { + if ($value -is [switch]) { + if ($value.IsPresent) { + if ($param.OriginalName) { $__commandArgs += $param.OriginalName } + } + elseif ($param.DefaultMissingValue) { $__commandArgs += $param.DefaultMissingValue } + } + elseif ( $param.NoGap ) { + $pFmt = "{0}{1}" + if($value -match "\s") { $pFmt = "{0}""{1}""" } + $__commandArgs += $pFmt -f $param.OriginalName, $value + } + else { + if($param.OriginalName) { $__commandArgs += $param.OriginalName } + $__commandArgs += $value | Foreach-Object {$_} + } + } + } + $__commandArgs = $__commandArgs | Where-Object {$_ -ne $null} + if ($__boundParameters["Debug"]){wait-debugger} + if ( $__boundParameters["Verbose"]) { + Write-Verbose -Verbose -Message winget.exe + $__commandArgs | Write-Verbose -Verbose + } + $__handlerInfo = $__outputHandlers[$PSCmdlet.ParameterSetName] + if (! $__handlerInfo ) { + $__handlerInfo = $__outputHandlers["Default"] # Guaranteed to be present + } + $__handler = $__handlerInfo.Handler + if ( $PSCmdlet.ShouldProcess("winget.exe $__commandArgs")) { + # check for the application and throw if it cannot be found + if ( -not (Get-Command -ErrorAction Ignore "winget.exe")) { + throw "Cannot find executable 'winget.exe'" + } + if ( $__handlerInfo.StreamOutput ) { + & "winget.exe" $__commandArgs | & $__handler + } + else { + $result = & "winget.exe" $__commandArgs + & $__handler $result + } + } + } # end PROCESS + +<# +.SYNOPSIS +Windows Package Manager (Preview) v1.3.1391-preview +Copyright (c) Microsoft Corporation. All rights reserved. + +The winget command line utility enables installing applications and other packages from the command line. + +usage: winget [<command>] [<options>] + +The following commands are available: + install Installs the given package + show Shows information about a package + source Manage sources of packages + search Find and show basic info of packages + list Display installed packages + upgrade Shows and performs available upgrades + uninstall Uninstalls the given package + hash Helper to hash installer files + validate Validates a manifest file + settings Open settings or set administrator settings + features Shows the status of experimental features + export Exports a list of the installed packages + import Installs all the packages in a file + +For more details on a specific command, pass it the help argument. [-?] + +The following options are available: + -v,--version Display the version of the tool + --info Display general info of the tool + +More help can be found at: https://aka.ms/winget-command-help + +.DESCRIPTION See help for winget.exe + +.PARAMETER Name + + + + +#> +} + + + + +function Disable-WinGetSetting +{ +[PowerShellCustomFunctionAttribute(RequiresElevation=$False)] +[CmdletBinding()] + +param( +[Parameter(Position=0,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true,Mandatory=$true)] +[string]$Name + ) + +BEGIN { + $__PARAMETERMAP = @{ + Name = @{ + OriginalName = '' + OriginalPosition = '0' + Position = '0' + ParameterType = 'string' + ApplyToExecutable = $False + NoGap = $False + } + } + + $__outputHandlers = @{ Default = @{ StreamOutput = $true; Handler = { $input } } } +} + +PROCESS { + $__boundParameters = $PSBoundParameters + $__defaultValueParameters = $PSCmdlet.MyInvocation.MyCommand.Parameters.Values.Where({$_.Attributes.Where({$_.TypeId.Name -eq "PSDefaultValueAttribute"})}).Name + $__defaultValueParameters.Where({ !$__boundParameters["$_"] }).ForEach({$__boundParameters["$_"] = get-variable -value $_}) + $__commandArgs = @() + $MyInvocation.MyCommand.Parameters.Values.Where({$_.SwitchParameter -and $_.Name -notmatch "Debug|Whatif|Confirm|Verbose" -and ! $__boundParameters[$_.Name]}).ForEach({$__boundParameters[$_.Name] = [switch]::new($false)}) + if ($__boundParameters["Debug"]){wait-debugger} + $__commandArgs += 'settings' + $__commandArgs += '--disable' + foreach ($paramName in $__boundParameters.Keys| + Where-Object {!$__PARAMETERMAP[$_].ApplyToExecutable}| + Sort-Object {$__PARAMETERMAP[$_].OriginalPosition}) { + $value = $__boundParameters[$paramName] + $param = $__PARAMETERMAP[$paramName] + if ($param) { + if ($value -is [switch]) { + if ($value.IsPresent) { + if ($param.OriginalName) { $__commandArgs += $param.OriginalName } + } + elseif ($param.DefaultMissingValue) { $__commandArgs += $param.DefaultMissingValue } + } + elseif ( $param.NoGap ) { + $pFmt = "{0}{1}" + if($value -match "\s") { $pFmt = "{0}""{1}""" } + $__commandArgs += $pFmt -f $param.OriginalName, $value + } + else { + if($param.OriginalName) { $__commandArgs += $param.OriginalName } + $__commandArgs += $value | Foreach-Object {$_} + } + } + } + $__commandArgs = $__commandArgs | Where-Object {$_ -ne $null} + if ($__boundParameters["Debug"]){wait-debugger} + if ( $__boundParameters["Verbose"]) { + Write-Verbose -Verbose -Message winget.exe + $__commandArgs | Write-Verbose -Verbose + } + $__handlerInfo = $__outputHandlers[$PSCmdlet.ParameterSetName] + if (! $__handlerInfo ) { + $__handlerInfo = $__outputHandlers["Default"] # Guaranteed to be present + } + $__handler = $__handlerInfo.Handler + if ( $PSCmdlet.ShouldProcess("winget.exe $__commandArgs")) { + # check for the application and throw if it cannot be found + if ( -not (Get-Command -ErrorAction Ignore "winget.exe")) { + throw "Cannot find executable 'winget.exe'" + } + if ( $__handlerInfo.StreamOutput ) { + & "winget.exe" $__commandArgs | & $__handler + } + else { + $result = & "winget.exe" $__commandArgs + & $__handler $result + } + } + } # end PROCESS + +<# +.SYNOPSIS +Windows Package Manager (Preview) v1.3.1391-preview +Copyright (c) Microsoft Corporation. All rights reserved. + +The winget command line utility enables installing applications and other packages from the command line. + +usage: winget [<command>] [<options>] + +The following commands are available: + install Installs the given package + show Shows information about a package + source Manage sources of packages + search Find and show basic info of packages + list Display installed packages + upgrade Shows and performs available upgrades + uninstall Uninstalls the given package + hash Helper to hash installer files + validate Validates a manifest file + settings Open settings or set administrator settings + features Shows the status of experimental features + export Exports a list of the installed packages + import Installs all the packages in a file + +For more details on a specific command, pass it the help argument. [-?] + +The following options are available: + -v,--version Display the version of the tool + --info Display general info of the tool + +More help can be found at: https://aka.ms/winget-command-help + +.DESCRIPTION See help for winget.exe + +.PARAMETER Name + + + + +#> +} + + + + +function Add-WinGetSource +{ +[PowerShellCustomFunctionAttribute(RequiresElevation=$False)] +[CmdletBinding()] + +param( +[Parameter(Position=0,ValueFromPipelineByPropertyName=$true,Mandatory=$true)] +[string]$Name, +[Parameter(Position=1,ValueFromPipelineByPropertyName=$true,Mandatory=$true)] +[string]$Argument, +[Parameter(Position=2,ValueFromPipelineByPropertyName=$true)] +[string]$Type + ) + +BEGIN { + $__PARAMETERMAP = @{ + Name = @{ + OriginalName = '--name' + OriginalPosition = '0' + Position = '0' + ParameterType = 'string' + ApplyToExecutable = $False + NoGap = $False + } + Argument = @{ + OriginalName = '--arg' + OriginalPosition = '0' + Position = '1' + ParameterType = 'string' + ApplyToExecutable = $False + NoGap = $False + } + Type = @{ + OriginalName = '--type' + OriginalPosition = '0' + Position = '2' + ParameterType = 'string' + ApplyToExecutable = $False + NoGap = $False + } + } + + $__outputHandlers = @{ Default = @{ StreamOutput = $true; Handler = { $input } } } +} + +PROCESS { + $__boundParameters = $PSBoundParameters + $__defaultValueParameters = $PSCmdlet.MyInvocation.MyCommand.Parameters.Values.Where({$_.Attributes.Where({$_.TypeId.Name -eq "PSDefaultValueAttribute"})}).Name + $__defaultValueParameters.Where({ !$__boundParameters["$_"] }).ForEach({$__boundParameters["$_"] = get-variable -value $_}) + $__commandArgs = @() + $MyInvocation.MyCommand.Parameters.Values.Where({$_.SwitchParameter -and $_.Name -notmatch "Debug|Whatif|Confirm|Verbose" -and ! $__boundParameters[$_.Name]}).ForEach({$__boundParameters[$_.Name] = [switch]::new($false)}) + if ($__boundParameters["Debug"]){wait-debugger} + $__commandArgs += 'source' + $__commandArgs += 'add' + foreach ($paramName in $__boundParameters.Keys| + Where-Object {!$__PARAMETERMAP[$_].ApplyToExecutable}| + Sort-Object {$__PARAMETERMAP[$_].OriginalPosition}) { + $value = $__boundParameters[$paramName] + $param = $__PARAMETERMAP[$paramName] + if ($param) { + if ($value -is [switch]) { + if ($value.IsPresent) { + if ($param.OriginalName) { $__commandArgs += $param.OriginalName } + } + elseif ($param.DefaultMissingValue) { $__commandArgs += $param.DefaultMissingValue } + } + elseif ( $param.NoGap ) { + $pFmt = "{0}{1}" + if($value -match "\s") { $pFmt = "{0}""{1}""" } + $__commandArgs += $pFmt -f $param.OriginalName, $value + } + else { + if($param.OriginalName) { $__commandArgs += $param.OriginalName } + $__commandArgs += $value | Foreach-Object {$_} + } + } + } + $__commandArgs = $__commandArgs | Where-Object {$_ -ne $null} + if ($__boundParameters["Debug"]){wait-debugger} + if ( $__boundParameters["Verbose"]) { + Write-Verbose -Verbose -Message winget.exe + $__commandArgs | Write-Verbose -Verbose + } + $__handlerInfo = $__outputHandlers[$PSCmdlet.ParameterSetName] + if (! $__handlerInfo ) { + $__handlerInfo = $__outputHandlers["Default"] # Guaranteed to be present + } + $__handler = $__handlerInfo.Handler + if ( $PSCmdlet.ShouldProcess("winget.exe $__commandArgs")) { + # check for the application and throw if it cannot be found + if ( -not (Get-Command -ErrorAction Ignore "winget.exe")) { + throw "Cannot find executable 'winget.exe'" + } + if ( $__handlerInfo.StreamOutput ) { + & "winget.exe" $__commandArgs | & $__handler + } + else { + $result = & "winget.exe" $__commandArgs + & $__handler $result + } + } + } # end PROCESS + +<# +.SYNOPSIS +Windows Package Manager (Preview) v1.3.1391-preview +Copyright (c) Microsoft Corporation. All rights reserved. + +The winget command line utility enables installing applications and other packages from the command line. + +usage: winget [<command>] [<options>] + +The following commands are available: + install Installs the given package + show Shows information about a package + source Manage sources of packages + search Find and show basic info of packages + list Display installed packages + upgrade Shows and performs available upgrades + uninstall Uninstalls the given package + hash Helper to hash installer files + validate Validates a manifest file + settings Open settings or set administrator settings + features Shows the status of experimental features + export Exports a list of the installed packages + import Installs all the packages in a file + +For more details on a specific command, pass it the help argument. [-?] + +The following options are available: + -v,--version Display the version of the tool + --info Display general info of the tool + +More help can be found at: https://aka.ms/winget-command-help + +.DESCRIPTION See help for winget.exe + +.PARAMETER Name + + + +.PARAMETER Argument + + + +.PARAMETER Type + + + + +#> +} + + + + +function Remove-WinGetSource +{ +[PowerShellCustomFunctionAttribute(RequiresElevation=$False)] +[CmdletBinding()] + +param( +[Parameter(Position=0,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true,Mandatory=$true)] +[string]$Name + ) + +BEGIN { + $__PARAMETERMAP = @{ + Name = @{ + OriginalName = '--name' + OriginalPosition = '0' + Position = '0' + ParameterType = 'string' + ApplyToExecutable = $False + NoGap = $False + } + } + + $__outputHandlers = @{ Default = @{ StreamOutput = $true; Handler = { $input } } } +} + +PROCESS { + $__boundParameters = $PSBoundParameters + $__defaultValueParameters = $PSCmdlet.MyInvocation.MyCommand.Parameters.Values.Where({$_.Attributes.Where({$_.TypeId.Name -eq "PSDefaultValueAttribute"})}).Name + $__defaultValueParameters.Where({ !$__boundParameters["$_"] }).ForEach({$__boundParameters["$_"] = get-variable -value $_}) + $__commandArgs = @() + $MyInvocation.MyCommand.Parameters.Values.Where({$_.SwitchParameter -and $_.Name -notmatch "Debug|Whatif|Confirm|Verbose" -and ! $__boundParameters[$_.Name]}).ForEach({$__boundParameters[$_.Name] = [switch]::new($false)}) + if ($__boundParameters["Debug"]){wait-debugger} + $__commandArgs += 'source' + $__commandArgs += 'remove' + foreach ($paramName in $__boundParameters.Keys| + Where-Object {!$__PARAMETERMAP[$_].ApplyToExecutable}| + Sort-Object {$__PARAMETERMAP[$_].OriginalPosition}) { + $value = $__boundParameters[$paramName] + $param = $__PARAMETERMAP[$paramName] + if ($param) { + if ($value -is [switch]) { + if ($value.IsPresent) { + if ($param.OriginalName) { $__commandArgs += $param.OriginalName } + } + elseif ($param.DefaultMissingValue) { $__commandArgs += $param.DefaultMissingValue } + } + elseif ( $param.NoGap ) { + $pFmt = "{0}{1}" + if($value -match "\s") { $pFmt = "{0}""{1}""" } + $__commandArgs += $pFmt -f $param.OriginalName, $value + } + else { + if($param.OriginalName) { $__commandArgs += $param.OriginalName } + $__commandArgs += $value | Foreach-Object {$_} + } + } + } + $__commandArgs = $__commandArgs | Where-Object {$_ -ne $null} + if ($__boundParameters["Debug"]){wait-debugger} + if ( $__boundParameters["Verbose"]) { + Write-Verbose -Verbose -Message winget.exe + $__commandArgs | Write-Verbose -Verbose + } + $__handlerInfo = $__outputHandlers[$PSCmdlet.ParameterSetName] + if (! $__handlerInfo ) { + $__handlerInfo = $__outputHandlers["Default"] # Guaranteed to be present + } + $__handler = $__handlerInfo.Handler + if ( $PSCmdlet.ShouldProcess("winget.exe $__commandArgs")) { + # check for the application and throw if it cannot be found + if ( -not (Get-Command -ErrorAction Ignore "winget.exe")) { + throw "Cannot find executable 'winget.exe'" + } + if ( $__handlerInfo.StreamOutput ) { + & "winget.exe" $__commandArgs | & $__handler + } + else { + $result = & "winget.exe" $__commandArgs + & $__handler $result + } + } + } # end PROCESS + +<# +.SYNOPSIS +Windows Package Manager (Preview) v1.3.1391-preview +Copyright (c) Microsoft Corporation. All rights reserved. + +The winget command line utility enables installing applications and other packages from the command line. + +usage: winget [<command>] [<options>] + +The following commands are available: + install Installs the given package + show Shows information about a package + source Manage sources of packages + search Find and show basic info of packages + list Display installed packages + upgrade Shows and performs available upgrades + uninstall Uninstalls the given package + hash Helper to hash installer files + validate Validates a manifest file + settings Open settings or set administrator settings + features Shows the status of experimental features + export Exports a list of the installed packages + import Installs all the packages in a file + +For more details on a specific command, pass it the help argument. [-?] + +The following options are available: + -v,--version Display the version of the tool + --info Display general info of the tool + +More help can be found at: https://aka.ms/winget-command-help + +.DESCRIPTION See help for winget.exe + +.PARAMETER Name + + + + +#> +} + + + + +function Reset-WinGetSource +{ +[PowerShellCustomFunctionAttribute(RequiresElevation=$False)] +[CmdletBinding()] + +param( +[Parameter(Position=0,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)] +[string]$Name + ) + +BEGIN { + $__PARAMETERMAP = @{ + Name = @{ + OriginalName = '--name' + OriginalPosition = '0' + Position = '0' + ParameterType = 'string' + ApplyToExecutable = $False + NoGap = $False + } + } + + $__outputHandlers = @{ Default = @{ StreamOutput = $true; Handler = { $input } } } +} + +PROCESS { + $__boundParameters = $PSBoundParameters + $__defaultValueParameters = $PSCmdlet.MyInvocation.MyCommand.Parameters.Values.Where({$_.Attributes.Where({$_.TypeId.Name -eq "PSDefaultValueAttribute"})}).Name + $__defaultValueParameters.Where({ !$__boundParameters["$_"] }).ForEach({$__boundParameters["$_"] = get-variable -value $_}) + $__commandArgs = @() + $MyInvocation.MyCommand.Parameters.Values.Where({$_.SwitchParameter -and $_.Name -notmatch "Debug|Whatif|Confirm|Verbose" -and ! $__boundParameters[$_.Name]}).ForEach({$__boundParameters[$_.Name] = [switch]::new($false)}) + if ($__boundParameters["Debug"]){wait-debugger} + $__commandArgs += 'source' + $__commandArgs += 'reset' + $__commandArgs += '--force' + foreach ($paramName in $__boundParameters.Keys| + Where-Object {!$__PARAMETERMAP[$_].ApplyToExecutable}| + Sort-Object {$__PARAMETERMAP[$_].OriginalPosition}) { + $value = $__boundParameters[$paramName] + $param = $__PARAMETERMAP[$paramName] + if ($param) { + if ($value -is [switch]) { + if ($value.IsPresent) { + if ($param.OriginalName) { $__commandArgs += $param.OriginalName } + } + elseif ($param.DefaultMissingValue) { $__commandArgs += $param.DefaultMissingValue } + } + elseif ( $param.NoGap ) { + $pFmt = "{0}{1}" + if($value -match "\s") { $pFmt = "{0}""{1}""" } + $__commandArgs += $pFmt -f $param.OriginalName, $value + } + else { + if($param.OriginalName) { $__commandArgs += $param.OriginalName } + $__commandArgs += $value | Foreach-Object {$_} + } + } + } + $__commandArgs = $__commandArgs | Where-Object {$_ -ne $null} + if ($__boundParameters["Debug"]){wait-debugger} + if ( $__boundParameters["Verbose"]) { + Write-Verbose -Verbose -Message winget.exe + $__commandArgs | Write-Verbose -Verbose + } + $__handlerInfo = $__outputHandlers[$PSCmdlet.ParameterSetName] + if (! $__handlerInfo ) { + $__handlerInfo = $__outputHandlers["Default"] # Guaranteed to be present + } + $__handler = $__handlerInfo.Handler + if ( $PSCmdlet.ShouldProcess("winget.exe $__commandArgs")) { + # check for the application and throw if it cannot be found + if ( -not (Get-Command -ErrorAction Ignore "winget.exe")) { + throw "Cannot find executable 'winget.exe'" + } + if ( $__handlerInfo.StreamOutput ) { + & "winget.exe" $__commandArgs | & $__handler + } + else { + $result = & "winget.exe" $__commandArgs + & $__handler $result + } + } + } # end PROCESS + +<# +.SYNOPSIS +Windows Package Manager (Preview) v1.3.1391-preview +Copyright (c) Microsoft Corporation. All rights reserved. + +The winget command line utility enables installing applications and other packages from the command line. + +usage: winget [<command>] [<options>] + +The following commands are available: + install Installs the given package + show Shows information about a package + source Manage sources of packages + search Find and show basic info of packages + list Display installed packages + upgrade Shows and performs available upgrades + uninstall Uninstalls the given package + hash Helper to hash installer files + validate Validates a manifest file + settings Open settings or set administrator settings + features Shows the status of experimental features + export Exports a list of the installed packages + import Installs all the packages in a file + +For more details on a specific command, pass it the help argument. [-?] + +The following options are available: + -v,--version Display the version of the tool + --info Display general info of the tool + +More help can be found at: https://aka.ms/winget-command-help + +.DESCRIPTION See help for winget.exe + +.PARAMETER Name + + + + +#> +} + + diff --git a/src/PowerShell/Microsoft.WinGet.Client/Properties/Resources.Designer.cs b/src/PowerShell/Microsoft.WinGet.Client/Properties/Resources.Designer.cs @@ -0,0 +1,153 @@ +//------------------------------------------------------------------------------ +// <auto-generated> +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// </auto-generated> +//------------------------------------------------------------------------------ + +namespace Microsoft.WinGet.Client.Properties { + using System; + + + /// <summary> + /// A strongly-typed resource class, for looking up localized strings, etc. + /// </summary> + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() { + } + + /// <summary> + /// Returns the cached ResourceManager instance used by this class. + /// </summary> + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Microsoft.WinGet.Client.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// <summary> + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// </summary> + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// <summary> + /// Looks up a localized string similar to No source matches the given value: {0}. + /// </summary> + internal static string ArgumentExceptionInvalidSource { + get { + return ResourceManager.GetString("ArgumentExceptionInvalidSource", resourceCulture); + } + } + + /// <summary> + /// Looks up a localized string similar to This cmdlet is currently disabled in an administrative context.. + /// </summary> + internal static string ExceptionAdministratorDisabled { + get { + return ResourceManager.GetString("ExceptionAdministratorDisabled", resourceCulture); + } + } + + /// <summary> + /// Looks up a localized string similar to An error occurred while searching for packages: {0}. + /// </summary> + internal static string FindPackagesExceptionMessage { + get { + return ResourceManager.GetString("FindPackagesExceptionMessage", resourceCulture); + } + } + + /// <summary> + /// Looks up a localized string similar to Installing '{0}'. + /// </summary> + internal static string ProgressRecordActivityInstalling { + get { + return ResourceManager.GetString("ProgressRecordActivityInstalling", resourceCulture); + } + } + + /// <summary> + /// Looks up a localized string similar to Uninstalling '{0}'. + /// </summary> + internal static string ProgressRecordActivityUninstalling { + get { + return ResourceManager.GetString("ProgressRecordActivityUninstalling", resourceCulture); + } + } + + /// <summary> + /// Looks up a localized string similar to Updating '{0}'. + /// </summary> + internal static string ProgressRecordActivityUpdating { + get { + return ResourceManager.GetString("ProgressRecordActivityUpdating", resourceCulture); + } + } + + /// <summary> + /// Looks up a localized string similar to An error occurred while connecting to the catalog.. + /// </summary> + internal static string RuntimeExceptionCatalogError { + get { + return ResourceManager.GetString("RuntimeExceptionCatalogError", resourceCulture); + } + } + + /// <summary> + /// Looks up a localized string similar to No versions matched the given value: {0}. + /// </summary> + internal static string RuntimeExceptionInvalidVersion { + get { + return ResourceManager.GetString("RuntimeExceptionInvalidVersion", resourceCulture); + } + } + + /// <summary> + /// Looks up a localized string similar to No packages matched the given input criteria.. + /// </summary> + internal static string RuntimeExceptionNoPackagesFound { + get { + return ResourceManager.GetString("RuntimeExceptionNoPackagesFound", resourceCulture); + } + } + + /// <summary> + /// Looks up a localized string similar to {0}, {1}, and {2} other packages matched the input criteria. Please refine the input.. + /// </summary> + internal static string VagueCriteriaExceptionMessage { + get { + return ResourceManager.GetString("VagueCriteriaExceptionMessage", resourceCulture); + } + } + } +} diff --git a/src/PowerShell/Microsoft.WinGet.Client/Properties/Resources.resx b/src/PowerShell/Microsoft.WinGet.Client/Properties/Resources.resx @@ -0,0 +1,157 @@ +<?xml version="1.0" encoding="utf-8"?> +<root> + <!-- + Microsoft ResX Schema + + Version 2.0 + + The primary goals of this format is to allow a simple XML format + that is mostly human readable. The generation and parsing of the + various data types are done through the TypeConverter classes + associated with the data types. + + Example: + + ... ado.net/XML headers & schema ... + <resheader name="resmimetype">text/microsoft-resx</resheader> + <resheader name="version">2.0</resheader> + <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader> + <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader> + <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data> + <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data> + <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64"> + <value>[base64 mime encoded serialized .NET Framework object]</value> + </data> + <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64"> + <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value> + <comment>This is a comment</comment> + </data> + + There are any number of "resheader" rows that contain simple + name/value pairs. + + Each data row contains a name, and value. The row also contains a + type or mimetype. Type corresponds to a .NET class that support + text/value conversion through the TypeConverter architecture. + Classes that don't support this are serialized and stored with the + mimetype set. + + The mimetype is used for serialized objects, and tells the + ResXResourceReader how to depersist the object. This is currently not + extensible. For a given mimetype the value must be set accordingly: + + Note - application/x-microsoft.net.object.binary.base64 is the format + that the ResXResourceWriter will generate, however the reader can + read any of the formats listed below. + + mimetype: application/x-microsoft.net.object.binary.base64 + value : The object must be serialized with + : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter + : and then encoded with base64 encoding. + + mimetype: application/x-microsoft.net.object.soap.base64 + value : The object must be serialized with + : System.Runtime.Serialization.Formatters.Soap.SoapFormatter + : and then encoded with base64 encoding. + + mimetype: application/x-microsoft.net.object.bytearray.base64 + value : The object must be serialized into a byte array + : using a System.ComponentModel.TypeConverter + : and then encoded with base64 encoding. + --> + <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"> + <xsd:import namespace="http://www.w3.org/XML/1998/namespace" /> + <xsd:element name="root" msdata:IsDataSet="true"> + <xsd:complexType> + <xsd:choice maxOccurs="unbounded"> + <xsd:element name="metadata"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="value" type="xsd:string" minOccurs="0" /> + </xsd:sequence> + <xsd:attribute name="name" use="required" type="xsd:string" /> + <xsd:attribute name="type" type="xsd:string" /> + <xsd:attribute name="mimetype" type="xsd:string" /> + <xsd:attribute ref="xml:space" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="assembly"> + <xsd:complexType> + <xsd:attribute name="alias" type="xsd:string" /> + <xsd:attribute name="name" type="xsd:string" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="data"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> + <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" /> + </xsd:sequence> + <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" /> + <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" /> + <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" /> + <xsd:attribute ref="xml:space" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="resheader"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> + </xsd:sequence> + <xsd:attribute name="name" type="xsd:string" use="required" /> + </xsd:complexType> + </xsd:element> + </xsd:choice> + </xsd:complexType> + </xsd:element> + </xsd:schema> + <resheader name="resmimetype"> + <value>text/microsoft-resx</value> + </resheader> + <resheader name="version"> + <value>2.0</value> + </resheader> + <resheader name="reader"> + <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> + </resheader> + <resheader name="writer"> + <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> + </resheader> + <data name="ArgumentExceptionInvalidSource" xml:space="preserve"> + <value>No source matches the given value: {0}</value> + <comment>{0} - The name of the source that was not found.</comment> + </data> + <data name="ExceptionAdministratorDisabled" xml:space="preserve"> + <value>This cmdlet is currently disabled in an administrative context.</value> + </data> + <data name="FindPackagesExceptionMessage" xml:space="preserve"> + <value>An error occurred while searching for packages: {0}</value> + <comment>{0} - A string representation of the error status returned by the catalog.</comment> + </data> + <data name="ProgressRecordActivityInstalling" xml:space="preserve"> + <value>Installing '{0}'</value> + <comment>{0} - The name of the package being installed.</comment> + </data> + <data name="ProgressRecordActivityUninstalling" xml:space="preserve"> + <value>Uninstalling '{0}'</value> + <comment>{0} - The name of the package being uninstalled.</comment> + </data> + <data name="ProgressRecordActivityUpdating" xml:space="preserve"> + <value>Updating '{0}'</value> + <comment>{0} - The name of the package being updated.</comment> + </data> + <data name="RuntimeExceptionCatalogError" xml:space="preserve"> + <value>An error occurred while connecting to the catalog.</value> + </data> + <data name="RuntimeExceptionInvalidVersion" xml:space="preserve"> + <value>No versions matched the given value: {0}</value> + <comment>{0} - The version string provided by the user.</comment> + </data> + <data name="RuntimeExceptionNoPackagesFound" xml:space="preserve"> + <value>No packages matched the given input criteria.</value> + </data> + <data name="VagueCriteriaExceptionMessage" xml:space="preserve"> + <value>{0}, {1}, and {2} other packages matched the input criteria. Please refine the input.</value> + <comment>{0} - The first conflicting package as a string. {1} - The second conflicting package. {2} - The number of other packages that also matched the input criteria.</comment> + </data> +</root>+ \ No newline at end of file diff --git a/src/PowerShell/Microsoft.WinGet.Client/stylecop.json b/src/PowerShell/Microsoft.WinGet.Client/stylecop.json @@ -0,0 +1,10 @@ +{ + "$schema": "https://raw.githubusercontent.com/DotNetAnalyzers/StyleCopAnalyzers/master/StyleCop.Analyzers/StyleCop.Analyzers/Settings/stylecop.schema.json", + "settings": { + "documentationRules": { + "companyName": "Microsoft Corporation", + "copyrightText": " Copyright (c) {companyName}. Licensed under the MIT License.", + "headerDecoration": "-----------------------------------------------------------------------------" + } + } +}