From 630785459c0cecc8ba6987f0a2c5ce4fe8c94689 Mon Sep 17 00:00:00 2001 From: Ryan Fu Date: Thu, 20 Oct 2022 10:46:06 -0700 Subject: [PATCH 01/49] save work --- .gitignore | 5 + .../AppInstallerCLIPackage.wapproj | 39 +++++- .../Package.appxmanifest | 12 +- .../Common/BaseClientCommand.cs | 1 + .../Common/Utilities.cs | 7 +- .../Helpers/ComObjectFactory.cs | 47 +++++-- .../UndockedRegFreeWinRT.vcxproj | 10 +- .../UndockedRegFreeWinRT.vcxproj.filters | 7 + .../UndockedRegFreeWinRT/catalog.cpp | 5 +- .../UndockedRegFreeWinRT/winrtact.def | 4 +- src/WinGetServer/WinGetServer.idl | Bin 0 -> 858 bytes src/WinGetServer/WinGetServer.vcxproj | 123 +++++++++++++++++- src/WinGetServer/WinGetServer.vcxproj.filters | 11 ++ .../WinGetServerManualActivation_Client.cpp | 100 ++++++++++++++ src/WinGetServer/WinMain.cpp | 116 ++++++++++++++++- src/WinGetServer/packages.config | 1 - src/WindowsPackageManager/Source.def | 1 + .../WindowsPackageManager.h | 3 + src/WindowsPackageManager/main.cpp | 11 ++ 19 files changed, 469 insertions(+), 34 deletions(-) create mode 100644 src/WinGetServer/WinGetServer.idl create mode 100644 src/WinGetServer/WinGetServerManualActivation_Client.cpp diff --git a/.gitignore b/.gitignore index 20106aeb70..409d93039d 100644 --- a/.gitignore +++ b/.gitignore @@ -329,3 +329,8 @@ ASALocalRun/ # MFractors (Xamarin productivity tool) working folder .mfractor/ + +# Generated files from WinGetServer.idl +**/WinGetServer/WinGetServer.h +**/WinGetServer/WinGetServer_c.c +**/WinGetServer/WinGetServer_s.c \ No newline at end of file diff --git a/src/AppInstallerCLIPackage/AppInstallerCLIPackage.wapproj b/src/AppInstallerCLIPackage/AppInstallerCLIPackage.wapproj index d659efee6b..84fe09707f 100644 --- a/src/AppInstallerCLIPackage/AppInstallerCLIPackage.wapproj +++ b/src/AppInstallerCLIPackage/AppInstallerCLIPackage.wapproj @@ -54,7 +54,7 @@ 10.0.22000.0 10.0.17763.0 en-US - false + True ..\AppInstallerCLI\AppInstallerCLI.vcxproj @@ -96,6 +96,43 @@ copy "$(TargetDir)\resources.pri" "$(ProjectDir)\..\$(Platform)\$(Configuration)\AppInstallerCLI\resources.pri" copy "$(TargetDir)\resources.pri" "$(TargetDir)\AppInstallerCLI\resources.pri" + False + True + True + x64 + 0 + C:\Users\ryfu\E2ETesting\appInstaller.pfx + SHA256 + + + Always + + + Always + + + Always + + + Always + + + Always + + + Always + + + Always + + + Always + + + Always + + + Always diff --git a/src/AppInstallerCLIPackage/Package.appxmanifest b/src/AppInstallerCLIPackage/Package.appxmanifest index d38215f422..c103032ae8 100644 --- a/src/AppInstallerCLIPackage/Package.appxmanifest +++ b/src/AppInstallerCLIPackage/Package.appxmanifest @@ -8,7 +8,7 @@ xmlns:com="http://schemas.microsoft.com/appx/manifest/com/windows10" xmlns:desktop6="http://schemas.microsoft.com/appx/manifest/desktop/windows10/6" IgnorableNamespaces="uap uap3 uap5 rescap"> - + WinGet Dev CLI Microsoft Corporation @@ -37,6 +37,16 @@ + + + + + + + + + + diff --git a/src/PowerShell/Microsoft.WinGet.Client/Common/BaseClientCommand.cs b/src/PowerShell/Microsoft.WinGet.Client/Common/BaseClientCommand.cs index 4961f03965..f636a110a6 100644 --- a/src/PowerShell/Microsoft.WinGet.Client/Common/BaseClientCommand.cs +++ b/src/PowerShell/Microsoft.WinGet.Client/Common/BaseClientCommand.cs @@ -29,6 +29,7 @@ static BaseClientCommand() public BaseClientCommand() : base() { + // this error should be removed if it is running as admin and call the correct activation path. if (Utilities.ExecutingAsAdministrator) { throw new Exception(Utilities.ResourceManager.GetString("ExceptionAdministratorDisabled")); diff --git a/src/PowerShell/Microsoft.WinGet.Client/Common/Utilities.cs b/src/PowerShell/Microsoft.WinGet.Client/Common/Utilities.cs index 7c9e00bcfc..3e43dfd0bd 100644 --- a/src/PowerShell/Microsoft.WinGet.Client/Common/Utilities.cs +++ b/src/PowerShell/Microsoft.WinGet.Client/Common/Utilities.cs @@ -32,9 +32,10 @@ public static bool ExecutingAsAdministrator { get { - WindowsIdentity identity = WindowsIdentity.GetCurrent(); - WindowsPrincipal principal = new (identity); - return principal.IsInRole(WindowsBuiltInRole.Administrator); + //WindowsIdentity identity = WindowsIdentity.GetCurrent(); + //WindowsPrincipal principal = new (identity); + //return principal.IsInRole(WindowsBuiltInRole.Administrator); + return false; } } } diff --git a/src/PowerShell/Microsoft.WinGet.Client/Helpers/ComObjectFactory.cs b/src/PowerShell/Microsoft.WinGet.Client/Helpers/ComObjectFactory.cs index cd4a907d50..668d2e9cfc 100644 --- a/src/PowerShell/Microsoft.WinGet.Client/Helpers/ComObjectFactory.cs +++ b/src/PowerShell/Microsoft.WinGet.Client/Helpers/ComObjectFactory.cs @@ -7,10 +7,10 @@ namespace Microsoft.WinGet.Client.Factories { using System; + using System.Runtime.InteropServices; using Microsoft.Management.Deployment; #if NET - using System.Runtime.InteropServices; using WinRT; #endif @@ -19,7 +19,14 @@ namespace Microsoft.WinGet.Client.Factories /// public class ComObjectFactory { -#if USE_TEST_CLSIDS + // TODO: Change to default to TEST CLSIDS based on USE_PROD_CLSIDS +#if !USE_TEST_CLSIDS + private static readonly Guid PackageManagerClsid = Guid.Parse("74CB3139-B7C5-4B9E-9388-E6616DEA288C"); + private static readonly Guid FindPackagesOptionsClsid = Guid.Parse("1BD8FF3A-EC50-4F69-AEEE-DF4C9D3BAA96"); + private static readonly Guid CreateCompositePackageCatalogOptionsClsid = Guid.Parse("EE160901-B317-4EA7-9CC6-5355C6D7D8A7"); + private static readonly Guid InstallOptionsClsid = Guid.Parse("44FE0580-62F7-44D4-9E91-AA9614AB3E86"); + private static readonly Guid UninstallOptionsClsid = Guid.Parse("AA2A5C04-1AD9-46C4-B74F-6B334AD7EB8C"); + private static readonly Guid PackageMatchFilterClsid = Guid.Parse("3F85B9F4-487A-4C48-9035-2903F8A6D9E8"); #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"); @@ -28,6 +35,12 @@ public class ComObjectFactory 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 Guid PackageManagerIid = Guid.Parse("B375E3B9-F2E0-5C93-87A7-B67497F7E593"); + private static readonly Guid FindPackagesOptionsIid = Guid.Parse("A5270EDD-7DA7-57A3-BACE-F2593553561F"); + private static readonly Guid CreateCompositePackageCatalogOptionsIid = Guid.Parse("21ABAA76-089D-51C5-A745-C85EEFE70116"); + private static readonly Guid InstallOptionsIid = Guid.Parse("6EE9DB69-AB48-5E72-A474-33A924CD23B3"); + private static readonly Guid UninstallOptionsIid = Guid.Parse("3EBC67F0-8339-594B-8A42-F90B69D02BBE"); + private static readonly Guid PackageMatchFilterIid = Guid.Parse("D981ECA3-4DE5-5AD7-967A-698C7D60FC3B"); private static readonly Type PackageManagerType = Type.GetTypeFromCLSID(PackageManagerClsid); private static readonly Type FindPackagesOptionsType = Type.GetTypeFromCLSID(FindPackagesOptionsClsid); @@ -42,7 +55,7 @@ public class ComObjectFactory /// A instance. public virtual PackageManager CreatePackageManager() { - return Create(PackageManagerType); + return Create(PackageManagerType, PackageManagerIid); } /// @@ -51,7 +64,7 @@ public virtual PackageManager CreatePackageManager() /// A instance. public virtual FindPackagesOptions CreateFindPackagesOptions() { - return Create(FindPackagesOptionsType); + return Create(FindPackagesOptionsType, FindPackagesOptionsIid); } /// @@ -60,7 +73,7 @@ public virtual FindPackagesOptions CreateFindPackagesOptions() /// A instance. public virtual CreateCompositePackageCatalogOptions CreateCreateCompositePackageCatalogOptions() { - return Create(CreateCompositePackageCatalogOptionsType); + return Create(CreateCompositePackageCatalogOptionsType, CreateCompositePackageCatalogOptionsIid); } /// @@ -69,7 +82,7 @@ public virtual CreateCompositePackageCatalogOptions CreateCreateCompositePackage /// An instance. public virtual InstallOptions CreateInstallOptions() { - return Create(InstallOptionsType); + return Create(InstallOptionsType, InstallOptionsIid); } /// @@ -78,7 +91,7 @@ public virtual InstallOptions CreateInstallOptions() /// A instance. public virtual UninstallOptions CreateUninstallOptions() { - return Create(UninstallOptionsType); + return Create(UninstallOptionsType, UninstallOptionsIid); } /// @@ -87,12 +100,19 @@ public virtual UninstallOptions CreateUninstallOptions() /// A instance. public virtual PackageMatchFilter CreatePackageMatchFilter() { - return Create(PackageMatchFilterType); + return Create(PackageMatchFilterType, PackageMatchFilterIid); } - private static T Create(Type type) + private static T Create(Type type, in Guid iid) { - object instance = Activator.CreateInstance(type); + //object instance = Activator.CreateInstance(type); + + object instance = null; + int hr = WinGetServerManualActivation_CreateInstance(type.GUID, iid, 0, out instance); + if (hr != 0) + { + throw new COMException("Failed to create instance.", hr); + } #if NET IntPtr pointer = Marshal.GetIUnknownForObject(instance); return MarshalInterface.FromAbi(pointer); @@ -100,5 +120,12 @@ private static T Create(Type type) return (T)instance; #endif } + + [DllImport("winrtact.dll", EntryPoint = "WinGetServerManualActivation_CreateInstance", ExactSpelling = true, PreserveSig = true)] + private static extern int WinGetServerManualActivation_CreateInstance( + [In, MarshalAs(UnmanagedType.LPStruct)] Guid clsid, + [In, MarshalAs(UnmanagedType.LPStruct)] Guid iid, + uint flags, + [Out, MarshalAs(UnmanagedType.IUnknown)] out object instance); } } diff --git a/src/UndockedRegFreeWinRT/UndockedRegFreeWinRT/UndockedRegFreeWinRT.vcxproj b/src/UndockedRegFreeWinRT/UndockedRegFreeWinRT/UndockedRegFreeWinRT.vcxproj index 4d4311ee27..d9f5513621 100644 --- a/src/UndockedRegFreeWinRT/UndockedRegFreeWinRT/UndockedRegFreeWinRT.vcxproj +++ b/src/UndockedRegFreeWinRT/UndockedRegFreeWinRT/UndockedRegFreeWinRT.vcxproj @@ -109,7 +109,7 @@ Windows true false - comsuppw.lib;shlwapi.lib;xmllite.lib;runtimeobject.lib;Pathcch.lib; + comsuppw.lib;shlwapi.lib;xmllite.lib;runtimeobject.lib;Pathcch.lib;Rometadata.lib;Rpcrt4.lib winrtact.def @@ -128,7 +128,7 @@ Windows true false - comsuppw.lib;shlwapi.lib;xmllite.lib;runtimeobject.lib;Pathcch.lib; + comsuppw.lib;shlwapi.lib;xmllite.lib;runtimeobject.lib;Pathcch.lib;Rometadata.lib;Rpcrt4.lib winrtact.def @@ -151,7 +151,7 @@ true true false - comsuppw.lib;shlwapi.lib;xmllite.lib;runtimeobject.lib;Pathcch.lib; + comsuppw.lib;shlwapi.lib;xmllite.lib;runtimeobject.lib;Pathcch.lib;Rometadata.lib;Rpcrt4.lib winrtact.def @@ -174,7 +174,7 @@ true true false - comsuppw.lib;shlwapi.lib;xmllite.lib;runtimeobject.lib;Pathcch.lib; + comsuppw.lib;shlwapi.lib;xmllite.lib;runtimeobject.lib;Pathcch.lib;Rometadata.lib;Rpcrt4.lib winrtact.def @@ -184,6 +184,8 @@ + + diff --git a/src/UndockedRegFreeWinRT/UndockedRegFreeWinRT/UndockedRegFreeWinRT.vcxproj.filters b/src/UndockedRegFreeWinRT/UndockedRegFreeWinRT/UndockedRegFreeWinRT.vcxproj.filters index 92faa391ba..0d3d646dc2 100644 --- a/src/UndockedRegFreeWinRT/UndockedRegFreeWinRT/UndockedRegFreeWinRT.vcxproj.filters +++ b/src/UndockedRegFreeWinRT/UndockedRegFreeWinRT/UndockedRegFreeWinRT.vcxproj.filters @@ -34,6 +34,13 @@ Source Files + + Source Files + + + Source Files + + diff --git a/src/UndockedRegFreeWinRT/UndockedRegFreeWinRT/catalog.cpp b/src/UndockedRegFreeWinRT/UndockedRegFreeWinRT/catalog.cpp index 448756179f..bad1706081 100644 --- a/src/UndockedRegFreeWinRT/UndockedRegFreeWinRT/catalog.cpp +++ b/src/UndockedRegFreeWinRT/UndockedRegFreeWinRT/catalog.cpp @@ -14,6 +14,7 @@ #include #include #include +#include #include #include "catalog.h" #include "TypeResolution.h" @@ -376,9 +377,7 @@ HRESULT WinRTGetMetadataFile( // will create an instance of the metadata reader to dispense metadata files. if (metaDataDispenser == nullptr) { - RETURN_IF_FAILED(CoCreateInstance(CLSID_CorMetaDataDispenser, - nullptr, - CLSCTX_INPROC, + RETURN_IF_FAILED(MetaDataGetDispenser(CLSID_CorMetaDataDispenser, IID_IMetaDataDispenser, &spMetaDataDispenser)); { diff --git a/src/UndockedRegFreeWinRT/UndockedRegFreeWinRT/winrtact.def b/src/UndockedRegFreeWinRT/UndockedRegFreeWinRT/winrtact.def index 3d1de76376..00dac8c4dc 100644 --- a/src/UndockedRegFreeWinRT/UndockedRegFreeWinRT/winrtact.def +++ b/src/UndockedRegFreeWinRT/UndockedRegFreeWinRT/winrtact.def @@ -1,4 +1,6 @@ LIBRARY winrtact EXPORTS - winrtact_Initialize \ No newline at end of file + winrtact_Initialize + + WinGetServerManualActivation_CreateInstance \ No newline at end of file diff --git a/src/WinGetServer/WinGetServer.idl b/src/WinGetServer/WinGetServer.idl new file mode 100644 index 0000000000000000000000000000000000000000..af9c18399723057de4e94338853749b2aa6d6ef4 GIT binary patch literal 858 zcmbW0UrPc(6vfYT(07oYR5I35QhLe~6{?5+5FsME?$*M#impXPU%mR>G0Ck6iDhT* z%$$49xp#Ko-y+>>qOqn*mD83UnV;ARG}BN6#y~rYG*Zmzfi|__-mV*S%S&fKFs;R1dg+vwRx{Hjt0)NS2YV22u>g0JuWi$)g&L}*vH^oha*94t1uDl

ZTtG=uF8eF0lr>QQS#zN`T<;@vm9m1A^dtha=Iq0iHCG8dV zg7e#Rqj9E=Ed=2c<@8@A>-bBi7j2!ZiQ6lk=o025Iukf=0j?6dlsaFgo6lq}@2l&o z?vdMqrK4japGvL2qi>!6D<@hDZwhBP-P0~QAvy!yqLsbjFP$-8Q_5-1)fLKou5uJv zPw+cb17yf!-^RLZ#%pyxlhtRQ(IeX{{=!*s+6~>{z6oNXJjv+V{Vcr~KL3zceE=kR BemejF literal 0 HcmV?d00001 diff --git a/src/WinGetServer/WinGetServer.vcxproj b/src/WinGetServer/WinGetServer.vcxproj index 7accd8fd12..ddf16724b6 100644 --- a/src/WinGetServer/WinGetServer.vcxproj +++ b/src/WinGetServer/WinGetServer.vcxproj @@ -1,6 +1,5 @@ - true true @@ -107,18 +106,22 @@ Windows false $(OutDir)..\Microsoft.Management.Deployment;$(OutDir)..\AppInstallerCLICore;$(OutDir)..\JsonCppLib;$(OutDir)..\AppInstallerRepositoryCore;$(OutDir)..\YamlCppLib;$(OutDir)..\AppInstallerCommonCore;$(OutDir)..\cpprestsdk;%(AdditionalLibraryDirectories) - %(AdditionalDependencies) + Rpcrt4.lib;Advapi32.lib;Shell32.lib;Ole32.lib;%(AdditionalDependencies) Disabled _DEBUG;%(PreprocessorDefinitions) + stdcpp17 + stdcpp17 + stdcpp17 WIN32;%(PreprocessorDefinitions) + stdcpp17 @@ -127,6 +130,10 @@ true true NDEBUG;%(PreprocessorDefinitions) + stdcpp17 + stdcpp17 + stdcpp17 + stdcpp17 true @@ -139,6 +146,17 @@ + + true + true + true + true + true + true + true + true + + @@ -150,10 +168,109 @@ {2046b5af-666d-4ce8-8d3e-c32c57908a56} + + + false + false + false + false + false + false + false + false + Stub + Stub + Stub + Stub + Stub + Stub + Stub + Stub + Stub + Stub + Stub + Stub + Stub + Stub + Stub + Stub + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + true + true + true + true + true + true + true + + - diff --git a/src/WinGetServer/WinGetServer.vcxproj.filters b/src/WinGetServer/WinGetServer.vcxproj.filters index 1b7135e521..9504000e60 100644 --- a/src/WinGetServer/WinGetServer.vcxproj.filters +++ b/src/WinGetServer/WinGetServer.vcxproj.filters @@ -23,6 +23,12 @@ Source Files + + Source Files + + + Source Files + @@ -36,4 +42,9 @@ Resource Files + + + Source Files + + \ No newline at end of file diff --git a/src/WinGetServer/WinGetServerManualActivation_Client.cpp b/src/WinGetServer/WinGetServerManualActivation_Client.cpp new file mode 100644 index 0000000000..a2e383bf05 --- /dev/null +++ b/src/WinGetServer/WinGetServerManualActivation_Client.cpp @@ -0,0 +1,100 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#include "WinGetServer.h" + +#include +#include + +#include +#include +#include + + +_Must_inspect_result_ +_Ret_maybenull_ _Post_writable_byte_size_(size) +void* __RPC_USER MIDL_user_allocate(_In_ size_t size) +{ + return malloc(size); +} + +void __RPC_USER MIDL_user_free(_Pre_maybenull_ _Post_invalid_ void* ptr) +{ + if (ptr) + { + free(ptr); + } +} + +unsigned char* GetUCharString(const std::string& str) +{ + return reinterpret_cast(const_cast(str.c_str())); +} + +struct FreeWithRpcStringFree { void operator()(RPC_CSTR* in) { RpcStringFreeA(in); } }; +using UniqueRpcString = std::unique_ptr; + +struct DeleteWithMidlFree { void operator()(void* m) { MIDL_user_free(m); } }; +using UniqueMidl = std::unique_ptr; + +void InitializeRpcBinding() +{ + std::string protocol = "ncacn_np"; + std::string endpoint = "\\pipe\\WinGetServerManualActivation_SID"; + + unsigned char* binding = nullptr; + UniqueRpcString bindingPtr; + + RPC_STATUS status = RpcStringBindingComposeA(nullptr, GetUCharString(protocol), nullptr, GetUCharString(endpoint), nullptr, &binding); + THROW_HR_IF(HRESULT_FROM_WIN32(status), status != RPC_S_OK); + bindingPtr.reset(&binding); + + status = RpcBindingFromStringBindingA(binding, &WinGetServerManualActivation_IfHandle); + THROW_HR_IF(HRESULT_FROM_WIN32(status), status != RPC_S_OK); +} + +HRESULT CallCreateInstance(const CLSID* clsid, const IID* iid, UINT32 flags, UINT32* bufferByteCount, BYTE** buffer) +{ + RpcTryExcept + { + RETURN_IF_FAILED(CreateInstance(*clsid, *iid, flags, bufferByteCount, buffer)); + } + RpcExcept(1) + { + return HRESULT_FROM_WIN32(RpcExceptionCode()); + } + RpcEndExcept; + + return S_OK; +} + +extern "C" HRESULT WinGetServerManualActivation_CreateInstance(const CLSID* clsid, const IID* iid, UINT32 flags, void** out) +{ + RETURN_HR_IF_NULL(E_POINTER, clsid); + RETURN_HR_IF_NULL(E_POINTER, iid); + RETURN_HR_IF_NULL(E_POINTER, out); + + static std::once_flag rpcBindingOnce; + try + { + std::call_once(rpcBindingOnce, InitializeRpcBinding); + } + CATCH_RETURN(); + + UINT32 bufferByteCount = 0; + BYTE* buffer = nullptr; + UniqueMidl bufferPtr; + + RETURN_IF_FAILED(CallCreateInstance(clsid, iid, flags, &bufferByteCount, &buffer)); + bufferPtr.reset(buffer); + + wil::com_ptr stream; + RETURN_IF_FAILED(CreateStreamOnHGlobal(nullptr, TRUE, &stream)); + RETURN_IF_FAILED(stream->Write(buffer, bufferByteCount, nullptr)); + RETURN_IF_FAILED(stream->Seek({}, STREAM_SEEK_SET, nullptr)); + + wil::com_ptr output; + RETURN_IF_FAILED(CoUnmarshalInterface(stream.get(), *iid, reinterpret_cast(&output))); + + *out = output.detach(); + return S_OK; +} \ No newline at end of file diff --git a/src/WinGetServer/WinMain.cpp b/src/WinGetServer/WinMain.cpp index 2d5077827d..e9fc34ba0a 100644 --- a/src/WinGetServer/WinMain.cpp +++ b/src/WinGetServer/WinMain.cpp @@ -1,12 +1,20 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. +#define NOMINMAX #pragma warning( push ) -#pragma warning ( disable : 6553) +#pragma warning ( disable : 6001 6553) #include +#include #pragma warning( pop ) -#include #include +#include +#include #include +#include "WinGetServer.h" + +#include +#include +#include // Holds the wwinmain open until COM tells us there are no more server connections wil::unique_event _comServerExitEvent; @@ -18,25 +26,119 @@ static void _releaseNotifier() noexcept _comServerExitEvent.SetEvent(); } -int __stdcall wWinMain(_In_ HINSTANCE, _In_opt_ HINSTANCE, _In_ LPWSTR, _In_ int) +unsigned char* GetUCharString(const char* in) +{ + return reinterpret_cast(const_cast(in)); +} + +HRESULT WindowsPackageManagerServerInitializeRPCServer() +{ + RPC_STATUS status = RpcServerUseProtseqEpA(GetUCharString("ncacn_np"), RPC_C_PROTSEQ_MAX_REQS_DEFAULT, GetUCharString("\\pipe\\WinGetServerManualActivation_SID"), nullptr); + RETURN_HR_IF(HRESULT_FROM_WIN32(status), status != RPC_S_OK); + + wil::unique_hlocal_security_descriptor securityDescriptor; + //// TODO: Verify that this limits clients to administrators + //RETURN_LAST_ERROR_IF(!ConvertStringSecurityDescriptorToSecurityDescriptorA("D:(A;;GA;;;BA)", SDDL_REVISION_1, &securityDescriptor, nullptr)); + + status = RpcServerRegisterIf3(WinGetServerManualActivation_v1_0_s_ifspec, nullptr, nullptr, RPC_IF_ALLOW_LOCAL_ONLY | RPC_IF_AUTOLISTEN, RPC_C_LISTEN_MAX_CALLS_DEFAULT, 0, nullptr, nullptr /*securityDescriptor.get()*/); + RETURN_HR_IF(HRESULT_FROM_WIN32(status), status != RPC_S_OK); + + return S_OK; +} + +_Must_inspect_result_ +_Ret_maybenull_ _Post_writable_byte_size_(size) +void* __RPC_USER MIDL_user_allocate(_In_ size_t size) +{ + return malloc(size); +} + +void __RPC_USER MIDL_user_free(_Pre_maybenull_ _Post_invalid_ void* ptr) +{ + if (ptr) + { + free(ptr); + } +} + +extern "C" HRESULT CreateInstance( + /* [in] */ GUID clsid, + /* [in] */ GUID iid, + /* [in] */ UINT32 flags, + /* [ref][out] */ UINT32 * pcbBuffer, + /* [size_is][size_is][ref][out] */ BYTE * *ppBuffer) +{ + UNREFERENCED_PARAMETER(flags); + + RETURN_HR_IF_NULL(E_POINTER, pcbBuffer); + RETURN_HR_IF_NULL(E_POINTER, ppBuffer); + + wil::com_ptr stream; + RETURN_IF_FAILED(CreateStreamOnHGlobal(nullptr, TRUE, &stream)); + + wil::com_ptr instance; + RETURN_IF_FAILED(WindowsPackageManagerServerCreateInstance(&clsid, &iid, reinterpret_cast(&instance))); + + RETURN_IF_FAILED(CoMarshalInterface(stream.get(), iid, instance.get(), MSHCTX_LOCAL, nullptr, MSHLFLAGS_NORMAL)); + + ULARGE_INTEGER streamSize{}; + RETURN_IF_FAILED(stream->Seek({}, STREAM_SEEK_CUR, &streamSize)); + RETURN_HR_IF(E_NOT_SUFFICIENT_BUFFER, streamSize.QuadPart > std::numeric_limits::max()); + + UINT32 bufferSize = static_cast(streamSize.QuadPart); + + struct DeleteWithMidlFree { void operator()(void* m) { MIDL_user_free(m); } }; + std::unique_ptr buffer{ reinterpret_cast(MIDL_user_allocate(bufferSize)) }; + + RETURN_IF_FAILED(stream->Seek({}, STREAM_SEEK_SET, nullptr)); + ULONG bytesRead = 0; + RETURN_IF_FAILED(stream->Read(buffer.get(), bufferSize, &bytesRead)); + RETURN_HR_IF(E_UNEXPECTED, bytesRead != bufferSize); + + *pcbBuffer = bufferSize; + *ppBuffer = buffer.release(); + + return S_OK; +} + +int __stdcall wWinMain(_In_ HINSTANCE, _In_opt_ HINSTANCE, _In_ LPWSTR cmdLine, _In_ int) { - winrt::init_apartment(); + RETURN_IF_FAILED(CoInitializeEx(nullptr, COINIT_MULTITHREADED)); // Enable fast rundown of objects so that the server exits faster when clients go away. { - winrt::com_ptr globalOptions; - winrt::check_hresult(CoCreateInstance(CLSID_GlobalOptions, nullptr, CLSCTX_INPROC, IID_PPV_ARGS(&globalOptions))); - winrt::check_hresult(globalOptions->Set(COMGLB_RO_SETTINGS, COMGLB_FAST_RUNDOWN)); + wil::com_ptr globalOptions; + RETURN_IF_FAILED(CoCreateInstance(CLSID_GlobalOptions, nullptr, CLSCTX_INPROC, IID_PPV_ARGS(&globalOptions))); + RETURN_IF_FAILED(globalOptions->Set(COMGLB_RO_SETTINGS, COMGLB_FAST_RUNDOWN)); } RETURN_IF_FAILED(WindowsPackageManagerServerInitialize()); + // Command line parsing + int argc = 0; + LPWSTR* argv = CommandLineToArgvW(cmdLine, &argc); + RETURN_LAST_ERROR_IF(!argv); + + bool manualActivation = false; + + // If command line gets more complicated, consider more complex parsing + if (argc == 1 && std::wstring_view{ L"--manualActivation" } == argv[0]) + { + manualActivation = true; + } + _comServerExitEvent.create(); RETURN_IF_FAILED(WindowsPackageManagerServerModuleCreate(&_releaseNotifier)); try { // Register all the CoCreatableClassWrlCreatorMapInclude classes RETURN_IF_FAILED(WindowsPackageManagerServerModuleRegister()); + + if (manualActivation) + { + RETURN_IF_FAILED(WindowsPackageManagerServerInitializeRPCServer()); + } + _comServerExitEvent.wait(); RETURN_IF_FAILED(WindowsPackageManagerServerModuleUnregister()); } diff --git a/src/WinGetServer/packages.config b/src/WinGetServer/packages.config index 5e899619db..0d7cdb0046 100644 --- a/src/WinGetServer/packages.config +++ b/src/WinGetServer/packages.config @@ -1,5 +1,4 @@  - \ No newline at end of file diff --git a/src/WindowsPackageManager/Source.def b/src/WindowsPackageManager/Source.def index 669121749c..d4dba28316 100644 --- a/src/WindowsPackageManager/Source.def +++ b/src/WindowsPackageManager/Source.def @@ -5,6 +5,7 @@ EXPORTS WindowsPackageManagerServerModuleCreate WindowsPackageManagerServerModuleRegister WindowsPackageManagerServerModuleUnregister + WindowsPackageManagerServerCreateInstance WindowsPackageManagerInProcModuleInitialize WindowsPackageManagerInProcModuleTerminate WindowsPackageManagerInProcModuleGetClassObject diff --git a/src/WindowsPackageManager/WindowsPackageManager.h b/src/WindowsPackageManager/WindowsPackageManager.h index d3198c2870..5961c56d44 100644 --- a/src/WindowsPackageManager/WindowsPackageManager.h +++ b/src/WindowsPackageManager/WindowsPackageManager.h @@ -25,6 +25,9 @@ extern "C" // Unregisters the server module class factories. WINDOWS_PACKAGE_MANAGER_API WindowsPackageManagerServerModuleUnregister(); + // Creates an out-of-proc instance for manual activation scenarios. + WINDOWS_PACKAGE_MANAGER_API WindowsPackageManagerServerCreateInstance(const CLSID* clsid, const IID* iid, void** out); + // Creates module for in-proc COM invocation. WINDOWS_PACKAGE_MANAGER_API WindowsPackageManagerInProcModuleInitialize(); diff --git a/src/WindowsPackageManager/main.cpp b/src/WindowsPackageManager/main.cpp index f575e4769b..dfc7ecc221 100644 --- a/src/WindowsPackageManager/main.cpp +++ b/src/WindowsPackageManager/main.cpp @@ -58,6 +58,17 @@ extern "C" } CATCH_RETURN(); + WINDOWS_PACKAGE_MANAGER_API WindowsPackageManagerServerCreateInstance(const CLSID* clsid, const IID* iid, void** out) try + { + RETURN_HR_IF_NULL(E_POINTER, clsid); + RETURN_HR_IF_NULL(E_POINTER, iid); + RETURN_HR_IF_NULL(E_POINTER, out); + ::Microsoft::WRL::ComPtr factory; + RETURN_IF_FAILED(::Microsoft::WRL::Module<::Microsoft::WRL::ModuleType::OutOfProc>::GetModule().GetClassObject(*clsid, IID_PPV_ARGS(&factory))); + RETURN_HR(factory->CreateInstance(nullptr, *iid, out)); + } + CATCH_RETURN(); + WINDOWS_PACKAGE_MANAGER_API WindowsPackageManagerInProcModuleInitialize() try { ::Microsoft::WRL::Module<::Microsoft::WRL::ModuleType::InProc>::Create(); From ccaa1dc5961d1c64cb219453168508d044f740ad Mon Sep 17 00:00:00 2001 From: Ryan Fu Date: Thu, 20 Oct 2022 18:19:27 -0700 Subject: [PATCH 02/49] save work --- .../PowerShell/PowerShellModule.cs | 28 +++++++++++++++++++ .../Package.appxmanifest | 2 +- .../Common/BaseClientCommand.cs | 11 ++++++-- .../Common/Utilities.cs | 20 ++++++++++--- .../Helpers/ComObjectFactory.cs | 4 ++- .../Properties/Resources.Designer.cs | 6 ++-- .../Properties/Resources.resx | 4 +-- .../WinGetServerManualActivation_Client.cpp | 6 +++- 8 files changed, 67 insertions(+), 14 deletions(-) create mode 100644 src/AppInstallerCLIE2ETests/PowerShell/PowerShellModule.cs diff --git a/src/AppInstallerCLIE2ETests/PowerShell/PowerShellModule.cs b/src/AppInstallerCLIE2ETests/PowerShell/PowerShellModule.cs new file mode 100644 index 0000000000..315fba530e --- /dev/null +++ b/src/AppInstallerCLIE2ETests/PowerShell/PowerShellModule.cs @@ -0,0 +1,28 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +namespace AppInstallerCLIE2ETests +{ + using NUnit.Framework; + using System.IO; + + public class PowerShellModule + { + // TODO: change this to either be an input or dynamically generated path. + private const string moduleManifestPath = @"C:\Users\ryfu\git\ryfu-msft\winget-cli\src\x64\Debug\PowerShell\Microsoft.WinGet.Client.psd1"; + + [SetUp] + public void Setup() + { + } + + // Repeat e2e tests for all commandlets for a basic sanity check. + + [Test] + public void FindWinGetPackage() + { + var result = TestCommon.RunCommandWithResult("pwsh", $"-Command ipmo {moduleManifestPath}; Find-WinGetPackage -Id Microsoft.WingetCreate"); + Assert.IsTrue(result.ExitCode == 0, "Powershell commandlet should succeed in admin mode."); + } + } +} \ No newline at end of file diff --git a/src/AppInstallerCLIPackage/Package.appxmanifest b/src/AppInstallerCLIPackage/Package.appxmanifest index c103032ae8..21d379cee1 100644 --- a/src/AppInstallerCLIPackage/Package.appxmanifest +++ b/src/AppInstallerCLIPackage/Package.appxmanifest @@ -8,7 +8,7 @@ xmlns:com="http://schemas.microsoft.com/appx/manifest/com/windows10" xmlns:desktop6="http://schemas.microsoft.com/appx/manifest/desktop/windows10/6" IgnorableNamespaces="uap uap3 uap5 rescap"> - + WinGet Dev CLI Microsoft Corporation diff --git a/src/PowerShell/Microsoft.WinGet.Client/Common/BaseClientCommand.cs b/src/PowerShell/Microsoft.WinGet.Client/Common/BaseClientCommand.cs index bd96949dc6..1371a5347f 100644 --- a/src/PowerShell/Microsoft.WinGet.Client/Common/BaseClientCommand.cs +++ b/src/PowerShell/Microsoft.WinGet.Client/Common/BaseClientCommand.cs @@ -8,6 +8,7 @@ namespace Microsoft.WinGet.Client.Common { using System; using System.Collections.Generic; + using System.Diagnostics; using System.Management.Automation; using System.Runtime.InteropServices; using Microsoft.Management.Deployment; @@ -29,10 +30,16 @@ static BaseClientCommand() public BaseClientCommand() : base() { - // this error should be removed if it is running as admin and call the correct activation path. + if (Utilities.ExecutingAsSystem) + { + throw new Exception(Utilities.ResourceManager.GetString("ExceptionSystemDisabled")); + } + if (Utilities.ExecutingAsAdministrator) { - throw new Exception(Utilities.ResourceManager.GetString("ExceptionAdministratorDisabled")); + // Start COM server when running in admin mode. + Process.Start("WindowsPackageManagerServerDev.exe"); + System.Threading.Thread.Sleep(1000); // wait for com server to activate after running it. } } diff --git a/src/PowerShell/Microsoft.WinGet.Client/Common/Utilities.cs b/src/PowerShell/Microsoft.WinGet.Client/Common/Utilities.cs index 3e43dfd0bd..ee24abe44c 100644 --- a/src/PowerShell/Microsoft.WinGet.Client/Common/Utilities.cs +++ b/src/PowerShell/Microsoft.WinGet.Client/Common/Utilities.cs @@ -32,10 +32,22 @@ public static bool ExecutingAsAdministrator { get { - //WindowsIdentity identity = WindowsIdentity.GetCurrent(); - //WindowsPrincipal principal = new (identity); - //return principal.IsInRole(WindowsBuiltInRole.Administrator); - return false; + WindowsIdentity identity = WindowsIdentity.GetCurrent(); + WindowsPrincipal principal = new (identity); + return principal.IsInRole(WindowsBuiltInRole.Administrator); + } + } + + ///

+ /// Gets a value indicating whether the current assembly is executing as a SYSTEM user. + /// + public static bool ExecutingAsSystem + { + get + { + WindowsIdentity identity = WindowsIdentity.GetCurrent(); + WindowsPrincipal principal = new (identity); + return principal.IsInRole(WindowsBuiltInRole.SystemOperator); } } } diff --git a/src/PowerShell/Microsoft.WinGet.Client/Helpers/ComObjectFactory.cs b/src/PowerShell/Microsoft.WinGet.Client/Helpers/ComObjectFactory.cs index 668d2e9cfc..46bd165abd 100644 --- a/src/PowerShell/Microsoft.WinGet.Client/Helpers/ComObjectFactory.cs +++ b/src/PowerShell/Microsoft.WinGet.Client/Helpers/ComObjectFactory.cs @@ -6,7 +6,8 @@ namespace Microsoft.WinGet.Client.Factories { - using System; + using System; + using System.Diagnostics; using System.Runtime.InteropServices; using Microsoft.Management.Deployment; @@ -108,6 +109,7 @@ private static T Create(Type type, in Guid iid) //object instance = Activator.CreateInstance(type); object instance = null; + int hr = WinGetServerManualActivation_CreateInstance(type.GUID, iid, 0, out instance); if (hr != 0) { diff --git a/src/PowerShell/Microsoft.WinGet.Client/Properties/Resources.Designer.cs b/src/PowerShell/Microsoft.WinGet.Client/Properties/Resources.Designer.cs index 94a6f6c577..5f4c91661c 100644 --- a/src/PowerShell/Microsoft.WinGet.Client/Properties/Resources.Designer.cs +++ b/src/PowerShell/Microsoft.WinGet.Client/Properties/Resources.Designer.cs @@ -70,11 +70,11 @@ internal static string ArgumentExceptionInvalidSource { } /// - /// Looks up a localized string similar to This cmdlet is currently disabled in an administrative context.. + /// Looks up a localized string similar to This cmdlet is currently disabled for SYSTEM users.. /// - internal static string ExceptionAdministratorDisabled { + internal static string ExceptionSystemDisabled { get { - return ResourceManager.GetString("ExceptionAdministratorDisabled", resourceCulture); + return ResourceManager.GetString("ExceptionSystemDisabled", resourceCulture); } } diff --git a/src/PowerShell/Microsoft.WinGet.Client/Properties/Resources.resx b/src/PowerShell/Microsoft.WinGet.Client/Properties/Resources.resx index 711ba74d6f..93d19b5543 100644 --- a/src/PowerShell/Microsoft.WinGet.Client/Properties/Resources.resx +++ b/src/PowerShell/Microsoft.WinGet.Client/Properties/Resources.resx @@ -121,8 +121,8 @@ No source matches the given value: {0} {0} - The name of the source that was not found. - - This cmdlet is currently disabled in an administrative context. + + This cmdlet is currently disabled for SYSTEM users. An error occurred while searching for packages: {0} diff --git a/src/WinGetServer/WinGetServerManualActivation_Client.cpp b/src/WinGetServer/WinGetServerManualActivation_Client.cpp index a2e383bf05..1d3a4e26f7 100644 --- a/src/WinGetServer/WinGetServerManualActivation_Client.cpp +++ b/src/WinGetServer/WinGetServerManualActivation_Client.cpp @@ -73,17 +73,21 @@ extern "C" HRESULT WinGetServerManualActivation_CreateInstance(const CLSID* clsi RETURN_HR_IF_NULL(E_POINTER, iid); RETURN_HR_IF_NULL(E_POINTER, out); + STARTUPINFO info = { sizeof(info) }; + PROCESS_INFORMATION processInfo; + static std::once_flag rpcBindingOnce; try { std::call_once(rpcBindingOnce, InitializeRpcBinding); } CATCH_RETURN(); - + UINT32 bufferByteCount = 0; BYTE* buffer = nullptr; UniqueMidl bufferPtr; + // Relaunch server if this fails RETURN_IF_FAILED(CallCreateInstance(clsid, iid, flags, &bufferByteCount, &buffer)); bufferPtr.reset(buffer); From e3dda9629475e452b729d8dc68a1248c57efa760 Mon Sep 17 00:00:00 2001 From: Ryan Fu Date: Fri, 21 Oct 2022 17:15:48 -0700 Subject: [PATCH 03/49] save work --- .../Package.appxmanifest | 2 +- .../Common/BaseClientCommand.cs | 7 +-- .../Microsoft.WinGet.Client.csproj | 3 +- .../WinGetServerManualActivation_Client.cpp | 45 ++++++++++++++++++- 4 files changed, 48 insertions(+), 9 deletions(-) diff --git a/src/AppInstallerCLIPackage/Package.appxmanifest b/src/AppInstallerCLIPackage/Package.appxmanifest index 21d379cee1..3a146aa3e8 100644 --- a/src/AppInstallerCLIPackage/Package.appxmanifest +++ b/src/AppInstallerCLIPackage/Package.appxmanifest @@ -8,7 +8,7 @@ xmlns:com="http://schemas.microsoft.com/appx/manifest/com/windows10" xmlns:desktop6="http://schemas.microsoft.com/appx/manifest/desktop/windows10/6" IgnorableNamespaces="uap uap3 uap5 rescap"> - + WinGet Dev CLI Microsoft Corporation diff --git a/src/PowerShell/Microsoft.WinGet.Client/Common/BaseClientCommand.cs b/src/PowerShell/Microsoft.WinGet.Client/Common/BaseClientCommand.cs index 1371a5347f..5dc4eb3107 100644 --- a/src/PowerShell/Microsoft.WinGet.Client/Common/BaseClientCommand.cs +++ b/src/PowerShell/Microsoft.WinGet.Client/Common/BaseClientCommand.cs @@ -35,12 +35,7 @@ public BaseClientCommand() throw new Exception(Utilities.ResourceManager.GetString("ExceptionSystemDisabled")); } - if (Utilities.ExecutingAsAdministrator) - { - // Start COM server when running in admin mode. - Process.Start("WindowsPackageManagerServerDev.exe"); - System.Threading.Thread.Sleep(1000); // wait for com server to activate after running it. - } + // } /// diff --git a/src/PowerShell/Microsoft.WinGet.Client/Microsoft.WinGet.Client.csproj b/src/PowerShell/Microsoft.WinGet.Client/Microsoft.WinGet.Client.csproj index 9e5d04ad19..efae4a3433 100644 --- a/src/PowerShell/Microsoft.WinGet.Client/Microsoft.WinGet.Client.csproj +++ b/src/PowerShell/Microsoft.WinGet.Client/Microsoft.WinGet.Client.csproj @@ -14,6 +14,7 @@ $(BuildOutputDirectory)PowerShell x64;x86 $(CoreFramework);$(DesktopFramework) + OnBuildSuccess @@ -73,7 +74,7 @@ - + diff --git a/src/WinGetServer/WinGetServerManualActivation_Client.cpp b/src/WinGetServer/WinGetServerManualActivation_Client.cpp index 1d3a4e26f7..e68fbb7fa3 100644 --- a/src/WinGetServer/WinGetServerManualActivation_Client.cpp +++ b/src/WinGetServer/WinGetServerManualActivation_Client.cpp @@ -73,16 +73,59 @@ extern "C" HRESULT WinGetServerManualActivation_CreateInstance(const CLSID* clsi RETURN_HR_IF_NULL(E_POINTER, iid); RETURN_HR_IF_NULL(E_POINTER, out); + + //If binding or activation fails, start RPC server, wait and try again. STARTUPINFO info = { sizeof(info) }; PROCESS_INFORMATION processInfo; + //LPCWSTR serverExePath = TEXT("%LOCALAPPDATA%\\Microsoft\\WindowsApps\\WinGetDevCLI_8wekyb3d8bbwe\\WindowsPackageManagerServerDev.exe"); + +#if PROD + std::wstring serverExePath = L"C:\\Users\\ryfu\\AppData\\Local\\Microsoft\\WindowsApps\\WinGetCLI_8wekyb3d8bbwe\\WindowsPackageManagerServer.exe --manualActivation"; +#else + std::wstring serverExePath = L"C:\\Users\\ryfu\\AppData\\Local\\Microsoft\\WindowsApps\\WinGetDevCLI_8wekyb3d8bbwe\\WindowsPackageManagerServerDev.exe"; +#endif + + // If running in admin mode, include '--manualActivation' + // TODO:: Check token membership here. + if (true) + { + serverExePath = serverExePath + L" --manualActivation"; + } + + if (!CreateProcessW( + NULL, // No module name (use command line) + &serverExePath[0], // Command line + NULL, // Process handle not inheritable + NULL, // Thread handle not inheritable + FALSE, // Set handle inheritance to FALSE + CREATE_NEW_CONSOLE, // No creation flags + NULL, // Use parent's environment block + NULL, // Use parent's starting directory + &info, // Pointer to STARTUPINFO structure + &processInfo) // Pointer to PROCESS_INFORMATION structure + ) + { + printf("hello"); + printf("CreateProcess failed (%d).\n", GetLastError()); + } + else + { + printf("Successfully started process"); + CloseHandle(processInfo.hProcess); + CloseHandle(processInfo.hThread); + } + + // Sleep to wait for server to start. + Sleep(1000); + static std::once_flag rpcBindingOnce; try { std::call_once(rpcBindingOnce, InitializeRpcBinding); } CATCH_RETURN(); - + UINT32 bufferByteCount = 0; BYTE* buffer = nullptr; UniqueMidl bufferPtr; From 4d732c25ad896e0bd00d8e3a83aed6942c603ea7 Mon Sep 17 00:00:00 2001 From: Ryan Fu Date: Wed, 26 Oct 2022 13:08:04 -0700 Subject: [PATCH 04/49] add E2E tests for powershell module --- src/AppInstallerCLIE2ETests/Constants.cs | 9 + .../PowerShell/PowerShellModule.cs | 79 +++- src/AppInstallerCLIE2ETests/README.md | 5 +- src/AppInstallerCLIE2ETests/SetUpFixture.cs | 5 + src/AppInstallerCLIE2ETests/Test.runsettings | 2 + src/AppInstallerCLIE2ETests/TestCommon.cs | 7 + .../Commands/GetSourceCommand.cs | 1 - .../Common/BaseClientCommand.cs | 3 - .../Helpers/ComObjectFactory.cs | 71 +-- .../UndockedRegFreeWinRT.vcxproj | 426 +++++++++--------- .../UndockedRegFreeWinRT.vcxproj.filters | 71 +-- src/WinGetServer/WinGetServer.vcxproj | 4 +- .../WinGetServerManualActivation_Client.cpp | 97 ++-- src/WinGetServer/WinMain.cpp | 27 +- templates/e2e-test.template.yml | 6 +- 15 files changed, 453 insertions(+), 360 deletions(-) diff --git a/src/AppInstallerCLIE2ETests/Constants.cs b/src/AppInstallerCLIE2ETests/Constants.cs index bcd821863c..9ac4f1e03c 100644 --- a/src/AppInstallerCLIE2ETests/Constants.cs +++ b/src/AppInstallerCLIE2ETests/Constants.cs @@ -17,6 +17,7 @@ public class Constants public const string MsiInstallerPathParameter = "MsiTestInstallerPath"; public const string MsixInstallerPathParameter = "MsixTestInstallerPath"; public const string PackageCertificatePathParameter = "PackageCertificatePath"; + public const string PowerShellModulePathParameter = "PowerShellModulePath"; public const string AppInstallerTestCert = "AppInstallerTest.cer"; public const string AppInstallerTestCertThumbprint = "d03e7a688b388b1edde8476a627531c49db88017"; @@ -74,6 +75,14 @@ public class Constants public const string TestExeUninstallerFileName = "UninstallTestExe.bat"; public const string TestExeUninstalledFileName = "TestExeUninstalled.txt"; + // PowerShell Cmdlets + public const string FindCmdlet = "Find-WinGetPackage"; + public const string GetCmdlet = "Get-WinGetPackage"; + public const string GetSourceCmdlet = "Get-WinGetSource"; + public const string InstallCmdlet = "Install-WinGetPackage"; + public const string UninstallCmdlet = "Uninstall-WinGetPackage"; + public const string UpdateCmdlet = "Update-WinGetPackage"; + // Locations public const string LocalAppData = "LocalAppData"; diff --git a/src/AppInstallerCLIE2ETests/PowerShell/PowerShellModule.cs b/src/AppInstallerCLIE2ETests/PowerShell/PowerShellModule.cs index 315fba530e..d18aada980 100644 --- a/src/AppInstallerCLIE2ETests/PowerShell/PowerShellModule.cs +++ b/src/AppInstallerCLIE2ETests/PowerShell/PowerShellModule.cs @@ -4,25 +4,88 @@ namespace AppInstallerCLIE2ETests { using NUnit.Framework; - using System.IO; + /// + /// Basic E2E tests for verifying that behavior of the PowerShell module cmdlets. + /// public class PowerShellModule { - // TODO: change this to either be an input or dynamically generated path. - private const string moduleManifestPath = @"C:\Users\ryfu\git\ryfu-msft\winget-cli\src\x64\Debug\PowerShell\Microsoft.WinGet.Client.psd1"; - - [SetUp] + [OneTimeSetUp] public void Setup() { + // Add-WinGetPackage is a function and not a cmdlet that uses COM. Add source to WinGetDev directly to ensure test source exists. + TestCommon.RunAICLICommand("source add", $"-n {Constants.TestSourceName} {Constants.TestSourceUrl}"); + } + + [OneTimeTearDown] + public void TearDown() + { + // Remove-WinGetPackage is a function and not a cmdlet that uses COM. Remove source from WinGetDev directory to ensure clean state. + TestCommon.RunAICLICommand("source remove", $"-n {Constants.TestSourceName}"); } - // Repeat e2e tests for all commandlets for a basic sanity check. + [Test] + public void GetWinGetSource() + { + var getSourceResult = TestCommon.RunPowerShellCommandWithResult(Constants.GetSourceCmdlet, $"-Name {Constants.TestSourceName}"); + Assert.IsTrue(getSourceResult.ExitCode == 0); + Assert.IsTrue(getSourceResult.StdOut.Contains($"{Constants.TestSourceName}")); + } [Test] public void FindWinGetPackage() { - var result = TestCommon.RunCommandWithResult("pwsh", $"-Command ipmo {moduleManifestPath}; Find-WinGetPackage -Id Microsoft.WingetCreate"); - Assert.IsTrue(result.ExitCode == 0, "Powershell commandlet should succeed in admin mode."); + var result = TestCommon.RunPowerShellCommandWithResult(Constants.FindCmdlet, $"-Id {Constants.ExeInstallerPackageId}"); + Assert.IsTrue(result.ExitCode == 0); + Assert.IsTrue(result.StdOut.Contains("TestExeInstaller")); + } + + [Test] + public void GetWinGetPackage() + { + var installResult = TestCommon.RunPowerShellCommandWithResult(Constants.InstallCmdlet, $"-Id {Constants.MsiInstallerPackageId}"); + var getResult = TestCommon.RunPowerShellCommandWithResult(Constants.GetCmdlet, $"-Id {Constants.MsiInstallerPackageId}"); + var uninstallResult = TestCommon.RunPowerShellCommandWithResult(Constants.UninstallCmdlet, $"-Id {Constants.MsiInstallerPackageId}"); + + Assert.IsTrue(installResult.ExitCode == 0); + Assert.IsTrue(getResult.ExitCode == 0); + Assert.IsTrue(uninstallResult.ExitCode == 0); + + Assert.IsTrue(!string.IsNullOrEmpty(installResult.StdOut)); + Assert.IsTrue(getResult.StdOut.Contains("TestMsiInstaller")); + Assert.IsTrue(!string.IsNullOrEmpty(uninstallResult.StdOut)); + } + + [Test] + public void InstallWinGetPackage() + { + var installResult = TestCommon.RunPowerShellCommandWithResult(Constants.InstallCmdlet, $"-Id {Constants.ExeInstallerPackageId}"); + var uninstallResult = TestCommon.RunPowerShellCommandWithResult(Constants.UninstallCmdlet, $"-Id {Constants.ExeInstallerPackageId}"); + + Assert.IsTrue(installResult.ExitCode == 0); + Assert.IsTrue(uninstallResult.ExitCode == 0); + + Assert.IsTrue(!string.IsNullOrEmpty(installResult.StdOut)); + Assert.IsTrue(!string.IsNullOrEmpty(uninstallResult.StdOut)); + } + + [Test] + public void UpdateWinGetPackage() + { + var installResult = TestCommon.RunPowerShellCommandWithResult(Constants.InstallCmdlet, $"-Id {Constants.ExeInstallerPackageId} -Version 1.0.0.0"); + var updateResult = TestCommon.RunPowerShellCommandWithResult(Constants.UpdateCmdlet, $"-Id {Constants.ExeInstallerPackageId}"); + var getResult = TestCommon.RunPowerShellCommandWithResult(Constants.GetCmdlet, $"-Id {Constants.ExeInstallerPackageId}"); + var uninstallResult = TestCommon.RunPowerShellCommandWithResult(Constants.UninstallCmdlet, $"-Id {Constants.ExeInstallerPackageId}"); + + Assert.IsTrue(installResult.ExitCode == 0); + Assert.IsTrue(updateResult.ExitCode == 0); + Assert.IsTrue(getResult.ExitCode == 0); + Assert.IsTrue(uninstallResult.ExitCode == 0); + + Assert.IsTrue(!string.IsNullOrEmpty(installResult.StdOut)); + Assert.IsTrue(!string.IsNullOrEmpty(updateResult.StdOut)); + Assert.IsTrue(getResult.StdOut.Contains("2.0.0.0")); + Assert.IsTrue(!string.IsNullOrEmpty(uninstallResult.StdOut)); } } } \ No newline at end of file diff --git a/src/AppInstallerCLIE2ETests/README.md b/src/AppInstallerCLIE2ETests/README.md index 6b07a0a552..a6417e5918 100644 --- a/src/AppInstallerCLIE2ETests/README.md +++ b/src/AppInstallerCLIE2ETests/README.md @@ -56,7 +56,8 @@ Therefore to run the executable in the command line, simply change into the dire | StaticFileRootPath | Path to the set of static test files that will be served as the source for testing purposes. This path should be identical to the one provided to the LocalHostWebServer| | MsixTestInstallerPath | The MSIX (or APPX) Installer executable under test. | | ExeTestInstallerPath |The Exe Installer executable under test. | -| PackageCertificatePath |Signing Certificate Path used to certify test index source package| +| PackageCertificatePath | Signing Certificate Path used to certify test index source package | +| PowerShellModulePath | Path to the PowerShell module manifest file under test | #### Example of Test.runsettings format: @@ -72,6 +73,7 @@ Therefore to run the executable in the command line, simply change into the dire + @@ -90,6 +92,7 @@ Make sure to replace **MSFT** with your own user name. Modifying this example wi + diff --git a/src/AppInstallerCLIE2ETests/SetUpFixture.cs b/src/AppInstallerCLIE2ETests/SetUpFixture.cs index 490924e250..583ab838f4 100644 --- a/src/AppInstallerCLIE2ETests/SetUpFixture.cs +++ b/src/AppInstallerCLIE2ETests/SetUpFixture.cs @@ -96,6 +96,11 @@ public void Setup() TestCommon.PackageCertificatePath = TestContext.Parameters.Get(Constants.PackageCertificatePathParameter); } + if (TestContext.Parameters.Exists(Constants.PowerShellModulePathParameter)) + { + TestCommon.PowerShellModulePath = TestContext.Parameters.Get(Constants.PowerShellModulePathParameter); + } + ReadTestInstallerPaths(); TestIndexSetup.GenerateTestDirectory(); diff --git a/src/AppInstallerCLIE2ETests/Test.runsettings b/src/AppInstallerCLIE2ETests/Test.runsettings index d28a7443e7..3109faab93 100644 --- a/src/AppInstallerCLIE2ETests/Test.runsettings +++ b/src/AppInstallerCLIE2ETests/Test.runsettings @@ -19,6 +19,7 @@ MsixTestInstallerPath: The MSIX (or APPX) Installer executable under test. ExeTestInstallerPath: The Exe Installer executable under test. PackageCertificatePath: Signing Certificate Path used to certify Index Source Package + PowerShellModulePath: Path to the PowerShell module manifest file under test --> @@ -32,5 +33,6 @@ + \ No newline at end of file diff --git a/src/AppInstallerCLIE2ETests/TestCommon.cs b/src/AppInstallerCLIE2ETests/TestCommon.cs index f40c1e6d19..3ed097643e 100644 --- a/src/AppInstallerCLIE2ETests/TestCommon.cs +++ b/src/AppInstallerCLIE2ETests/TestCommon.cs @@ -36,6 +36,8 @@ public class TestCommon public static string PackageCertificatePath { get; set; } + public static string PowerShellModulePath { get; set; } + public static string SettingsJsonFilePath { get { @@ -252,6 +254,11 @@ public static RunCommandResult RunCommandWithResult(string fileName, string args return result; } + public static RunCommandResult RunPowerShellCommandWithResult(string cmdlet, string args, int timeOut = 60000) + { + return RunCommandWithResult("pwsh", $"-Command ipmo {PowerShellModulePath}; {cmdlet} {args}", timeOut); + } + public static string GetTestFile(string fileName) { return Path.Combine(TestContext.CurrentContext.TestDirectory, fileName); diff --git a/src/PowerShell/Microsoft.WinGet.Client/Commands/GetSourceCommand.cs b/src/PowerShell/Microsoft.WinGet.Client/Commands/GetSourceCommand.cs index 1daaeca661..42a0effbdb 100644 --- a/src/PowerShell/Microsoft.WinGet.Client/Commands/GetSourceCommand.cs +++ b/src/PowerShell/Microsoft.WinGet.Client/Commands/GetSourceCommand.cs @@ -6,7 +6,6 @@ namespace Microsoft.WinGet.Client.Commands { - using System; using System.Management.Automation; using Microsoft.Management.Deployment; using Microsoft.WinGet.Client.Common; diff --git a/src/PowerShell/Microsoft.WinGet.Client/Common/BaseClientCommand.cs b/src/PowerShell/Microsoft.WinGet.Client/Common/BaseClientCommand.cs index 5dc4eb3107..1113163c81 100644 --- a/src/PowerShell/Microsoft.WinGet.Client/Common/BaseClientCommand.cs +++ b/src/PowerShell/Microsoft.WinGet.Client/Common/BaseClientCommand.cs @@ -8,7 +8,6 @@ namespace Microsoft.WinGet.Client.Common { using System; using System.Collections.Generic; - using System.Diagnostics; using System.Management.Automation; using System.Runtime.InteropServices; using Microsoft.Management.Deployment; @@ -34,8 +33,6 @@ public BaseClientCommand() { throw new Exception(Utilities.ResourceManager.GetString("ExceptionSystemDisabled")); } - - // } /// diff --git a/src/PowerShell/Microsoft.WinGet.Client/Helpers/ComObjectFactory.cs b/src/PowerShell/Microsoft.WinGet.Client/Helpers/ComObjectFactory.cs index 46bd165abd..778b8478dd 100644 --- a/src/PowerShell/Microsoft.WinGet.Client/Helpers/ComObjectFactory.cs +++ b/src/PowerShell/Microsoft.WinGet.Client/Helpers/ComObjectFactory.cs @@ -7,10 +7,11 @@ namespace Microsoft.WinGet.Client.Factories { using System; - using System.Diagnostics; - using System.Runtime.InteropServices; - using Microsoft.Management.Deployment; - + using System.Runtime.InteropServices; + using System.Threading; + using Microsoft.Management.Deployment; + using Microsoft.WinGet.Client.Common; + #if NET using WinRT; #endif @@ -20,35 +21,35 @@ namespace Microsoft.WinGet.Client.Factories /// public class ComObjectFactory { - // TODO: Change to default to TEST CLSIDS based on USE_PROD_CLSIDS -#if !USE_TEST_CLSIDS - private static readonly Guid PackageManagerClsid = Guid.Parse("74CB3139-B7C5-4B9E-9388-E6616DEA288C"); - private static readonly Guid FindPackagesOptionsClsid = Guid.Parse("1BD8FF3A-EC50-4F69-AEEE-DF4C9D3BAA96"); - private static readonly Guid CreateCompositePackageCatalogOptionsClsid = Guid.Parse("EE160901-B317-4EA7-9CC6-5355C6D7D8A7"); - private static readonly Guid InstallOptionsClsid = Guid.Parse("44FE0580-62F7-44D4-9E91-AA9614AB3E86"); - private static readonly Guid UninstallOptionsClsid = Guid.Parse("AA2A5C04-1AD9-46C4-B74F-6B334AD7EB8C"); - private static readonly Guid PackageMatchFilterClsid = Guid.Parse("3F85B9F4-487A-4C48-9035-2903F8A6D9E8"); -#else +#if USE_PROD_CLSIDS 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"); +#else + private static readonly Guid PackageManagerClsid = Guid.Parse("74CB3139-B7C5-4B9E-9388-E6616DEA288C"); + private static readonly Guid FindPackagesOptionsClsid = Guid.Parse("1BD8FF3A-EC50-4F69-AEEE-DF4C9D3BAA96"); + private static readonly Guid CreateCompositePackageCatalogOptionsClsid = Guid.Parse("EE160901-B317-4EA7-9CC6-5355C6D7D8A7"); + private static readonly Guid InstallOptionsClsid = Guid.Parse("44FE0580-62F7-44D4-9E91-AA9614AB3E86"); + private static readonly Guid UninstallOptionsClsid = Guid.Parse("AA2A5C04-1AD9-46C4-B74F-6B334AD7EB8C"); + private static readonly Guid PackageMatchFilterClsid = Guid.Parse("3F85B9F4-487A-4C48-9035-2903F8A6D9E8"); #endif - private static readonly Guid PackageManagerIid = Guid.Parse("B375E3B9-F2E0-5C93-87A7-B67497F7E593"); - private static readonly Guid FindPackagesOptionsIid = Guid.Parse("A5270EDD-7DA7-57A3-BACE-F2593553561F"); - private static readonly Guid CreateCompositePackageCatalogOptionsIid = Guid.Parse("21ABAA76-089D-51C5-A745-C85EEFE70116"); - private static readonly Guid InstallOptionsIid = Guid.Parse("6EE9DB69-AB48-5E72-A474-33A924CD23B3"); - private static readonly Guid UninstallOptionsIid = Guid.Parse("3EBC67F0-8339-594B-8A42-F90B69D02BBE"); - private static readonly Guid PackageMatchFilterIid = Guid.Parse("D981ECA3-4DE5-5AD7-967A-698C7D60FC3B"); 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); + private static readonly Type PackageMatchFilterType = Type.GetTypeFromCLSID(PackageMatchFilterClsid); + + private static readonly Guid PackageManagerIid = Guid.Parse("B375E3B9-F2E0-5C93-87A7-B67497F7E593"); + private static readonly Guid FindPackagesOptionsIid = Guid.Parse("A5270EDD-7DA7-57A3-BACE-F2593553561F"); + private static readonly Guid CreateCompositePackageCatalogOptionsIid = Guid.Parse("21ABAA76-089D-51C5-A745-C85EEFE70116"); + private static readonly Guid InstallOptionsIid = Guid.Parse("6EE9DB69-AB48-5E72-A474-33A924CD23B3"); + private static readonly Guid UninstallOptionsIid = Guid.Parse("3EBC67F0-8339-594B-8A42-F90B69D02BBE"); + private static readonly Guid PackageMatchFilterIid = Guid.Parse("D981ECA3-4DE5-5AD7-967A-698C7D60FC3B"); /// /// Creates an instance of the class. @@ -106,15 +107,31 @@ public virtual PackageMatchFilter CreatePackageMatchFilter() private static T Create(Type type, in Guid iid) { - //object instance = Activator.CreateInstance(type); + object instance; - object instance = null; - - int hr = WinGetServerManualActivation_CreateInstance(type.GUID, iid, 0, out instance); - if (hr != 0) - { - throw new COMException("Failed to create instance.", hr); + if (Utilities.ExecutingAsAdministrator) + { + instance = null; + + int hr = WinGetServerManualActivation_CreateInstance(type.GUID, iid, 0, out instance); + + // If create instance fails, wait and retry. + if (hr != 0) + { + Thread.Sleep(2000); + hr = WinGetServerManualActivation_CreateInstance(type.GUID, iid, 0, out instance); + } + + if (hr != 0) + { + throw new COMException("Failed to create instance.", hr); + } + } + else + { + instance = Activator.CreateInstance(type); } + #if NET IntPtr pointer = Marshal.GetIUnknownForObject(instance); return MarshalInterface.FromAbi(pointer); diff --git a/src/UndockedRegFreeWinRT/UndockedRegFreeWinRT/UndockedRegFreeWinRT.vcxproj b/src/UndockedRegFreeWinRT/UndockedRegFreeWinRT/UndockedRegFreeWinRT.vcxproj index 779387f2e2..1fb170c42a 100644 --- a/src/UndockedRegFreeWinRT/UndockedRegFreeWinRT/UndockedRegFreeWinRT.vcxproj +++ b/src/UndockedRegFreeWinRT/UndockedRegFreeWinRT/UndockedRegFreeWinRT.vcxproj @@ -1,213 +1,215 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - Debug - x64 - - - Release - x64 - - - - 16.0 - {31ED69A8-5310-45A9-953F-56C351D2C3E1} - Win32Proj - UndockedRegFreeWinRT - 10.0 - - - - DynamicLibrary - true - v142 - Unicode - - - DynamicLibrary - false - v142 - true - Unicode - - - DynamicLibrary - true - v142 - Unicode - - - DynamicLibrary - false - v142 - true - Unicode - - - - - - - - - - - - - - - - - - - - - winrtact - true - $(Platform)\$(Configuration)\ - $(SolutionDir)$(Platform)\$(Configuration)\$(ProjectName)\ - - - winrtact - true - $(Platform)\$(Configuration)\ - $(SolutionDir)$(Platform)\$(Configuration)\$(ProjectName)\ - - - winrtact - false - $(Platform)\$(Configuration)\ - $(SolutionDir)$(Platform)\$(Configuration)\$(ProjectName)\ - - - winrtact - false - $(Platform)\$(Configuration)\ - $(SolutionDir)$(Platform)\$(Configuration)\$(ProjectName)\ - - - - NotUsing - Level3 - true - WIN32;_DEBUG;UNDOCKEDREGFREEWINRT_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - true - pch.h - $(PorjectDir)\..\detours\include;%(AdditionalUsingDirectories) - stdcpp17 - - - Windows - true - false - comsuppw.lib;shlwapi.lib;xmllite.lib;runtimeobject.lib;Pathcch.lib;Rometadata.lib;Rpcrt4.lib - winrtact.def - - - - - NotUsing - Level3 - true - _DEBUG;UNDOCKEDREGFREEWINRT_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - true - pch.h - $(PorjectDir)\..\detours\include;%(AdditionalUsingDirectories) - stdcpp17 - - - Windows - true - false - comsuppw.lib;shlwapi.lib;xmllite.lib;runtimeobject.lib;Pathcch.lib;Rometadata.lib;Rpcrt4.lib - winrtact.def - - - - - NotUsing - Level3 - true - true - true - WIN32;NDEBUG;UNDOCKEDREGFREEWINRT_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - true - pch.h - $(PorjectDir)\..\detours\include;%(AdditionalUsingDirectories) - stdcpp17 - - - Windows - true - true - true - false - comsuppw.lib;shlwapi.lib;xmllite.lib;runtimeobject.lib;Pathcch.lib;Rometadata.lib;Rpcrt4.lib - winrtact.def - - - - - NotUsing - Level3 - true - true - true - NDEBUG;UNDOCKEDREGFREEWINRT_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) - true - pch.h - $(PorjectDir)\..\detours\include;%(AdditionalUsingDirectories) - stdcpp17 - - - Windows - true - true - true - false - comsuppw.lib;shlwapi.lib;xmllite.lib;runtimeobject.lib;Pathcch.lib;Rometadata.lib;Rpcrt4.lib - winrtact.def - - - - - - - - - - - - - - - - - - - - - - {787ec629-c0fb-4ba9-9746-4a82cd06b73e} - - - - - - - - - This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - - - + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 16.0 + {31ED69A8-5310-45A9-953F-56C351D2C3E1} + Win32Proj + UndockedRegFreeWinRT + 10.0 + + + + DynamicLibrary + true + v142 + Unicode + + + DynamicLibrary + false + v142 + true + Unicode + + + DynamicLibrary + true + v142 + Unicode + + + DynamicLibrary + false + v142 + true + Unicode + + + + + + + + + + + + + + + + + + + + + winrtact + true + $(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\$(ProjectName)\ + + + winrtact + true + $(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\$(ProjectName)\ + + + winrtact + false + $(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\$(ProjectName)\ + + + winrtact + false + $(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\$(ProjectName)\ + + + + NotUsing + Level3 + true + WIN32;_DEBUG;UNDOCKEDREGFREEWINRT_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + true + pch.h + $(PorjectDir)\..\detours\include;%(AdditionalUsingDirectories) + stdcpp17 + + + Windows + true + false + comsuppw.lib;shlwapi.lib;xmllite.lib;runtimeobject.lib;Pathcch.lib;Rometadata.lib;Rpcrt4.lib + winrtact.def + + + + + NotUsing + Level3 + true + _DEBUG;UNDOCKEDREGFREEWINRT_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + true + pch.h + $(PorjectDir)\..\detours\include;%(AdditionalUsingDirectories) + stdcpp17 + + + + + Windows + true + false + comsuppw.lib;shlwapi.lib;xmllite.lib;runtimeobject.lib;Pathcch.lib;Rometadata.lib;Rpcrt4.lib; + winrtact.def + + + + + NotUsing + Level3 + true + true + true + WIN32;NDEBUG;UNDOCKEDREGFREEWINRT_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + true + pch.h + $(PorjectDir)\..\detours\include;%(AdditionalUsingDirectories) + stdcpp17 + + + Windows + true + true + true + false + comsuppw.lib;shlwapi.lib;xmllite.lib;runtimeobject.lib;Pathcch.lib;Rometadata.lib;Rpcrt4.lib + winrtact.def + + + + + NotUsing + Level3 + true + true + true + NDEBUG;UNDOCKEDREGFREEWINRT_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + true + pch.h + $(PorjectDir)\..\detours\include;%(AdditionalUsingDirectories) + stdcpp17 + + + Windows + true + true + true + false + comsuppw.lib;shlwapi.lib;xmllite.lib;runtimeobject.lib;Pathcch.lib;Rometadata.lib;Rpcrt4.lib + winrtact.def + + + + + + + + + + + + + + + + + + + + + + {787ec629-c0fb-4ba9-9746-4a82cd06b73e} + + + + + + + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + \ No newline at end of file diff --git a/src/UndockedRegFreeWinRT/UndockedRegFreeWinRT/UndockedRegFreeWinRT.vcxproj.filters b/src/UndockedRegFreeWinRT/UndockedRegFreeWinRT/UndockedRegFreeWinRT.vcxproj.filters index 0d3d646dc2..88f7ce6c8b 100644 --- a/src/UndockedRegFreeWinRT/UndockedRegFreeWinRT/UndockedRegFreeWinRT.vcxproj.filters +++ b/src/UndockedRegFreeWinRT/UndockedRegFreeWinRT/UndockedRegFreeWinRT.vcxproj.filters @@ -1,53 +1,20 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hh;hpp;hxx;hm;inl;inc;ipp;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - - - - Source Files - - - - - - Source Files - - - Source Files - - - Header Files - - - Source Files - - - Source Files - - - Source Files - - - - - - Header Files - - - Header Files - - + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/WinGetServer/WinGetServer.vcxproj b/src/WinGetServer/WinGetServer.vcxproj index ddf16724b6..16466c3c7a 100644 --- a/src/WinGetServer/WinGetServer.vcxproj +++ b/src/WinGetServer/WinGetServer.vcxproj @@ -100,7 +100,7 @@ true true true - $(ProjectDir)..\WindowsPackageManager;%(AdditionalIncludeDirectories) + $(ProjectDir)..\WindowsPackageManager;%(AdditionalIncludeDirectories); Windows @@ -121,7 +121,7 @@ WIN32;%(PreprocessorDefinitions) - stdcpp17 + stdcpp17 diff --git a/src/WinGetServer/WinGetServerManualActivation_Client.cpp b/src/WinGetServer/WinGetServerManualActivation_Client.cpp index e68fbb7fa3..c8e004b365 100644 --- a/src/WinGetServer/WinGetServerManualActivation_Client.cpp +++ b/src/WinGetServer/WinGetServerManualActivation_Client.cpp @@ -4,11 +4,17 @@ #include #include +#include #include #include #include +#if PROD +const std::wstring& s_ServerExePath = L"\\Microsoft\\WindowsApps\\Microsoft.DesktopAppInstaller_8wekyb3d8bbwe\\WindowsPackageManagerServer.exe"; +#else +const std::wstring& s_ServerExePath = L"\\Microsoft\\WindowsApps\\WinGetDevCLI_8wekyb3d8bbwe\\WindowsPackageManagerServerDev.exe"; +#endif _Must_inspect_result_ _Ret_maybenull_ _Post_writable_byte_size_(size) @@ -30,6 +36,29 @@ unsigned char* GetUCharString(const std::string& str) return reinterpret_cast(const_cast(str.c_str())); } +std::wstring ExpandEnvironmentVariables(const std::wstring& input) +{ + if (input.empty()) + { + return {}; + } + + DWORD charCount = ExpandEnvironmentStringsW(input.c_str(), nullptr, 0); + THROW_LAST_ERROR_IF(charCount == 0); + + std::wstring result(wil::safe_cast(charCount), L'\0'); + + DWORD charCountWritten = ExpandEnvironmentStringsW(input.c_str(), &result[0], charCount); + THROW_HR_IF(E_UNEXPECTED, charCount != charCountWritten); + + if (result.back() == L'\0') + { + result.resize(result.size() - 1); + } + + return result; +} + struct FreeWithRpcStringFree { void operator()(RPC_CSTR* in) { RpcStringFreeA(in); } }; using UniqueRpcString = std::unique_ptr; @@ -52,6 +81,20 @@ void InitializeRpcBinding() THROW_HR_IF(HRESULT_FROM_WIN32(status), status != RPC_S_OK); } +void LaunchWinGetServerWithManualActivation() +{ + const std::wstring& localAppDataPath = ExpandEnvironmentVariables(L"%LOCALAPPDATA%"); + std::wstring serverExePath = localAppDataPath + s_ServerExePath + L" --manualActivation"; + + STARTUPINFO info = { sizeof(info) }; + PROCESS_INFORMATION processInfo; + CreateProcessW(NULL, &serverExePath[0], NULL, NULL, FALSE, 0, NULL, NULL, &info, &processInfo); + + CloseHandle(processInfo.hProcess); + CloseHandle(processInfo.hThread); + Sleep(1000); +} + HRESULT CallCreateInstance(const CLSID* clsid, const IID* iid, UINT32 flags, UINT32* bufferByteCount, BYTE** buffer) { RpcTryExcept @@ -73,52 +116,6 @@ extern "C" HRESULT WinGetServerManualActivation_CreateInstance(const CLSID* clsi RETURN_HR_IF_NULL(E_POINTER, iid); RETURN_HR_IF_NULL(E_POINTER, out); - - //If binding or activation fails, start RPC server, wait and try again. - STARTUPINFO info = { sizeof(info) }; - PROCESS_INFORMATION processInfo; - - //LPCWSTR serverExePath = TEXT("%LOCALAPPDATA%\\Microsoft\\WindowsApps\\WinGetDevCLI_8wekyb3d8bbwe\\WindowsPackageManagerServerDev.exe"); - -#if PROD - std::wstring serverExePath = L"C:\\Users\\ryfu\\AppData\\Local\\Microsoft\\WindowsApps\\WinGetCLI_8wekyb3d8bbwe\\WindowsPackageManagerServer.exe --manualActivation"; -#else - std::wstring serverExePath = L"C:\\Users\\ryfu\\AppData\\Local\\Microsoft\\WindowsApps\\WinGetDevCLI_8wekyb3d8bbwe\\WindowsPackageManagerServerDev.exe"; -#endif - - // If running in admin mode, include '--manualActivation' - // TODO:: Check token membership here. - if (true) - { - serverExePath = serverExePath + L" --manualActivation"; - } - - if (!CreateProcessW( - NULL, // No module name (use command line) - &serverExePath[0], // Command line - NULL, // Process handle not inheritable - NULL, // Thread handle not inheritable - FALSE, // Set handle inheritance to FALSE - CREATE_NEW_CONSOLE, // No creation flags - NULL, // Use parent's environment block - NULL, // Use parent's starting directory - &info, // Pointer to STARTUPINFO structure - &processInfo) // Pointer to PROCESS_INFORMATION structure - ) - { - printf("hello"); - printf("CreateProcess failed (%d).\n", GetLastError()); - } - else - { - printf("Successfully started process"); - CloseHandle(processInfo.hProcess); - CloseHandle(processInfo.hThread); - } - - // Sleep to wait for server to start. - Sleep(1000); - static std::once_flag rpcBindingOnce; try { @@ -130,8 +127,12 @@ extern "C" HRESULT WinGetServerManualActivation_CreateInstance(const CLSID* clsi BYTE* buffer = nullptr; UniqueMidl bufferPtr; - // Relaunch server if this fails - RETURN_IF_FAILED(CallCreateInstance(clsid, iid, flags, &bufferByteCount, &buffer)); + if (FAILED(CallCreateInstance(clsid, iid, flags, &bufferByteCount, &buffer))) + { + LaunchWinGetServerWithManualActivation(); + RETURN_IF_FAILED(CallCreateInstance(clsid, iid, flags, &bufferByteCount, &buffer)); + } + bufferPtr.reset(buffer); wil::com_ptr stream; diff --git a/src/WinGetServer/WinMain.cpp b/src/WinGetServer/WinMain.cpp index e9fc34ba0a..8e36235cf5 100644 --- a/src/WinGetServer/WinMain.cpp +++ b/src/WinGetServer/WinMain.cpp @@ -37,10 +37,9 @@ HRESULT WindowsPackageManagerServerInitializeRPCServer() RETURN_HR_IF(HRESULT_FROM_WIN32(status), status != RPC_S_OK); wil::unique_hlocal_security_descriptor securityDescriptor; - //// TODO: Verify that this limits clients to administrators - //RETURN_LAST_ERROR_IF(!ConvertStringSecurityDescriptorToSecurityDescriptorA("D:(A;;GA;;;BA)", SDDL_REVISION_1, &securityDescriptor, nullptr)); + RETURN_LAST_ERROR_IF(!ConvertStringSecurityDescriptorToSecurityDescriptorA("D:(A;;GA;;;BA)", SDDL_REVISION_1, &securityDescriptor, nullptr)); - status = RpcServerRegisterIf3(WinGetServerManualActivation_v1_0_s_ifspec, nullptr, nullptr, RPC_IF_ALLOW_LOCAL_ONLY | RPC_IF_AUTOLISTEN, RPC_C_LISTEN_MAX_CALLS_DEFAULT, 0, nullptr, nullptr /*securityDescriptor.get()*/); + status = RpcServerRegisterIf3(WinGetServerManualActivation_v1_0_s_ifspec, nullptr, nullptr, RPC_IF_ALLOW_SECURE_ONLY, RPC_C_LISTEN_MAX_CALLS_DEFAULT, 0, nullptr, securityDescriptor.get()); RETURN_HR_IF(HRESULT_FROM_WIN32(status), status != RPC_S_OK); return S_OK; @@ -103,6 +102,25 @@ extern "C" HRESULT CreateInstance( int __stdcall wWinMain(_In_ HINSTANCE, _In_opt_ HINSTANCE, _In_ LPWSTR cmdLine, _In_ int) { + // Create/open mutex and attempt to take ownership. + HANDLE hMutex = NULL; + hMutex = CreateMutex(NULL, FALSE, TEXT("WinGetServerMutex")); + + if (hMutex == NULL) + { + return 1; + } + else + { + // Attempt to take ownership of mutex with 0 timeout. + DWORD waitResult = WaitForSingleObject(hMutex, 0); + if (waitResult != 0) + { + // Immediate ownership of mutex failed, terminate as another server is running. + return 1; + } + } + RETURN_IF_FAILED(CoInitializeEx(nullptr, COINIT_MULTITHREADED)); // Enable fast rundown of objects so that the server exits faster when clients go away. @@ -138,8 +156,9 @@ int __stdcall wWinMain(_In_ HINSTANCE, _In_opt_ HINSTANCE, _In_ LPWSTR cmdLine, { RETURN_IF_FAILED(WindowsPackageManagerServerInitializeRPCServer()); } - _comServerExitEvent.wait(); + + ReleaseMutex(hMutex); RETURN_IF_FAILED(WindowsPackageManagerServerModuleUnregister()); } CATCH_RETURN() diff --git a/templates/e2e-test.template.yml b/templates/e2e-test.template.yml index 7e38114bd6..8b36c84506 100644 --- a/templates/e2e-test.template.yml +++ b/templates/e2e-test.template.yml @@ -25,7 +25,8 @@ steps: -MsiTestInstallerPath $(System.DefaultWorkingDirectory)\src\AppInstallerCLIE2ETests\TestData\AppInstallerTestMsiInstaller.msi -MsixTestInstallerPath $(Build.ArtifactStagingDirectory)\AppInstallerTestMsixInstaller.msix -ExeTestInstallerPath $(buildOutDir)\AppInstallerTestExeInstaller\AppInstallerTestExeInstaller.exe - -PackageCertificatePath $(AppInstallerTest.secureFilePath)' + -PackageCertificatePath $(AppInstallerTest.secureFilePath) + -PowerShellModulePath $(buildOutDir)\PowerShell\Microsoft.WinGet.Client.psd1' ${{ else }}: overrideTestrunParameters: '-PackagedContext false -AICLIPath $(System.DefaultWorkingDirectory)\src\AppInstallerCLIPackage\bin\$(buildPlatform)\$(buildConfiguration)\AppInstallerCLI\winget.exe @@ -34,4 +35,5 @@ steps: -MsiTestInstallerPath $(System.DefaultWorkingDirectory)\src\AppInstallerCLIE2ETests\TestData\AppInstallerTestMsiInstaller.msi -MsixTestInstallerPath $(Build.ArtifactStagingDirectory)\AppInstallerTestMsixInstaller.msix -ExeTestInstallerPath $(buildOutDir)\AppInstallerTestExeInstaller\AppInstallerTestExeInstaller.exe - -PackageCertificatePath $(AppInstallerTest.secureFilePath)' + -PackageCertificatePath $(AppInstallerTest.secureFilePath) + -PowerShellModulePath $(buildOutDir)\PowerShell\Microsoft.WinGet.Client.psd1' From 0febd7492f2611dfd15d491418c894eea1e69961 Mon Sep 17 00:00:00 2001 From: Ryan Fu Date: Wed, 26 Oct 2022 13:54:19 -0700 Subject: [PATCH 05/49] revert unnecessary changes --- .../AppInstallerCLIPackage.wapproj | 39 +------------- .../Package.appxmanifest | 2 +- .../Microsoft.WinGet.Client.csproj | 1 - .../UndockedRegFreeWinRT.vcxproj.filters | 54 +++++++++++++++---- src/WinGetServer/WinMain.cpp | 2 +- 5 files changed, 46 insertions(+), 52 deletions(-) diff --git a/src/AppInstallerCLIPackage/AppInstallerCLIPackage.wapproj b/src/AppInstallerCLIPackage/AppInstallerCLIPackage.wapproj index 84fe09707f..ee9c9e72b8 100644 --- a/src/AppInstallerCLIPackage/AppInstallerCLIPackage.wapproj +++ b/src/AppInstallerCLIPackage/AppInstallerCLIPackage.wapproj @@ -54,7 +54,7 @@ 10.0.22000.0 10.0.17763.0 en-US - True + False ..\AppInstallerCLI\AppInstallerCLI.vcxproj @@ -96,43 +96,6 @@ copy "$(TargetDir)\resources.pri" "$(ProjectDir)\..\$(Platform)\$(Configuration)\AppInstallerCLI\resources.pri" copy "$(TargetDir)\resources.pri" "$(TargetDir)\AppInstallerCLI\resources.pri" - False - True - True - x64 - 0 - C:\Users\ryfu\E2ETesting\appInstaller.pfx - SHA256 - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always diff --git a/src/AppInstallerCLIPackage/Package.appxmanifest b/src/AppInstallerCLIPackage/Package.appxmanifest index 3a146aa3e8..431838174d 100644 --- a/src/AppInstallerCLIPackage/Package.appxmanifest +++ b/src/AppInstallerCLIPackage/Package.appxmanifest @@ -8,7 +8,7 @@ xmlns:com="http://schemas.microsoft.com/appx/manifest/com/windows10" xmlns:desktop6="http://schemas.microsoft.com/appx/manifest/desktop/windows10/6" IgnorableNamespaces="uap uap3 uap5 rescap"> - + WinGet Dev CLI Microsoft Corporation diff --git a/src/PowerShell/Microsoft.WinGet.Client/Microsoft.WinGet.Client.csproj b/src/PowerShell/Microsoft.WinGet.Client/Microsoft.WinGet.Client.csproj index efae4a3433..a9b513bcfa 100644 --- a/src/PowerShell/Microsoft.WinGet.Client/Microsoft.WinGet.Client.csproj +++ b/src/PowerShell/Microsoft.WinGet.Client/Microsoft.WinGet.Client.csproj @@ -14,7 +14,6 @@ $(BuildOutputDirectory)PowerShell x64;x86 $(CoreFramework);$(DesktopFramework) - OnBuildSuccess diff --git a/src/UndockedRegFreeWinRT/UndockedRegFreeWinRT/UndockedRegFreeWinRT.vcxproj.filters b/src/UndockedRegFreeWinRT/UndockedRegFreeWinRT/UndockedRegFreeWinRT.vcxproj.filters index 88f7ce6c8b..de5fc4c2a0 100644 --- a/src/UndockedRegFreeWinRT/UndockedRegFreeWinRT/UndockedRegFreeWinRT.vcxproj.filters +++ b/src/UndockedRegFreeWinRT/UndockedRegFreeWinRT/UndockedRegFreeWinRT.vcxproj.filters @@ -1,20 +1,52 @@  - - - - - - - - - - + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;ipp;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + Source Files + - + + + + Source Files + + + Source Files + + + Header Files + + + Source Files + + + Source Files + + + Source Files + + + + + Header Files + + + Header Files + \ No newline at end of file diff --git a/src/WinGetServer/WinMain.cpp b/src/WinGetServer/WinMain.cpp index 8e36235cf5..c9c966f91c 100644 --- a/src/WinGetServer/WinMain.cpp +++ b/src/WinGetServer/WinMain.cpp @@ -158,8 +158,8 @@ int __stdcall wWinMain(_In_ HINSTANCE, _In_opt_ HINSTANCE, _In_ LPWSTR cmdLine, } _comServerExitEvent.wait(); - ReleaseMutex(hMutex); RETURN_IF_FAILED(WindowsPackageManagerServerModuleUnregister()); + ReleaseMutex(hMutex); } CATCH_RETURN() From 0a11caa743bd9d3fff3201e97f6016bdc3713aab Mon Sep 17 00:00:00 2001 From: Ryan Fu Date: Wed, 26 Oct 2022 14:33:35 -0700 Subject: [PATCH 06/49] fix build issues --- src/WinGetServer/WinGetServerManualActivation_Client.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/WinGetServer/WinGetServerManualActivation_Client.cpp b/src/WinGetServer/WinGetServerManualActivation_Client.cpp index c8e004b365..e583bec604 100644 --- a/src/WinGetServer/WinGetServerManualActivation_Client.cpp +++ b/src/WinGetServer/WinGetServerManualActivation_Client.cpp @@ -3,7 +3,6 @@ #include "WinGetServer.h" #include -#include #include #include From 6813160a0d8ee2537a0c40c8d5d4aae1f5177294 Mon Sep 17 00:00:00 2001 From: Ryan Fu Date: Wed, 26 Oct 2022 15:02:31 -0700 Subject: [PATCH 07/49] try again --- src/WinGetServer/WinGetServerManualActivation_Client.cpp | 1 + src/WinGetServer/WinMain.cpp | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/WinGetServer/WinGetServerManualActivation_Client.cpp b/src/WinGetServer/WinGetServerManualActivation_Client.cpp index e583bec604..c8e004b365 100644 --- a/src/WinGetServer/WinGetServerManualActivation_Client.cpp +++ b/src/WinGetServer/WinGetServerManualActivation_Client.cpp @@ -3,6 +3,7 @@ #include "WinGetServer.h" #include +#include #include #include diff --git a/src/WinGetServer/WinMain.cpp b/src/WinGetServer/WinMain.cpp index c9c966f91c..5ddaa10394 100644 --- a/src/WinGetServer/WinMain.cpp +++ b/src/WinGetServer/WinMain.cpp @@ -2,7 +2,7 @@ // Licensed under the MIT License. #define NOMINMAX #pragma warning( push ) -#pragma warning ( disable : 6001 6553) +#pragma warning ( disable : 6001 6388 6553) #include #include #pragma warning( pop ) @@ -102,7 +102,7 @@ extern "C" HRESULT CreateInstance( int __stdcall wWinMain(_In_ HINSTANCE, _In_opt_ HINSTANCE, _In_ LPWSTR cmdLine, _In_ int) { - // Create/open mutex and attempt to take ownership. + // Create mutex and attempt to take ownership. HANDLE hMutex = NULL; hMutex = CreateMutex(NULL, FALSE, TEXT("WinGetServerMutex")); From f1d7b4583c1a524089c25d1f224b54e54f92414c Mon Sep 17 00:00:00 2001 From: Ryan Fu Date: Wed, 2 Nov 2022 16:36:33 -0700 Subject: [PATCH 08/49] address PR comments --- .../Common/ErrorCode.cs | 16 +++ .../Microsoft.WinGet.Client/Format.ps1xml | 4 +- .../Helpers/ComObjectFactory.cs | 10 +- .../Microsoft.WinGet.Client.csproj | 6 +- .../Properties/Resources.Designer.cs | 11 +- .../Properties/Resources.resx | 5 +- .../UndockedRegFreeWinRT.vcxproj | 10 +- .../UndockedRegFreeWinRT.vcxproj.filters | 6 + .../UndockedRegFreeWinRT/winrtact.def | 1 - src/WinGetServer/Utils.cpp | 35 ++++++ src/WinGetServer/Utils.h | 8 ++ src/WinGetServer/WinGetServer.idl | Bin 858 -> 428 bytes src/WinGetServer/WinGetServer.vcxproj | 7 ++ src/WinGetServer/WinGetServer.vcxproj.filters | 6 + .../WinGetServerManualActivation_Client.cpp | 114 +++++++++--------- src/WinGetServer/WinMain.cpp | 46 +++---- 16 files changed, 184 insertions(+), 101 deletions(-) create mode 100644 src/PowerShell/Microsoft.WinGet.Client/Common/ErrorCode.cs create mode 100644 src/WinGetServer/Utils.cpp create mode 100644 src/WinGetServer/Utils.h diff --git a/src/PowerShell/Microsoft.WinGet.Client/Common/ErrorCode.cs b/src/PowerShell/Microsoft.WinGet.Client/Common/ErrorCode.cs new file mode 100644 index 0000000000..09cdd61e9e --- /dev/null +++ b/src/PowerShell/Microsoft.WinGet.Client/Common/ErrorCode.cs @@ -0,0 +1,16 @@ +// ----------------------------------------------------------------------------- +// +// Copyright (c) Microsoft Corporation. Licensed under the MIT License. +// +// ----------------------------------------------------------------------------- + +namespace Microsoft.WinGet.Client.Common +{ + /// + /// Error code constants. + /// + public class ErrorCode + { + public const int ERROR_FILE_NOT_FOUND = unchecked((int)0x80070002); + } +} diff --git a/src/PowerShell/Microsoft.WinGet.Client/Format.ps1xml b/src/PowerShell/Microsoft.WinGet.Client/Format.ps1xml index 77aab233b0..3c140ab2b5 100644 --- a/src/PowerShell/Microsoft.WinGet.Client/Format.ps1xml +++ b/src/PowerShell/Microsoft.WinGet.Client/Format.ps1xml @@ -74,10 +74,10 @@ $_.Info.Name - $_.Info.Type + $_.Info.Argument - $_.Info.Argument + $_.Info.Type diff --git a/src/PowerShell/Microsoft.WinGet.Client/Helpers/ComObjectFactory.cs b/src/PowerShell/Microsoft.WinGet.Client/Helpers/ComObjectFactory.cs index 778b8478dd..41bf905e35 100644 --- a/src/PowerShell/Microsoft.WinGet.Client/Helpers/ComObjectFactory.cs +++ b/src/PowerShell/Microsoft.WinGet.Client/Helpers/ComObjectFactory.cs @@ -8,7 +8,6 @@ namespace Microsoft.WinGet.Client.Factories { using System; using System.Runtime.InteropServices; - using System.Threading; using Microsoft.Management.Deployment; using Microsoft.WinGet.Client.Common; @@ -115,14 +114,11 @@ private static T Create(Type type, in Guid iid) int hr = WinGetServerManualActivation_CreateInstance(type.GUID, iid, 0, out instance); - // If create instance fails, wait and retry. - if (hr != 0) + if (hr == ErrorCode.ERROR_FILE_NOT_FOUND) { - Thread.Sleep(2000); - hr = WinGetServerManualActivation_CreateInstance(type.GUID, iid, 0, out instance); + throw new Exception(Utilities.ResourceManager.GetString("WinGetPackageNotInstalled")); } - - if (hr != 0) + else if (hr != 0) { throw new COMException("Failed to create instance.", hr); } diff --git a/src/PowerShell/Microsoft.WinGet.Client/Microsoft.WinGet.Client.csproj b/src/PowerShell/Microsoft.WinGet.Client/Microsoft.WinGet.Client.csproj index a9b513bcfa..80c58ad81e 100644 --- a/src/PowerShell/Microsoft.WinGet.Client/Microsoft.WinGet.Client.csproj +++ b/src/PowerShell/Microsoft.WinGet.Client/Microsoft.WinGet.Client.csproj @@ -16,6 +16,10 @@ $(CoreFramework);$(DesktopFramework) + + USE_PROD_CLSIDS + + @@ -48,7 +52,7 @@ - + True True diff --git a/src/PowerShell/Microsoft.WinGet.Client/Properties/Resources.Designer.cs b/src/PowerShell/Microsoft.WinGet.Client/Properties/Resources.Designer.cs index 5f4c91661c..dcb3db8807 100644 --- a/src/PowerShell/Microsoft.WinGet.Client/Properties/Resources.Designer.cs +++ b/src/PowerShell/Microsoft.WinGet.Client/Properties/Resources.Designer.cs @@ -70,7 +70,7 @@ internal static string ArgumentExceptionInvalidSource { } /// - /// Looks up a localized string similar to This cmdlet is currently disabled for SYSTEM users.. + /// Looks up a localized string similar to This cmdlet is currently disabled for SYSTEM.. /// internal static string ExceptionSystemDisabled { get { @@ -149,5 +149,14 @@ internal static string VagueCriteriaExceptionMessage { return ResourceManager.GetString("VagueCriteriaExceptionMessage", resourceCulture); } } + + /// + /// Looks up a localized string similar to Unable to execute command; WinGet package not installed.. + /// + internal static string WinGetPackageNotInstalled { + get { + return ResourceManager.GetString("WinGetPackageNotInstalled", resourceCulture); + } + } } } diff --git a/src/PowerShell/Microsoft.WinGet.Client/Properties/Resources.resx b/src/PowerShell/Microsoft.WinGet.Client/Properties/Resources.resx index 93d19b5543..5ccafe9c41 100644 --- a/src/PowerShell/Microsoft.WinGet.Client/Properties/Resources.resx +++ b/src/PowerShell/Microsoft.WinGet.Client/Properties/Resources.resx @@ -122,7 +122,7 @@ {0} - The name of the source that was not found. - This cmdlet is currently disabled for SYSTEM users. + This cmdlet is currently disabled for SYSTEM. An error occurred while searching for packages: {0} @@ -154,4 +154,7 @@ {0}, {1}, and {2} other packages matched the input criteria. Please refine the input. {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. + + Unable to execute command; WinGet package not installed. + \ No newline at end of file diff --git a/src/UndockedRegFreeWinRT/UndockedRegFreeWinRT/UndockedRegFreeWinRT.vcxproj b/src/UndockedRegFreeWinRT/UndockedRegFreeWinRT/UndockedRegFreeWinRT.vcxproj index 1fb170c42a..747f75ee8c 100644 --- a/src/UndockedRegFreeWinRT/UndockedRegFreeWinRT/UndockedRegFreeWinRT.vcxproj +++ b/src/UndockedRegFreeWinRT/UndockedRegFreeWinRT/UndockedRegFreeWinRT.vcxproj @@ -109,7 +109,7 @@ Windows true false - comsuppw.lib;shlwapi.lib;xmllite.lib;runtimeobject.lib;Pathcch.lib;Rometadata.lib;Rpcrt4.lib + comsuppw.lib;shlwapi.lib;xmllite.lib;runtimeobject.lib;Pathcch.lib;Rometadata.lib;Rpcrt4.lib;Shell32.lib;Advapi32.lib winrtact.def @@ -130,7 +130,7 @@ Windows true false - comsuppw.lib;shlwapi.lib;xmllite.lib;runtimeobject.lib;Pathcch.lib;Rometadata.lib;Rpcrt4.lib; + comsuppw.lib;shlwapi.lib;xmllite.lib;runtimeobject.lib;Pathcch.lib;Rometadata.lib;Rpcrt4.lib;Shell32.lib;Advapi32.lib winrtact.def @@ -153,7 +153,7 @@ true true false - comsuppw.lib;shlwapi.lib;xmllite.lib;runtimeobject.lib;Pathcch.lib;Rometadata.lib;Rpcrt4.lib + comsuppw.lib;shlwapi.lib;xmllite.lib;runtimeobject.lib;Pathcch.lib;Rometadata.lib;Rpcrt4.lib;Shell32.lib;Advapi32.lib winrtact.def @@ -176,7 +176,7 @@ true true false - comsuppw.lib;shlwapi.lib;xmllite.lib;runtimeobject.lib;Pathcch.lib;Rometadata.lib;Rpcrt4.lib + comsuppw.lib;shlwapi.lib;xmllite.lib;runtimeobject.lib;Pathcch.lib;Rometadata.lib;Rpcrt4.lib;Shell32.lib;Advapi32.lib winrtact.def @@ -188,6 +188,8 @@ + + diff --git a/src/UndockedRegFreeWinRT/UndockedRegFreeWinRT/UndockedRegFreeWinRT.vcxproj.filters b/src/UndockedRegFreeWinRT/UndockedRegFreeWinRT/UndockedRegFreeWinRT.vcxproj.filters index de5fc4c2a0..96767b28ca 100644 --- a/src/UndockedRegFreeWinRT/UndockedRegFreeWinRT/UndockedRegFreeWinRT.vcxproj.filters +++ b/src/UndockedRegFreeWinRT/UndockedRegFreeWinRT/UndockedRegFreeWinRT.vcxproj.filters @@ -40,6 +40,12 @@ Source Files + + Header Files + + + Source Files + diff --git a/src/UndockedRegFreeWinRT/UndockedRegFreeWinRT/winrtact.def b/src/UndockedRegFreeWinRT/UndockedRegFreeWinRT/winrtact.def index 00dac8c4dc..c7341b4437 100644 --- a/src/UndockedRegFreeWinRT/UndockedRegFreeWinRT/winrtact.def +++ b/src/UndockedRegFreeWinRT/UndockedRegFreeWinRT/winrtact.def @@ -2,5 +2,4 @@ LIBRARY winrtact EXPORTS winrtact_Initialize - WinGetServerManualActivation_CreateInstance \ No newline at end of file diff --git a/src/WinGetServer/Utils.cpp b/src/WinGetServer/Utils.cpp new file mode 100644 index 0000000000..044f5b272a --- /dev/null +++ b/src/WinGetServer/Utils.cpp @@ -0,0 +1,35 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#include "Utils.h" +#pragma warning( push ) +#pragma warning ( disable : 6001 6388 6553) +#include +#pragma warning( pop ) +#include +#include +#include + +unsigned char* GetUCharString(const std::string& str) +{ + return reinterpret_cast(const_cast(str.c_str())); +} + +std::string GetUserSID() +{ + HANDLE hToken = NULL; + THROW_LAST_ERROR_IF(!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken)); + + DWORD dwBufferSize = 0; + THROW_LAST_ERROR_IF(!GetTokenInformation(hToken, TokenUser, NULL, 0, &dwBufferSize) && GetLastError() != ERROR_INSUFFICIENT_BUFFER); + + std::vector buffer; + buffer.resize(dwBufferSize); + PTOKEN_USER pTokenUser = reinterpret_cast(&buffer[0]); + + THROW_LAST_ERROR_IF(!GetTokenInformation(hToken, TokenUser, pTokenUser, dwBufferSize, &dwBufferSize)); + THROW_LAST_ERROR_IF(!IsValidSid(pTokenUser->User.Sid)); + + LPSTR pszSID = NULL; + ConvertSidToStringSidA(pTokenUser->User.Sid, &pszSID); + return std::string{ pszSID }; +} \ No newline at end of file diff --git a/src/WinGetServer/Utils.h b/src/WinGetServer/Utils.h new file mode 100644 index 0000000000..80b73dfcfb --- /dev/null +++ b/src/WinGetServer/Utils.h @@ -0,0 +1,8 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +#pragma once +#include + +unsigned char* GetUCharString(const std::string& str); + +std::string GetUserSID(); \ No newline at end of file diff --git a/src/WinGetServer/WinGetServer.idl b/src/WinGetServer/WinGetServer.idl index af9c18399723057de4e94338853749b2aa6d6ef4..87f8a7a42c76e24467a924f3d46d1a41c2db1440 100644 GIT binary patch literal 428 zcmaKpK}*9x5QXo7{D-Bdq$DNPhPHUJTH1hmun8h1gvsu#4y4<#yQ!%7-;J({qBxg< zdG8zEFtls;+OoleeQeRxU~ojD8Jzf@?`?gL_0@GGf`mgd7Xsp0I+gKcI+t+`lR6eK zo2Fu(Bk`hW08LkCM+3?b?Po+3FsYXfSZCvh0S`3hf4U4_$)lpgHB14q*EQ zRVLT(_R#lA-y>yFOW^n~k97ERfdeKRV`Y&6=3_W2*CWzSZ%NdqzahorP OJ={9hG0Ck6iDhT* z%$$49xp#Ko-y+>>qOqn*mD83UnV;ARG}BN6#y~rYG*Zmzfi|__-mV*S%S&fKFs;R1dg+vwRx{Hjt0)NS2YV22u>g0JuWi$)g&L}*vH^oha*94t1uDl

ZTtG=uF8eF0lr>QQS#zN`T<;@vm9m1A^dtha=Iq0iHCG8dV zg7e#Rqj9E=Ed=2c<@8@A>-bBi7j2!ZiQ6lk=o025Iukf=0j?6dlsaFgo6lq}@2l&o z?vdMqrK4japGvL2qi>!6D<@hDZwhBP-P0~QAvy!yqLsbjFP$-8Q_5-1)fLKou5uJv zPw+cb17yf!-^RLZ#%pyxlhtRQ(IeX{{=!*s+6~>{z6oNXJjv+V{Vcr~KL3zceE=kR BemejF diff --git a/src/WinGetServer/WinGetServer.vcxproj b/src/WinGetServer/WinGetServer.vcxproj index 16466c3c7a..38e885faef 100644 --- a/src/WinGetServer/WinGetServer.vcxproj +++ b/src/WinGetServer/WinGetServer.vcxproj @@ -144,6 +144,11 @@ /debug:full /debugtype:cv,fixup /incremental:no %(AdditionalOptions) + + + USE_PROD_WINGET_SERVER;%(PreprocessorDefinitions) + + @@ -162,6 +167,8 @@ + + diff --git a/src/WinGetServer/WinGetServer.vcxproj.filters b/src/WinGetServer/WinGetServer.vcxproj.filters index 9504000e60..71519a4d9d 100644 --- a/src/WinGetServer/WinGetServer.vcxproj.filters +++ b/src/WinGetServer/WinGetServer.vcxproj.filters @@ -18,6 +18,9 @@ Header Files + + Header Files + @@ -29,6 +32,9 @@ Source Files + + Source Files + diff --git a/src/WinGetServer/WinGetServerManualActivation_Client.cpp b/src/WinGetServer/WinGetServerManualActivation_Client.cpp index c8e004b365..65f85749a3 100644 --- a/src/WinGetServer/WinGetServerManualActivation_Client.cpp +++ b/src/WinGetServer/WinGetServerManualActivation_Client.cpp @@ -1,6 +1,7 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. #include "WinGetServer.h" +#include "Utils.h" #include #include @@ -9,11 +10,14 @@ #include #include #include +#include +#include +#include -#if PROD -const std::wstring& s_ServerExePath = L"\\Microsoft\\WindowsApps\\Microsoft.DesktopAppInstaller_8wekyb3d8bbwe\\WindowsPackageManagerServer.exe"; +#if USE_PROD_WINGET_SERVER +const std::wstring_view s_ServerExePath = L"\\Microsoft\\WindowsApps\\Microsoft.DesktopAppInstaller_8wekyb3d8bbwe\\WindowsPackageManagerServer.exe"; #else -const std::wstring& s_ServerExePath = L"\\Microsoft\\WindowsApps\\WinGetDevCLI_8wekyb3d8bbwe\\WindowsPackageManagerServerDev.exe"; +const std::wstring_view s_ServerExePath = L"\\Microsoft\\WindowsApps\\WinGetDevCLI_8wekyb3d8bbwe\\WindowsPackageManagerServerDev.exe"; #endif _Must_inspect_result_ @@ -31,32 +35,11 @@ void __RPC_USER MIDL_user_free(_Pre_maybenull_ _Post_invalid_ void* ptr) } } -unsigned char* GetUCharString(const std::string& str) +std::filesystem::path GetKnownFolderPath(const KNOWNFOLDERID& id) { - return reinterpret_cast(const_cast(str.c_str())); -} - -std::wstring ExpandEnvironmentVariables(const std::wstring& input) -{ - if (input.empty()) - { - return {}; - } - - DWORD charCount = ExpandEnvironmentStringsW(input.c_str(), nullptr, 0); - THROW_LAST_ERROR_IF(charCount == 0); - - std::wstring result(wil::safe_cast(charCount), L'\0'); - - DWORD charCountWritten = ExpandEnvironmentStringsW(input.c_str(), &result[0], charCount); - THROW_HR_IF(E_UNEXPECTED, charCount != charCountWritten); - - if (result.back() == L'\0') - { - result.resize(result.size() - 1); - } - - return result; + wil::unique_cotaskmem_string knownFolder = nullptr; + THROW_IF_FAILED(SHGetKnownFolderPath(id, KF_FLAG_NO_ALIAS | KF_FLAG_DONT_VERIFY | KF_FLAG_NO_PACKAGE_REDIRECTION, NULL, &knownFolder)); + return knownFolder.get(); } struct FreeWithRpcStringFree { void operator()(RPC_CSTR* in) { RpcStringFreeA(in); } }; @@ -68,7 +51,7 @@ using UniqueMidl = std::unique_ptr; void InitializeRpcBinding() { std::string protocol = "ncacn_np"; - std::string endpoint = "\\pipe\\WinGetServerManualActivation_SID"; + std::string endpoint = "\\pipe\\WinGetServerManualActivation_" + GetUserSID(); unsigned char* binding = nullptr; UniqueRpcString bindingPtr; @@ -81,18 +64,24 @@ void InitializeRpcBinding() THROW_HR_IF(HRESULT_FROM_WIN32(status), status != RPC_S_OK); } -void LaunchWinGetServerWithManualActivation() +HRESULT LaunchWinGetServerWithManualActivation() { - const std::wstring& localAppDataPath = ExpandEnvironmentVariables(L"%LOCALAPPDATA%"); - std::wstring serverExePath = localAppDataPath + s_ServerExePath + L" --manualActivation"; + const std::filesystem::path& localAppDataPath = GetKnownFolderPath(FOLDERID_LocalAppData); + std::wstring serverExePath = std::wstring{ localAppDataPath } + std::wstring{ s_ServerExePath } + L" --manualActivation"; STARTUPINFO info = { sizeof(info) }; PROCESS_INFORMATION processInfo; - CreateProcessW(NULL, &serverExePath[0], NULL, NULL, FALSE, 0, NULL, NULL, &info, &processInfo); - - CloseHandle(processInfo.hProcess); - CloseHandle(processInfo.hThread); - Sleep(1000); + if (CreateProcessW(NULL, &serverExePath[0], NULL, NULL, FALSE, 0, NULL, NULL, &info, &processInfo)) + { + WaitForSingleObject(processInfo.hThread, 500); + CloseHandle(processInfo.hProcess); + CloseHandle(processInfo.hThread); + return S_OK; + } + else + { + return HRESULT_FROM_WIN32(GetLastError()); + } } HRESULT CallCreateInstance(const CLSID* clsid, const IID* iid, UINT32 flags, UINT32* bufferByteCount, BYTE** buffer) @@ -110,28 +99,14 @@ HRESULT CallCreateInstance(const CLSID* clsid, const IID* iid, UINT32 flags, UIN return S_OK; } -extern "C" HRESULT WinGetServerManualActivation_CreateInstance(const CLSID* clsid, const IID* iid, UINT32 flags, void** out) +HRESULT LaunchServerAndCreateInstance(const CLSID* clsid, const IID* iid, UINT32 flags, void** out) { - RETURN_HR_IF_NULL(E_POINTER, clsid); - RETURN_HR_IF_NULL(E_POINTER, iid); - RETURN_HR_IF_NULL(E_POINTER, out); - - static std::once_flag rpcBindingOnce; - try - { - std::call_once(rpcBindingOnce, InitializeRpcBinding); - } - CATCH_RETURN(); - UINT32 bufferByteCount = 0; BYTE* buffer = nullptr; UniqueMidl bufferPtr; - if (FAILED(CallCreateInstance(clsid, iid, flags, &bufferByteCount, &buffer))) - { - LaunchWinGetServerWithManualActivation(); - RETURN_IF_FAILED(CallCreateInstance(clsid, iid, flags, &bufferByteCount, &buffer)); - } + RETURN_IF_FAILED(LaunchWinGetServerWithManualActivation()); + RETURN_IF_FAILED(CallCreateInstance(clsid, iid, flags, &bufferByteCount, &buffer)); bufferPtr.reset(buffer); @@ -142,7 +117,36 @@ extern "C" HRESULT WinGetServerManualActivation_CreateInstance(const CLSID* clsi wil::com_ptr output; RETURN_IF_FAILED(CoUnmarshalInterface(stream.get(), *iid, reinterpret_cast(&output))); - *out = output.detach(); return S_OK; +} + +extern "C" HRESULT WinGetServerManualActivation_CreateInstance(const CLSID* clsid, const IID* iid, UINT32 flags, void** out) +{ + RETURN_HR_IF_NULL(E_POINTER, clsid); + RETURN_HR_IF_NULL(E_POINTER, iid); + RETURN_HR_IF_NULL(E_POINTER, out); + + if (WinGetServerManualActivation_IfHandle == NULL) + { + static std::once_flag rpcBindingOnce; + try + { + std::call_once(rpcBindingOnce, InitializeRpcBinding); + } + CATCH_RETURN(); + } + + HRESULT result; + + for (int i = 0; i < 3; i++) + { + result = LaunchServerAndCreateInstance(clsid, iid, flags, out); + if (SUCCEEDED(result) || result == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)) + { + break; + } + } + + return result; } \ No newline at end of file diff --git a/src/WinGetServer/WinMain.cpp b/src/WinGetServer/WinMain.cpp index 5ddaa10394..c994ff842f 100644 --- a/src/WinGetServer/WinMain.cpp +++ b/src/WinGetServer/WinMain.cpp @@ -11,6 +11,7 @@ #include #include #include "WinGetServer.h" +#include "Utils.h" #include #include @@ -26,20 +27,17 @@ static void _releaseNotifier() noexcept _comServerExitEvent.SetEvent(); } -unsigned char* GetUCharString(const char* in) -{ - return reinterpret_cast(const_cast(in)); -} - HRESULT WindowsPackageManagerServerInitializeRPCServer() { - RPC_STATUS status = RpcServerUseProtseqEpA(GetUCharString("ncacn_np"), RPC_C_PROTSEQ_MAX_REQS_DEFAULT, GetUCharString("\\pipe\\WinGetServerManualActivation_SID"), nullptr); + std::string userSID = GetUserSID(); + std::string endpoint = "\\pipe\\WinGetServerManualActivation_" + userSID; + RPC_STATUS status = RpcServerUseProtseqEpA(GetUCharString("ncacn_np"), RPC_C_PROTSEQ_MAX_REQS_DEFAULT, GetUCharString(endpoint), nullptr); RETURN_HR_IF(HRESULT_FROM_WIN32(status), status != RPC_S_OK); wil::unique_hlocal_security_descriptor securityDescriptor; - RETURN_LAST_ERROR_IF(!ConvertStringSecurityDescriptorToSecurityDescriptorA("D:(A;;GA;;;BA)", SDDL_REVISION_1, &securityDescriptor, nullptr)); + RETURN_LAST_ERROR_IF(!ConvertStringSecurityDescriptorToSecurityDescriptorA("S:(ML;;NW;;;HI)D:(A;;GA;;;PS)", SDDL_REVISION_1, &securityDescriptor, nullptr)); - status = RpcServerRegisterIf3(WinGetServerManualActivation_v1_0_s_ifspec, nullptr, nullptr, RPC_IF_ALLOW_SECURE_ONLY, RPC_C_LISTEN_MAX_CALLS_DEFAULT, 0, nullptr, securityDescriptor.get()); + status = RpcServerRegisterIf3(WinGetServerManualActivation_v1_0_s_ifspec, nullptr, nullptr, RPC_IF_ALLOW_LOCAL_ONLY | RPC_IF_AUTOLISTEN, RPC_C_LISTEN_MAX_CALLS_DEFAULT, 0, nullptr, securityDescriptor.get()); RETURN_HR_IF(HRESULT_FROM_WIN32(status), status != RPC_S_OK); return S_OK; @@ -102,25 +100,6 @@ extern "C" HRESULT CreateInstance( int __stdcall wWinMain(_In_ HINSTANCE, _In_opt_ HINSTANCE, _In_ LPWSTR cmdLine, _In_ int) { - // Create mutex and attempt to take ownership. - HANDLE hMutex = NULL; - hMutex = CreateMutex(NULL, FALSE, TEXT("WinGetServerMutex")); - - if (hMutex == NULL) - { - return 1; - } - else - { - // Attempt to take ownership of mutex with 0 timeout. - DWORD waitResult = WaitForSingleObject(hMutex, 0); - if (waitResult != 0) - { - // Immediate ownership of mutex failed, terminate as another server is running. - return 1; - } - } - RETURN_IF_FAILED(CoInitializeEx(nullptr, COINIT_MULTITHREADED)); // Enable fast rundown of objects so that the server exits faster when clients go away. @@ -153,13 +132,22 @@ int __stdcall wWinMain(_In_ HINSTANCE, _In_opt_ HINSTANCE, _In_ LPWSTR cmdLine, RETURN_IF_FAILED(WindowsPackageManagerServerModuleRegister()); if (manualActivation) - { + { + HANDLE hMutex = NULL; + hMutex = CreateMutex(NULL, FALSE, TEXT("WinGetServerMutex")); + RETURN_HR_IF_NULL(OSS_MUTEX_NOT_CREATED, hMutex); + + DWORD waitResult = WaitForSingleObject(hMutex, 0); + if (waitResult != 0 && waitResult != WAIT_ABANDONED) + { + return ERROR_SERVICE_ALREADY_RUNNING; + } + RETURN_IF_FAILED(WindowsPackageManagerServerInitializeRPCServer()); } _comServerExitEvent.wait(); RETURN_IF_FAILED(WindowsPackageManagerServerModuleUnregister()); - ReleaseMutex(hMutex); } CATCH_RETURN() From 74414aed42a9f3f5a6b6450de7d151b9ec6a450f Mon Sep 17 00:00:00 2001 From: Ryan Fu Date: Wed, 2 Nov 2022 18:18:31 -0700 Subject: [PATCH 09/49] fix build issues --- .../UndockedRegFreeWinRT/UndockedRegFreeWinRT.vcxproj | 2 +- .../UndockedRegFreeWinRT.vcxproj.filters | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/UndockedRegFreeWinRT/UndockedRegFreeWinRT/UndockedRegFreeWinRT.vcxproj b/src/UndockedRegFreeWinRT/UndockedRegFreeWinRT/UndockedRegFreeWinRT.vcxproj index 747f75ee8c..2924e8ad96 100644 --- a/src/UndockedRegFreeWinRT/UndockedRegFreeWinRT/UndockedRegFreeWinRT.vcxproj +++ b/src/UndockedRegFreeWinRT/UndockedRegFreeWinRT/UndockedRegFreeWinRT.vcxproj @@ -188,7 +188,7 @@ - + diff --git a/src/UndockedRegFreeWinRT/UndockedRegFreeWinRT/UndockedRegFreeWinRT.vcxproj.filters b/src/UndockedRegFreeWinRT/UndockedRegFreeWinRT/UndockedRegFreeWinRT.vcxproj.filters index 96767b28ca..1c48914b19 100644 --- a/src/UndockedRegFreeWinRT/UndockedRegFreeWinRT/UndockedRegFreeWinRT.vcxproj.filters +++ b/src/UndockedRegFreeWinRT/UndockedRegFreeWinRT/UndockedRegFreeWinRT.vcxproj.filters @@ -40,9 +40,6 @@ Source Files - - Header Files - Source Files @@ -54,5 +51,8 @@ Header Files + + Header Files + \ No newline at end of file From 71633e0bad21c0dc0430ba9fb70358a2f29840aa Mon Sep 17 00:00:00 2001 From: Ryan Fu Date: Thu, 3 Nov 2022 23:06:18 -0700 Subject: [PATCH 10/49] set execution policy --- .../PowerShell/PowerShellModule.cs | 22 +++++++++---------- src/AppInstallerCLIE2ETests/TestCommon.cs | 2 +- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/AppInstallerCLIE2ETests/PowerShell/PowerShellModule.cs b/src/AppInstallerCLIE2ETests/PowerShell/PowerShellModule.cs index d18aada980..68f3452c74 100644 --- a/src/AppInstallerCLIE2ETests/PowerShell/PowerShellModule.cs +++ b/src/AppInstallerCLIE2ETests/PowerShell/PowerShellModule.cs @@ -28,7 +28,7 @@ public void TearDown() public void GetWinGetSource() { var getSourceResult = TestCommon.RunPowerShellCommandWithResult(Constants.GetSourceCmdlet, $"-Name {Constants.TestSourceName}"); - Assert.IsTrue(getSourceResult.ExitCode == 0); + Assert.IsTrue(getSourceResult.ExitCode == 0, $"Failed with the following output: {getSourceResult.StdOut}"); Assert.IsTrue(getSourceResult.StdOut.Contains($"{Constants.TestSourceName}")); } @@ -36,7 +36,7 @@ public void GetWinGetSource() public void FindWinGetPackage() { var result = TestCommon.RunPowerShellCommandWithResult(Constants.FindCmdlet, $"-Id {Constants.ExeInstallerPackageId}"); - Assert.IsTrue(result.ExitCode == 0); + Assert.IsTrue(result.ExitCode == 0, $"Failed with the following output: {result.StdOut}"); Assert.IsTrue(result.StdOut.Contains("TestExeInstaller")); } @@ -47,9 +47,9 @@ public void GetWinGetPackage() var getResult = TestCommon.RunPowerShellCommandWithResult(Constants.GetCmdlet, $"-Id {Constants.MsiInstallerPackageId}"); var uninstallResult = TestCommon.RunPowerShellCommandWithResult(Constants.UninstallCmdlet, $"-Id {Constants.MsiInstallerPackageId}"); - Assert.IsTrue(installResult.ExitCode == 0); - Assert.IsTrue(getResult.ExitCode == 0); - Assert.IsTrue(uninstallResult.ExitCode == 0); + Assert.IsTrue(installResult.ExitCode == 0, $"Failed with the following output: {installResult.StdOut}"); + Assert.IsTrue(getResult.ExitCode == 0, $"Failed with the following output: {getResult.StdOut}"); + Assert.IsTrue(uninstallResult.ExitCode == 0, $"Failed with the following output: {uninstallResult.StdOut}"); Assert.IsTrue(!string.IsNullOrEmpty(installResult.StdOut)); Assert.IsTrue(getResult.StdOut.Contains("TestMsiInstaller")); @@ -62,8 +62,8 @@ public void InstallWinGetPackage() var installResult = TestCommon.RunPowerShellCommandWithResult(Constants.InstallCmdlet, $"-Id {Constants.ExeInstallerPackageId}"); var uninstallResult = TestCommon.RunPowerShellCommandWithResult(Constants.UninstallCmdlet, $"-Id {Constants.ExeInstallerPackageId}"); - Assert.IsTrue(installResult.ExitCode == 0); - Assert.IsTrue(uninstallResult.ExitCode == 0); + Assert.IsTrue(installResult.ExitCode == 0, $"Failed with the following output: {installResult.StdOut}"); + Assert.IsTrue(uninstallResult.ExitCode == 0, $"Failed with the following output: {uninstallResult.StdOut}"); Assert.IsTrue(!string.IsNullOrEmpty(installResult.StdOut)); Assert.IsTrue(!string.IsNullOrEmpty(uninstallResult.StdOut)); @@ -77,10 +77,10 @@ public void UpdateWinGetPackage() var getResult = TestCommon.RunPowerShellCommandWithResult(Constants.GetCmdlet, $"-Id {Constants.ExeInstallerPackageId}"); var uninstallResult = TestCommon.RunPowerShellCommandWithResult(Constants.UninstallCmdlet, $"-Id {Constants.ExeInstallerPackageId}"); - Assert.IsTrue(installResult.ExitCode == 0); - Assert.IsTrue(updateResult.ExitCode == 0); - Assert.IsTrue(getResult.ExitCode == 0); - Assert.IsTrue(uninstallResult.ExitCode == 0); + Assert.IsTrue(installResult.ExitCode == 0, $"Failed with the following output: {installResult.StdOut}"); + Assert.IsTrue(updateResult.ExitCode == 0, $"Failed with the following output: {updateResult.StdOut}"); + Assert.IsTrue(getResult.ExitCode == 0, $"Failed with the following output: {getResult.StdOut}"); + Assert.IsTrue(uninstallResult.ExitCode == 0, $"Failed with the following output: {uninstallResult.StdOut}"); Assert.IsTrue(!string.IsNullOrEmpty(installResult.StdOut)); Assert.IsTrue(!string.IsNullOrEmpty(updateResult.StdOut)); diff --git a/src/AppInstallerCLIE2ETests/TestCommon.cs b/src/AppInstallerCLIE2ETests/TestCommon.cs index 3ed097643e..0ffd6f54f5 100644 --- a/src/AppInstallerCLIE2ETests/TestCommon.cs +++ b/src/AppInstallerCLIE2ETests/TestCommon.cs @@ -256,7 +256,7 @@ public static RunCommandResult RunCommandWithResult(string fileName, string args public static RunCommandResult RunPowerShellCommandWithResult(string cmdlet, string args, int timeOut = 60000) { - return RunCommandWithResult("pwsh", $"-Command ipmo {PowerShellModulePath}; {cmdlet} {args}", timeOut); + return RunCommandWithResult("pwsh", $"-Command Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass; ipmo {PowerShellModulePath}; {cmdlet} {args}", timeOut); } public static string GetTestFile(string fileName) From adc0c0570f0c7a234e2fb2eb342235b520d40d4b Mon Sep 17 00:00:00 2001 From: Ryan Fu Date: Fri, 4 Nov 2022 12:02:46 -0700 Subject: [PATCH 11/49] try again --- azure-pipelines.yml | 61 +++++++++++-------- .../PowerShell/PowerShellModule.cs | 3 + src/AppInstallerCLIE2ETests/TestCommon.cs | 2 +- .../Helpers/ComObjectFactory.cs | 4 +- src/WinGetServer/WinMain.cpp | 3 +- 5 files changed, 43 insertions(+), 30 deletions(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index d5a657f19b..49bb256ba4 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -140,34 +140,43 @@ jobs: inputs: packageFeedSelector: 'nugetOrg' - - task: DownloadSecureFile@1 - name: PsExec - displayName: 'Download PsExec.exe' - inputs: - secureFile: 'PsExec.exe' - - - task: CmdLine@2 - displayName: Run Unit Tests Unpackaged Under System Context - inputs: - script: | - $(PsExec.secureFilePath) -accepteula -s -i $(buildOutDir)\AppInstallerCLITests\AppInstallerCLITests.exe -logto $(artifactsDir)\AICLI-Unpackaged-System.log -s -r junit -o $(artifactsDir)\TEST-AppInstallerCLI-Unpackaged-System.xml - workingDirectory: '$(buildOutDir)\AppInstallerCLITests' - continueOnError: true - + # - task: DownloadSecureFile@1 + # name: PsExec + # displayName: 'Download PsExec.exe' + # inputs: + # secureFile: 'PsExec.exe' + + # - task: CmdLine@2 + # displayName: Run Unit Tests Unpackaged Under System Context + # inputs: + # script: | + # $(PsExec.secureFilePath) -accepteula -s -i $(buildOutDir)\AppInstallerCLITests\AppInstallerCLITests.exe -logto $(artifactsDir)\AICLI-Unpackaged-System.log -s -r junit -o $(artifactsDir)\TEST-AppInstallerCLI-Unpackaged-System.xml + # workingDirectory: '$(buildOutDir)\AppInstallerCLITests' + # continueOnError: true + + # - task: PowerShell@2 + # displayName: Run Unit Tests Packaged + # inputs: + # filePath: 'src\AppInstallerCLITests\Run-TestsInPackage.ps1' + # arguments: '-Args "~[pips]" -BuildRoot $(buildOutDir) -PackageRoot AppInstallerCLIPackage\bin\$(buildPlatform)\$(buildConfiguration) -LogTarget $(artifactsDir)\AICLI-Packaged.log -TestResultsTarget $(artifactsDir)\TEST-AppInstallerCLI-Packaged.xml -ScriptWait' + # workingDirectory: 'src' + # continueOnError: true + + # - task: PublishTestResults@2 + # displayName: Publish Unit Test Results + # inputs: + # testResultsFormat: 'JUnit' + # testResultsFiles: '$(artifactsDir)\TEST-*.xml' + # failTaskOnFailedTests: true + - task: PowerShell@2 - displayName: Run Unit Tests Packaged - inputs: - filePath: 'src\AppInstallerCLITests\Run-TestsInPackage.ps1' - arguments: '-Args "~[pips]" -BuildRoot $(buildOutDir) -PackageRoot AppInstallerCLIPackage\bin\$(buildPlatform)\$(buildConfiguration) -LogTarget $(artifactsDir)\AICLI-Packaged.log -TestResultsTarget $(artifactsDir)\TEST-AppInstallerCLI-Packaged.xml -ScriptWait' - workingDirectory: 'src' - continueOnError: true - - - task: PublishTestResults@2 - displayName: Publish Unit Test Results + displayName: Check PowerShell Core version inputs: - testResultsFormat: 'JUnit' - testResultsFiles: '$(artifactsDir)\TEST-*.xml' - failTaskOnFailedTests: true + targetType: 'inline' + script: | + # Checking PowerShell version + pwsh + $env:path -split ';' - task: DownloadSecureFile@1 name: AppInstallerTest diff --git a/src/AppInstallerCLIE2ETests/PowerShell/PowerShellModule.cs b/src/AppInstallerCLIE2ETests/PowerShell/PowerShellModule.cs index 68f3452c74..f22ce390ce 100644 --- a/src/AppInstallerCLIE2ETests/PowerShell/PowerShellModule.cs +++ b/src/AppInstallerCLIE2ETests/PowerShell/PowerShellModule.cs @@ -13,6 +13,9 @@ public class PowerShellModule [OneTimeSetUp] public void Setup() { + // install powershell prior to running module tests. + TestCommon.RunAICLICommand("install", $"--id Microsoft.PowerShell"); + // Add-WinGetPackage is a function and not a cmdlet that uses COM. Add source to WinGetDev directly to ensure test source exists. TestCommon.RunAICLICommand("source add", $"-n {Constants.TestSourceName} {Constants.TestSourceUrl}"); } diff --git a/src/AppInstallerCLIE2ETests/TestCommon.cs b/src/AppInstallerCLIE2ETests/TestCommon.cs index 0ffd6f54f5..3ed097643e 100644 --- a/src/AppInstallerCLIE2ETests/TestCommon.cs +++ b/src/AppInstallerCLIE2ETests/TestCommon.cs @@ -256,7 +256,7 @@ public static RunCommandResult RunCommandWithResult(string fileName, string args public static RunCommandResult RunPowerShellCommandWithResult(string cmdlet, string args, int timeOut = 60000) { - return RunCommandWithResult("pwsh", $"-Command Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass; ipmo {PowerShellModulePath}; {cmdlet} {args}", timeOut); + return RunCommandWithResult("pwsh", $"-Command ipmo {PowerShellModulePath}; {cmdlet} {args}", timeOut); } public static string GetTestFile(string fileName) diff --git a/src/PowerShell/Microsoft.WinGet.Client/Helpers/ComObjectFactory.cs b/src/PowerShell/Microsoft.WinGet.Client/Helpers/ComObjectFactory.cs index 41bf905e35..bb1f4b8106 100644 --- a/src/PowerShell/Microsoft.WinGet.Client/Helpers/ComObjectFactory.cs +++ b/src/PowerShell/Microsoft.WinGet.Client/Helpers/ComObjectFactory.cs @@ -106,8 +106,8 @@ public virtual PackageMatchFilter CreatePackageMatchFilter() private static T Create(Type type, in Guid iid) { - object instance; - + object instance; + if (Utilities.ExecutingAsAdministrator) { instance = null; diff --git a/src/WinGetServer/WinMain.cpp b/src/WinGetServer/WinMain.cpp index c994ff842f..ace2332ea1 100644 --- a/src/WinGetServer/WinMain.cpp +++ b/src/WinGetServer/WinMain.cpp @@ -35,7 +35,8 @@ HRESULT WindowsPackageManagerServerInitializeRPCServer() RETURN_HR_IF(HRESULT_FROM_WIN32(status), status != RPC_S_OK); wil::unique_hlocal_security_descriptor securityDescriptor; - RETURN_LAST_ERROR_IF(!ConvertStringSecurityDescriptorToSecurityDescriptorA("S:(ML;;NW;;;HI)D:(A;;GA;;;PS)", SDDL_REVISION_1, &securityDescriptor, nullptr)); + std::string securityDescriptorString = "S:(ML;;NW;;;HI)D:(A;;GA;;;" + userSID + ")"; + RETURN_LAST_ERROR_IF(!ConvertStringSecurityDescriptorToSecurityDescriptorA(securityDescriptorString.c_str(), SDDL_REVISION_1, &securityDescriptor, nullptr)); status = RpcServerRegisterIf3(WinGetServerManualActivation_v1_0_s_ifspec, nullptr, nullptr, RPC_IF_ALLOW_LOCAL_ONLY | RPC_IF_AUTOLISTEN, RPC_C_LISTEN_MAX_CALLS_DEFAULT, 0, nullptr, securityDescriptor.get()); RETURN_HR_IF(HRESULT_FROM_WIN32(status), status != RPC_S_OK); From bd9635321114a06788c89de43b9abbc886f4b7a0 Mon Sep 17 00:00:00 2001 From: Ryan Fu Date: Fri, 4 Nov 2022 12:25:00 -0700 Subject: [PATCH 12/49] fix spacing --- azure-pipelines.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 49bb256ba4..4d9c2aa117 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -168,15 +168,15 @@ jobs: # testResultsFormat: 'JUnit' # testResultsFiles: '$(artifactsDir)\TEST-*.xml' # failTaskOnFailedTests: true - + - task: PowerShell@2 displayName: Check PowerShell Core version inputs: - targetType: 'inline' - script: | - # Checking PowerShell version - pwsh - $env:path -split ';' + targetType: 'inline' + script: | + # Checking PowerShell version + pwsh + $env:path -split ';' - task: DownloadSecureFile@1 name: AppInstallerTest From 04524b65efb0a11756e0a9302a84f081cad37145 Mon Sep 17 00:00:00 2001 From: Ryan Fu Date: Fri, 4 Nov 2022 14:05:00 -0700 Subject: [PATCH 13/49] run module in powershell task --- azure-pipelines.yml | 11 ++++++++--- .../PowerShell/PowerShellModule.cs | 11 ++++------- src/AppInstallerCLIE2ETests/TestCommon.cs | 2 +- 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 4d9c2aa117..5e5ed74b68 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -174,9 +174,14 @@ jobs: inputs: targetType: 'inline' script: | - # Checking PowerShell version - pwsh - $env:path -split ';' + # Import PowerShell Module + ipmo 'D:\a\1\s\src\x64\Release\PowerShell\Microsoft.WinGet.Client.psd1' + # Run Basic powershell commands + Get-WinGetVersion + Get-WinGetSource + Find-WinGetPackage + pwsh: true + - task: DownloadSecureFile@1 name: AppInstallerTest diff --git a/src/AppInstallerCLIE2ETests/PowerShell/PowerShellModule.cs b/src/AppInstallerCLIE2ETests/PowerShell/PowerShellModule.cs index f22ce390ce..190c5ded34 100644 --- a/src/AppInstallerCLIE2ETests/PowerShell/PowerShellModule.cs +++ b/src/AppInstallerCLIE2ETests/PowerShell/PowerShellModule.cs @@ -13,9 +13,6 @@ public class PowerShellModule [OneTimeSetUp] public void Setup() { - // install powershell prior to running module tests. - TestCommon.RunAICLICommand("install", $"--id Microsoft.PowerShell"); - // Add-WinGetPackage is a function and not a cmdlet that uses COM. Add source to WinGetDev directly to ensure test source exists. TestCommon.RunAICLICommand("source add", $"-n {Constants.TestSourceName} {Constants.TestSourceUrl}"); } @@ -31,7 +28,7 @@ public void TearDown() public void GetWinGetSource() { var getSourceResult = TestCommon.RunPowerShellCommandWithResult(Constants.GetSourceCmdlet, $"-Name {Constants.TestSourceName}"); - Assert.IsTrue(getSourceResult.ExitCode == 0, $"Failed with the following output: {getSourceResult.StdOut}"); + Assert.IsTrue(getSourceResult.ExitCode == 0, $"ExitCode: {getSourceResult.ExitCode} Failed with the following output: {getSourceResult.StdOut}, {getSourceResult.StdErr}"); Assert.IsTrue(getSourceResult.StdOut.Contains($"{Constants.TestSourceName}")); } @@ -39,7 +36,7 @@ public void GetWinGetSource() public void FindWinGetPackage() { var result = TestCommon.RunPowerShellCommandWithResult(Constants.FindCmdlet, $"-Id {Constants.ExeInstallerPackageId}"); - Assert.IsTrue(result.ExitCode == 0, $"Failed with the following output: {result.StdOut}"); + Assert.IsTrue(result.ExitCode == 0, $"ExitCode: {result.ExitCode} Failed with the following output: {result.StdOut}; {result.StdErr}"); Assert.IsTrue(result.StdOut.Contains("TestExeInstaller")); } @@ -50,7 +47,7 @@ public void GetWinGetPackage() var getResult = TestCommon.RunPowerShellCommandWithResult(Constants.GetCmdlet, $"-Id {Constants.MsiInstallerPackageId}"); var uninstallResult = TestCommon.RunPowerShellCommandWithResult(Constants.UninstallCmdlet, $"-Id {Constants.MsiInstallerPackageId}"); - Assert.IsTrue(installResult.ExitCode == 0, $"Failed with the following output: {installResult.StdOut}"); + Assert.IsTrue(installResult.ExitCode == 0, $"ExitCode: {installResult.ExitCode}; Failed with the following output: {installResult.StdOut}; {installResult.StdErr}"); Assert.IsTrue(getResult.ExitCode == 0, $"Failed with the following output: {getResult.StdOut}"); Assert.IsTrue(uninstallResult.ExitCode == 0, $"Failed with the following output: {uninstallResult.StdOut}"); @@ -65,7 +62,7 @@ public void InstallWinGetPackage() var installResult = TestCommon.RunPowerShellCommandWithResult(Constants.InstallCmdlet, $"-Id {Constants.ExeInstallerPackageId}"); var uninstallResult = TestCommon.RunPowerShellCommandWithResult(Constants.UninstallCmdlet, $"-Id {Constants.ExeInstallerPackageId}"); - Assert.IsTrue(installResult.ExitCode == 0, $"Failed with the following output: {installResult.StdOut}"); + Assert.IsTrue(installResult.ExitCode == 0, $"ExitCode: {installResult.ExitCode}; Failed with the following output: {installResult.StdOut}; {installResult.StdErr}"); Assert.IsTrue(uninstallResult.ExitCode == 0, $"Failed with the following output: {uninstallResult.StdOut}"); Assert.IsTrue(!string.IsNullOrEmpty(installResult.StdOut)); diff --git a/src/AppInstallerCLIE2ETests/TestCommon.cs b/src/AppInstallerCLIE2ETests/TestCommon.cs index 3ed097643e..4b3574cef8 100644 --- a/src/AppInstallerCLIE2ETests/TestCommon.cs +++ b/src/AppInstallerCLIE2ETests/TestCommon.cs @@ -256,7 +256,7 @@ public static RunCommandResult RunCommandWithResult(string fileName, string args public static RunCommandResult RunPowerShellCommandWithResult(string cmdlet, string args, int timeOut = 60000) { - return RunCommandWithResult("pwsh", $"-Command ipmo {PowerShellModulePath}; {cmdlet} {args}", timeOut); + return RunCommandWithResult("pwsh.exe", $"-Command ipmo {PowerShellModulePath}; {cmdlet} {args}", timeOut); } public static string GetTestFile(string fileName) From 0b68135e8dcc6b2fca14f5181b209e9504b53e2b Mon Sep 17 00:00:00 2001 From: Ryan Fu Date: Fri, 4 Nov 2022 14:47:06 -0700 Subject: [PATCH 14/49] install test package --- azure-pipelines.yml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 5e5ed74b68..d99872fd61 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -168,6 +168,13 @@ jobs: # testResultsFormat: 'JUnit' # testResultsFiles: '$(artifactsDir)\TEST-*.xml' # failTaskOnFailedTests: true + - task: PowerShell@2 + displayName: Install Winget Test Package for Powershell Module tests + inputs: + targetType: 'inline' + script: | + Add-AppxPackage AppInstallerCLIPackage_0.0.2.0_Test\AppInstallerCLIPackage_0.0.2.0_$(buildPlatform).msixbundle + workingDirectory: $(appxPackageDir) - task: PowerShell@2 displayName: Check PowerShell Core version @@ -182,7 +189,6 @@ jobs: Find-WinGetPackage pwsh: true - - task: DownloadSecureFile@1 name: AppInstallerTest displayName: 'Download Source Package Certificate' From 76260671ae804310754ff35884b6ca48cb421f67 Mon Sep 17 00:00:00 2001 From: Ryan Fu Date: Fri, 4 Nov 2022 15:57:42 -0700 Subject: [PATCH 15/49] enable verbose logging --- azure-pipelines.yml | 20 ------------------- .../Commands/InstallPackageCommand.cs | 7 ++----- templates/e2e-test.template.yml | 2 ++ 3 files changed, 4 insertions(+), 25 deletions(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index d99872fd61..6dd30e3624 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -168,26 +168,6 @@ jobs: # testResultsFormat: 'JUnit' # testResultsFiles: '$(artifactsDir)\TEST-*.xml' # failTaskOnFailedTests: true - - task: PowerShell@2 - displayName: Install Winget Test Package for Powershell Module tests - inputs: - targetType: 'inline' - script: | - Add-AppxPackage AppInstallerCLIPackage_0.0.2.0_Test\AppInstallerCLIPackage_0.0.2.0_$(buildPlatform).msixbundle - workingDirectory: $(appxPackageDir) - - - task: PowerShell@2 - displayName: Check PowerShell Core version - inputs: - targetType: 'inline' - script: | - # Import PowerShell Module - ipmo 'D:\a\1\s\src\x64\Release\PowerShell\Microsoft.WinGet.Client.psd1' - # Run Basic powershell commands - Get-WinGetVersion - Get-WinGetSource - Find-WinGetPackage - pwsh: true - task: DownloadSecureFile@1 name: AppInstallerTest diff --git a/src/PowerShell/Microsoft.WinGet.Client/Commands/InstallPackageCommand.cs b/src/PowerShell/Microsoft.WinGet.Client/Commands/InstallPackageCommand.cs index e9affbb38b..d918bfae7e 100644 --- a/src/PowerShell/Microsoft.WinGet.Client/Commands/InstallPackageCommand.cs +++ b/src/PowerShell/Microsoft.WinGet.Client/Commands/InstallPackageCommand.cs @@ -4,15 +4,12 @@ // // ----------------------------------------------------------------------------- -#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; + using Windows.System; ///

/// Installs a package from the pipeline or from a configured source. diff --git a/templates/e2e-test.template.yml b/templates/e2e-test.template.yml index 8b36c84506..510cffe76d 100644 --- a/templates/e2e-test.template.yml +++ b/templates/e2e-test.template.yml @@ -19,6 +19,7 @@ steps: overrideTestrunParameters: '-PackagedContext true -AICLIPackagePath $(System.DefaultWorkingDirectory)\src\AppInstallerCLIPackage\bin\$(buildPlatform)\$(buildConfiguration) -AICLIPath AppInstallerCLI\winget.exe + -VerboseLogging true -LooseFileRegistration true -InvokeCommandInDesktopPackage true -StaticFileRootPath $(Agent.TempDirectory)\TestLocalIndex @@ -30,6 +31,7 @@ steps: ${{ else }}: overrideTestrunParameters: '-PackagedContext false -AICLIPath $(System.DefaultWorkingDirectory)\src\AppInstallerCLIPackage\bin\$(buildPlatform)\$(buildConfiguration)\AppInstallerCLI\winget.exe + -VerboseLogging true -InvokeCommandInDesktopPackage false -StaticFileRootPath $(Agent.TempDirectory)\TestLocalIndex -MsiTestInstallerPath $(System.DefaultWorkingDirectory)\src\AppInstallerCLIE2ETests\TestData\AppInstallerTestMsiInstaller.msi From a7a8c787a9d77efa09b6f70b02c6b27a722c3d8d Mon Sep 17 00:00:00 2001 From: Ryan Fu Date: Mon, 7 Nov 2022 10:55:09 -0800 Subject: [PATCH 16/49] fix x86 and add error code to output --- .../Helpers/ComObjectFactory.cs | 18 ++++++++++++------ .../Microsoft.WinGet.Client.csproj | 6 ++++++ .../WinGetServerManualActivation_Client.cpp | 2 +- 3 files changed, 19 insertions(+), 7 deletions(-) diff --git a/src/PowerShell/Microsoft.WinGet.Client/Helpers/ComObjectFactory.cs b/src/PowerShell/Microsoft.WinGet.Client/Helpers/ComObjectFactory.cs index bb1f4b8106..9a6f186868 100644 --- a/src/PowerShell/Microsoft.WinGet.Client/Helpers/ComObjectFactory.cs +++ b/src/PowerShell/Microsoft.WinGet.Client/Helpers/ComObjectFactory.cs @@ -114,14 +114,20 @@ private static T Create(Type type, in Guid iid) int hr = WinGetServerManualActivation_CreateInstance(type.GUID, iid, 0, out instance); - if (hr == ErrorCode.ERROR_FILE_NOT_FOUND) + if (hr != 0) { - throw new Exception(Utilities.ResourceManager.GetString("WinGetPackageNotInstalled")); - } - else if (hr != 0) - { - throw new COMException("Failed to create instance.", hr); + throw new COMException($"Failed with error code {hr}.", hr); } + + //if (hr == ErrorCode.ERROR_FILE_NOT_FOUND) + //{ + // throw new Exception(Utilities.ResourceManager.GetString("WinGetPackageNotInstalled")); + //} + //else if (hr != 0) + //{ + // Console.WriteLine($"Error code: {hr}"); + // throw new COMException("Failed to create instance.", hr); + //} } else { diff --git a/src/PowerShell/Microsoft.WinGet.Client/Microsoft.WinGet.Client.csproj b/src/PowerShell/Microsoft.WinGet.Client/Microsoft.WinGet.Client.csproj index 80c58ad81e..09400c2fed 100644 --- a/src/PowerShell/Microsoft.WinGet.Client/Microsoft.WinGet.Client.csproj +++ b/src/PowerShell/Microsoft.WinGet.Client/Microsoft.WinGet.Client.csproj @@ -91,6 +91,12 @@ + + + + + + diff --git a/src/WinGetServer/WinGetServerManualActivation_Client.cpp b/src/WinGetServer/WinGetServerManualActivation_Client.cpp index 65f85749a3..6e493c3517 100644 --- a/src/WinGetServer/WinGetServerManualActivation_Client.cpp +++ b/src/WinGetServer/WinGetServerManualActivation_Client.cpp @@ -17,7 +17,7 @@ #if USE_PROD_WINGET_SERVER const std::wstring_view s_ServerExePath = L"\\Microsoft\\WindowsApps\\Microsoft.DesktopAppInstaller_8wekyb3d8bbwe\\WindowsPackageManagerServer.exe"; #else -const std::wstring_view s_ServerExePath = L"\\Microsoft\\WindowsApps\\WinGetDevCLI_8wekyb3d8bbwe\\WindowsPackageManagerServerDev.exe"; +const std::wstring_view s_ServerExePath = L"\\Microsoft\\WindowsApps\\WinGetDevCLI_8wekyb3d8bbwe\\asdf\\WindowsPackageManagerServerDev.exe"; #endif _Must_inspect_result_ From 9fe098e4db3f9a2047416d68dc7297d612449ec1 Mon Sep 17 00:00:00 2001 From: Ryan Fu Date: Mon, 7 Nov 2022 11:06:58 -0800 Subject: [PATCH 17/49] fix path --- src/WinGetServer/WinGetServerManualActivation_Client.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/WinGetServer/WinGetServerManualActivation_Client.cpp b/src/WinGetServer/WinGetServerManualActivation_Client.cpp index 6e493c3517..65f85749a3 100644 --- a/src/WinGetServer/WinGetServerManualActivation_Client.cpp +++ b/src/WinGetServer/WinGetServerManualActivation_Client.cpp @@ -17,7 +17,7 @@ #if USE_PROD_WINGET_SERVER const std::wstring_view s_ServerExePath = L"\\Microsoft\\WindowsApps\\Microsoft.DesktopAppInstaller_8wekyb3d8bbwe\\WindowsPackageManagerServer.exe"; #else -const std::wstring_view s_ServerExePath = L"\\Microsoft\\WindowsApps\\WinGetDevCLI_8wekyb3d8bbwe\\asdf\\WindowsPackageManagerServerDev.exe"; +const std::wstring_view s_ServerExePath = L"\\Microsoft\\WindowsApps\\WinGetDevCLI_8wekyb3d8bbwe\\WindowsPackageManagerServerDev.exe"; #endif _Must_inspect_result_ From b9d7affb68e5acca809a9ffed88570459de3d89c Mon Sep 17 00:00:00 2001 From: Ryan Fu Date: Mon, 7 Nov 2022 14:57:07 -0800 Subject: [PATCH 18/49] copy winrt act properly --- .../Microsoft.WinGet.Client.csproj | 10 +- .../Microsoft.WinGet.Client.psd1 | 160 ++++++++++++++++++ 2 files changed, 166 insertions(+), 4 deletions(-) create mode 100644 src/PowerShell/Microsoft.WinGet.Client/ModuleManifest-x86/Microsoft.WinGet.Client.psd1 diff --git a/src/PowerShell/Microsoft.WinGet.Client/Microsoft.WinGet.Client.csproj b/src/PowerShell/Microsoft.WinGet.Client/Microsoft.WinGet.Client.csproj index 09400c2fed..219b4069cd 100644 --- a/src/PowerShell/Microsoft.WinGet.Client/Microsoft.WinGet.Client.csproj +++ b/src/PowerShell/Microsoft.WinGet.Client/Microsoft.WinGet.Client.csproj @@ -79,9 +79,11 @@ - - - + + + + + @@ -94,7 +96,7 @@ - + diff --git a/src/PowerShell/Microsoft.WinGet.Client/ModuleManifest-x86/Microsoft.WinGet.Client.psd1 b/src/PowerShell/Microsoft.WinGet.Client/ModuleManifest-x86/Microsoft.WinGet.Client.psd1 new file mode 100644 index 0000000000..8719d66290 --- /dev/null +++ b/src/PowerShell/Microsoft.WinGet.Client/ModuleManifest-x86/Microsoft.WinGet.Client.psd1 @@ -0,0 +1,160 @@ +# NOTE: This module manifest is only used for explicitly targeting the x86 powershell module and should not be used in production. +# +# 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 = "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 = '' + +} From ddb488b66b9c56d799dfb070c3f341a03e39f2d5 Mon Sep 17 00:00:00 2001 From: Ryan Fu Date: Mon, 7 Nov 2022 17:02:47 -0800 Subject: [PATCH 19/49] fix x86 build output --- azure-pipelines.yml | 6 ++++++ src/AppInstallerCLI.sln | 5 ++--- .../PowerShell/PowerShellModule.cs | 2 +- .../Microsoft.WinGet.Client.csproj | 17 +++++++++++++---- 4 files changed, 22 insertions(+), 8 deletions(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 6dd30e3624..0cf9ddbd65 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -213,6 +213,12 @@ jobs: CleanTargetFolder: false OverWrite: true + - task: PublishPipelineArtifact@1 + displayName: Publish Pipeline Artifacts + inputs: + targetPath: '$(buildOutDir)\PowerShell\' + condition: always() + - template: templates/e2e-test.template.yml parameters: title: "E2E Tests Packaged" diff --git a/src/AppInstallerCLI.sln b/src/AppInstallerCLI.sln index 7b0c805c38..ac3bc91a94 100644 --- a/src/AppInstallerCLI.sln +++ b/src/AppInstallerCLI.sln @@ -990,8 +990,8 @@ Global {31ED69A8-5310-45A9-953F-56C351D2C3E1}.Release|ARM64.ActiveCfg = Debug|Win32 {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}.Release|x86.ActiveCfg = Release|Win32 + {31ED69A8-5310-45A9-953F-56C351D2C3E1}.Release|x86.Build.0 = Release|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 @@ -1094,7 +1094,6 @@ Global ManifestSchema\ManifestSchema.vcxitems*{1622da16-914f-4f57-a259-d5169003cc8c}*SharedItemsImports = 4 Valijson\Valijson.vcxitems*{1c6e0108-2860-4b17-9f7e-fa5c6c1f3d3d}*SharedItemsImports = 4 WinGetSchemas\WinGetSchemas.vcxitems*{1c6e0108-2860-4b17-9f7e-fa5c6c1f3d3d}*SharedItemsImports = 4 - COMServer\COMServer.vcxitems*{1cc41a9a-ae66-459d-9210-1e572dd7be69}*SharedItemsImports = 4 binver\binver.vcxitems*{2046b5af-666d-4ce8-8d3e-c32c57908a56}*SharedItemsImports = 4 CertificateResources\CertificateResources.vcxitems*{2046b5af-666d-4ce8-8d3e-c32c57908a56}*SharedItemsImports = 4 COMServer\COMServer.vcxitems*{2046b5af-666d-4ce8-8d3e-c32c57908a56}*SharedItemsImports = 4 diff --git a/src/AppInstallerCLIE2ETests/PowerShell/PowerShellModule.cs b/src/AppInstallerCLIE2ETests/PowerShell/PowerShellModule.cs index 190c5ded34..f8635a74c1 100644 --- a/src/AppInstallerCLIE2ETests/PowerShell/PowerShellModule.cs +++ b/src/AppInstallerCLIE2ETests/PowerShell/PowerShellModule.cs @@ -8,7 +8,7 @@ namespace AppInstallerCLIE2ETests /// /// Basic E2E tests for verifying that behavior of the PowerShell module cmdlets. /// - public class PowerShellModule + public class APowerShellModule { [OneTimeSetUp] public void Setup() diff --git a/src/PowerShell/Microsoft.WinGet.Client/Microsoft.WinGet.Client.csproj b/src/PowerShell/Microsoft.WinGet.Client/Microsoft.WinGet.Client.csproj index 219b4069cd..0b889169d8 100644 --- a/src/PowerShell/Microsoft.WinGet.Client/Microsoft.WinGet.Client.csproj +++ b/src/PowerShell/Microsoft.WinGet.Client/Microsoft.WinGet.Client.csproj @@ -74,10 +74,9 @@ 10.0.17763.0 - + - - + @@ -85,6 +84,16 @@ + + + + + + + + + + @@ -94,7 +103,7 @@ - + From 987fad6dcd9ac48ae5e438e68736fa262f141900 Mon Sep 17 00:00:00 2001 From: Ryan Fu Date: Tue, 8 Nov 2022 15:42:07 -0800 Subject: [PATCH 20/49] add com tracing --- azure-pipelines.yml | 14 +++++++++++++- src/AppInstallerCLI.sln | 1 + src/PowerShell/ComTrace.wprp | 35 +++++++++++++++++++++++++++++++++++ 3 files changed, 49 insertions(+), 1 deletion(-) create mode 100644 src/PowerShell/ComTrace.wprp diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 0cf9ddbd65..8917ddd2a6 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -213,8 +213,20 @@ jobs: CleanTargetFolder: false OverWrite: true + - task: PowerShell@2 + displayName: Run wpf for com trace logging + inputs: + targetType: 'inline' + script: | + wpr -start $(Build.SourcesDirectory)\src\PowerShell\ComTrace.wprp -filemode + ipmo $(buildOutDir)\PowerShell\Microsoft.WinGet.Client.psd1 + Find-WinGetPackage + wpr -stop .\comtrace.etl + pwsh: true + workingDirectory: '$(buildOutDir)\PowerShell\' + - task: PublishPipelineArtifact@1 - displayName: Publish Pipeline Artifacts + displayName: Publish powershell artifacts inputs: targetPath: '$(buildOutDir)\PowerShell\' condition: always() diff --git a/src/AppInstallerCLI.sln b/src/AppInstallerCLI.sln index ac3bc91a94..586c513883 100644 --- a/src/AppInstallerCLI.sln +++ b/src/AppInstallerCLI.sln @@ -1094,6 +1094,7 @@ Global ManifestSchema\ManifestSchema.vcxitems*{1622da16-914f-4f57-a259-d5169003cc8c}*SharedItemsImports = 4 Valijson\Valijson.vcxitems*{1c6e0108-2860-4b17-9f7e-fa5c6c1f3d3d}*SharedItemsImports = 4 WinGetSchemas\WinGetSchemas.vcxitems*{1c6e0108-2860-4b17-9f7e-fa5c6c1f3d3d}*SharedItemsImports = 4 + COMServer\COMServer.vcxitems*{1cc41a9a-ae66-459d-9210-1e572dd7be69}*SharedItemsImports = 4 binver\binver.vcxitems*{2046b5af-666d-4ce8-8d3e-c32c57908a56}*SharedItemsImports = 4 CertificateResources\CertificateResources.vcxitems*{2046b5af-666d-4ce8-8d3e-c32c57908a56}*SharedItemsImports = 4 COMServer\COMServer.vcxitems*{2046b5af-666d-4ce8-8d3e-c32c57908a56}*SharedItemsImports = 4 diff --git a/src/PowerShell/ComTrace.wprp b/src/PowerShell/ComTrace.wprp new file mode 100644 index 0000000000..b7f3c9d700 --- /dev/null +++ b/src/PowerShell/ComTrace.wprp @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From f0836e6379f881ec52aee958e01dfdf1f9b1a89c Mon Sep 17 00:00:00 2001 From: Ryan Fu Date: Tue, 8 Nov 2022 16:26:50 -0800 Subject: [PATCH 21/49] continue on error --- azure-pipelines.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 8917ddd2a6..1cc07d3597 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -223,6 +223,7 @@ jobs: Find-WinGetPackage wpr -stop .\comtrace.etl pwsh: true + errorActionPreference: continue workingDirectory: '$(buildOutDir)\PowerShell\' - task: PublishPipelineArtifact@1 From 9590eaef8643ec853576701d5f9fafb6e28d8e87 Mon Sep 17 00:00:00 2001 From: Ryan Fu Date: Wed, 9 Nov 2022 10:59:27 -0800 Subject: [PATCH 22/49] comment out e2e tests --- azure-pipelines.yml | 23 +- .../FeaturesCommand.cs | 4 +- src/AppInstallerCLIE2ETests/GroupPolicy.cs | 20 +- src/AppInstallerCLIE2ETests/HashCommand.cs | 8 +- src/AppInstallerCLIE2ETests/ImportCommand.cs | 266 +++--- src/AppInstallerCLIE2ETests/InstallCommand.cs | 892 +++++++++--------- src/AppInstallerCLIE2ETests/ListCommand.cs | 222 ++--- .../PowerShell/PowerShellModule.cs | 8 +- src/AppInstallerCLIE2ETests/SearchCommand.cs | 310 +++--- src/AppInstallerCLIE2ETests/ShowCommand.cs | 168 ++-- src/AppInstallerCLIE2ETests/SourceCommand.cs | 278 +++--- .../UninstallCommand.cs | 290 +++--- src/AppInstallerCLIE2ETests/UpgradeCommand.cs | 272 +++--- .../ValidateCommand.cs | 74 +- .../WinGetUtil/WinGetUtilCompareVersions.cs | 62 +- .../WinGetUtil/WinGetUtilDownload.cs | 46 +- .../WinGetUtilInstallerMetadataCollection.cs | 130 +-- .../WinGetUtil/WinGetUtilLog.cs | 2 +- .../WinGetUtil/WinGetUtilManifest.cs | 116 +-- .../WinGetUtil/WinGetUtilSQLiteIndex.cs | 278 +++--- 20 files changed, 1738 insertions(+), 1731 deletions(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 1cc07d3597..cb4666e2ad 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -219,8 +219,21 @@ jobs: targetType: 'inline' script: | wpr -start $(Build.SourcesDirectory)\src\PowerShell\ComTrace.wprp -filemode - ipmo $(buildOutDir)\PowerShell\Microsoft.WinGet.Client.psd1 - Find-WinGetPackage + pwsh: true + errorActionPreference: continue + workingDirectory: '$(buildOutDir)\PowerShell\' + + - template: templates/e2e-test.template.yml + parameters: + title: "E2E Tests Packaged" + isPackaged: true + filter: "TestCategory!=InProcess&TestCategory!=OutOfProcess" + + - task: PowerShell@2 + displayName: Run wpf for com trace logging + inputs: + targetType: 'inline' + script: | wpr -stop .\comtrace.etl pwsh: true errorActionPreference: continue @@ -232,12 +245,6 @@ jobs: targetPath: '$(buildOutDir)\PowerShell\' condition: always() - - template: templates/e2e-test.template.yml - parameters: - title: "E2E Tests Packaged" - isPackaged: true - filter: "TestCategory!=InProcess&TestCategory!=OutOfProcess" - - task: PowerShell@2 displayName: 'Set program files directory' inputs: diff --git a/src/AppInstallerCLIE2ETests/FeaturesCommand.cs b/src/AppInstallerCLIE2ETests/FeaturesCommand.cs index 52551dc4df..ab8e00a607 100644 --- a/src/AppInstallerCLIE2ETests/FeaturesCommand.cs +++ b/src/AppInstallerCLIE2ETests/FeaturesCommand.cs @@ -19,7 +19,7 @@ public void TearDown() InitializeAllFeatures(false); } - [Test] + //[Test] public void DisplayFeatures() { var result = TestCommon.RunAICLICommand("features", ""); @@ -28,7 +28,7 @@ public void DisplayFeatures() Assert.False(result.StdOut.Contains("Enabled")); } - [Test] + //[Test] public void EnableExperimentalFeatures() { ConfigureFeature("experimentalArg", true); diff --git a/src/AppInstallerCLIE2ETests/GroupPolicy.cs b/src/AppInstallerCLIE2ETests/GroupPolicy.cs index b869960802..0d3488b011 100644 --- a/src/AppInstallerCLIE2ETests/GroupPolicy.cs +++ b/src/AppInstallerCLIE2ETests/GroupPolicy.cs @@ -25,7 +25,7 @@ public void TearDown() GroupPolicyHelper.DeleteExistingPolicies(); } - [Test] + //[Test] public void PolicyEnableWinget() { GroupPolicyHelper.EnableWinget.Disable(); @@ -33,7 +33,7 @@ public void PolicyEnableWinget() Assert.AreEqual(Constants.ErrorCode.ERROR_BLOCKED_BY_POLICY, result.ExitCode); } - [Test] + //[Test] public void EnableSettings() { GroupPolicyHelper.EnableSettings.Disable(); @@ -41,7 +41,7 @@ public void EnableSettings() Assert.AreEqual(Constants.ErrorCode.ERROR_BLOCKED_BY_POLICY, result.ExitCode); } - [Test] + //[Test] public void EnableExperimentalFeatures() { ConfigureFeature("experimentalCmd", true); @@ -55,7 +55,7 @@ public void EnableExperimentalFeatures() Assert.AreEqual(Constants.ErrorCode.ERROR_INVALID_CL_ARGUMENTS, result.ExitCode); } - [Test] + //[Test] public void EnableLocalManifests() { GroupPolicyHelper.EnableLocalManifests.Disable(); @@ -63,7 +63,7 @@ public void EnableLocalManifests() Assert.AreEqual(Constants.ErrorCode.ERROR_BLOCKED_BY_POLICY, result.ExitCode); } - [Test] + //[Test] public void EnableHashOverride() { GroupPolicyHelper.EnableHashOverride.Disable(); @@ -71,7 +71,7 @@ public void EnableHashOverride() Assert.AreEqual(Constants.ErrorCode.ERROR_BLOCKED_BY_POLICY, result.ExitCode); } - [Test] + //[Test] public void EnableDefaultSource() { // Default sources are disabled during setup so they are missing. @@ -83,7 +83,7 @@ public void EnableDefaultSource() Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); } - [Test] + //[Test] public void EnableMicrosoftStoreSource() { // Default sources are disabled during setup so they are missing. @@ -95,7 +95,7 @@ public void EnableMicrosoftStoreSource() Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); } - [Test] + //[Test] public void EnableAdditionalSources() { // Remove the test source, then add it with policy. @@ -112,7 +112,7 @@ public void EnableAdditionalSources() Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); } - [Test] + //[Test] public void EnableAllowedSources() { // Try listing the test source. We should only see it if it is allowed. @@ -140,7 +140,7 @@ public void EnableAllowedSources() Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); } - [Test] + //[Test] public void SourceAutoUpdateInterval() { // Test this policy by inspecting the result of --info diff --git a/src/AppInstallerCLIE2ETests/HashCommand.cs b/src/AppInstallerCLIE2ETests/HashCommand.cs index f8525ed3ba..0806dc2845 100644 --- a/src/AppInstallerCLIE2ETests/HashCommand.cs +++ b/src/AppInstallerCLIE2ETests/HashCommand.cs @@ -8,7 +8,7 @@ namespace AppInstallerCLIE2ETests public class HashCommand : BaseCommand { - [Test] + //[Test] public void HashFile() { var result = TestCommon.RunAICLICommand("hash", TestCommon.GetTestDataFile("AppInstallerTest.cer")); @@ -16,7 +16,7 @@ public void HashFile() Assert.True(result.StdOut.Contains("9b4c49ad7e47afd97d2e666e93347745e1647c55f1a7ebba6d31b7dd5f69ee68")); } - [Test] + //[Test] public void HashMSIX() { var result = TestCommon.RunAICLICommand("hash", TestCommon.GetTestDataFile(Constants.TestPackage) + " -m"); @@ -25,7 +25,7 @@ public void HashMSIX() Assert.True(result.StdOut.Contains("223b318c4b1154a1fb72b1bc23422810faa5ce899a8e774ba2a02834b2058f00")); } - [Test] + //[Test] public void HashInvalidMSIX() { var result = TestCommon.RunAICLICommand("hash", TestCommon.GetTestDataFile("AppInstallerTest.cer") + " -m"); @@ -34,7 +34,7 @@ public void HashInvalidMSIX() Assert.True(result.StdOut.Contains("Please verify that the input file is a valid, signed MSIX.")); } - [Test] + //[Test] public void HashFileNotFound() { var result = TestCommon.RunAICLICommand("hash", TestCommon.GetTestDataFile("DoesNot.Exist")); diff --git a/src/AppInstallerCLIE2ETests/ImportCommand.cs b/src/AppInstallerCLIE2ETests/ImportCommand.cs index 4f60fed0fc..716f48f203 100644 --- a/src/AppInstallerCLIE2ETests/ImportCommand.cs +++ b/src/AppInstallerCLIE2ETests/ImportCommand.cs @@ -1,133 +1,133 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -namespace AppInstallerCLIE2ETests -{ - using System.IO; - using NUnit.Framework; - - public class ImportCommand : BaseCommand - { - [SetUp] - public void Setup() - { - CleanupTestExe(); - } - - [Test] - public void ImportSuccessful_1_0() - { - var result = TestCommon.RunAICLICommand("import", GetTestImportFile("ImportFile-Good.1.0.json")); - Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); - Assert.True(VerifyTestExeInstalled()); - UninstallTestExe(); - } - - [Test] - public void ImportSuccessful_2_0() - { - var result = TestCommon.RunAICLICommand("import", GetTestImportFile("ImportFile-Good.2.0.json")); - Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); - Assert.True(VerifyTestExeInstalled()); - UninstallTestExe(); - } - - // Ignore while we don't have schema validation - [Test] - public void ImportInvalidFile() - { - // Verify failure when trying to import with an invalid file - var result = TestCommon.RunAICLICommand("import", GetTestImportFile("ImportFile-Bad-Invalid.json")); - Assert.AreEqual(Constants.ErrorCode.ERROR_JSON_INVALID_FILE, result.ExitCode); - Assert.True(result.StdOut.Contains("JSON file is not valid")); - } - - [Test] - public void ImportUnknownSource() - { - // Verify failure when trying to import from an unknown source - var result = TestCommon.RunAICLICommand("import", GetTestImportFile("ImportFile-Bad-UnknownSource.json")); - Assert.AreEqual(Constants.ErrorCode.ERROR_SOURCE_NAME_DOES_NOT_EXIST, result.ExitCode); - Assert.True(result.StdOut.Contains("Source required for import is not installed")); - } - - [Test] - public void ImportUnavailablePackage() - { - // Verify failure when trying to import an unavailable package - var result = TestCommon.RunAICLICommand("import", GetTestImportFile("ImportFile-Bad-UnknownPackage.json")); - Assert.AreEqual(Constants.ErrorCode.ERROR_NOT_ALL_PACKAGES_FOUND, result.ExitCode); - Assert.True(result.StdOut.Contains("Package not found for import")); - } - - [Test] - public void ImportUnavailableVersion() - { - // Verify failure when trying to import an unavailable package - var result = TestCommon.RunAICLICommand("import", GetTestImportFile("ImportFile-Bad-UnknownPackageVersion.json")); - Assert.AreEqual(Constants.ErrorCode.ERROR_NOT_ALL_PACKAGES_FOUND, result.ExitCode); - Assert.True(result.StdOut.Contains("Package not found for import")); - } - - [Test] - public void ImportAlreadyInstalled() - { - // Verify success with message when trying to import a package that is already installed - var installDir = TestCommon.GetRandomTestDir(); - TestCommon.RunAICLICommand("install", $"AppInstallerTest.TestExeInstaller -l {installDir}"); - var result = TestCommon.RunAICLICommand("import", $"{GetTestImportFile("ImportFile-Good.1.0.json")}"); - Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); - Assert.True(result.StdOut.Contains("Package is already installed")); - Assert.False(VerifyTestExeInstalled()); - UninstallTestExe(); - } - - [Test] - public void ImportExportedFile() - { - // Verify success when importing an exported list of packages. - // First install the test package to ensure it is exported. - TestCommon.RunAICLICommand("install", Constants.ExeInstallerPackageId); - - var jsonFile = TestCommon.GetRandomTestFile(".json"); - TestCommon.RunAICLICommand("export", $"{jsonFile} -s TestSource"); - - // Uninstall the package to ensure we can install it again - UninstallTestExe(); - - // Import the file - var result = TestCommon.RunAICLICommand("import", jsonFile); - Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); - Assert.True(VerifyTestExeInstalled()); - UninstallTestExe(); - } - - private string GetTestImportFile(string importFileName) - { - return TestCommon.GetTestDataFile(Path.Combine("ImportFiles", importFileName)); - } - - private bool VerifyTestExeInstalled(string installDir = null) - { - if (string.IsNullOrEmpty(installDir)) - { - // Default location used by installer - installDir = Path.GetTempPath(); - } - - return File.Exists(Path.Combine(installDir, Constants.TestExeInstalledFileName)); - } - - private void UninstallTestExe() - { - TestCommon.RunAICLICommand("uninstall", Constants.ExeInstallerPackageId); - } - - private void CleanupTestExe() - { - UninstallTestExe(); - File.Delete(Path.Combine(Path.GetTempPath(), Constants.TestExeInstalledFileName)); - File.Delete(Path.Combine(Path.GetTempPath(), Constants.TestExeUninstallerFileName)); - } - } -} \ No newline at end of file +//// Copyright (c) Microsoft Corporation. +//// Licensed under the MIT License. + +//namespace AppInstallerCLIE2ETests +//{ +// using System.IO; +// using NUnit.Framework; + +// public class ImportCommand : BaseCommand +// { +// [SetUp] +// public void Setup() +// { +// CleanupTestExe(); +// } + +// [Test] +// public void ImportSuccessful_1_0() +// { +// var result = TestCommon.RunAICLICommand("import", GetTestImportFile("ImportFile-Good.1.0.json")); +// Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); +// Assert.True(VerifyTestExeInstalled()); +// UninstallTestExe(); +// } + +// [Test] +// public void ImportSuccessful_2_0() +// { +// var result = TestCommon.RunAICLICommand("import", GetTestImportFile("ImportFile-Good.2.0.json")); +// Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); +// Assert.True(VerifyTestExeInstalled()); +// UninstallTestExe(); +// } + +// // Ignore while we don't have schema validation +// [Test] +// public void ImportInvalidFile() +// { +// // Verify failure when trying to import with an invalid file +// var result = TestCommon.RunAICLICommand("import", GetTestImportFile("ImportFile-Bad-Invalid.json")); +// Assert.AreEqual(Constants.ErrorCode.ERROR_JSON_INVALID_FILE, result.ExitCode); +// Assert.True(result.StdOut.Contains("JSON file is not valid")); +// } + +// [Test] +// public void ImportUnknownSource() +// { +// // Verify failure when trying to import from an unknown source +// var result = TestCommon.RunAICLICommand("import", GetTestImportFile("ImportFile-Bad-UnknownSource.json")); +// Assert.AreEqual(Constants.ErrorCode.ERROR_SOURCE_NAME_DOES_NOT_EXIST, result.ExitCode); +// Assert.True(result.StdOut.Contains("Source required for import is not installed")); +// } + +// [Test] +// public void ImportUnavailablePackage() +// { +// // Verify failure when trying to import an unavailable package +// var result = TestCommon.RunAICLICommand("import", GetTestImportFile("ImportFile-Bad-UnknownPackage.json")); +// Assert.AreEqual(Constants.ErrorCode.ERROR_NOT_ALL_PACKAGES_FOUND, result.ExitCode); +// Assert.True(result.StdOut.Contains("Package not found for import")); +// } + +// [Test] +// public void ImportUnavailableVersion() +// { +// // Verify failure when trying to import an unavailable package +// var result = TestCommon.RunAICLICommand("import", GetTestImportFile("ImportFile-Bad-UnknownPackageVersion.json")); +// Assert.AreEqual(Constants.ErrorCode.ERROR_NOT_ALL_PACKAGES_FOUND, result.ExitCode); +// Assert.True(result.StdOut.Contains("Package not found for import")); +// } + +// [Test] +// public void ImportAlreadyInstalled() +// { +// // Verify success with message when trying to import a package that is already installed +// var installDir = TestCommon.GetRandomTestDir(); +// TestCommon.RunAICLICommand("install", $"AppInstallerTest.TestExeInstaller -l {installDir}"); +// var result = TestCommon.RunAICLICommand("import", $"{GetTestImportFile("ImportFile-Good.1.0.json")}"); +// Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); +// Assert.True(result.StdOut.Contains("Package is already installed")); +// Assert.False(VerifyTestExeInstalled()); +// UninstallTestExe(); +// } + +// [Test] +// public void ImportExportedFile() +// { +// // Verify success when importing an exported list of packages. +// // First install the test package to ensure it is exported. +// TestCommon.RunAICLICommand("install", Constants.ExeInstallerPackageId); + +// var jsonFile = TestCommon.GetRandomTestFile(".json"); +// TestCommon.RunAICLICommand("export", $"{jsonFile} -s TestSource"); + +// // Uninstall the package to ensure we can install it again +// UninstallTestExe(); + +// // Import the file +// var result = TestCommon.RunAICLICommand("import", jsonFile); +// Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); +// Assert.True(VerifyTestExeInstalled()); +// UninstallTestExe(); +// } + +// private string GetTestImportFile(string importFileName) +// { +// return TestCommon.GetTestDataFile(Path.Combine("ImportFiles", importFileName)); +// } + +// private bool VerifyTestExeInstalled(string installDir = null) +// { +// if (string.IsNullOrEmpty(installDir)) +// { +// // Default location used by installer +// installDir = Path.GetTempPath(); +// } + +// return File.Exists(Path.Combine(installDir, Constants.TestExeInstalledFileName)); +// } + +// private void UninstallTestExe() +// { +// TestCommon.RunAICLICommand("uninstall", Constants.ExeInstallerPackageId); +// } + +// private void CleanupTestExe() +// { +// UninstallTestExe(); +// File.Delete(Path.Combine(Path.GetTempPath(), Constants.TestExeInstalledFileName)); +// File.Delete(Path.Combine(Path.GetTempPath(), Constants.TestExeUninstallerFileName)); +// } +// } +//} \ No newline at end of file diff --git a/src/AppInstallerCLIE2ETests/InstallCommand.cs b/src/AppInstallerCLIE2ETests/InstallCommand.cs index 595dab05a1..245c3c7d0a 100644 --- a/src/AppInstallerCLIE2ETests/InstallCommand.cs +++ b/src/AppInstallerCLIE2ETests/InstallCommand.cs @@ -1,446 +1,446 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -namespace AppInstallerCLIE2ETests -{ - using NUnit.Framework; - using System.IO; - - public class InstallCommand : BaseCommand - { - [OneTimeSetUp] - public void OneTimeSetup() - { - ConfigureFeature("zipInstall", true); - } - - [SetUp] - public void Setup() - { - // Try clean up TestExeInstaller for failure cases where cleanup is not successful - TestCommon.RunAICLICommand("uninstall", "AppInstallerTest.TestExeInstaller"); - } - - [Test] - public void InstallAppDoesNotExist() - { - var result = TestCommon.RunAICLICommand("install", "DoesNotExist"); - Assert.AreEqual(Constants.ErrorCode.ERROR_NO_APPLICATIONS_FOUND, result.ExitCode); - Assert.True(result.StdOut.Contains("No package found matching input criteria.")); - } - - [Test] - public void InstallWithMultipleAppsMatchingQuery() - { - var result = TestCommon.RunAICLICommand("install", "TestExeInstaller"); - Assert.AreEqual(Constants.ErrorCode.ERROR_MULTIPLE_APPLICATIONS_FOUND, result.ExitCode); - Assert.True(result.StdOut.Contains("Multiple packages found matching input criteria. Please refine the input.")); - } - - [Test] - public void InstallExe() - { - var installDir = TestCommon.GetRandomTestDir(); - var result = TestCommon.RunAICLICommand("install", $"AppInstallerTest.TestExeInstaller --silent -l {installDir}"); - Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); - Assert.True(result.StdOut.Contains("Successfully installed")); - Assert.True(TestCommon.VerifyTestExeInstalledAndCleanup(installDir, "/execustom")); - } - - [Test] - public void InstallExeWithInsufficientMinOsVersion() - { - var installDir = TestCommon.GetRandomTestDir(); - var result = TestCommon.RunAICLICommand("install", $"InapplicableOsVersion --silent -l {installDir}"); - // MinOSVersion is moved to installer level, the check is performed during installer selection - Assert.AreEqual(Constants.ErrorCode.ERROR_NO_APPLICABLE_INSTALLER, result.ExitCode); - Assert.False(TestCommon.VerifyTestExeInstalledAndCleanup(installDir)); - } - - [Test] - public void InstallExeWithHashMismatch() - { - var installDir = TestCommon.GetRandomTestDir(); - var result = TestCommon.RunAICLICommand("install", $"TestExeSha256Mismatch --silent -l {installDir}"); - Assert.AreEqual(Constants.ErrorCode.ERROR_INSTALLER_HASH_MISMATCH, result.ExitCode); - Assert.True(result.StdOut.Contains("Installer hash does not match")); - Assert.False(TestCommon.VerifyTestExeInstalledAndCleanup(installDir)); - } - - [Test] - public void InstallWithInno() - { - // Install test inno, manifest does not provide silent switch, we should be populating the default - var installDir = TestCommon.GetRandomTestDir(); - var result = TestCommon.RunAICLICommand("install", $"TestInnoInstaller --silent -l {installDir}"); - Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); - Assert.True(result.StdOut.Contains("Successfully installed")); - Assert.True(TestCommon.VerifyTestExeInstalledAndCleanup(installDir, "/VERYSILENT")); - } - - [Test] - public void InstallBurn() - { - // Install test burn, manifest does not provide silent switch, we should be populating the default - var installDir = TestCommon.GetRandomTestDir(); - var result = TestCommon.RunAICLICommand("install", $"TestBurnInstaller --silent -l {installDir}"); - Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); - Assert.True(result.StdOut.Contains("Successfully installed")); - Assert.True(TestCommon.VerifyTestExeInstalledAndCleanup(installDir, "/quiet")); - } - - [Test] - public void InstallNullSoft() - { - // Install test Nullsoft, manifest does not provide silent switch, we should be populating the default - var installDir = TestCommon.GetRandomTestDir(); - var result = TestCommon.RunAICLICommand("install", $"TestNullsoftInstaller --silent -l {installDir}"); - Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); - Assert.True(result.StdOut.Contains("Successfully installed")); - Assert.True(TestCommon.VerifyTestExeInstalledAndCleanup(installDir, "/S")); - } - - [Test] - public void InstallMSI() - { - var installDir = TestCommon.GetRandomTestDir(); - var result = TestCommon.RunAICLICommand("install", $"TestMsiInstaller --silent -l {installDir}"); - Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); - Assert.True(result.StdOut.Contains("Successfully installed")); - Assert.True(TestCommon.VerifyTestMsiInstalledAndCleanup(installDir)); - } - - [Test] - public void InstallMSIX() - { - var result = TestCommon.RunAICLICommand("install", $"TestMsixInstaller"); - Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); - Assert.True(result.StdOut.Contains("Successfully installed")); - Assert.True(TestCommon.VerifyTestMsixInstalledAndCleanup()); - } - - [Test] - public void InstallMSIXWithSignature() - { - var installDir = TestCommon.GetRandomTestDir(); - var result = TestCommon.RunAICLICommand("install", $"TestMsixWithSignatureHash --silent -l {installDir}"); - Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); - Assert.True(result.StdOut.Contains("Successfully installed")); - Assert.True(TestCommon.VerifyTestMsixInstalledAndCleanup()); - } - - [Test] - public void InstallMSIXWithSignatureHashMismatch() - { - var result = TestCommon.RunAICLICommand("install", $"TestMsixSignatureHashMismatch"); - Assert.AreEqual(Constants.ErrorCode.ERROR_INSTALLER_HASH_MISMATCH, result.ExitCode); - Assert.True(result.StdOut.Contains("Installer hash does not match")); - Assert.False(TestCommon.VerifyTestMsixInstalledAndCleanup()); - } - - [Test] - public void InstallExeWithAlternateSourceFailure() - { - TestCommon.RunAICLICommand("source add", "failSearch \"{ \"\"SearchHR\"\": \"\"0x80070002\"\" }\" Microsoft.Test.Configurable --header \"{}\""); - - try - { - var installDir = TestCommon.GetRandomTestDir(); - var result = TestCommon.RunAICLICommand("install", $"AppInstallerTest.TestExeInstaller --silent -l {installDir}"); - Assert.AreEqual(unchecked((int)0x80070002), result.ExitCode); - Assert.True(result.StdOut.Contains("Failed when searching source: failSearch")); - Assert.True(result.StdOut.Contains("AppInstallerTest.TestExeInstaller")); - Assert.False(result.StdOut.Contains("Successfully installed")); - Assert.False(TestCommon.VerifyTestExeInstalledAndCleanup(installDir)); - } - finally - { - ResetTestSource(); - } - } - - [Test] - public void InstallPortableExe() - { - string installDir = TestCommon.GetPortablePackagesDirectory(); - string packageId, commandAlias, fileName, packageDirName, productCode; - packageId = "AppInstallerTest.TestPortableExe"; - packageDirName = productCode = packageId + "_" + Constants.TestSourceIdentifier; - commandAlias = fileName = "AppInstallerTestExeInstaller.exe"; - - var result = TestCommon.RunAICLICommand("install", $"{packageId}"); - Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); - Assert.True(result.StdOut.Contains("Successfully installed")); - // If no location specified, default behavior is to create a package directory with the name "{packageId}_{sourceId}" - TestCommon.VerifyPortablePackage(Path.Combine(installDir, packageDirName), commandAlias, fileName, productCode, true); - } - - [Test] - public void InstallPortableExeWithCommand() - { - var installDir = TestCommon.GetRandomTestDir(); - string packageId, commandAlias, fileName, productCode; - packageId = "AppInstallerTest.TestPortableExeWithCommand"; - productCode = packageId + "_" + Constants.TestSourceIdentifier; - fileName = "AppInstallerTestExeInstaller.exe"; - commandAlias = "testCommand.exe"; - - var result = TestCommon.RunAICLICommand("install", $"{packageId} -l {installDir}"); - Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); - Assert.True(result.StdOut.Contains("Successfully installed")); - TestCommon.VerifyPortablePackage(installDir, commandAlias, fileName, productCode, true); - } - - [Test] - public void InstallPortableExeWithRename() - { - var installDir = TestCommon.GetRandomTestDir(); - string packageId, productCode, renameArgValue; - packageId = "AppInstallerTest.TestPortableExeWithCommand"; - productCode = packageId + "_" + Constants.TestSourceIdentifier; - renameArgValue = "testRename.exe"; - - var result = TestCommon.RunAICLICommand("install", $"{packageId} -l {installDir} --rename {renameArgValue}"); - Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); - Assert.True(result.StdOut.Contains("Successfully installed")); - TestCommon.VerifyPortablePackage(installDir, renameArgValue, renameArgValue, productCode, true); - } - - [Test] - public void InstallPortableInvalidRename() - { - var installDir = TestCommon.GetRandomTestDir(); - string packageId, renameArgValue; - packageId = "AppInstallerTest.TestPortableExeWithCommand"; - renameArgValue = "test?"; - - var result = TestCommon.RunAICLICommand("install", $"{packageId} -l {installDir} --rename {renameArgValue}"); - Assert.AreNotEqual(Constants.ErrorCode.S_OK, result.ExitCode); - Assert.True(result.StdOut.Contains("The specified filename is not a valid filename")); - } - - [Test] - public void InstallPortableReservedNames() - { - var installDir = TestCommon.GetRandomTestDir(); - string packageId, renameArgValue; - packageId = "AppInstallerTest.TestPortableExeWithCommand"; - renameArgValue = "CON"; - - var result = TestCommon.RunAICLICommand("install", $"{packageId} -l {installDir} --rename {renameArgValue}"); - Assert.AreNotEqual(Constants.ErrorCode.S_OK, result.ExitCode); - Assert.True(result.StdOut.Contains("The specified filename is not a valid filename")); - } - - [Test] - public void InstallPortableToExistingDirectory() - { - var installDir = TestCommon.GetRandomTestDir(); - var existingDir = Path.Combine(installDir, "testDirectory"); - Directory.CreateDirectory(existingDir); - - string packageId, commandAlias, fileName, productCode; - packageId = "AppInstallerTest.TestPortableExe"; - productCode = packageId + "_" + Constants.TestSourceIdentifier; - commandAlias = fileName = "AppInstallerTestExeInstaller.exe"; - - var result = TestCommon.RunAICLICommand("install", $"{packageId} -l {existingDir}"); - Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); - Assert.True(result.StdOut.Contains("Successfully installed")); - TestCommon.VerifyPortablePackage(existingDir, commandAlias, fileName, productCode, true); - } - - [Test] - public void InstallPortableFailsWithCleanup() - { - string packageId, commandAlias; - packageId = "AppInstallerTest.TestPortableExe"; - commandAlias = "AppInstallerTestExeInstaller.exe"; - - // Create a directory with the same name as the symlink in order to cause install to fail. - string symlinkDirectory = TestCommon.GetPortableSymlinkDirectory(TestCommon.Scope.User); - string conflictDirectory = Path.Combine(symlinkDirectory, commandAlias); - - Directory.CreateDirectory(conflictDirectory); - - var result = TestCommon.RunAICLICommand("install", $"{packageId}"); - - // Remove directory prior to assertions as this will impact other tests if assertions fail. - Directory.Delete(conflictDirectory, true); - - Assert.AreNotEqual(Constants.ErrorCode.S_OK, result.ExitCode); - Assert.True(result.StdOut.Contains("Unable to create symlink, path points to a directory.")); - } - - [Test] - public void ReinstallPortable() - { - string installDir = TestCommon.GetPortablePackagesDirectory(); - string packageId, commandAlias, fileName, packageDirName, productCode; - packageId = "AppInstallerTest.TestPortableExe"; - packageDirName = productCode = packageId + "_" + Constants.TestSourceIdentifier; - commandAlias = fileName = "AppInstallerTestExeInstaller.exe"; - - var result = TestCommon.RunAICLICommand("install", $"{packageId}"); - Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); - - string symlinkDirectory = TestCommon.GetPortableSymlinkDirectory(TestCommon.Scope.User); - string symlinkPath = Path.Combine(symlinkDirectory, commandAlias); - - // Clean first install should not display file overwrite message. - Assert.True(result.StdOut.Contains("Successfully installed")); - Assert.False(result.StdOut.Contains($"Overwriting existing file: {symlinkPath}")); - - // Perform second install and verify that file overwrite message is displayed. - var result2 = TestCommon.RunAICLICommand("install", $"{packageId} --force"); - Assert.AreEqual(Constants.ErrorCode.S_OK, result2.ExitCode); - Assert.True(result2.StdOut.Contains("Successfully installed")); - - TestCommon.VerifyPortablePackage(Path.Combine(installDir, packageDirName), commandAlias, fileName, productCode, true); - } - - [Test] - public void InstallPortable_UserScope() - { - string installDir = TestCommon.GetRandomTestDir(); - ConfigureInstallBehavior(Constants.PortablePackageUserRoot, installDir); - - string packageId, commandAlias, fileName, packageDirName, productCode; - packageId = "AppInstallerTest.TestPortableExe"; - packageDirName = productCode = packageId + "_" + Constants.TestSourceIdentifier; - commandAlias = fileName = "AppInstallerTestExeInstaller.exe"; - - var result = TestCommon.RunAICLICommand("install", $"{packageId} --scope user"); - ConfigureInstallBehavior(Constants.PortablePackageUserRoot, string.Empty); - Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); - Assert.True(result.StdOut.Contains("Successfully installed")); - TestCommon.VerifyPortablePackage(Path.Combine(installDir, packageDirName), commandAlias, fileName, productCode, true); - } - - [Test] - public void InstallPortable_MachineScope() - { - string installDir = TestCommon.GetRandomTestDir(); - ConfigureInstallBehavior(Constants.PortablePackageMachineRoot, installDir); - - string packageId, commandAlias, fileName, packageDirName, productCode; - packageId = "AppInstallerTest.TestPortableExe"; - packageDirName = productCode = packageId + "_" + Constants.TestSourceIdentifier; - commandAlias = fileName = "AppInstallerTestExeInstaller.exe"; - - var result = TestCommon.RunAICLICommand("install", $"{packageId} --scope machine"); - ConfigureInstallBehavior(Constants.PortablePackageMachineRoot, string.Empty); - Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); - Assert.True(result.StdOut.Contains("Successfully installed")); - TestCommon.VerifyPortablePackage(Path.Combine(installDir, packageDirName), commandAlias, fileName, productCode, true, TestCommon.Scope.Machine); - } - - [Test] - public void InstallZip_Exe() - { - var installDir = TestCommon.GetRandomTestDir(); - var result = TestCommon.RunAICLICommand("install", $"AppInstallerTest.TestZipInstallerWithExe --silent -l {installDir}"); - Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); - Assert.True(result.StdOut.Contains("Successfully installed")); - Assert.True(TestCommon.VerifyTestExeInstalledAndCleanup(installDir, "/execustom")); - } - - [Test] - public void InstallZip_Portable() - { - string installDir = TestCommon.GetPortablePackagesDirectory(); - string packageId, commandAlias, fileName, packageDirName, productCode; - packageId = "AppInstallerTest.TestZipInstallerWithPortable"; - packageDirName = productCode = packageId + "_" + Constants.TestSourceIdentifier; - commandAlias = "TestPortable.exe"; - fileName = "AppInstallerTestExeInstaller.exe"; - - var result = TestCommon.RunAICLICommand("install", $"{packageId}"); - Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); - Assert.True(result.StdOut.Contains("Successfully installed")); - TestCommon.VerifyPortablePackage(Path.Combine(installDir, packageDirName), commandAlias, fileName, productCode, true, TestCommon.Scope.User); - } - - [Test] - public void InstallZipWithInvalidRelativeFilePath() - { - var result = TestCommon.RunAICLICommand("install", $"AppInstallerTest.TestZipInvalidRelativePath"); - Assert.AreNotEqual(Constants.ErrorCode.S_OK, result.ExitCode); - Assert.True(result.StdOut.Contains("Invalid relative file path to the nested installer; path points to a location outside of the install directory")); - } - - [Test] - public void InstallZipWithMsi() - { - var installDir = TestCommon.GetRandomTestDir(); - var result = TestCommon.RunAICLICommand("install", $"AppInstallerTest.TestZipInstallerWithMsi --silent -l {installDir}"); - Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); - Assert.True(result.StdOut.Contains("Successfully installed")); - Assert.True(TestCommon.VerifyTestMsiInstalledAndCleanup(installDir)); - } - - [Test] - public void InstallZipWithMsix() - { - var result = TestCommon.RunAICLICommand("install", $"AppInstallerTest.TestZipInstallerWithMsix"); - Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); - Assert.True(result.StdOut.Contains("Successfully installed")); - Assert.True(TestCommon.VerifyTestMsixInstalledAndCleanup()); - } - - [Test] - public void InstallExeFoundExistingConvertToUpgrade() - { - var baseDir = TestCommon.GetRandomTestDir(); - var baseResult = TestCommon.RunAICLICommand("install", $"AppInstallerTest.TestExeInstaller -v 1.0.0.0 --silent -l {baseDir}"); - Assert.AreEqual(Constants.ErrorCode.S_OK, baseResult.ExitCode); - Assert.True(baseResult.StdOut.Contains("Successfully installed")); - - // Install will convert to upgrade - var upgradeDir = TestCommon.GetRandomTestDir(); - var upgradeResult = TestCommon.RunAICLICommand("install", $"AppInstallerTest.TestExeInstaller --silent -l {upgradeDir}"); - Assert.AreEqual(Constants.ErrorCode.S_OK, upgradeResult.ExitCode); - Assert.True(upgradeResult.StdOut.Contains("Trying to upgrade the installed package...")); - Assert.True(upgradeResult.StdOut.Contains("Successfully installed")); - - Assert.True(TestCommon.VerifyTestExeInstalledAndCleanup(baseDir)); - Assert.True(TestCommon.VerifyTestExeInstalledAndCleanup(upgradeDir, "/Version 2.0.0.0")); - } - - [Test] - public void InstallExeFoundExistingConvertToUpgradeNoAvailableUpgrade() - { - var baseDir = TestCommon.GetRandomTestDir(); - var baseResult = TestCommon.RunAICLICommand("install", $"AppInstallerTest.TestExeInstaller -v 2.0.0.0 --silent -l {baseDir}"); - Assert.AreEqual(Constants.ErrorCode.S_OK, baseResult.ExitCode); - Assert.True(baseResult.StdOut.Contains("Successfully installed")); - - // Install will convert to upgrade - var upgradeDir = TestCommon.GetRandomTestDir(); - var upgradeResult = TestCommon.RunAICLICommand("install", $"AppInstallerTest.TestExeInstaller --silent -l {upgradeDir}"); - Assert.AreEqual(Constants.ErrorCode.ERROR_UPDATE_NOT_APPLICABLE, upgradeResult.ExitCode); - Assert.True(upgradeResult.StdOut.Contains("Trying to upgrade the installed package...")); - Assert.True(upgradeResult.StdOut.Contains("No applicable upgrade")); - - Assert.True(TestCommon.VerifyTestExeInstalledAndCleanup(baseDir)); - } - - [Test] - public void InstallExeWithLatestInstalledWithForce() - { - var baseDir = TestCommon.GetRandomTestDir(); - var baseResult = TestCommon.RunAICLICommand("install", $"AppInstallerTest.TestExeInstaller -v 2.0.0.0 --silent -l {baseDir}"); - Assert.AreEqual(Constants.ErrorCode.S_OK, baseResult.ExitCode); - Assert.True(baseResult.StdOut.Contains("Successfully installed")); - - // Install will not convert to upgrade - var installDir = TestCommon.GetRandomTestDir(); - var installResult = TestCommon.RunAICLICommand("install", $"AppInstallerTest.TestExeInstaller -v 1.0.0.0 --silent -l {installDir} --force"); - Assert.AreEqual(Constants.ErrorCode.S_OK, installResult.ExitCode); - Assert.True(installResult.StdOut.Contains("Successfully installed")); - - Assert.True(TestCommon.VerifyTestExeInstalledAndCleanup(baseDir)); - Assert.True(TestCommon.VerifyTestExeInstalledAndCleanup(installDir, "/execustom")); - } - } -} \ No newline at end of file +//// Copyright (c) Microsoft Corporation. +//// Licensed under the MIT License. + +//namespace AppInstallerCLIE2ETests +//{ +// using NUnit.Framework; +// using System.IO; + +// public class InstallCommand : BaseCommand +// { +// [OneTimeSetUp] +// public void OneTimeSetup() +// { +// ConfigureFeature("zipInstall", true); +// } + +// [SetUp] +// public void Setup() +// { +// // Try clean up TestExeInstaller for failure cases where cleanup is not successful +// TestCommon.RunAICLICommand("uninstall", "AppInstallerTest.TestExeInstaller"); +// } + +// [Test] +// public void InstallAppDoesNotExist() +// { +// var result = TestCommon.RunAICLICommand("install", "DoesNotExist"); +// Assert.AreEqual(Constants.ErrorCode.ERROR_NO_APPLICATIONS_FOUND, result.ExitCode); +// Assert.True(result.StdOut.Contains("No package found matching input criteria.")); +// } + +// [Test] +// public void InstallWithMultipleAppsMatchingQuery() +// { +// var result = TestCommon.RunAICLICommand("install", "TestExeInstaller"); +// Assert.AreEqual(Constants.ErrorCode.ERROR_MULTIPLE_APPLICATIONS_FOUND, result.ExitCode); +// Assert.True(result.StdOut.Contains("Multiple packages found matching input criteria. Please refine the input.")); +// } + +// [Test] +// public void InstallExe() +// { +// var installDir = TestCommon.GetRandomTestDir(); +// var result = TestCommon.RunAICLICommand("install", $"AppInstallerTest.TestExeInstaller --silent -l {installDir}"); +// Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); +// Assert.True(result.StdOut.Contains("Successfully installed")); +// Assert.True(TestCommon.VerifyTestExeInstalledAndCleanup(installDir, "/execustom")); +// } + +// [Test] +// public void InstallExeWithInsufficientMinOsVersion() +// { +// var installDir = TestCommon.GetRandomTestDir(); +// var result = TestCommon.RunAICLICommand("install", $"InapplicableOsVersion --silent -l {installDir}"); +// // MinOSVersion is moved to installer level, the check is performed during installer selection +// Assert.AreEqual(Constants.ErrorCode.ERROR_NO_APPLICABLE_INSTALLER, result.ExitCode); +// Assert.False(TestCommon.VerifyTestExeInstalledAndCleanup(installDir)); +// } + +// [Test] +// public void InstallExeWithHashMismatch() +// { +// var installDir = TestCommon.GetRandomTestDir(); +// var result = TestCommon.RunAICLICommand("install", $"TestExeSha256Mismatch --silent -l {installDir}"); +// Assert.AreEqual(Constants.ErrorCode.ERROR_INSTALLER_HASH_MISMATCH, result.ExitCode); +// Assert.True(result.StdOut.Contains("Installer hash does not match")); +// Assert.False(TestCommon.VerifyTestExeInstalledAndCleanup(installDir)); +// } + +// [Test] +// public void InstallWithInno() +// { +// // Install test inno, manifest does not provide silent switch, we should be populating the default +// var installDir = TestCommon.GetRandomTestDir(); +// var result = TestCommon.RunAICLICommand("install", $"TestInnoInstaller --silent -l {installDir}"); +// Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); +// Assert.True(result.StdOut.Contains("Successfully installed")); +// Assert.True(TestCommon.VerifyTestExeInstalledAndCleanup(installDir, "/VERYSILENT")); +// } + +// [Test] +// public void InstallBurn() +// { +// // Install test burn, manifest does not provide silent switch, we should be populating the default +// var installDir = TestCommon.GetRandomTestDir(); +// var result = TestCommon.RunAICLICommand("install", $"TestBurnInstaller --silent -l {installDir}"); +// Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); +// Assert.True(result.StdOut.Contains("Successfully installed")); +// Assert.True(TestCommon.VerifyTestExeInstalledAndCleanup(installDir, "/quiet")); +// } + +// [Test] +// public void InstallNullSoft() +// { +// // Install test Nullsoft, manifest does not provide silent switch, we should be populating the default +// var installDir = TestCommon.GetRandomTestDir(); +// var result = TestCommon.RunAICLICommand("install", $"TestNullsoftInstaller --silent -l {installDir}"); +// Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); +// Assert.True(result.StdOut.Contains("Successfully installed")); +// Assert.True(TestCommon.VerifyTestExeInstalledAndCleanup(installDir, "/S")); +// } + +// [Test] +// public void InstallMSI() +// { +// var installDir = TestCommon.GetRandomTestDir(); +// var result = TestCommon.RunAICLICommand("install", $"TestMsiInstaller --silent -l {installDir}"); +// Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); +// Assert.True(result.StdOut.Contains("Successfully installed")); +// Assert.True(TestCommon.VerifyTestMsiInstalledAndCleanup(installDir)); +// } + +// [Test] +// public void InstallMSIX() +// { +// var result = TestCommon.RunAICLICommand("install", $"TestMsixInstaller"); +// Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); +// Assert.True(result.StdOut.Contains("Successfully installed")); +// Assert.True(TestCommon.VerifyTestMsixInstalledAndCleanup()); +// } + +// [Test] +// public void InstallMSIXWithSignature() +// { +// var installDir = TestCommon.GetRandomTestDir(); +// var result = TestCommon.RunAICLICommand("install", $"TestMsixWithSignatureHash --silent -l {installDir}"); +// Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); +// Assert.True(result.StdOut.Contains("Successfully installed")); +// Assert.True(TestCommon.VerifyTestMsixInstalledAndCleanup()); +// } + +// [Test] +// public void InstallMSIXWithSignatureHashMismatch() +// { +// var result = TestCommon.RunAICLICommand("install", $"TestMsixSignatureHashMismatch"); +// Assert.AreEqual(Constants.ErrorCode.ERROR_INSTALLER_HASH_MISMATCH, result.ExitCode); +// Assert.True(result.StdOut.Contains("Installer hash does not match")); +// Assert.False(TestCommon.VerifyTestMsixInstalledAndCleanup()); +// } + +// [Test] +// public void InstallExeWithAlternateSourceFailure() +// { +// TestCommon.RunAICLICommand("source add", "failSearch \"{ \"\"SearchHR\"\": \"\"0x80070002\"\" }\" Microsoft.Test.Configurable --header \"{}\""); + +// try +// { +// var installDir = TestCommon.GetRandomTestDir(); +// var result = TestCommon.RunAICLICommand("install", $"AppInstallerTest.TestExeInstaller --silent -l {installDir}"); +// Assert.AreEqual(unchecked((int)0x80070002), result.ExitCode); +// Assert.True(result.StdOut.Contains("Failed when searching source: failSearch")); +// Assert.True(result.StdOut.Contains("AppInstallerTest.TestExeInstaller")); +// Assert.False(result.StdOut.Contains("Successfully installed")); +// Assert.False(TestCommon.VerifyTestExeInstalledAndCleanup(installDir)); +// } +// finally +// { +// ResetTestSource(); +// } +// } + +// [Test] +// public void InstallPortableExe() +// { +// string installDir = TestCommon.GetPortablePackagesDirectory(); +// string packageId, commandAlias, fileName, packageDirName, productCode; +// packageId = "AppInstallerTest.TestPortableExe"; +// packageDirName = productCode = packageId + "_" + Constants.TestSourceIdentifier; +// commandAlias = fileName = "AppInstallerTestExeInstaller.exe"; + +// var result = TestCommon.RunAICLICommand("install", $"{packageId}"); +// Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); +// Assert.True(result.StdOut.Contains("Successfully installed")); +// // If no location specified, default behavior is to create a package directory with the name "{packageId}_{sourceId}" +// TestCommon.VerifyPortablePackage(Path.Combine(installDir, packageDirName), commandAlias, fileName, productCode, true); +// } + +// [Test] +// public void InstallPortableExeWithCommand() +// { +// var installDir = TestCommon.GetRandomTestDir(); +// string packageId, commandAlias, fileName, productCode; +// packageId = "AppInstallerTest.TestPortableExeWithCommand"; +// productCode = packageId + "_" + Constants.TestSourceIdentifier; +// fileName = "AppInstallerTestExeInstaller.exe"; +// commandAlias = "testCommand.exe"; + +// var result = TestCommon.RunAICLICommand("install", $"{packageId} -l {installDir}"); +// Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); +// Assert.True(result.StdOut.Contains("Successfully installed")); +// TestCommon.VerifyPortablePackage(installDir, commandAlias, fileName, productCode, true); +// } + +// [Test] +// public void InstallPortableExeWithRename() +// { +// var installDir = TestCommon.GetRandomTestDir(); +// string packageId, productCode, renameArgValue; +// packageId = "AppInstallerTest.TestPortableExeWithCommand"; +// productCode = packageId + "_" + Constants.TestSourceIdentifier; +// renameArgValue = "testRename.exe"; + +// var result = TestCommon.RunAICLICommand("install", $"{packageId} -l {installDir} --rename {renameArgValue}"); +// Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); +// Assert.True(result.StdOut.Contains("Successfully installed")); +// TestCommon.VerifyPortablePackage(installDir, renameArgValue, renameArgValue, productCode, true); +// } + +// [Test] +// public void InstallPortableInvalidRename() +// { +// var installDir = TestCommon.GetRandomTestDir(); +// string packageId, renameArgValue; +// packageId = "AppInstallerTest.TestPortableExeWithCommand"; +// renameArgValue = "test?"; + +// var result = TestCommon.RunAICLICommand("install", $"{packageId} -l {installDir} --rename {renameArgValue}"); +// Assert.AreNotEqual(Constants.ErrorCode.S_OK, result.ExitCode); +// Assert.True(result.StdOut.Contains("The specified filename is not a valid filename")); +// } + +// [Test] +// public void InstallPortableReservedNames() +// { +// var installDir = TestCommon.GetRandomTestDir(); +// string packageId, renameArgValue; +// packageId = "AppInstallerTest.TestPortableExeWithCommand"; +// renameArgValue = "CON"; + +// var result = TestCommon.RunAICLICommand("install", $"{packageId} -l {installDir} --rename {renameArgValue}"); +// Assert.AreNotEqual(Constants.ErrorCode.S_OK, result.ExitCode); +// Assert.True(result.StdOut.Contains("The specified filename is not a valid filename")); +// } + +// [Test] +// public void InstallPortableToExistingDirectory() +// { +// var installDir = TestCommon.GetRandomTestDir(); +// var existingDir = Path.Combine(installDir, "testDirectory"); +// Directory.CreateDirectory(existingDir); + +// string packageId, commandAlias, fileName, productCode; +// packageId = "AppInstallerTest.TestPortableExe"; +// productCode = packageId + "_" + Constants.TestSourceIdentifier; +// commandAlias = fileName = "AppInstallerTestExeInstaller.exe"; + +// var result = TestCommon.RunAICLICommand("install", $"{packageId} -l {existingDir}"); +// Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); +// Assert.True(result.StdOut.Contains("Successfully installed")); +// TestCommon.VerifyPortablePackage(existingDir, commandAlias, fileName, productCode, true); +// } + +// [Test] +// public void InstallPortableFailsWithCleanup() +// { +// string packageId, commandAlias; +// packageId = "AppInstallerTest.TestPortableExe"; +// commandAlias = "AppInstallerTestExeInstaller.exe"; + +// // Create a directory with the same name as the symlink in order to cause install to fail. +// string symlinkDirectory = TestCommon.GetPortableSymlinkDirectory(TestCommon.Scope.User); +// string conflictDirectory = Path.Combine(symlinkDirectory, commandAlias); + +// Directory.CreateDirectory(conflictDirectory); + +// var result = TestCommon.RunAICLICommand("install", $"{packageId}"); + +// // Remove directory prior to assertions as this will impact other tests if assertions fail. +// Directory.Delete(conflictDirectory, true); + +// Assert.AreNotEqual(Constants.ErrorCode.S_OK, result.ExitCode); +// Assert.True(result.StdOut.Contains("Unable to create symlink, path points to a directory.")); +// } + +// [Test] +// public void ReinstallPortable() +// { +// string installDir = TestCommon.GetPortablePackagesDirectory(); +// string packageId, commandAlias, fileName, packageDirName, productCode; +// packageId = "AppInstallerTest.TestPortableExe"; +// packageDirName = productCode = packageId + "_" + Constants.TestSourceIdentifier; +// commandAlias = fileName = "AppInstallerTestExeInstaller.exe"; + +// var result = TestCommon.RunAICLICommand("install", $"{packageId}"); +// Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); + +// string symlinkDirectory = TestCommon.GetPortableSymlinkDirectory(TestCommon.Scope.User); +// string symlinkPath = Path.Combine(symlinkDirectory, commandAlias); + +// // Clean first install should not display file overwrite message. +// Assert.True(result.StdOut.Contains("Successfully installed")); +// Assert.False(result.StdOut.Contains($"Overwriting existing file: {symlinkPath}")); + +// // Perform second install and verify that file overwrite message is displayed. +// var result2 = TestCommon.RunAICLICommand("install", $"{packageId} --force"); +// Assert.AreEqual(Constants.ErrorCode.S_OK, result2.ExitCode); +// Assert.True(result2.StdOut.Contains("Successfully installed")); + +// TestCommon.VerifyPortablePackage(Path.Combine(installDir, packageDirName), commandAlias, fileName, productCode, true); +// } + +// [Test] +// public void InstallPortable_UserScope() +// { +// string installDir = TestCommon.GetRandomTestDir(); +// ConfigureInstallBehavior(Constants.PortablePackageUserRoot, installDir); + +// string packageId, commandAlias, fileName, packageDirName, productCode; +// packageId = "AppInstallerTest.TestPortableExe"; +// packageDirName = productCode = packageId + "_" + Constants.TestSourceIdentifier; +// commandAlias = fileName = "AppInstallerTestExeInstaller.exe"; + +// var result = TestCommon.RunAICLICommand("install", $"{packageId} --scope user"); +// ConfigureInstallBehavior(Constants.PortablePackageUserRoot, string.Empty); +// Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); +// Assert.True(result.StdOut.Contains("Successfully installed")); +// TestCommon.VerifyPortablePackage(Path.Combine(installDir, packageDirName), commandAlias, fileName, productCode, true); +// } + +// [Test] +// public void InstallPortable_MachineScope() +// { +// string installDir = TestCommon.GetRandomTestDir(); +// ConfigureInstallBehavior(Constants.PortablePackageMachineRoot, installDir); + +// string packageId, commandAlias, fileName, packageDirName, productCode; +// packageId = "AppInstallerTest.TestPortableExe"; +// packageDirName = productCode = packageId + "_" + Constants.TestSourceIdentifier; +// commandAlias = fileName = "AppInstallerTestExeInstaller.exe"; + +// var result = TestCommon.RunAICLICommand("install", $"{packageId} --scope machine"); +// ConfigureInstallBehavior(Constants.PortablePackageMachineRoot, string.Empty); +// Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); +// Assert.True(result.StdOut.Contains("Successfully installed")); +// TestCommon.VerifyPortablePackage(Path.Combine(installDir, packageDirName), commandAlias, fileName, productCode, true, TestCommon.Scope.Machine); +// } + +// [Test] +// public void InstallZip_Exe() +// { +// var installDir = TestCommon.GetRandomTestDir(); +// var result = TestCommon.RunAICLICommand("install", $"AppInstallerTest.TestZipInstallerWithExe --silent -l {installDir}"); +// Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); +// Assert.True(result.StdOut.Contains("Successfully installed")); +// Assert.True(TestCommon.VerifyTestExeInstalledAndCleanup(installDir, "/execustom")); +// } + +// [Test] +// public void InstallZip_Portable() +// { +// string installDir = TestCommon.GetPortablePackagesDirectory(); +// string packageId, commandAlias, fileName, packageDirName, productCode; +// packageId = "AppInstallerTest.TestZipInstallerWithPortable"; +// packageDirName = productCode = packageId + "_" + Constants.TestSourceIdentifier; +// commandAlias = "TestPortable.exe"; +// fileName = "AppInstallerTestExeInstaller.exe"; + +// var result = TestCommon.RunAICLICommand("install", $"{packageId}"); +// Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); +// Assert.True(result.StdOut.Contains("Successfully installed")); +// TestCommon.VerifyPortablePackage(Path.Combine(installDir, packageDirName), commandAlias, fileName, productCode, true, TestCommon.Scope.User); +// } + +// [Test] +// public void InstallZipWithInvalidRelativeFilePath() +// { +// var result = TestCommon.RunAICLICommand("install", $"AppInstallerTest.TestZipInvalidRelativePath"); +// Assert.AreNotEqual(Constants.ErrorCode.S_OK, result.ExitCode); +// Assert.True(result.StdOut.Contains("Invalid relative file path to the nested installer; path points to a location outside of the install directory")); +// } + +// [Test] +// public void InstallZipWithMsi() +// { +// var installDir = TestCommon.GetRandomTestDir(); +// var result = TestCommon.RunAICLICommand("install", $"AppInstallerTest.TestZipInstallerWithMsi --silent -l {installDir}"); +// Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); +// Assert.True(result.StdOut.Contains("Successfully installed")); +// Assert.True(TestCommon.VerifyTestMsiInstalledAndCleanup(installDir)); +// } + +// [Test] +// public void InstallZipWithMsix() +// { +// var result = TestCommon.RunAICLICommand("install", $"AppInstallerTest.TestZipInstallerWithMsix"); +// Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); +// Assert.True(result.StdOut.Contains("Successfully installed")); +// Assert.True(TestCommon.VerifyTestMsixInstalledAndCleanup()); +// } + +// [Test] +// public void InstallExeFoundExistingConvertToUpgrade() +// { +// var baseDir = TestCommon.GetRandomTestDir(); +// var baseResult = TestCommon.RunAICLICommand("install", $"AppInstallerTest.TestExeInstaller -v 1.0.0.0 --silent -l {baseDir}"); +// Assert.AreEqual(Constants.ErrorCode.S_OK, baseResult.ExitCode); +// Assert.True(baseResult.StdOut.Contains("Successfully installed")); + +// // Install will convert to upgrade +// var upgradeDir = TestCommon.GetRandomTestDir(); +// var upgradeResult = TestCommon.RunAICLICommand("install", $"AppInstallerTest.TestExeInstaller --silent -l {upgradeDir}"); +// Assert.AreEqual(Constants.ErrorCode.S_OK, upgradeResult.ExitCode); +// Assert.True(upgradeResult.StdOut.Contains("Trying to upgrade the installed package...")); +// Assert.True(upgradeResult.StdOut.Contains("Successfully installed")); + +// Assert.True(TestCommon.VerifyTestExeInstalledAndCleanup(baseDir)); +// Assert.True(TestCommon.VerifyTestExeInstalledAndCleanup(upgradeDir, "/Version 2.0.0.0")); +// } + +// [Test] +// public void InstallExeFoundExistingConvertToUpgradeNoAvailableUpgrade() +// { +// var baseDir = TestCommon.GetRandomTestDir(); +// var baseResult = TestCommon.RunAICLICommand("install", $"AppInstallerTest.TestExeInstaller -v 2.0.0.0 --silent -l {baseDir}"); +// Assert.AreEqual(Constants.ErrorCode.S_OK, baseResult.ExitCode); +// Assert.True(baseResult.StdOut.Contains("Successfully installed")); + +// // Install will convert to upgrade +// var upgradeDir = TestCommon.GetRandomTestDir(); +// var upgradeResult = TestCommon.RunAICLICommand("install", $"AppInstallerTest.TestExeInstaller --silent -l {upgradeDir}"); +// Assert.AreEqual(Constants.ErrorCode.ERROR_UPDATE_NOT_APPLICABLE, upgradeResult.ExitCode); +// Assert.True(upgradeResult.StdOut.Contains("Trying to upgrade the installed package...")); +// Assert.True(upgradeResult.StdOut.Contains("No applicable upgrade")); + +// Assert.True(TestCommon.VerifyTestExeInstalledAndCleanup(baseDir)); +// } + +// [Test] +// public void InstallExeWithLatestInstalledWithForce() +// { +// var baseDir = TestCommon.GetRandomTestDir(); +// var baseResult = TestCommon.RunAICLICommand("install", $"AppInstallerTest.TestExeInstaller -v 2.0.0.0 --silent -l {baseDir}"); +// Assert.AreEqual(Constants.ErrorCode.S_OK, baseResult.ExitCode); +// Assert.True(baseResult.StdOut.Contains("Successfully installed")); + +// // Install will not convert to upgrade +// var installDir = TestCommon.GetRandomTestDir(); +// var installResult = TestCommon.RunAICLICommand("install", $"AppInstallerTest.TestExeInstaller -v 1.0.0.0 --silent -l {installDir} --force"); +// Assert.AreEqual(Constants.ErrorCode.S_OK, installResult.ExitCode); +// Assert.True(installResult.StdOut.Contains("Successfully installed")); + +// Assert.True(TestCommon.VerifyTestExeInstalledAndCleanup(baseDir)); +// Assert.True(TestCommon.VerifyTestExeInstalledAndCleanup(installDir, "/execustom")); +// } +// } +//} \ No newline at end of file diff --git a/src/AppInstallerCLIE2ETests/ListCommand.cs b/src/AppInstallerCLIE2ETests/ListCommand.cs index 0115ab814e..d314e87a7e 100644 --- a/src/AppInstallerCLIE2ETests/ListCommand.cs +++ b/src/AppInstallerCLIE2ETests/ListCommand.cs @@ -1,111 +1,111 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -namespace AppInstallerCLIE2ETests -{ - using NUnit.Framework; - using System.IO; - - public class ListCommand : BaseCommand - { - [Test] - public void ListSelf() - { - var result = TestCommon.RunAICLICommand("list", Constants.AICLIPackageFamilyName); - Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); - Assert.True(result.StdOut.Contains(Constants.AICLIPackageFamilyName)); - } - - [Test] - public void ListAfterInstall() - { - System.Guid guid = System.Guid.NewGuid(); - string productCode = guid.ToString(); - var installDir = TestCommon.GetRandomTestDir(); - - // DisplayName must be set to avoid conflicts with other packages that use the same exe installer. - string displayName = "TestExeInstaller"; - string localAppDataPath = System.Environment.GetEnvironmentVariable(Constants.LocalAppData); - string logFilePath = System.IO.Path.Combine(localAppDataPath, Constants.E2ETestLogsPathPackaged); - logFilePath = System.IO.Path.Combine(logFilePath, "ListAfterInstall-" + System.IO.Path.GetRandomFileName() + ".log"); - - var result = TestCommon.RunAICLICommand("list", productCode); - Assert.AreEqual(Constants.ErrorCode.ERROR_NO_APPLICATIONS_FOUND, result.ExitCode); - - result = TestCommon.RunAICLICommand("install", $"AppInstallerTest.TestExeInstaller --override \"/InstallDir {installDir} /ProductID {productCode} /LogFile {logFilePath} /DisplayName {displayName}\""); - Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); - - result = TestCommon.RunAICLICommand("list", productCode); - Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); - Assert.True(result.StdOut.Contains("AppInstallerTest.TestExeInstaller")); - Assert.True(result.StdOut.Contains("1.0.0.0")); - Assert.True(result.StdOut.Contains("2.0.0.0")); - } - - [Test] - public void ListWithArpVersionMapping() - { - // No mapping performed - ArpVersionMappingTest("AppInstallerTest.TestArpVersionSameVersion", "TestArpVersionSameVersion", "0.5", "0.5", "< 1.0"); - - // Partial mapping performed(i.e. only if version falls within arp version range) - ArpVersionMappingTest("AppInstallerTest.TestArpVersionOppositeOrder", "TestArpVersionOppositeOrder", "10.1", "1.0", "10.1"); - ArpVersionMappingTest("AppInstallerTest.TestArpVersionOppositeOrder", "TestArpVersionOppositeOrder", "9.9", "9.9", "> 2.0"); - - // Full mapping performed - ArpVersionMappingTest("AppInstallerTest.TestArpVersionSameOrder", "TestArpVersionSameOrder", "7.0", "< 1.0", "7.0"); - ArpVersionMappingTest("AppInstallerTest.TestArpVersionSameOrder", "TestArpVersionSameOrder", "10.1", "1.0", "10.1"); - ArpVersionMappingTest("AppInstallerTest.TestArpVersionSameOrder", "TestArpVersionSameOrder", "10.7", "< 2.0", "10.7"); - ArpVersionMappingTest("AppInstallerTest.TestArpVersionSameOrder", "TestArpVersionSameOrder", "11.1", "2.0", "11.1"); - ArpVersionMappingTest("AppInstallerTest.TestArpVersionSameOrder", "TestArpVersionSameOrder", "12.0", "> 2.0", "12.0"); - } - - [Test] - public void ListWithUpgradeCode() - { - // Installs the MSI installer using the TestMsiInstaller package. - // Then tries listing the TestMsiInstallerUpgradeCode package, which should - // be correlated to it by the UpgradeCode. - if (string.IsNullOrEmpty(TestCommon.MsiInstallerPath)) - { - Assert.Ignore("MSI installer not available"); - } - - var installDir = TestCommon.GetRandomTestDir(); - Assert.AreEqual(Constants.ErrorCode.S_OK, TestCommon.RunAICLICommand("install", $"TestMsiInstaller --silent -l {installDir}").ExitCode); - - var result = TestCommon.RunAICLICommand("list", "TestMsiInstallerUpgradeCode"); - Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); - Assert.True(result.StdOut.Contains("AppInstallerTest.TestMsiInstallerUpgradeCode")); - } - - private void ArpVersionMappingTest(string packageIdentifier, string displayNameOverride, string displayVersionOverride, string expectedListVersion, string notExpectedListVersion = "") - { - System.Guid guid = System.Guid.NewGuid(); - string productCode = guid.ToString(); - var installDir = TestCommon.GetRandomTestDir(); - - var result = TestCommon.RunAICLICommand("list", productCode); - Assert.AreEqual(Constants.ErrorCode.ERROR_NO_APPLICATIONS_FOUND, result.ExitCode); - - result = TestCommon.RunAICLICommand("install", $"{packageIdentifier} --override \"/InstallDir {installDir} /ProductID {productCode} /DisplayName {displayNameOverride} /Version {displayVersionOverride}\""); - Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); - - result = TestCommon.RunAICLICommand("list", productCode); - Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); - - Assert.True(result.StdOut.Contains(packageIdentifier)); - Assert.True(result.StdOut.Contains(expectedListVersion)); - if (!string.IsNullOrEmpty(notExpectedListVersion)) - { - Assert.False(result.StdOut.Contains(notExpectedListVersion)); - } - - // Try clean up - if (File.Exists(Path.Combine(installDir, Constants.TestExeInstalledFileName))) - { - TestCommon.RunCommand(Path.Combine(installDir, Constants.TestExeUninstallerFileName)); - } - } - } -} +//// Copyright (c) Microsoft Corporation. +//// Licensed under the MIT License. + +//namespace AppInstallerCLIE2ETests +//{ +// using NUnit.Framework; +// using System.IO; + +// public class ListCommand : BaseCommand +// { +// [Test] +// public void ListSelf() +// { +// var result = TestCommon.RunAICLICommand("list", Constants.AICLIPackageFamilyName); +// Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); +// Assert.True(result.StdOut.Contains(Constants.AICLIPackageFamilyName)); +// } + +// [Test] +// public void ListAfterInstall() +// { +// System.Guid guid = System.Guid.NewGuid(); +// string productCode = guid.ToString(); +// var installDir = TestCommon.GetRandomTestDir(); + +// // DisplayName must be set to avoid conflicts with other packages that use the same exe installer. +// string displayName = "TestExeInstaller"; +// string localAppDataPath = System.Environment.GetEnvironmentVariable(Constants.LocalAppData); +// string logFilePath = System.IO.Path.Combine(localAppDataPath, Constants.E2ETestLogsPathPackaged); +// logFilePath = System.IO.Path.Combine(logFilePath, "ListAfterInstall-" + System.IO.Path.GetRandomFileName() + ".log"); + +// var result = TestCommon.RunAICLICommand("list", productCode); +// Assert.AreEqual(Constants.ErrorCode.ERROR_NO_APPLICATIONS_FOUND, result.ExitCode); + +// result = TestCommon.RunAICLICommand("install", $"AppInstallerTest.TestExeInstaller --override \"/InstallDir {installDir} /ProductID {productCode} /LogFile {logFilePath} /DisplayName {displayName}\""); +// Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); + +// result = TestCommon.RunAICLICommand("list", productCode); +// Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); +// Assert.True(result.StdOut.Contains("AppInstallerTest.TestExeInstaller")); +// Assert.True(result.StdOut.Contains("1.0.0.0")); +// Assert.True(result.StdOut.Contains("2.0.0.0")); +// } + +// [Test] +// public void ListWithArpVersionMapping() +// { +// // No mapping performed +// ArpVersionMappingTest("AppInstallerTest.TestArpVersionSameVersion", "TestArpVersionSameVersion", "0.5", "0.5", "< 1.0"); + +// // Partial mapping performed(i.e. only if version falls within arp version range) +// ArpVersionMappingTest("AppInstallerTest.TestArpVersionOppositeOrder", "TestArpVersionOppositeOrder", "10.1", "1.0", "10.1"); +// ArpVersionMappingTest("AppInstallerTest.TestArpVersionOppositeOrder", "TestArpVersionOppositeOrder", "9.9", "9.9", "> 2.0"); + +// // Full mapping performed +// ArpVersionMappingTest("AppInstallerTest.TestArpVersionSameOrder", "TestArpVersionSameOrder", "7.0", "< 1.0", "7.0"); +// ArpVersionMappingTest("AppInstallerTest.TestArpVersionSameOrder", "TestArpVersionSameOrder", "10.1", "1.0", "10.1"); +// ArpVersionMappingTest("AppInstallerTest.TestArpVersionSameOrder", "TestArpVersionSameOrder", "10.7", "< 2.0", "10.7"); +// ArpVersionMappingTest("AppInstallerTest.TestArpVersionSameOrder", "TestArpVersionSameOrder", "11.1", "2.0", "11.1"); +// ArpVersionMappingTest("AppInstallerTest.TestArpVersionSameOrder", "TestArpVersionSameOrder", "12.0", "> 2.0", "12.0"); +// } + +// [Test] +// public void ListWithUpgradeCode() +// { +// // Installs the MSI installer using the TestMsiInstaller package. +// // Then tries listing the TestMsiInstallerUpgradeCode package, which should +// // be correlated to it by the UpgradeCode. +// if (string.IsNullOrEmpty(TestCommon.MsiInstallerPath)) +// { +// Assert.Ignore("MSI installer not available"); +// } + +// var installDir = TestCommon.GetRandomTestDir(); +// Assert.AreEqual(Constants.ErrorCode.S_OK, TestCommon.RunAICLICommand("install", $"TestMsiInstaller --silent -l {installDir}").ExitCode); + +// var result = TestCommon.RunAICLICommand("list", "TestMsiInstallerUpgradeCode"); +// Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); +// Assert.True(result.StdOut.Contains("AppInstallerTest.TestMsiInstallerUpgradeCode")); +// } + +// private void ArpVersionMappingTest(string packageIdentifier, string displayNameOverride, string displayVersionOverride, string expectedListVersion, string notExpectedListVersion = "") +// { +// System.Guid guid = System.Guid.NewGuid(); +// string productCode = guid.ToString(); +// var installDir = TestCommon.GetRandomTestDir(); + +// var result = TestCommon.RunAICLICommand("list", productCode); +// Assert.AreEqual(Constants.ErrorCode.ERROR_NO_APPLICATIONS_FOUND, result.ExitCode); + +// result = TestCommon.RunAICLICommand("install", $"{packageIdentifier} --override \"/InstallDir {installDir} /ProductID {productCode} /DisplayName {displayNameOverride} /Version {displayVersionOverride}\""); +// Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); + +// result = TestCommon.RunAICLICommand("list", productCode); +// Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); + +// Assert.True(result.StdOut.Contains(packageIdentifier)); +// Assert.True(result.StdOut.Contains(expectedListVersion)); +// if (!string.IsNullOrEmpty(notExpectedListVersion)) +// { +// Assert.False(result.StdOut.Contains(notExpectedListVersion)); +// } + +// // Try clean up +// if (File.Exists(Path.Combine(installDir, Constants.TestExeInstalledFileName))) +// { +// TestCommon.RunCommand(Path.Combine(installDir, Constants.TestExeUninstallerFileName)); +// } +// } +// } +//} diff --git a/src/AppInstallerCLIE2ETests/PowerShell/PowerShellModule.cs b/src/AppInstallerCLIE2ETests/PowerShell/PowerShellModule.cs index f8635a74c1..2fca0e0b4a 100644 --- a/src/AppInstallerCLIE2ETests/PowerShell/PowerShellModule.cs +++ b/src/AppInstallerCLIE2ETests/PowerShell/PowerShellModule.cs @@ -32,7 +32,7 @@ public void GetWinGetSource() Assert.IsTrue(getSourceResult.StdOut.Contains($"{Constants.TestSourceName}")); } - [Test] + //[Test] public void FindWinGetPackage() { var result = TestCommon.RunPowerShellCommandWithResult(Constants.FindCmdlet, $"-Id {Constants.ExeInstallerPackageId}"); @@ -40,7 +40,7 @@ public void FindWinGetPackage() Assert.IsTrue(result.StdOut.Contains("TestExeInstaller")); } - [Test] + //[Test] public void GetWinGetPackage() { var installResult = TestCommon.RunPowerShellCommandWithResult(Constants.InstallCmdlet, $"-Id {Constants.MsiInstallerPackageId}"); @@ -56,7 +56,7 @@ public void GetWinGetPackage() Assert.IsTrue(!string.IsNullOrEmpty(uninstallResult.StdOut)); } - [Test] + //[Test] public void InstallWinGetPackage() { var installResult = TestCommon.RunPowerShellCommandWithResult(Constants.InstallCmdlet, $"-Id {Constants.ExeInstallerPackageId}"); @@ -69,7 +69,7 @@ public void InstallWinGetPackage() Assert.IsTrue(!string.IsNullOrEmpty(uninstallResult.StdOut)); } - [Test] + //[Test] public void UpdateWinGetPackage() { var installResult = TestCommon.RunPowerShellCommandWithResult(Constants.InstallCmdlet, $"-Id {Constants.ExeInstallerPackageId} -Version 1.0.0.0"); diff --git a/src/AppInstallerCLIE2ETests/SearchCommand.cs b/src/AppInstallerCLIE2ETests/SearchCommand.cs index aca227fca3..955151aeb5 100644 --- a/src/AppInstallerCLIE2ETests/SearchCommand.cs +++ b/src/AppInstallerCLIE2ETests/SearchCommand.cs @@ -1,170 +1,170 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. +//// Copyright (c) Microsoft Corporation. +//// Licensed under the MIT License. -namespace AppInstallerCLIE2ETests -{ - using NUnit.Framework; +//namespace AppInstallerCLIE2ETests +//{ +// using NUnit.Framework; - public class SearchCommand : BaseCommand - { - [Test] - public void SearchWithoutArgs() - { - var result = TestCommon.RunAICLICommand("search", ""); - Assert.AreEqual(Constants.ErrorCode.ERROR_INVALID_CL_ARGUMENTS, result.ExitCode); - } +// public class SearchCommand : BaseCommand +// { +// [Test] +// public void SearchWithoutArgs() +// { +// var result = TestCommon.RunAICLICommand("search", ""); +// Assert.AreEqual(Constants.ErrorCode.ERROR_INVALID_CL_ARGUMENTS, result.ExitCode); +// } - [Test] - public void SearchQuery() - { - var result = TestCommon.RunAICLICommand("search", "TestExampleInstaller"); - Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); - Assert.True(result.StdOut.Contains("TestExampleInstaller")); - Assert.True(result.StdOut.Contains("AppInstallerTest.TestExampleInstaller")); - } +// [Test] +// public void SearchQuery() +// { +// var result = TestCommon.RunAICLICommand("search", "TestExampleInstaller"); +// Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); +// Assert.True(result.StdOut.Contains("TestExampleInstaller")); +// Assert.True(result.StdOut.Contains("AppInstallerTest.TestExampleInstaller")); +// } - public void SearchUsingAlias() - { - var result = TestCommon.RunAICLICommand("find", "TestExampleInstaller"); - Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); - Assert.True(result.StdOut.Contains("TestExampleInstaller")); - Assert.True(result.StdOut.Contains("AppInstallerTest.TestExampleInstaller")); - } +// public void SearchUsingAlias() +// { +// var result = TestCommon.RunAICLICommand("find", "TestExampleInstaller"); +// Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); +// Assert.True(result.StdOut.Contains("TestExampleInstaller")); +// Assert.True(result.StdOut.Contains("AppInstallerTest.TestExampleInstaller")); +// } - [Test] - public void SearchWithName() - { - var result = TestCommon.RunAICLICommand("search", "--name testexampleinstaller"); - Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); - Assert.True(result.StdOut.Contains("TestExampleInstaller")); - Assert.True(result.StdOut.Contains("AppInstallerTest.TestExampleInstaller")); - } +// [Test] +// public void SearchWithName() +// { +// var result = TestCommon.RunAICLICommand("search", "--name testexampleinstaller"); +// Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); +// Assert.True(result.StdOut.Contains("TestExampleInstaller")); +// Assert.True(result.StdOut.Contains("AppInstallerTest.TestExampleInstaller")); +// } - [Test] - public void SearchWithID() - { - var result = TestCommon.RunAICLICommand("search", "--id appinstallertest.testexampleinstaller"); - Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); - Assert.True(result.StdOut.Contains("TestExampleInstaller")); - Assert.True(result.StdOut.Contains("AppInstallerTest.TestExampleInstaller")); - } +// [Test] +// public void SearchWithID() +// { +// var result = TestCommon.RunAICLICommand("search", "--id appinstallertest.testexampleinstaller"); +// Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); +// Assert.True(result.StdOut.Contains("TestExampleInstaller")); +// Assert.True(result.StdOut.Contains("AppInstallerTest.TestExampleInstaller")); +// } - [Test] - public void SearchWithInvalidName() - { - var result = TestCommon.RunAICLICommand("search", "--name InvalidName"); - Assert.AreEqual(Constants.ErrorCode.ERROR_NO_APPLICATIONS_FOUND, result.ExitCode); - Assert.True(result.StdOut.Contains("No package found matching input criteria.")); - } +// [Test] +// public void SearchWithInvalidName() +// { +// var result = TestCommon.RunAICLICommand("search", "--name InvalidName"); +// Assert.AreEqual(Constants.ErrorCode.ERROR_NO_APPLICATIONS_FOUND, result.ExitCode); +// Assert.True(result.StdOut.Contains("No package found matching input criteria.")); +// } - [Test] - public void SearchReturnsMultiple() - { - // Search Microsoft should return multiple - var result = TestCommon.RunAICLICommand("search", "AppInstallerTest"); - Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); - Assert.True(result.StdOut.Contains("AppInstallerTest.TestExeInstaller")); - Assert.True(result.StdOut.Contains("AppInstallerTest.TestBurnInstaller")); - Assert.True(result.StdOut.Contains("AppInstallerTest.TestExampleInstaller")); - } +// [Test] +// public void SearchReturnsMultiple() +// { +// // Search Microsoft should return multiple +// var result = TestCommon.RunAICLICommand("search", "AppInstallerTest"); +// Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); +// Assert.True(result.StdOut.Contains("AppInstallerTest.TestExeInstaller")); +// Assert.True(result.StdOut.Contains("AppInstallerTest.TestBurnInstaller")); +// Assert.True(result.StdOut.Contains("AppInstallerTest.TestExampleInstaller")); +// } - [Test] - public void SearchWithExactName() - { - var result = TestCommon.RunAICLICommand("search", "--exact TestExampleInstaller"); - Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); - Assert.True(result.StdOut.Contains("TestExampleInstaller")); - Assert.True(result.StdOut.Contains("AppInstallerTest.TestExampleInstaller")); - } +// [Test] +// public void SearchWithExactName() +// { +// var result = TestCommon.RunAICLICommand("search", "--exact TestExampleInstaller"); +// Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); +// Assert.True(result.StdOut.Contains("TestExampleInstaller")); +// Assert.True(result.StdOut.Contains("AppInstallerTest.TestExampleInstaller")); +// } - [Test] - public void SearchWithExactID() - { - var result = TestCommon.RunAICLICommand("search", "--exact AppInstallerTest.TestExampleInstaller"); - Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); - Assert.True(result.StdOut.Contains("TestExampleInstaller")); - Assert.True(result.StdOut.Contains("AppInstallerTest.TestExampleInstaller")); - } +// [Test] +// public void SearchWithExactID() +// { +// var result = TestCommon.RunAICLICommand("search", "--exact AppInstallerTest.TestExampleInstaller"); +// Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); +// Assert.True(result.StdOut.Contains("TestExampleInstaller")); +// Assert.True(result.StdOut.Contains("AppInstallerTest.TestExampleInstaller")); +// } - [Test] - public void SearchWithExactArgCaseSensitivity() - { - var result = TestCommon.RunAICLICommand("search", "--exact testexampleinstaller"); - Assert.AreEqual(Constants.ErrorCode.ERROR_NO_APPLICATIONS_FOUND, result.ExitCode); - Assert.True(result.StdOut.Contains("No package found matching input criteria.")); - } +// [Test] +// public void SearchWithExactArgCaseSensitivity() +// { +// var result = TestCommon.RunAICLICommand("search", "--exact testexampleinstaller"); +// Assert.AreEqual(Constants.ErrorCode.ERROR_NO_APPLICATIONS_FOUND, result.ExitCode); +// Assert.True(result.StdOut.Contains("No package found matching input criteria.")); +// } - [Test] - public void SearchWithSingleSourceFailure() - { - TestCommon.RunAICLICommand("source add", "failSearch \"{ \"\"OpenHR\"\": \"\"0x80070002\"\" }\" Microsoft.Test.Configurable --header \"{}\""); +// [Test] +// public void SearchWithSingleSourceFailure() +// { +// TestCommon.RunAICLICommand("source add", "failSearch \"{ \"\"OpenHR\"\": \"\"0x80070002\"\" }\" Microsoft.Test.Configurable --header \"{}\""); - try - { - var result = TestCommon.RunAICLICommand("search", "--exact AppInstallerTest.TestExampleInstaller"); - Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); - Assert.True(result.StdOut.Contains("Failed when searching source; results will not be included: failSearch")); - Assert.True(result.StdOut.Contains("TestExampleInstaller")); - Assert.True(result.StdOut.Contains("AppInstallerTest.TestExampleInstaller")); - } - finally - { - ResetTestSource(); - } - } +// try +// { +// var result = TestCommon.RunAICLICommand("search", "--exact AppInstallerTest.TestExampleInstaller"); +// Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); +// Assert.True(result.StdOut.Contains("Failed when searching source; results will not be included: failSearch")); +// Assert.True(result.StdOut.Contains("TestExampleInstaller")); +// Assert.True(result.StdOut.Contains("AppInstallerTest.TestExampleInstaller")); +// } +// finally +// { +// ResetTestSource(); +// } +// } - [Test] - public void SearchStoreWithBadPin() - { - // Configure as close as possible to the real chain but use the test cert for everything - // This will at least force the public key to be checked rather than simply failing based on chain length - GroupPolicyHelper.EnableAdditionalSources.SetEnabledList(new GroupPolicySource[] - { - new GroupPolicySource - { - Name = Constants.TestAlternateSourceName, - Arg = Constants.DefaultMSStoreSourceUrl, - Type = Constants.DefaultMSStoreSourceType, - Data = "", - Identifier = Constants.DefaultMSStoreSourceIdentifier, - CertificatePinning = new GroupPolicyCertificatePinning - { - Chains = new GroupPolicyCertificatePinningChain[] { - new GroupPolicyCertificatePinningChain - { - Chain = new GroupPolicyCertificatePinningDetails[] - { - new GroupPolicyCertificatePinningDetails - { - Validation = new string[] { "publickey" }, - EmbeddedCertificate = TestCommon.GetTestServerCertificateHexString() - }, - new GroupPolicyCertificatePinningDetails - { - Validation = new string[] { "subject", "issuer" }, - EmbeddedCertificate = TestCommon.GetTestServerCertificateHexString() - }, - new GroupPolicyCertificatePinningDetails - { - Validation = new string[] { "subject", "issuer" }, - EmbeddedCertificate = TestCommon.GetTestServerCertificateHexString() - } - } - } - } - } - } - }); +// [Test] +// public void SearchStoreWithBadPin() +// { +// // Configure as close as possible to the real chain but use the test cert for everything +// // This will at least force the public key to be checked rather than simply failing based on chain length +// GroupPolicyHelper.EnableAdditionalSources.SetEnabledList(new GroupPolicySource[] +// { +// new GroupPolicySource +// { +// Name = Constants.TestAlternateSourceName, +// Arg = Constants.DefaultMSStoreSourceUrl, +// Type = Constants.DefaultMSStoreSourceType, +// Data = "", +// Identifier = Constants.DefaultMSStoreSourceIdentifier, +// CertificatePinning = new GroupPolicyCertificatePinning +// { +// Chains = new GroupPolicyCertificatePinningChain[] { +// new GroupPolicyCertificatePinningChain +// { +// Chain = new GroupPolicyCertificatePinningDetails[] +// { +// new GroupPolicyCertificatePinningDetails +// { +// Validation = new string[] { "publickey" }, +// EmbeddedCertificate = TestCommon.GetTestServerCertificateHexString() +// }, +// new GroupPolicyCertificatePinningDetails +// { +// Validation = new string[] { "subject", "issuer" }, +// EmbeddedCertificate = TestCommon.GetTestServerCertificateHexString() +// }, +// new GroupPolicyCertificatePinningDetails +// { +// Validation = new string[] { "subject", "issuer" }, +// EmbeddedCertificate = TestCommon.GetTestServerCertificateHexString() +// } +// } +// } +// } +// } +// } +// }); - try - { - var result = TestCommon.RunAICLICommand("search", $"-s {Constants.TestAlternateSourceName} foo --verbose-logs"); - Assert.AreEqual(Constants.ErrorCode.ERROR_PINNED_CERTIFICATE_MISMATCH, result.ExitCode); - } - finally - { - ResetTestSource(); - } - } - } -} +// try +// { +// var result = TestCommon.RunAICLICommand("search", $"-s {Constants.TestAlternateSourceName} foo --verbose-logs"); +// Assert.AreEqual(Constants.ErrorCode.ERROR_PINNED_CERTIFICATE_MISMATCH, result.ExitCode); +// } +// finally +// { +// ResetTestSource(); +// } +// } +// } +//} diff --git a/src/AppInstallerCLIE2ETests/ShowCommand.cs b/src/AppInstallerCLIE2ETests/ShowCommand.cs index 69a65e6043..575e3d1847 100644 --- a/src/AppInstallerCLIE2ETests/ShowCommand.cs +++ b/src/AppInstallerCLIE2ETests/ShowCommand.cs @@ -1,94 +1,94 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. +//// Copyright (c) Microsoft Corporation. +//// Licensed under the MIT License. -namespace AppInstallerCLIE2ETests -{ - using NUnit.Framework; +//namespace AppInstallerCLIE2ETests +//{ +// using NUnit.Framework; - public class ShowCommand : BaseCommand - { - [Test] - public void ShowWithNoArgs() - { - var result = TestCommon.RunAICLICommand("show", ""); - Assert.AreEqual(Constants.ErrorCode.ERROR_INVALID_CL_ARGUMENTS, result.ExitCode); - } +// public class ShowCommand : BaseCommand +// { +// [Test] +// public void ShowWithNoArgs() +// { +// var result = TestCommon.RunAICLICommand("show", ""); +// Assert.AreEqual(Constants.ErrorCode.ERROR_INVALID_CL_ARGUMENTS, result.ExitCode); +// } - [Test] - public void ShowWithNoMatches() - { - // Show with 0 search match shows a "please refine input" - var result = TestCommon.RunAICLICommand("show", $"DoesNotExist"); - Assert.AreEqual(Constants.ErrorCode.ERROR_NO_APPLICATIONS_FOUND, result.ExitCode); - Assert.True(result.StdOut.Contains("No package found matching input criteria.")); - } +// [Test] +// public void ShowWithNoMatches() +// { +// // Show with 0 search match shows a "please refine input" +// var result = TestCommon.RunAICLICommand("show", $"DoesNotExist"); +// Assert.AreEqual(Constants.ErrorCode.ERROR_NO_APPLICATIONS_FOUND, result.ExitCode); +// Assert.True(result.StdOut.Contains("No package found matching input criteria.")); +// } - [Test] - public void ShowWithSubstringMatch() - { - // Show with a substring match still returns 0 results - var result = TestCommon.RunAICLICommand("show", $"AppInstallerTest"); - Assert.AreEqual(Constants.ErrorCode.ERROR_NO_APPLICATIONS_FOUND, result.ExitCode); - Assert.True(result.StdOut.Contains("No package found matching input criteria.")); - } +// [Test] +// public void ShowWithSubstringMatch() +// { +// // Show with a substring match still returns 0 results +// var result = TestCommon.RunAICLICommand("show", $"AppInstallerTest"); +// Assert.AreEqual(Constants.ErrorCode.ERROR_NO_APPLICATIONS_FOUND, result.ExitCode); +// Assert.True(result.StdOut.Contains("No package found matching input criteria.")); +// } - [Test] - public void ShowWithNameMatch() - { - var result = TestCommon.RunAICLICommand("show", $"--name testexampleinstaller"); - Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); - Assert.True(result.StdOut.Contains("Found TestExampleInstaller [AppInstallerTest.TestExampleInstaller]")); - Assert.True(result.StdOut.Contains("TestExampleInstaller")); - Assert.True(result.StdOut.Contains("AppInstallerTest.TestExampleInstaller")); - } +// [Test] +// public void ShowWithNameMatch() +// { +// var result = TestCommon.RunAICLICommand("show", $"--name testexampleinstaller"); +// Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); +// Assert.True(result.StdOut.Contains("Found TestExampleInstaller [AppInstallerTest.TestExampleInstaller]")); +// Assert.True(result.StdOut.Contains("TestExampleInstaller")); +// Assert.True(result.StdOut.Contains("AppInstallerTest.TestExampleInstaller")); +// } - [Test] - public void ShowWithIDMatch() - { - var result = TestCommon.RunAICLICommand("show", $"--id appinstallertest.testexampleinstaller"); - Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); - Assert.True(result.StdOut.Contains("Found TestExampleInstaller [AppInstallerTest.TestExampleInstaller]")); - Assert.True(result.StdOut.Contains("TestExampleInstaller")); - Assert.True(result.StdOut.Contains("AppInstallerTest.TestExampleInstaller")); - } +// [Test] +// public void ShowWithIDMatch() +// { +// var result = TestCommon.RunAICLICommand("show", $"--id appinstallertest.testexampleinstaller"); +// Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); +// Assert.True(result.StdOut.Contains("Found TestExampleInstaller [AppInstallerTest.TestExampleInstaller]")); +// Assert.True(result.StdOut.Contains("TestExampleInstaller")); +// Assert.True(result.StdOut.Contains("AppInstallerTest.TestExampleInstaller")); +// } - [Test] - public void ShowWithVersions() - { - // Show with --versions list the versions - var result = TestCommon.RunAICLICommand("show", $"TestExampleInstaller --versions"); - Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); - Assert.True(result.StdOut.Contains("TestExampleInstaller")); - Assert.True(result.StdOut.Contains("AppInstallerTest.TestExampleInstaller")); - Assert.True(result.StdOut.Contains("1.2.3.4")); - } +// [Test] +// public void ShowWithVersions() +// { +// // Show with --versions list the versions +// var result = TestCommon.RunAICLICommand("show", $"TestExampleInstaller --versions"); +// Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); +// Assert.True(result.StdOut.Contains("TestExampleInstaller")); +// Assert.True(result.StdOut.Contains("AppInstallerTest.TestExampleInstaller")); +// Assert.True(result.StdOut.Contains("1.2.3.4")); +// } - [Test] - public void ShowWithExactName() - { - var result = TestCommon.RunAICLICommand("show", $"--exact TestExampleInstaller"); - Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); - Assert.True(result.StdOut.Contains("Found TestExampleInstaller [AppInstallerTest.TestExampleInstaller]")); - Assert.True(result.StdOut.Contains("TestExampleInstaller")); - Assert.True(result.StdOut.Contains("AppInstallerTest.TestExampleInstaller")); - } +// [Test] +// public void ShowWithExactName() +// { +// var result = TestCommon.RunAICLICommand("show", $"--exact TestExampleInstaller"); +// Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); +// Assert.True(result.StdOut.Contains("Found TestExampleInstaller [AppInstallerTest.TestExampleInstaller]")); +// Assert.True(result.StdOut.Contains("TestExampleInstaller")); +// Assert.True(result.StdOut.Contains("AppInstallerTest.TestExampleInstaller")); +// } - [Test] - public void ShowWithExactID() - { - var result = TestCommon.RunAICLICommand("show", $"--exact AppInstallerTest.TestExampleInstaller"); - Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); - Assert.True(result.StdOut.Contains("Found TestExampleInstaller [AppInstallerTest.TestExampleInstaller]")); - Assert.True(result.StdOut.Contains("TestExampleInstaller")); - Assert.True(result.StdOut.Contains("AppInstallerTest.TestExampleInstaller")); - } +// [Test] +// public void ShowWithExactID() +// { +// var result = TestCommon.RunAICLICommand("show", $"--exact AppInstallerTest.TestExampleInstaller"); +// Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); +// Assert.True(result.StdOut.Contains("Found TestExampleInstaller [AppInstallerTest.TestExampleInstaller]")); +// Assert.True(result.StdOut.Contains("TestExampleInstaller")); +// Assert.True(result.StdOut.Contains("AppInstallerTest.TestExampleInstaller")); +// } - [Test] - public void ShowWithExactArgCaseSensitivity() - { - var result = TestCommon.RunAICLICommand("show", $"--exact testexampleinstaller"); - Assert.AreEqual(Constants.ErrorCode.ERROR_NO_APPLICATIONS_FOUND, result.ExitCode); - Assert.True(result.StdOut.Contains("No package found matching input criteria.")); - } - } -} \ No newline at end of file +// [Test] +// public void ShowWithExactArgCaseSensitivity() +// { +// var result = TestCommon.RunAICLICommand("show", $"--exact testexampleinstaller"); +// Assert.AreEqual(Constants.ErrorCode.ERROR_NO_APPLICATIONS_FOUND, result.ExitCode); +// Assert.True(result.StdOut.Contains("No package found matching input criteria.")); +// } +// } +//} \ No newline at end of file diff --git a/src/AppInstallerCLIE2ETests/SourceCommand.cs b/src/AppInstallerCLIE2ETests/SourceCommand.cs index e2cc644589..b13f2c00ba 100644 --- a/src/AppInstallerCLIE2ETests/SourceCommand.cs +++ b/src/AppInstallerCLIE2ETests/SourceCommand.cs @@ -1,139 +1,139 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -namespace AppInstallerCLIE2ETests -{ - using NUnit.Framework; - - public class SourceCommand : BaseCommand - { - [SetUp] - public void Setup() - { - ResetTestSource(false); - } - - [Test] - public void SourceAdd() - { - var result = TestCommon.RunAICLICommand("source add", $"SourceTest {Constants.TestSourceUrl}"); - Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); - Assert.True(result.StdOut.Contains("Done")); - TestCommon.RunAICLICommand("source remove", $"-n SourceTest"); - } - - [Test] - public void SourceAddWithDuplicateName() - { - // Add source with duplicate name should fail - var result = TestCommon.RunAICLICommand("source add", $"{Constants.TestSourceName} https://microsoft.com"); - Assert.AreEqual(Constants.ErrorCode.ERROR_SOURCE_NAME_ALREADY_EXISTS, result.ExitCode); - Assert.True(result.StdOut.Contains("A source with the given name already exists and refers to a different location")); - } - - [Test] - public void SourceAddWithInvalidURL() - { - // Add source with invalid url should fail - var result = TestCommon.RunAICLICommand("source add", $"AnotherSource {Constants.TestSourceUrl}/Invalid/Directory/Dont/Add/Me"); - Assert.AreEqual(Constants.ErrorCode.HTTP_E_STATUS_NOT_FOUND, result.ExitCode); - Assert.True(result.StdOut.Contains("An unexpected error occurred while executing the command")); - } - - - [Test] - public void SourceAddWithHttpURL() - { - // Add source with an HTTP url should fail - var result = TestCommon.RunAICLICommand("source add", "Insecure http://microsoft.com"); - Assert.AreEqual(Constants.ErrorCode.ERROR_SOURCE_NOT_SECURE, result.ExitCode); - Assert.True(result.StdOut.Contains("error occurred while executing the command")); - } - - [Test] - public void SourceListWithNoArgs() - { - // List with no args should list all available sources - var result = TestCommon.RunAICLICommand("source list", ""); - Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); - Assert.True(result.StdOut.Contains(Constants.TestSourceUrl)); - } - - [Test] - public void SourceListWithName() - { - var result = TestCommon.RunAICLICommand("source list", $"-n {Constants.TestSourceName}"); - Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); - Assert.True(result.StdOut.Contains(Constants.TestSourceName)); - Assert.True(result.StdOut.Contains(Constants.TestSourceUrl)); - Assert.True(result.StdOut.Contains("Microsoft.PreIndexed.Package")); - Assert.True(result.StdOut.Contains("Updated")); - } - - [Test] - public void SourceListNameMismatch() - { - var result = TestCommon.RunAICLICommand("source list", "-n UnknownName"); - Assert.AreEqual(Constants.ErrorCode.ERROR_SOURCE_NAME_DOES_NOT_EXIST, result.ExitCode); - Assert.True(result.StdOut.Contains("Did not find a source named")); - } - - [Test] - public void SourceUpdate() - { - var result = TestCommon.RunAICLICommand("source update", $"-n {Constants.TestSourceName}"); - Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); - Assert.True(result.StdOut.Contains("Done")); - } - - [Test] - public void SourceUpdateWithInvalidName() - { - var result = TestCommon.RunAICLICommand("source update", "-n UnknownName"); - Assert.AreEqual(Constants.ErrorCode.ERROR_SOURCE_NAME_DOES_NOT_EXIST, result.ExitCode); - Assert.True(result.StdOut.Contains("Did not find a source named: UnknownName")); - } - - [Test] - public void SourceRemoveValidName() - { - var result = TestCommon.RunAICLICommand("source remove", $"-n {Constants.TestSourceName}"); - Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); - Assert.True(result.StdOut.Contains("Done")); - ResetTestSource(false); - } - - [Test] - public void SourceRemoveInvalidName() - { - var result = TestCommon.RunAICLICommand("source remove", "-n UnknownName"); - Assert.AreEqual(Constants.ErrorCode.ERROR_SOURCE_NAME_DOES_NOT_EXIST, result.ExitCode); - Assert.True(result.StdOut.Contains("Did not find a source named: UnknownName")); - } - - [Test] - public void SourceReset() - { - var result = TestCommon.RunAICLICommand("source reset", ""); - Assert.True(result.StdOut.Contains("The following sources will be reset if the --force option is given:")); - Assert.True(result.StdOut.Contains(Constants.TestSourceName)); - Assert.True(result.StdOut.Contains(Constants.TestSourceUrl)); - } - - [Test] - public void SourceForceReset() - { - // Force Reset Sources - var result = TestCommon.RunAICLICommand("source reset", "--force"); - Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); - Assert.True(result.StdOut.Contains("Resetting all sources...Done")); - - //Verify sources have been reset - result = TestCommon.RunAICLICommand("source list", ""); - Assert.True(result.StdOut.Contains("winget")); - Assert.True(result.StdOut.Contains("https://cdn.winget.microsoft.com/cache")); - Assert.False(result.StdOut.Contains(Constants.TestSourceName)); - Assert.False(result.StdOut.Contains(Constants.TestSourceUrl)); - } - } -} \ No newline at end of file +//// Copyright (c) Microsoft Corporation. +//// Licensed under the MIT License. + +//namespace AppInstallerCLIE2ETests +//{ +// using NUnit.Framework; + +// public class SourceCommand : BaseCommand +// { +// [SetUp] +// public void Setup() +// { +// ResetTestSource(false); +// } + +// [Test] +// public void SourceAdd() +// { +// var result = TestCommon.RunAICLICommand("source add", $"SourceTest {Constants.TestSourceUrl}"); +// Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); +// Assert.True(result.StdOut.Contains("Done")); +// TestCommon.RunAICLICommand("source remove", $"-n SourceTest"); +// } + +// [Test] +// public void SourceAddWithDuplicateName() +// { +// // Add source with duplicate name should fail +// var result = TestCommon.RunAICLICommand("source add", $"{Constants.TestSourceName} https://microsoft.com"); +// Assert.AreEqual(Constants.ErrorCode.ERROR_SOURCE_NAME_ALREADY_EXISTS, result.ExitCode); +// Assert.True(result.StdOut.Contains("A source with the given name already exists and refers to a different location")); +// } + +// [Test] +// public void SourceAddWithInvalidURL() +// { +// // Add source with invalid url should fail +// var result = TestCommon.RunAICLICommand("source add", $"AnotherSource {Constants.TestSourceUrl}/Invalid/Directory/Dont/Add/Me"); +// Assert.AreEqual(Constants.ErrorCode.HTTP_E_STATUS_NOT_FOUND, result.ExitCode); +// Assert.True(result.StdOut.Contains("An unexpected error occurred while executing the command")); +// } + + +// [Test] +// public void SourceAddWithHttpURL() +// { +// // Add source with an HTTP url should fail +// var result = TestCommon.RunAICLICommand("source add", "Insecure http://microsoft.com"); +// Assert.AreEqual(Constants.ErrorCode.ERROR_SOURCE_NOT_SECURE, result.ExitCode); +// Assert.True(result.StdOut.Contains("error occurred while executing the command")); +// } + +// [Test] +// public void SourceListWithNoArgs() +// { +// // List with no args should list all available sources +// var result = TestCommon.RunAICLICommand("source list", ""); +// Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); +// Assert.True(result.StdOut.Contains(Constants.TestSourceUrl)); +// } + +// [Test] +// public void SourceListWithName() +// { +// var result = TestCommon.RunAICLICommand("source list", $"-n {Constants.TestSourceName}"); +// Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); +// Assert.True(result.StdOut.Contains(Constants.TestSourceName)); +// Assert.True(result.StdOut.Contains(Constants.TestSourceUrl)); +// Assert.True(result.StdOut.Contains("Microsoft.PreIndexed.Package")); +// Assert.True(result.StdOut.Contains("Updated")); +// } + +// [Test] +// public void SourceListNameMismatch() +// { +// var result = TestCommon.RunAICLICommand("source list", "-n UnknownName"); +// Assert.AreEqual(Constants.ErrorCode.ERROR_SOURCE_NAME_DOES_NOT_EXIST, result.ExitCode); +// Assert.True(result.StdOut.Contains("Did not find a source named")); +// } + +// [Test] +// public void SourceUpdate() +// { +// var result = TestCommon.RunAICLICommand("source update", $"-n {Constants.TestSourceName}"); +// Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); +// Assert.True(result.StdOut.Contains("Done")); +// } + +// [Test] +// public void SourceUpdateWithInvalidName() +// { +// var result = TestCommon.RunAICLICommand("source update", "-n UnknownName"); +// Assert.AreEqual(Constants.ErrorCode.ERROR_SOURCE_NAME_DOES_NOT_EXIST, result.ExitCode); +// Assert.True(result.StdOut.Contains("Did not find a source named: UnknownName")); +// } + +// [Test] +// public void SourceRemoveValidName() +// { +// var result = TestCommon.RunAICLICommand("source remove", $"-n {Constants.TestSourceName}"); +// Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); +// Assert.True(result.StdOut.Contains("Done")); +// ResetTestSource(false); +// } + +// [Test] +// public void SourceRemoveInvalidName() +// { +// var result = TestCommon.RunAICLICommand("source remove", "-n UnknownName"); +// Assert.AreEqual(Constants.ErrorCode.ERROR_SOURCE_NAME_DOES_NOT_EXIST, result.ExitCode); +// Assert.True(result.StdOut.Contains("Did not find a source named: UnknownName")); +// } + +// [Test] +// public void SourceReset() +// { +// var result = TestCommon.RunAICLICommand("source reset", ""); +// Assert.True(result.StdOut.Contains("The following sources will be reset if the --force option is given:")); +// Assert.True(result.StdOut.Contains(Constants.TestSourceName)); +// Assert.True(result.StdOut.Contains(Constants.TestSourceUrl)); +// } + +// [Test] +// public void SourceForceReset() +// { +// // Force Reset Sources +// var result = TestCommon.RunAICLICommand("source reset", "--force"); +// Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); +// Assert.True(result.StdOut.Contains("Resetting all sources...Done")); + +// //Verify sources have been reset +// result = TestCommon.RunAICLICommand("source list", ""); +// Assert.True(result.StdOut.Contains("winget")); +// Assert.True(result.StdOut.Contains("https://cdn.winget.microsoft.com/cache")); +// Assert.False(result.StdOut.Contains(Constants.TestSourceName)); +// Assert.False(result.StdOut.Contains(Constants.TestSourceUrl)); +// } +// } +//} \ No newline at end of file diff --git a/src/AppInstallerCLIE2ETests/UninstallCommand.cs b/src/AppInstallerCLIE2ETests/UninstallCommand.cs index 61a15dacbb..3ef0fb229c 100644 --- a/src/AppInstallerCLIE2ETests/UninstallCommand.cs +++ b/src/AppInstallerCLIE2ETests/UninstallCommand.cs @@ -1,170 +1,170 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. +//// Copyright (c) Microsoft Corporation. +//// Licensed under the MIT License. -namespace AppInstallerCLIE2ETests -{ - using NUnit.Framework; - using System.IO; +//namespace AppInstallerCLIE2ETests +//{ +// using NUnit.Framework; +// using System.IO; - public class UninstallCommand : BaseCommand - { - // Custom product code for overriding the default in the test exe - private const string CustomProductCode = "{f08fc03c-0b7e-4fca-9b3c-3a384d18a9f3}"; +// public class UninstallCommand : BaseCommand +// { +// // Custom product code for overriding the default in the test exe +// private const string CustomProductCode = "{f08fc03c-0b7e-4fca-9b3c-3a384d18a9f3}"; - // File written when uninstalling the test exe - private const string UninstallTestExeUninstalledFile = "TestExeUninstalled.txt"; +// // File written when uninstalling the test exe +// private const string UninstallTestExeUninstalledFile = "TestExeUninstalled.txt"; - // Name of a file installed by the MSI that will be removed during uninstall - private const string UninstallTestMsiInstalledFile = "AppInstallerTestExeInstaller.exe"; +// // Name of a file installed by the MSI that will be removed during uninstall +// private const string UninstallTestMsiInstalledFile = "AppInstallerTestExeInstaller.exe"; - // Package name of the test MSIX package - private const string UninstallTestMsixName = "6c6338fe-41b7-46ca-8ba6-b5ad5312bb0e"; +// // Package name of the test MSIX package +// private const string UninstallTestMsixName = "6c6338fe-41b7-46ca-8ba6-b5ad5312bb0e"; - [Test] - public void UninstallTestExe() - { - // Uninstall an Exe - var installDir = TestCommon.GetRandomTestDir(); - TestCommon.RunAICLICommand("install", $"{Constants.ExeInstallerPackageId} --silent -l {installDir}"); - var result = TestCommon.RunAICLICommand("uninstall", Constants.ExeInstallerPackageId); - Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); - Assert.True(result.StdOut.Contains("Successfully uninstalled")); - Assert.True(TestCommon.VerifyTestExeUninstalled(installDir)); - } +// [Test] +// public void UninstallTestExe() +// { +// // Uninstall an Exe +// var installDir = TestCommon.GetRandomTestDir(); +// TestCommon.RunAICLICommand("install", $"{Constants.ExeInstallerPackageId} --silent -l {installDir}"); +// var result = TestCommon.RunAICLICommand("uninstall", Constants.ExeInstallerPackageId); +// Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); +// Assert.True(result.StdOut.Contains("Successfully uninstalled")); +// Assert.True(TestCommon.VerifyTestExeUninstalled(installDir)); +// } - [Test] - public void UninstallTestMsi() - { - if (string.IsNullOrEmpty(TestCommon.MsiInstallerPath)) - { - Assert.Ignore("MSI installer not available"); - } +// [Test] +// public void UninstallTestMsi() +// { +// if (string.IsNullOrEmpty(TestCommon.MsiInstallerPath)) +// { +// Assert.Ignore("MSI installer not available"); +// } - // Uninstall an MSI - var installDir = TestCommon.GetRandomTestDir(); - TestCommon.RunAICLICommand("install", $"{Constants.MsiInstallerPackageId} -l {installDir}"); - var result = TestCommon.RunAICLICommand("uninstall", Constants.MsiInstallerPackageId); - Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); - Assert.True(result.StdOut.Contains("Successfully uninstalled")); - Assert.True(TestCommon.VerifyTestMsiUninstalled(installDir)); - } +// // Uninstall an MSI +// var installDir = TestCommon.GetRandomTestDir(); +// TestCommon.RunAICLICommand("install", $"{Constants.MsiInstallerPackageId} -l {installDir}"); +// var result = TestCommon.RunAICLICommand("uninstall", Constants.MsiInstallerPackageId); +// Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); +// Assert.True(result.StdOut.Contains("Successfully uninstalled")); +// Assert.True(TestCommon.VerifyTestMsiUninstalled(installDir)); +// } - [Test] - public void UninstallTestMsix() - { - // Uninstall an MSIX - TestCommon.RunAICLICommand("install", Constants.MsixInstallerPackageId); - var result = TestCommon.RunAICLICommand("uninstall", Constants.MsixInstallerPackageId); - Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); - Assert.True(result.StdOut.Contains("Successfully uninstalled")); - Assert.True(TestCommon.VerifyTestMsixUninstalled()); - } +// [Test] +// public void UninstallTestMsix() +// { +// // Uninstall an MSIX +// TestCommon.RunAICLICommand("install", Constants.MsixInstallerPackageId); +// var result = TestCommon.RunAICLICommand("uninstall", Constants.MsixInstallerPackageId); +// Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); +// Assert.True(result.StdOut.Contains("Successfully uninstalled")); +// Assert.True(TestCommon.VerifyTestMsixUninstalled()); +// } - [Test] - public void UninstallPortable() - { - // Uninstall a Portable - string installDir = Path.Combine(System.Environment.GetEnvironmentVariable("LocalAppData"), "Microsoft", "WinGet", "Packages"); - string packageId, commandAlias, fileName, packageDirName, productCode; - packageId = "AppInstallerTest.TestPortableExe"; - packageDirName = productCode = packageId + "_" + Constants.TestSourceIdentifier; - commandAlias = fileName = "AppInstallerTestExeInstaller.exe"; +// [Test] +// public void UninstallPortable() +// { +// // Uninstall a Portable +// string installDir = Path.Combine(System.Environment.GetEnvironmentVariable("LocalAppData"), "Microsoft", "WinGet", "Packages"); +// string packageId, commandAlias, fileName, packageDirName, productCode; +// packageId = "AppInstallerTest.TestPortableExe"; +// packageDirName = productCode = packageId + "_" + Constants.TestSourceIdentifier; +// commandAlias = fileName = "AppInstallerTestExeInstaller.exe"; - TestCommon.RunAICLICommand("install", $"{packageId}"); - var result = TestCommon.RunAICLICommand("uninstall", $"{packageId}"); - Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); - Assert.True(result.StdOut.Contains("Successfully uninstalled")); - TestCommon.VerifyPortablePackage(Path.Combine(installDir, packageDirName), commandAlias, fileName, productCode, false); - } +// TestCommon.RunAICLICommand("install", $"{packageId}"); +// var result = TestCommon.RunAICLICommand("uninstall", $"{packageId}"); +// Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); +// Assert.True(result.StdOut.Contains("Successfully uninstalled")); +// TestCommon.VerifyPortablePackage(Path.Combine(installDir, packageDirName), commandAlias, fileName, productCode, false); +// } - [Test] - public void UninstallPortableWithProductCode() - { - // Uninstall a Portable with ProductCode - string installDir = TestCommon.GetPortablePackagesDirectory(); - string packageId, commandAlias, fileName, packageDirName, productCode; - packageId = "AppInstallerTest.TestPortableExe"; - packageDirName = productCode = packageId + "_" + Constants.TestSourceIdentifier; - commandAlias = fileName = "AppInstallerTestExeInstaller.exe"; +// [Test] +// public void UninstallPortableWithProductCode() +// { +// // Uninstall a Portable with ProductCode +// string installDir = TestCommon.GetPortablePackagesDirectory(); +// string packageId, commandAlias, fileName, packageDirName, productCode; +// packageId = "AppInstallerTest.TestPortableExe"; +// packageDirName = productCode = packageId + "_" + Constants.TestSourceIdentifier; +// commandAlias = fileName = "AppInstallerTestExeInstaller.exe"; - TestCommon.RunAICLICommand("install", $"{packageId}"); - var result = TestCommon.RunAICLICommand("uninstall", $"--product-code {productCode}"); - Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); - Assert.True(result.StdOut.Contains("Successfully uninstalled")); - TestCommon.VerifyPortablePackage(Path.Combine(installDir, packageDirName), commandAlias, fileName, productCode, false); - } +// TestCommon.RunAICLICommand("install", $"{packageId}"); +// var result = TestCommon.RunAICLICommand("uninstall", $"--product-code {productCode}"); +// Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); +// Assert.True(result.StdOut.Contains("Successfully uninstalled")); +// TestCommon.VerifyPortablePackage(Path.Combine(installDir, packageDirName), commandAlias, fileName, productCode, false); +// } - [Test] - public void UninstallPortableModifiedSymlink() - { - string installDir = TestCommon.GetPortablePackagesDirectory(); - string packageId, commandAlias, fileName, packageDirName, productCode; - packageId = "AppInstallerTest.TestPortableExe"; - packageDirName = productCode = packageId + "_" + Constants.TestSourceIdentifier; - commandAlias = fileName = "AppInstallerTestExeInstaller.exe"; +// [Test] +// public void UninstallPortableModifiedSymlink() +// { +// string installDir = TestCommon.GetPortablePackagesDirectory(); +// string packageId, commandAlias, fileName, packageDirName, productCode; +// packageId = "AppInstallerTest.TestPortableExe"; +// packageDirName = productCode = packageId + "_" + Constants.TestSourceIdentifier; +// commandAlias = fileName = "AppInstallerTestExeInstaller.exe"; - TestCommon.RunAICLICommand("install", $"{packageId}"); +// TestCommon.RunAICLICommand("install", $"{packageId}"); - string symlinkDirectory = TestCommon.GetPortableSymlinkDirectory(TestCommon.Scope.User); - string symlinkPath = Path.Combine(symlinkDirectory, commandAlias); +// string symlinkDirectory = TestCommon.GetPortableSymlinkDirectory(TestCommon.Scope.User); +// string symlinkPath = Path.Combine(symlinkDirectory, commandAlias); - // Replace symlink with modified symlink - File.Delete(symlinkPath); - FileSystemInfo modifiedSymlinkInfo = File.CreateSymbolicLink(symlinkPath, "fakeTargetExe"); +// // Replace symlink with modified symlink +// File.Delete(symlinkPath); +// FileSystemInfo modifiedSymlinkInfo = File.CreateSymbolicLink(symlinkPath, "fakeTargetExe"); - var result = TestCommon.RunAICLICommand("uninstall", $"{packageId}"); - Assert.AreEqual(Constants.ErrorCode.ERROR_PORTABLE_UNINSTALL_FAILED, result.ExitCode); - Assert.True(result.StdOut.Contains("Unable to remove Portable package as it has been modified; to override this check use --force")); - Assert.True(modifiedSymlinkInfo.Exists, "Modified symlink should still exist"); +// var result = TestCommon.RunAICLICommand("uninstall", $"{packageId}"); +// Assert.AreEqual(Constants.ErrorCode.ERROR_PORTABLE_UNINSTALL_FAILED, result.ExitCode); +// Assert.True(result.StdOut.Contains("Unable to remove Portable package as it has been modified; to override this check use --force")); +// Assert.True(modifiedSymlinkInfo.Exists, "Modified symlink should still exist"); - // Try again with --force - var result2 = TestCommon.RunAICLICommand("uninstall", $"{packageId} --force"); - Assert.AreEqual(Constants.ErrorCode.S_OK, result2.ExitCode); - Assert.True(result2.StdOut.Contains("Portable package has been modified; proceeding due to --force")); - Assert.True(result2.StdOut.Contains("Successfully uninstalled")); +// // Try again with --force +// var result2 = TestCommon.RunAICLICommand("uninstall", $"{packageId} --force"); +// Assert.AreEqual(Constants.ErrorCode.S_OK, result2.ExitCode); +// Assert.True(result2.StdOut.Contains("Portable package has been modified; proceeding due to --force")); +// Assert.True(result2.StdOut.Contains("Successfully uninstalled")); - TestCommon.VerifyPortablePackage(Path.Combine(installDir, packageDirName), commandAlias, fileName, productCode, false); - } +// TestCommon.VerifyPortablePackage(Path.Combine(installDir, packageDirName), commandAlias, fileName, productCode, false); +// } - [Test] - public void UninstallZip_Portable() - { - string installDir = TestCommon.GetPortablePackagesDirectory(); - string packageId, commandAlias, fileName, packageDirName, productCode; - packageId = "AppInstallerTest.TestZipInstallerWithPortable"; - packageDirName = productCode = packageId + "_" + Constants.TestSourceIdentifier; - commandAlias = "TestPortable.exe"; - fileName = "AppInstallerTestExeInstaller.exe"; +// [Test] +// public void UninstallZip_Portable() +// { +// string installDir = TestCommon.GetPortablePackagesDirectory(); +// string packageId, commandAlias, fileName, packageDirName, productCode; +// packageId = "AppInstallerTest.TestZipInstallerWithPortable"; +// packageDirName = productCode = packageId + "_" + Constants.TestSourceIdentifier; +// commandAlias = "TestPortable.exe"; +// fileName = "AppInstallerTestExeInstaller.exe"; - var testreuslt = TestCommon.RunAICLICommand("install", $"{packageId}"); - var result = TestCommon.RunAICLICommand("uninstall", $"{packageId}"); - Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); - Assert.True(result.StdOut.Contains("Successfully uninstalled")); - TestCommon.VerifyPortablePackage(Path.Combine(installDir, packageDirName), commandAlias, fileName, productCode, false); - } +// var testreuslt = TestCommon.RunAICLICommand("install", $"{packageId}"); +// var result = TestCommon.RunAICLICommand("uninstall", $"{packageId}"); +// Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); +// Assert.True(result.StdOut.Contains("Successfully uninstalled")); +// TestCommon.VerifyPortablePackage(Path.Combine(installDir, packageDirName), commandAlias, fileName, productCode, false); +// } - [Test] - public void UninstallNotIndexed() - { - // Uninstalls a package found with ARP not matching any known manifest. - // Install the test EXE providing a custom Product Code so that it cannot be mapped - // back to its manifest, then uninstall it using its Product Code - var installDir = TestCommon.GetRandomTestDir(); - TestCommon.RunAICLICommand("install", $"{Constants.ExeInstallerPackageId} --override \"/ProductID {CustomProductCode} /InstallDir {installDir}"); - var result = TestCommon.RunAICLICommand("uninstall", CustomProductCode); - Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); - Assert.True(result.StdOut.Contains("Successfully uninstalled")); - Assert.True(TestCommon.VerifyTestExeUninstalled(installDir)); - } +// [Test] +// public void UninstallNotIndexed() +// { +// // Uninstalls a package found with ARP not matching any known manifest. +// // Install the test EXE providing a custom Product Code so that it cannot be mapped +// // back to its manifest, then uninstall it using its Product Code +// var installDir = TestCommon.GetRandomTestDir(); +// TestCommon.RunAICLICommand("install", $"{Constants.ExeInstallerPackageId} --override \"/ProductID {CustomProductCode} /InstallDir {installDir}"); +// var result = TestCommon.RunAICLICommand("uninstall", CustomProductCode); +// Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); +// Assert.True(result.StdOut.Contains("Successfully uninstalled")); +// Assert.True(TestCommon.VerifyTestExeUninstalled(installDir)); +// } - [Test] - public void UninstallAppNotInstalled() - { - // Verify failure when trying to uninstall an app that is not installed. - var result = TestCommon.RunAICLICommand("uninstall", $"TestMsixInstaller"); - Assert.AreEqual(Constants.ErrorCode.ERROR_NO_APPLICATIONS_FOUND, result.ExitCode); - Assert.True(result.StdOut.Contains("No installed package found matching input criteria.")); - } - } -} +// [Test] +// public void UninstallAppNotInstalled() +// { +// // Verify failure when trying to uninstall an app that is not installed. +// var result = TestCommon.RunAICLICommand("uninstall", $"TestMsixInstaller"); +// Assert.AreEqual(Constants.ErrorCode.ERROR_NO_APPLICATIONS_FOUND, result.ExitCode); +// Assert.True(result.StdOut.Contains("No installed package found matching input criteria.")); +// } +// } +//} diff --git a/src/AppInstallerCLIE2ETests/UpgradeCommand.cs b/src/AppInstallerCLIE2ETests/UpgradeCommand.cs index 293fdc18b0..c63b454b72 100644 --- a/src/AppInstallerCLIE2ETests/UpgradeCommand.cs +++ b/src/AppInstallerCLIE2ETests/UpgradeCommand.cs @@ -1,137 +1,137 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -namespace AppInstallerCLIE2ETests -{ - using NUnit.Framework; - using System.IO; - - public class UpgradeCommand : BaseCommand - { - [Test] - public void UpgradePortable() - { - string installDir = TestCommon.GetPortablePackagesDirectory(); - string packageId, commandAlias, fileName, packageDirName, productCode; - packageId = "AppInstallerTest.TestPortableExe"; - packageDirName = productCode = packageId + "_" + Constants.TestSourceIdentifier; - commandAlias = fileName = "AppInstallerTestExeInstaller.exe"; - - var result = TestCommon.RunAICLICommand("install", "AppInstallerTest.TestPortableExe -v 1.0.0.0"); - Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); - Assert.True(result.StdOut.Contains("Successfully installed")); +//// Copyright (c) Microsoft Corporation. +//// Licensed under the MIT License. + +//namespace AppInstallerCLIE2ETests +//{ +// using NUnit.Framework; +// using System.IO; + +// public class UpgradeCommand : BaseCommand +// { +// [Test] +// public void UpgradePortable() +// { +// string installDir = TestCommon.GetPortablePackagesDirectory(); +// string packageId, commandAlias, fileName, packageDirName, productCode; +// packageId = "AppInstallerTest.TestPortableExe"; +// packageDirName = productCode = packageId + "_" + Constants.TestSourceIdentifier; +// commandAlias = fileName = "AppInstallerTestExeInstaller.exe"; + +// var result = TestCommon.RunAICLICommand("install", "AppInstallerTest.TestPortableExe -v 1.0.0.0"); +// Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); +// Assert.True(result.StdOut.Contains("Successfully installed")); - var result2 = TestCommon.RunAICLICommand("upgrade", $"{packageId} -v 2.0.0.0"); - Assert.AreEqual(Constants.ErrorCode.S_OK, result2.ExitCode); - Assert.True(result2.StdOut.Contains("Successfully installed")); - TestCommon.VerifyPortablePackage(Path.Combine(installDir, packageDirName), commandAlias, fileName, productCode, true); - } - - [Test] - public void UpgradePortableARPMismatch() - { - string packageId = "AppInstallerTest.TestPortableExe"; - string productCode = packageId + "_" + Constants.TestSourceIdentifier; - - var installResult = TestCommon.RunAICLICommand("install", "AppInstallerTest.TestPortableExe -v 1.0.0.0"); - Assert.AreEqual(Constants.ErrorCode.S_OK, installResult.ExitCode); - Assert.True(installResult.StdOut.Contains("Successfully installed")); - - // Modify packageId to cause mismatch. - TestCommon.ModifyPortableARPEntryValue(productCode, Constants.WinGetPackageIdentifier, "testPackageId"); - - var upgradeResult = TestCommon.RunAICLICommand("upgrade", $"{packageId} -v 2.0.0.0"); - - // Reset and perform uninstall cleanup - TestCommon.ModifyPortableARPEntryValue(productCode, Constants.WinGetPackageIdentifier, packageId); - TestCommon.RunAICLICommand("uninstall", $"--product-code {productCode}"); - - Assert.AreNotEqual(Constants.ErrorCode.S_OK, upgradeResult.ExitCode); - Assert.True(upgradeResult.StdOut.Contains("Portable package from a different source already exists")); - } - - [Test] - public void UpgradePortableForcedOverride() - { - string installDir = TestCommon.GetPortablePackagesDirectory(); - string packageId, commandAlias, fileName, packageDirName, productCode; - packageId = "AppInstallerTest.TestPortableExe"; - packageDirName = productCode = packageId + "_" + Constants.TestSourceIdentifier; - commandAlias = fileName = "AppInstallerTestExeInstaller.exe"; - - var installResult = TestCommon.RunAICLICommand("install", "AppInstallerTest.TestPortableExe -v 1.0.0.0"); - Assert.AreEqual(Constants.ErrorCode.S_OK, installResult.ExitCode); - Assert.True(installResult.StdOut.Contains("Successfully installed")); - - // Modify packageId and sourceId to cause mismatch. - TestCommon.ModifyPortableARPEntryValue(productCode, Constants.WinGetPackageIdentifier, "testPackageId"); - TestCommon.ModifyPortableARPEntryValue(productCode, Constants.WinGetSourceIdentifier, "testSourceId"); - - var upgradeResult = TestCommon.RunAICLICommand("upgrade", $"{packageId} -v 2.0.0.0 --force"); - Assert.AreEqual(Constants.ErrorCode.S_OK, upgradeResult.ExitCode); - Assert.True(upgradeResult.StdOut.Contains("Successfully installed")); - TestCommon.VerifyPortablePackage(Path.Combine(installDir, packageDirName), commandAlias, fileName, productCode, true); - } - - [Test] - public void UpgradePortableUninstallPrevious() - { - string installDir = TestCommon.GetPortablePackagesDirectory(); - string packageId, commandAlias, fileName, packageDirName, productCode; - packageId = "AppInstallerTest.TestPortableExe"; - packageDirName = productCode = packageId + "_" + Constants.TestSourceIdentifier; - commandAlias = fileName = "AppInstallerTestExeInstaller.exe"; - - var result = TestCommon.RunAICLICommand("install", $"{packageId} -v 1.0.0.0"); - Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); - Assert.True(result.StdOut.Contains("Successfully installed")); - - var result2 = TestCommon.RunAICLICommand("upgrade", $"{packageId} -v 3.0.0.0"); - Assert.AreEqual(Constants.ErrorCode.S_OK, result2.ExitCode); - Assert.True(result2.StdOut.Contains("Successfully installed")); - TestCommon.VerifyPortablePackage(Path.Combine(installDir, packageDirName), commandAlias, fileName, productCode, true); - } - - [Test] - public void UpgradePortableMachineScope() - { - string installDir = TestCommon.GetRandomTestDir(); - ConfigureInstallBehavior(Constants.PortablePackageMachineRoot, installDir); - - string packageId, commandAlias, fileName, packageDirName, productCode; - packageId = "AppInstallerTest.TestPortableExe"; - packageDirName = productCode = packageId + "_" + Constants.TestSourceIdentifier; - commandAlias = fileName = "AppInstallerTestExeInstaller.exe"; - - var result = TestCommon.RunAICLICommand("install", $"{packageId} -v 1.0.0.0 --scope machine"); - Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); - Assert.True(result.StdOut.Contains("Successfully installed")); - - var result2 = TestCommon.RunAICLICommand("upgrade", $"{packageId} -v 2.0.0.0"); - ConfigureInstallBehavior(Constants.PortablePackageMachineRoot, string.Empty); - Assert.AreEqual(Constants.ErrorCode.S_OK, result2.ExitCode); - Assert.True(result2.StdOut.Contains("Successfully installed")); - TestCommon.VerifyPortablePackage(Path.Combine(installDir, packageDirName), commandAlias, fileName, productCode, true, TestCommon.Scope.Machine); - } - - [Test] - public void UpgradeZip_Portable() - { - string installDir = TestCommon.GetPortablePackagesDirectory(); - string packageId, commandAlias, fileName, packageDirName, productCode; - packageId = "AppInstallerTest.TestZipInstallerWithPortable"; - packageDirName = productCode = packageId + "_" + Constants.TestSourceIdentifier; - commandAlias = "TestPortable.exe"; - fileName = "AppInstallerTestExeInstaller.exe"; - - var result = TestCommon.RunAICLICommand("install", $"AppInstallerTest.TestZipInstallerWithPortable -v 1.0.0.0"); - Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); - Assert.True(result.StdOut.Contains("Successfully installed")); - - var result2 = TestCommon.RunAICLICommand("upgrade", $"{packageId} -v 2.0.0.0"); - Assert.AreEqual(Constants.ErrorCode.S_OK, result2.ExitCode); - Assert.True(result2.StdOut.Contains("Successfully installed")); - TestCommon.VerifyPortablePackage(Path.Combine(installDir, packageDirName), commandAlias, fileName, productCode, true, TestCommon.Scope.User); - } - } -} +// var result2 = TestCommon.RunAICLICommand("upgrade", $"{packageId} -v 2.0.0.0"); +// Assert.AreEqual(Constants.ErrorCode.S_OK, result2.ExitCode); +// Assert.True(result2.StdOut.Contains("Successfully installed")); +// TestCommon.VerifyPortablePackage(Path.Combine(installDir, packageDirName), commandAlias, fileName, productCode, true); +// } + +// [Test] +// public void UpgradePortableARPMismatch() +// { +// string packageId = "AppInstallerTest.TestPortableExe"; +// string productCode = packageId + "_" + Constants.TestSourceIdentifier; + +// var installResult = TestCommon.RunAICLICommand("install", "AppInstallerTest.TestPortableExe -v 1.0.0.0"); +// Assert.AreEqual(Constants.ErrorCode.S_OK, installResult.ExitCode); +// Assert.True(installResult.StdOut.Contains("Successfully installed")); + +// // Modify packageId to cause mismatch. +// TestCommon.ModifyPortableARPEntryValue(productCode, Constants.WinGetPackageIdentifier, "testPackageId"); + +// var upgradeResult = TestCommon.RunAICLICommand("upgrade", $"{packageId} -v 2.0.0.0"); + +// // Reset and perform uninstall cleanup +// TestCommon.ModifyPortableARPEntryValue(productCode, Constants.WinGetPackageIdentifier, packageId); +// TestCommon.RunAICLICommand("uninstall", $"--product-code {productCode}"); + +// Assert.AreNotEqual(Constants.ErrorCode.S_OK, upgradeResult.ExitCode); +// Assert.True(upgradeResult.StdOut.Contains("Portable package from a different source already exists")); +// } + +// [Test] +// public void UpgradePortableForcedOverride() +// { +// string installDir = TestCommon.GetPortablePackagesDirectory(); +// string packageId, commandAlias, fileName, packageDirName, productCode; +// packageId = "AppInstallerTest.TestPortableExe"; +// packageDirName = productCode = packageId + "_" + Constants.TestSourceIdentifier; +// commandAlias = fileName = "AppInstallerTestExeInstaller.exe"; + +// var installResult = TestCommon.RunAICLICommand("install", "AppInstallerTest.TestPortableExe -v 1.0.0.0"); +// Assert.AreEqual(Constants.ErrorCode.S_OK, installResult.ExitCode); +// Assert.True(installResult.StdOut.Contains("Successfully installed")); + +// // Modify packageId and sourceId to cause mismatch. +// TestCommon.ModifyPortableARPEntryValue(productCode, Constants.WinGetPackageIdentifier, "testPackageId"); +// TestCommon.ModifyPortableARPEntryValue(productCode, Constants.WinGetSourceIdentifier, "testSourceId"); + +// var upgradeResult = TestCommon.RunAICLICommand("upgrade", $"{packageId} -v 2.0.0.0 --force"); +// Assert.AreEqual(Constants.ErrorCode.S_OK, upgradeResult.ExitCode); +// Assert.True(upgradeResult.StdOut.Contains("Successfully installed")); +// TestCommon.VerifyPortablePackage(Path.Combine(installDir, packageDirName), commandAlias, fileName, productCode, true); +// } + +// [Test] +// public void UpgradePortableUninstallPrevious() +// { +// string installDir = TestCommon.GetPortablePackagesDirectory(); +// string packageId, commandAlias, fileName, packageDirName, productCode; +// packageId = "AppInstallerTest.TestPortableExe"; +// packageDirName = productCode = packageId + "_" + Constants.TestSourceIdentifier; +// commandAlias = fileName = "AppInstallerTestExeInstaller.exe"; + +// var result = TestCommon.RunAICLICommand("install", $"{packageId} -v 1.0.0.0"); +// Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); +// Assert.True(result.StdOut.Contains("Successfully installed")); + +// var result2 = TestCommon.RunAICLICommand("upgrade", $"{packageId} -v 3.0.0.0"); +// Assert.AreEqual(Constants.ErrorCode.S_OK, result2.ExitCode); +// Assert.True(result2.StdOut.Contains("Successfully installed")); +// TestCommon.VerifyPortablePackage(Path.Combine(installDir, packageDirName), commandAlias, fileName, productCode, true); +// } + +// [Test] +// public void UpgradePortableMachineScope() +// { +// string installDir = TestCommon.GetRandomTestDir(); +// ConfigureInstallBehavior(Constants.PortablePackageMachineRoot, installDir); + +// string packageId, commandAlias, fileName, packageDirName, productCode; +// packageId = "AppInstallerTest.TestPortableExe"; +// packageDirName = productCode = packageId + "_" + Constants.TestSourceIdentifier; +// commandAlias = fileName = "AppInstallerTestExeInstaller.exe"; + +// var result = TestCommon.RunAICLICommand("install", $"{packageId} -v 1.0.0.0 --scope machine"); +// Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); +// Assert.True(result.StdOut.Contains("Successfully installed")); + +// var result2 = TestCommon.RunAICLICommand("upgrade", $"{packageId} -v 2.0.0.0"); +// ConfigureInstallBehavior(Constants.PortablePackageMachineRoot, string.Empty); +// Assert.AreEqual(Constants.ErrorCode.S_OK, result2.ExitCode); +// Assert.True(result2.StdOut.Contains("Successfully installed")); +// TestCommon.VerifyPortablePackage(Path.Combine(installDir, packageDirName), commandAlias, fileName, productCode, true, TestCommon.Scope.Machine); +// } + +// [Test] +// public void UpgradeZip_Portable() +// { +// string installDir = TestCommon.GetPortablePackagesDirectory(); +// string packageId, commandAlias, fileName, packageDirName, productCode; +// packageId = "AppInstallerTest.TestZipInstallerWithPortable"; +// packageDirName = productCode = packageId + "_" + Constants.TestSourceIdentifier; +// commandAlias = "TestPortable.exe"; +// fileName = "AppInstallerTestExeInstaller.exe"; + +// var result = TestCommon.RunAICLICommand("install", $"AppInstallerTest.TestZipInstallerWithPortable -v 1.0.0.0"); +// Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); +// Assert.True(result.StdOut.Contains("Successfully installed")); + +// var result2 = TestCommon.RunAICLICommand("upgrade", $"{packageId} -v 2.0.0.0"); +// Assert.AreEqual(Constants.ErrorCode.S_OK, result2.ExitCode); +// Assert.True(result2.StdOut.Contains("Successfully installed")); +// TestCommon.VerifyPortablePackage(Path.Combine(installDir, packageDirName), commandAlias, fileName, productCode, true, TestCommon.Scope.User); +// } +// } +//} diff --git a/src/AppInstallerCLIE2ETests/ValidateCommand.cs b/src/AppInstallerCLIE2ETests/ValidateCommand.cs index 1a8e45e54d..744188004d 100644 --- a/src/AppInstallerCLIE2ETests/ValidateCommand.cs +++ b/src/AppInstallerCLIE2ETests/ValidateCommand.cs @@ -1,42 +1,42 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. +//// Copyright (c) Microsoft Corporation. +//// Licensed under the MIT License. -namespace AppInstallerCLIE2ETests -{ - using NUnit.Framework; +//namespace AppInstallerCLIE2ETests +//{ +// using NUnit.Framework; - public class ValidateCommand : BaseCommand - { - [Test] - public void ValidateManifest() - { - var result = TestCommon.RunAICLICommand("validate", TestCommon.GetTestDataFile("Manifests\\TestValidManifest.yaml")); - Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); - Assert.True(result.StdOut.Contains("Manifest validation succeeded.")); - } +// public class ValidateCommand : BaseCommand +// { +// [Test] +// public void ValidateManifest() +// { +// var result = TestCommon.RunAICLICommand("validate", TestCommon.GetTestDataFile("Manifests\\TestValidManifest.yaml")); +// Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); +// Assert.True(result.StdOut.Contains("Manifest validation succeeded.")); +// } - [Test] - public void ValidateManifestWithExtendedCharacter() - { - var result = TestCommon.RunAICLICommand("validate", TestCommon.GetTestDataFile("Manifests\\TëstExeInstaller.yaml")); - Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); - Assert.True(result.StdOut.Contains("Manifest validation succeeded.")); - } +// [Test] +// public void ValidateManifestWithExtendedCharacter() +// { +// var result = TestCommon.RunAICLICommand("validate", TestCommon.GetTestDataFile("Manifests\\TëstExeInstaller.yaml")); +// Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); +// Assert.True(result.StdOut.Contains("Manifest validation succeeded.")); +// } - [Test] - public void ValidateInvalidManifest() - { - var result = TestCommon.RunAICLICommand("validate", TestCommon.GetTestDataFile("Manifests\\TestInvalidManifest.yaml")); - Assert.AreEqual(Constants.ErrorCode.ERROR_MANIFEST_VALIDATION_FAILURE, result.ExitCode); - Assert.True(result.StdOut.Contains("Manifest validation failed.")); - } +// [Test] +// public void ValidateInvalidManifest() +// { +// var result = TestCommon.RunAICLICommand("validate", TestCommon.GetTestDataFile("Manifests\\TestInvalidManifest.yaml")); +// Assert.AreEqual(Constants.ErrorCode.ERROR_MANIFEST_VALIDATION_FAILURE, result.ExitCode); +// Assert.True(result.StdOut.Contains("Manifest validation failed.")); +// } - [Test] - public void ValidateManifestDoesNotExist() - { - var result = TestCommon.RunAICLICommand("validate", TestCommon.GetTestDataFile("Manifests\\DoesNotExist")); - Assert.AreEqual(Constants.ErrorCode.ERROR_PATH_NOT_FOUND, result.ExitCode); - Assert.True(result.StdOut.Contains("Path does not exist")); - } - } -} \ No newline at end of file +// [Test] +// public void ValidateManifestDoesNotExist() +// { +// var result = TestCommon.RunAICLICommand("validate", TestCommon.GetTestDataFile("Manifests\\DoesNotExist")); +// Assert.AreEqual(Constants.ErrorCode.ERROR_PATH_NOT_FOUND, result.ExitCode); +// Assert.True(result.StdOut.Contains("Path does not exist")); +// } +// } +//} \ No newline at end of file diff --git a/src/AppInstallerCLIE2ETests/WinGetUtil/WinGetUtilCompareVersions.cs b/src/AppInstallerCLIE2ETests/WinGetUtil/WinGetUtilCompareVersions.cs index 84abc1825b..2dd1b577d9 100644 --- a/src/AppInstallerCLIE2ETests/WinGetUtil/WinGetUtilCompareVersions.cs +++ b/src/AppInstallerCLIE2ETests/WinGetUtil/WinGetUtilCompareVersions.cs @@ -1,33 +1,33 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. +//// Copyright (c) Microsoft Corporation. +//// Licensed under the MIT License. -namespace AppInstallerCLIE2ETests.WinGetUtil -{ - using NUnit.Framework; +//namespace AppInstallerCLIE2ETests.WinGetUtil +//{ +// using NUnit.Framework; - public class WinGetUtilCompareVersions - { - [Test] - // V1 = V2 - [TestCase("1.0.0.0", "1.0.0.0", 0)] - [TestCase("1.0.0", "1.0.0.0", 0)] - [TestCase("1.0", "1.0.0.0", 0)] - [TestCase("1", "1.0.0.0", 0)] - // V1 > V2 - [TestCase("1.0.0.1", "1.0.0.0", 1)] - [TestCase("1.0.1.0", "1.0.0.0", 1)] - [TestCase("1.1.0.0", "1.0.0.0", 1)] - [TestCase("2.0.0.0", "1.0.0.0", 1)] - // V1 < V2 - [TestCase("1.0.0.0", "1.0.0.1", -1)] - [TestCase("1.0.0.0", "1.0.1.0", -1)] - [TestCase("1.0.0.0", "1.1.0.0", -1)] - [TestCase("1.0.0.0", "2.0.0.0", -1)] - public void WinGetUtil_CompareVersions(string version1, string version2, int expectedResult) - { - // Compare versions - WinGetUtilWrapper.WinGetCompareVersions(version1, version2, out int result); - Assert.AreEqual(expectedResult, result); - } - } -} +// public class WinGetUtilCompareVersions +// { +// [Test] +// // V1 = V2 +// [TestCase("1.0.0.0", "1.0.0.0", 0)] +// [TestCase("1.0.0", "1.0.0.0", 0)] +// [TestCase("1.0", "1.0.0.0", 0)] +// [TestCase("1", "1.0.0.0", 0)] +// // V1 > V2 +// [TestCase("1.0.0.1", "1.0.0.0", 1)] +// [TestCase("1.0.1.0", "1.0.0.0", 1)] +// [TestCase("1.1.0.0", "1.0.0.0", 1)] +// [TestCase("2.0.0.0", "1.0.0.0", 1)] +// // V1 < V2 +// [TestCase("1.0.0.0", "1.0.0.1", -1)] +// [TestCase("1.0.0.0", "1.0.1.0", -1)] +// [TestCase("1.0.0.0", "1.1.0.0", -1)] +// [TestCase("1.0.0.0", "2.0.0.0", -1)] +// public void WinGetUtil_CompareVersions(string version1, string version2, int expectedResult) +// { +// // Compare versions +// WinGetUtilWrapper.WinGetCompareVersions(version1, version2, out int result); +// Assert.AreEqual(expectedResult, result); +// } +// } +//} diff --git a/src/AppInstallerCLIE2ETests/WinGetUtil/WinGetUtilDownload.cs b/src/AppInstallerCLIE2ETests/WinGetUtil/WinGetUtilDownload.cs index d31a6073a1..1ac94f5015 100644 --- a/src/AppInstallerCLIE2ETests/WinGetUtil/WinGetUtilDownload.cs +++ b/src/AppInstallerCLIE2ETests/WinGetUtil/WinGetUtilDownload.cs @@ -1,27 +1,27 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. +//// Copyright (c) Microsoft Corporation. +//// Licensed under the MIT License. -namespace AppInstallerCLIE2ETests.WinGetUtil -{ - using System.IO; - using System.Linq; - using NUnit.Framework; +//namespace AppInstallerCLIE2ETests.WinGetUtil +//{ +// using System.IO; +// using System.Linq; +// using NUnit.Framework; - public class WinGetUtilDownload - { - [Test] - public void WinGetUtil_Download() - { - uint hashSize = 32; - byte[] sha256Hash = new byte[hashSize]; - string installerUrl = @"https://localhost:5001/TestKit/AppInstallerTestExeInstaller/AppInstallerTestExeInstaller.exe"; - string filePath = TestCommon.GetRandomTestFile(".exe"); +// public class WinGetUtilDownload +// { +// [Test] +// public void WinGetUtil_Download() +// { +// uint hashSize = 32; +// byte[] sha256Hash = new byte[hashSize]; +// string installerUrl = @"https://localhost:5001/TestKit/AppInstallerTestExeInstaller/AppInstallerTestExeInstaller.exe"; +// string filePath = TestCommon.GetRandomTestFile(".exe"); - // Download - WinGetUtilWrapper.WinGetDownload(installerUrl, filePath, sha256Hash, hashSize); +// // Download +// WinGetUtilWrapper.WinGetDownload(installerUrl, filePath, sha256Hash, hashSize); - Assert.True(File.Exists(filePath)); - Assert.False(sha256Hash.All(byteVal => byteVal == 0)); - } - } -} +// Assert.True(File.Exists(filePath)); +// Assert.False(sha256Hash.All(byteVal => byteVal == 0)); +// } +// } +//} diff --git a/src/AppInstallerCLIE2ETests/WinGetUtil/WinGetUtilInstallerMetadataCollection.cs b/src/AppInstallerCLIE2ETests/WinGetUtil/WinGetUtilInstallerMetadataCollection.cs index d11c11128f..6f71bd72e0 100644 --- a/src/AppInstallerCLIE2ETests/WinGetUtil/WinGetUtilInstallerMetadataCollection.cs +++ b/src/AppInstallerCLIE2ETests/WinGetUtil/WinGetUtilInstallerMetadataCollection.cs @@ -1,77 +1,77 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. +//// Copyright (c) Microsoft Corporation. +//// Licensed under the MIT License. -namespace AppInstallerCLIE2ETests.WinGetUtil -{ - using Newtonsoft.Json; - using NUnit.Framework; - using System; - using System.IO; - using System.Runtime.InteropServices; +//namespace AppInstallerCLIE2ETests.WinGetUtil +//{ +// using Newtonsoft.Json; +// using NUnit.Framework; +// using System; +// using System.IO; +// using System.Runtime.InteropServices; - public class WinGetUtilInstallerMetadataCollection - { - [Test] - public void WinGetUtil_BeginCompleteInstallerMetadataCollection() - { - string logFilePath = TestCommon.GetRandomTestFile(".log"); - string inputJson = TestCommon.GetTestDataFile(@"WinGetUtil\InstallerMetadata\Minimal.json"); - string outputFilePath = TestCommon.GetRandomTestFile(".json"); +// public class WinGetUtilInstallerMetadataCollection +// { +// [Test] +// public void WinGetUtil_BeginCompleteInstallerMetadataCollection() +// { +// string logFilePath = TestCommon.GetRandomTestFile(".log"); +// string inputJson = TestCommon.GetTestDataFile(@"WinGetUtil\InstallerMetadata\Minimal.json"); +// string outputFilePath = TestCommon.GetRandomTestFile(".json"); - WinGetUtilWrapper.WinGetBeginInstallerMetadataCollection( - inputJson, - logFilePath, - WinGetUtilWrapper.WinGetBeginInstallerMetadataCollectionOptions.WinGetBeginInstallerMetadataCollectionOption_InputIsFilePath, - out IntPtr collectionHandle); +// WinGetUtilWrapper.WinGetBeginInstallerMetadataCollection( +// inputJson, +// logFilePath, +// WinGetUtilWrapper.WinGetBeginInstallerMetadataCollectionOptions.WinGetBeginInstallerMetadataCollectionOption_InputIsFilePath, +// out IntPtr collectionHandle); - Assert.AreNotEqual(IntPtr.Zero, collectionHandle); - Assert.True(File.Exists(logFilePath)); +// Assert.AreNotEqual(IntPtr.Zero, collectionHandle); +// Assert.True(File.Exists(logFilePath)); - WinGetUtilWrapper.WinGetCompleteInstallerMetadataCollection( - collectionHandle, - outputFilePath, - WinGetUtilWrapper.WinGetCompleteInstallerMetadataCollectionOptions.WinGetCompleteInstallerMetadataCollectionOption_None); +// WinGetUtilWrapper.WinGetCompleteInstallerMetadataCollection( +// collectionHandle, +// outputFilePath, +// WinGetUtilWrapper.WinGetCompleteInstallerMetadataCollectionOptions.WinGetCompleteInstallerMetadataCollectionOption_None); - string outputJson = File.ReadAllText(outputFilePath); - Assert.IsNotEmpty(JsonConvert.DeserializeObject(outputJson).ToString()); - } +// string outputJson = File.ReadAllText(outputFilePath); +// Assert.IsNotEmpty(JsonConvert.DeserializeObject(outputJson).ToString()); +// } - [Test] - public void WinGetUtil_MergeInstallerMetadata_Success() - { - string logFilePath = TestCommon.GetRandomTestFile(".log"); - string inputJsonPath = TestCommon.GetTestDataFile(@"WinGetUtil\InstallerMetadata\MergeValid.json"); - string inputJson = File.ReadAllText(inputJsonPath); +// [Test] +// public void WinGetUtil_MergeInstallerMetadata_Success() +// { +// string logFilePath = TestCommon.GetRandomTestFile(".log"); +// string inputJsonPath = TestCommon.GetTestDataFile(@"WinGetUtil\InstallerMetadata\MergeValid.json"); +// string inputJson = File.ReadAllText(inputJsonPath); - WinGetUtilWrapper.WinGetMergeInstallerMetadata( - inputJson, - out string outputJson, - 0, - logFilePath, - WinGetUtilWrapper.WinGetMergeInstallerMetadataOptions.WinGetMergeInstallerMetadataOptions_None); +// WinGetUtilWrapper.WinGetMergeInstallerMetadata( +// inputJson, +// out string outputJson, +// 0, +// logFilePath, +// WinGetUtilWrapper.WinGetMergeInstallerMetadataOptions.WinGetMergeInstallerMetadataOptions_None); - Assert.True(File.Exists(logFilePath)); - Assert.IsNotEmpty(JsonConvert.DeserializeObject(outputJson).ToString()); - } +// Assert.True(File.Exists(logFilePath)); +// Assert.IsNotEmpty(JsonConvert.DeserializeObject(outputJson).ToString()); +// } - [Test] - public void WinGetUtil_MergeInstallerMetadata_Fail_SubmissionMismatch() - { - string logFilePath = TestCommon.GetRandomTestFile(".log"); - string inputJsonPath = TestCommon.GetTestDataFile(@"WinGetUtil\InstallerMetadata\MergeSubmissionMismatch.json"); - string inputJson = File.ReadAllText(inputJsonPath); +// [Test] +// public void WinGetUtil_MergeInstallerMetadata_Fail_SubmissionMismatch() +// { +// string logFilePath = TestCommon.GetRandomTestFile(".log"); +// string inputJsonPath = TestCommon.GetTestDataFile(@"WinGetUtil\InstallerMetadata\MergeSubmissionMismatch.json"); +// string inputJson = File.ReadAllText(inputJsonPath); - Assert.Throws(() => - { - WinGetUtilWrapper.WinGetMergeInstallerMetadata( - inputJson, - out string outputJson, - 0, - logFilePath, - WinGetUtilWrapper.WinGetMergeInstallerMetadataOptions.WinGetMergeInstallerMetadataOptions_None); - }); +// Assert.Throws(() => +// { +// WinGetUtilWrapper.WinGetMergeInstallerMetadata( +// inputJson, +// out string outputJson, +// 0, +// logFilePath, +// WinGetUtilWrapper.WinGetMergeInstallerMetadataOptions.WinGetMergeInstallerMetadataOptions_None); +// }); - Assert.True(File.Exists(logFilePath)); - } - } -} +// Assert.True(File.Exists(logFilePath)); +// } +// } +//} diff --git a/src/AppInstallerCLIE2ETests/WinGetUtil/WinGetUtilLog.cs b/src/AppInstallerCLIE2ETests/WinGetUtil/WinGetUtilLog.cs index 635f3a4af4..2eac3d132b 100644 --- a/src/AppInstallerCLIE2ETests/WinGetUtil/WinGetUtilLog.cs +++ b/src/AppInstallerCLIE2ETests/WinGetUtil/WinGetUtilLog.cs @@ -8,7 +8,7 @@ namespace AppInstallerCLIE2ETests.WinGetUtil public class WinGetUtilLog { - [Test] + //[Test] public void WinGetUtil_Logging() { string filePath = TestCommon.GetRandomTestFile(".log"); diff --git a/src/AppInstallerCLIE2ETests/WinGetUtil/WinGetUtilManifest.cs b/src/AppInstallerCLIE2ETests/WinGetUtil/WinGetUtilManifest.cs index 8dee02baaf..2d42f09f7d 100644 --- a/src/AppInstallerCLIE2ETests/WinGetUtil/WinGetUtilManifest.cs +++ b/src/AppInstallerCLIE2ETests/WinGetUtil/WinGetUtilManifest.cs @@ -1,68 +1,68 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. +//// Copyright (c) Microsoft Corporation. +//// Licensed under the MIT License. -namespace AppInstallerCLIE2ETests.WinGetUtil -{ - using System; - using System.IO; - using NUnit.Framework; +//namespace AppInstallerCLIE2ETests.WinGetUtil +//{ +// using System; +// using System.IO; +// using NUnit.Framework; - public class WinGetUtilManifest - { - private IntPtr indexHandle; +// public class WinGetUtilManifest +// { +// private IntPtr indexHandle; - [SetUp] - public void SetUp() - { - this.indexHandle = IntPtr.Zero; - var sqliteFile = TestCommon.GetRandomTestFile(".db"); - uint majorVersion = 1; - uint minorVersion = 2; - WinGetUtilWrapper.WinGetSQLiteIndexCreate(sqliteFile, majorVersion, minorVersion, out this.indexHandle); ; - } +// [SetUp] +// public void SetUp() +// { +// this.indexHandle = IntPtr.Zero; +// var sqliteFile = TestCommon.GetRandomTestFile(".db"); +// uint majorVersion = 1; +// uint minorVersion = 2; +// WinGetUtilWrapper.WinGetSQLiteIndexCreate(sqliteFile, majorVersion, minorVersion, out this.indexHandle); ; +// } - [TearDown] - public void TearDown() - { - WinGetUtilWrapper.WinGetSQLiteIndexClose(this.indexHandle); - } +// [TearDown] +// public void TearDown() +// { +// WinGetUtilWrapper.WinGetSQLiteIndexClose(this.indexHandle); +// } - [Test] - [TestCase(WinGetUtilWrapper.CreateManifestOption.NoValidation)] - [TestCase(WinGetUtilWrapper.CreateManifestOption.SchemaAndSemanticValidation)] - public void WinGetUtil_ValidateManifest_Success(WinGetUtilWrapper.CreateManifestOption createManifestOption) - { - string manifestsDir = TestCommon.GetTestDataFile(@"WinGetUtil\Manifests\Unmerged\ValidateManifest"); - string mergedManifestPath = TestCommon.GetRandomTestFile(".yaml"); +// [Test] +// [TestCase(WinGetUtilWrapper.CreateManifestOption.NoValidation)] +// [TestCase(WinGetUtilWrapper.CreateManifestOption.SchemaAndSemanticValidation)] +// public void WinGetUtil_ValidateManifest_Success(WinGetUtilWrapper.CreateManifestOption createManifestOption) +// { +// string manifestsDir = TestCommon.GetTestDataFile(@"WinGetUtil\Manifests\Unmerged\ValidateManifest"); +// string mergedManifestPath = TestCommon.GetRandomTestFile(".yaml"); - // Create manifest - WinGetUtilWrapper.WinGetCreateManifest( - manifestsDir, - out bool succeeded, - out IntPtr manifestHandle, - out string createFailureMessage, - mergedManifestPath, - createManifestOption); +// // Create manifest +// WinGetUtilWrapper.WinGetCreateManifest( +// manifestsDir, +// out bool succeeded, +// out IntPtr manifestHandle, +// out string createFailureMessage, +// mergedManifestPath, +// createManifestOption); - Assert.True(succeeded); - Assert.AreNotEqual(IntPtr.Zero, manifestHandle); - Assert.IsNull(createFailureMessage); - Assert.True(File.Exists(mergedManifestPath)); +// Assert.True(succeeded); +// Assert.AreNotEqual(IntPtr.Zero, manifestHandle); +// Assert.IsNull(createFailureMessage); +// Assert.True(File.Exists(mergedManifestPath)); - // Validate manifest - WinGetUtilWrapper.WinGetValidateManifestV3( - manifestHandle, - indexHandle, - out WinGetUtilWrapper.ValidateManifestResultCode resultCode, - out string validateFailureMessage, - WinGetUtilWrapper.ValidateManifestOptionV2.ArpVersionValidation, - WinGetUtilWrapper.ValidateManifestOperationType.Add); +// // Validate manifest +// WinGetUtilWrapper.WinGetValidateManifestV3( +// manifestHandle, +// indexHandle, +// out WinGetUtilWrapper.ValidateManifestResultCode resultCode, +// out string validateFailureMessage, +// WinGetUtilWrapper.ValidateManifestOptionV2.ArpVersionValidation, +// WinGetUtilWrapper.ValidateManifestOperationType.Add); - Assert.AreEqual(WinGetUtilWrapper.ValidateManifestResultCode.Success, resultCode); - Assert.IsEmpty(validateFailureMessage); +// Assert.AreEqual(WinGetUtilWrapper.ValidateManifestResultCode.Success, resultCode); +// Assert.IsEmpty(validateFailureMessage); - // Close manifest - WinGetUtilWrapper.WinGetCloseManifest(manifestHandle); - } - } -} +// // Close manifest +// WinGetUtilWrapper.WinGetCloseManifest(manifestHandle); +// } +// } +//} diff --git a/src/AppInstallerCLIE2ETests/WinGetUtil/WinGetUtilSQLiteIndex.cs b/src/AppInstallerCLIE2ETests/WinGetUtil/WinGetUtilSQLiteIndex.cs index 652d04ad97..36d764f2b9 100644 --- a/src/AppInstallerCLIE2ETests/WinGetUtil/WinGetUtilSQLiteIndex.cs +++ b/src/AppInstallerCLIE2ETests/WinGetUtil/WinGetUtilSQLiteIndex.cs @@ -1,142 +1,142 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -namespace AppInstallerCLIE2ETests.WinGetUtil -{ - using System; - using System.IO; - using System.Runtime.InteropServices; - using NUnit.Framework; - - public class WinGetUtilSQLiteIndex - { - private string sqlitePath; - private readonly uint majorVersion = 1; - private readonly uint minorVersion = 2; - - // Manifest example 1 - private readonly string addManifestsFile_1 = TestCommon.GetTestDataFile(@"WinGetUtil\Manifests\Merged\WinGetUtilTest.Add.yaml"); - private readonly string updateManifestsFile_1 = TestCommon.GetTestDataFile(@"WinGetUtil\Manifests\Merged\WinGetUtilTest.Update.yaml"); - private readonly string relativePath_1 = @"manifests\a\AppInstallerTest\WinGetUtilTest\1.0.0.0\WinGetTest.yaml"; - - [SetUp] - public void SetUp() - { - this.sqlitePath = TestCommon.GetRandomTestFile(".sql"); - } - - [Test] - public void WinGetUtil_SQLiteIndex_AddManifest() - { - SQLiteIndex((indexHandle) => - { - // Add manifest - WinGetUtilWrapper.WinGetSQLiteIndexAddManifest(indexHandle, addManifestsFile_1, relativePath_1); - }); - } - - [Test] - public void WinGetUtil_SQLiteIndex_UpdateManifest_Success() - { - SQLiteIndex((indexHandle) => - { - // Add manifest - WinGetUtilWrapper.WinGetSQLiteIndexAddManifest(indexHandle, addManifestsFile_1, relativePath_1); +//// Copyright (c) Microsoft Corporation. +//// Licensed under the MIT License. + +//namespace AppInstallerCLIE2ETests.WinGetUtil +//{ +// using System; +// using System.IO; +// using System.Runtime.InteropServices; +// using NUnit.Framework; + +// public class WinGetUtilSQLiteIndex +// { +// private string sqlitePath; +// private readonly uint majorVersion = 1; +// private readonly uint minorVersion = 2; + +// // Manifest example 1 +// private readonly string addManifestsFile_1 = TestCommon.GetTestDataFile(@"WinGetUtil\Manifests\Merged\WinGetUtilTest.Add.yaml"); +// private readonly string updateManifestsFile_1 = TestCommon.GetTestDataFile(@"WinGetUtil\Manifests\Merged\WinGetUtilTest.Update.yaml"); +// private readonly string relativePath_1 = @"manifests\a\AppInstallerTest\WinGetUtilTest\1.0.0.0\WinGetTest.yaml"; + +// [SetUp] +// public void SetUp() +// { +// this.sqlitePath = TestCommon.GetRandomTestFile(".sql"); +// } + +// [Test] +// public void WinGetUtil_SQLiteIndex_AddManifest() +// { +// SQLiteIndex((indexHandle) => +// { +// // Add manifest +// WinGetUtilWrapper.WinGetSQLiteIndexAddManifest(indexHandle, addManifestsFile_1, relativePath_1); +// }); +// } + +// [Test] +// public void WinGetUtil_SQLiteIndex_UpdateManifest_Success() +// { +// SQLiteIndex((indexHandle) => +// { +// // Add manifest +// WinGetUtilWrapper.WinGetSQLiteIndexAddManifest(indexHandle, addManifestsFile_1, relativePath_1); - // Update manifest - WinGetUtilWrapper.WinGetSQLiteIndexUpdateManifest(indexHandle, updateManifestsFile_1, relativePath_1, out bool indexModified); - Assert.True(indexModified); - }); - } - - [Test] - public void WinGetUtil_SQLiteIndex_UpdateManifest_Fail_NotFound() - { - SQLiteIndex((indexHandle) => - { - // Update non-existing manifest - Assert.Throws(() => - { - WinGetUtilWrapper.WinGetSQLiteIndexUpdateManifest(indexHandle, updateManifestsFile_1, relativePath_1, out bool indexModified); - }); - }); - } - - [Test] - public void WinGetUtil_SQLiteIndex_RemoveManifest_Success() - { - SQLiteIndex((indexHandle) => - { - // Add manifest - WinGetUtilWrapper.WinGetSQLiteIndexAddManifest(indexHandle, addManifestsFile_1, relativePath_1); +// // Update manifest +// WinGetUtilWrapper.WinGetSQLiteIndexUpdateManifest(indexHandle, updateManifestsFile_1, relativePath_1, out bool indexModified); +// Assert.True(indexModified); +// }); +// } + +// [Test] +// public void WinGetUtil_SQLiteIndex_UpdateManifest_Fail_NotFound() +// { +// SQLiteIndex((indexHandle) => +// { +// // Update non-existing manifest +// Assert.Throws(() => +// { +// WinGetUtilWrapper.WinGetSQLiteIndexUpdateManifest(indexHandle, updateManifestsFile_1, relativePath_1, out bool indexModified); +// }); +// }); +// } + +// [Test] +// public void WinGetUtil_SQLiteIndex_RemoveManifest_Success() +// { +// SQLiteIndex((indexHandle) => +// { +// // Add manifest +// WinGetUtilWrapper.WinGetSQLiteIndexAddManifest(indexHandle, addManifestsFile_1, relativePath_1); - // Remove manifest - WinGetUtilWrapper.WinGetSQLiteIndexRemoveManifest(indexHandle, addManifestsFile_1, relativePath_1); - }); - } - - [Test] - public void WinGetUtil_SQLiteIndex_RemoveManifest_Fail_NotFound() - { - SQLiteIndex((indexHandle) => - { - // Remove non-existing manifest - Assert.Throws(() => - { - WinGetUtilWrapper.WinGetSQLiteIndexRemoveManifest(indexHandle, addManifestsFile_1, relativePath_1); - }); - }); - } - - [Test] - public void WinGetUtil_SQLiteIndex_OpenClose() - { - SQLiteIndex((_) => - { - // Open - WinGetUtilWrapper.WinGetSQLiteIndexOpen(sqlitePath, out IntPtr indexHandle); - - // Add manifest - WinGetUtilWrapper.WinGetSQLiteIndexAddManifest(indexHandle, addManifestsFile_1, relativePath_1); - - // Close - WinGetUtilWrapper.WinGetSQLiteIndexClose(indexHandle); - }); - } - - [Test] - public void WinGetUtil_SQLiteIndex_CheckConsistency() - { - SQLiteIndex((indexHandle) => - { - // Add manifest - WinGetUtilWrapper.WinGetSQLiteIndexAddManifest(indexHandle, addManifestsFile_1, relativePath_1); - - // Prepare for packaging - WinGetUtilWrapper.WinGetSQLiteIndexPrepareForPackaging(indexHandle); - - // Check consistency - WinGetUtilWrapper.WinGetSQLiteIndexCheckConsistency(indexHandle, out bool succeeded); - Assert.True(succeeded); - }); - } - - /// - /// Create and close an sqlite index file. - /// - /// Function to execute. - private void SQLiteIndex(Action Execute) - { - // Create - WinGetUtilWrapper.WinGetSQLiteIndexCreate(sqlitePath, majorVersion, minorVersion, out IntPtr indexHandle); - Assert.True(File.Exists(sqlitePath)); - Assert.AreNotEqual(IntPtr.Zero, indexHandle); +// // Remove manifest +// WinGetUtilWrapper.WinGetSQLiteIndexRemoveManifest(indexHandle, addManifestsFile_1, relativePath_1); +// }); +// } + +// [Test] +// public void WinGetUtil_SQLiteIndex_RemoveManifest_Fail_NotFound() +// { +// SQLiteIndex((indexHandle) => +// { +// // Remove non-existing manifest +// Assert.Throws(() => +// { +// WinGetUtilWrapper.WinGetSQLiteIndexRemoveManifest(indexHandle, addManifestsFile_1, relativePath_1); +// }); +// }); +// } + +// [Test] +// public void WinGetUtil_SQLiteIndex_OpenClose() +// { +// SQLiteIndex((_) => +// { +// // Open +// WinGetUtilWrapper.WinGetSQLiteIndexOpen(sqlitePath, out IntPtr indexHandle); + +// // Add manifest +// WinGetUtilWrapper.WinGetSQLiteIndexAddManifest(indexHandle, addManifestsFile_1, relativePath_1); + +// // Close +// WinGetUtilWrapper.WinGetSQLiteIndexClose(indexHandle); +// }); +// } + +// [Test] +// public void WinGetUtil_SQLiteIndex_CheckConsistency() +// { +// SQLiteIndex((indexHandle) => +// { +// // Add manifest +// WinGetUtilWrapper.WinGetSQLiteIndexAddManifest(indexHandle, addManifestsFile_1, relativePath_1); + +// // Prepare for packaging +// WinGetUtilWrapper.WinGetSQLiteIndexPrepareForPackaging(indexHandle); + +// // Check consistency +// WinGetUtilWrapper.WinGetSQLiteIndexCheckConsistency(indexHandle, out bool succeeded); +// Assert.True(succeeded); +// }); +// } + +// /// +// /// Create and close an sqlite index file. +// /// +// /// Function to execute. +// private void SQLiteIndex(Action Execute) +// { +// // Create +// WinGetUtilWrapper.WinGetSQLiteIndexCreate(sqlitePath, majorVersion, minorVersion, out IntPtr indexHandle); +// Assert.True(File.Exists(sqlitePath)); +// Assert.AreNotEqual(IntPtr.Zero, indexHandle); - // Execute provided function - Execute(indexHandle); - - // Close - WinGetUtilWrapper.WinGetSQLiteIndexClose(indexHandle); - } - } -} +// // Execute provided function +// Execute(indexHandle); + +// // Close +// WinGetUtilWrapper.WinGetSQLiteIndexClose(indexHandle); +// } +// } +//} From ecd46bdd76ebfeac62456abb138fa8ca1c40024d Mon Sep 17 00:00:00 2001 From: Ryan Fu Date: Wed, 9 Nov 2022 11:29:48 -0800 Subject: [PATCH 23/49] always run task --- azure-pipelines.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index cb4666e2ad..7aa68394ab 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -222,6 +222,7 @@ jobs: pwsh: true errorActionPreference: continue workingDirectory: '$(buildOutDir)\PowerShell\' + condition: always() - template: templates/e2e-test.template.yml parameters: @@ -238,6 +239,7 @@ jobs: pwsh: true errorActionPreference: continue workingDirectory: '$(buildOutDir)\PowerShell\' + condition: always() - task: PublishPipelineArtifact@1 displayName: Publish powershell artifacts From d1e55e775cd4876da1c4245d88b1b757e955dbe5 Mon Sep 17 00:00:00 2001 From: Ryan Fu Date: Wed, 9 Nov 2022 13:28:05 -0800 Subject: [PATCH 24/49] publish appx package --- azure-pipelines.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 7aa68394ab..388eab6aca 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -135,6 +135,12 @@ jobs: Add-AppxPackage AppInstallerCLIPackage_0.0.2.0_Test\Dependencies\$(buildPlatform)\Microsoft.VCLibs.$(buildPlatform).14.00.Desktop.appx workingDirectory: $(appxPackageDir) + - task: PublishPipelineArtifact@1 + displayName: Publish powershell artifacts + inputs: + targetPath: '$(appxPackageDir)' + condition: always() + - task: VisualStudioTestPlatformInstaller@1 displayName: Prepare VSTest for E2E Tests inputs: From 708e082fea3a1300377ea0112d49f495cf9fd20e Mon Sep 17 00:00:00 2001 From: Ryan Fu Date: Mon, 14 Nov 2022 10:05:50 -0800 Subject: [PATCH 25/49] Enable logging for com --- azure-pipelines.yml | 13 +++++++++++++ .../Helpers/ComObjectFactory.cs | 1 - src/WinGetServer/WinGetServer.vcxproj | 2 +- src/WinGetServer/WinMain.cpp | 12 ++++++++++++ src/WindowsPackageManager/Source.def | 1 + .../WindowsPackageManager.h | 6 ++++++ .../WindowsPackageManager.vcxproj | 16 ++++++++-------- src/WindowsPackageManager/main.cpp | 12 ++++++++++++ 8 files changed, 53 insertions(+), 10 deletions(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 388eab6aca..4ca0799342 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -307,6 +307,19 @@ jobs: TargetFolder: '$(artifactsDir)\E2ETestsPackagedLog' condition: succeededOrFailed() + - task: PowerShell@2 + displayName: 'Run powershell module' + inputs: + targetType: 'inline' + script: | + # Import PowerShell Module + ipmo 'D:\a\1\s\src\x64\Release\PowerShell\Microsoft.WinGet.Client.psd1' + # Run Basic powershell commands + Get-WinGetVersion + Get-WinGetSource + Find-WinGetPackage + pwsh: true + - task: CopyFiles@2 displayName: 'Copy Files: WinGetUtilInterop.UnitTests' inputs: diff --git a/src/PowerShell/Microsoft.WinGet.Client/Helpers/ComObjectFactory.cs b/src/PowerShell/Microsoft.WinGet.Client/Helpers/ComObjectFactory.cs index 9a6f186868..5e72f8a184 100644 --- a/src/PowerShell/Microsoft.WinGet.Client/Helpers/ComObjectFactory.cs +++ b/src/PowerShell/Microsoft.WinGet.Client/Helpers/ComObjectFactory.cs @@ -118,7 +118,6 @@ private static T Create(Type type, in Guid iid) { throw new COMException($"Failed with error code {hr}.", hr); } - //if (hr == ErrorCode.ERROR_FILE_NOT_FOUND) //{ // throw new Exception(Utilities.ResourceManager.GetString("WinGetPackageNotInstalled")); diff --git a/src/WinGetServer/WinGetServer.vcxproj b/src/WinGetServer/WinGetServer.vcxproj index 38e885faef..14e3cdda59 100644 --- a/src/WinGetServer/WinGetServer.vcxproj +++ b/src/WinGetServer/WinGetServer.vcxproj @@ -100,7 +100,7 @@ true true true - $(ProjectDir)..\WindowsPackageManager;%(AdditionalIncludeDirectories); + $(ProjectDir)..\WindowsPackageManager;$(ProjectDir)..\AppInstallerCommonCore;%(AdditionalIncludeDirectories); Windows diff --git a/src/WinGetServer/WinMain.cpp b/src/WinGetServer/WinMain.cpp index ace2332ea1..15af38b78f 100644 --- a/src/WinGetServer/WinMain.cpp +++ b/src/WinGetServer/WinMain.cpp @@ -29,6 +29,11 @@ static void _releaseNotifier() noexcept HRESULT WindowsPackageManagerServerInitializeRPCServer() { + if (true) + { + RETURN_HR(E_FAIL); + } + std::string userSID = GetUserSID(); std::string endpoint = "\\pipe\\WinGetServerManualActivation_" + userSID; RPC_STATUS status = RpcServerUseProtseqEpA(GetUCharString("ncacn_np"), RPC_C_PROTSEQ_MAX_REQS_DEFAULT, GetUCharString(endpoint), nullptr); @@ -101,6 +106,8 @@ extern "C" HRESULT CreateInstance( int __stdcall wWinMain(_In_ HINSTANCE, _In_opt_ HINSTANCE, _In_ LPWSTR cmdLine, _In_ int) { + wil::SetResultLoggingCallback(&WindowsPackageManagerServerLogWilResult); + RETURN_IF_FAILED(CoInitializeEx(nullptr, COINIT_MULTITHREADED)); // Enable fast rundown of objects so that the server exits faster when clients go away. @@ -112,6 +119,11 @@ int __stdcall wWinMain(_In_ HINSTANCE, _In_opt_ HINSTANCE, _In_ LPWSTR cmdLine, RETURN_IF_FAILED(WindowsPackageManagerServerInitialize()); + if (true) + { + RETURN_HR(E_FAIL); + } + // Command line parsing int argc = 0; LPWSTR* argv = CommandLineToArgvW(cmdLine, &argc); diff --git a/src/WindowsPackageManager/Source.def b/src/WindowsPackageManager/Source.def index d4dba28316..f8f1d2c4db 100644 --- a/src/WindowsPackageManager/Source.def +++ b/src/WindowsPackageManager/Source.def @@ -5,6 +5,7 @@ EXPORTS WindowsPackageManagerServerModuleCreate WindowsPackageManagerServerModuleRegister WindowsPackageManagerServerModuleUnregister + WindowsPackageManagerServerLogWilResult WindowsPackageManagerServerCreateInstance WindowsPackageManagerInProcModuleInitialize WindowsPackageManagerInProcModuleTerminate diff --git a/src/WindowsPackageManager/WindowsPackageManager.h b/src/WindowsPackageManager/WindowsPackageManager.h index 5961c56d44..3112107801 100644 --- a/src/WindowsPackageManager/WindowsPackageManager.h +++ b/src/WindowsPackageManager/WindowsPackageManager.h @@ -3,6 +3,9 @@ #pragma once #include +// Forward declaration +namespace wil { struct FailureInfo; } + extern "C" { #define WINDOWS_PACKAGE_MANAGER_API_CALLING_CONVENTION __stdcall @@ -25,6 +28,9 @@ extern "C" // Unregisters the server module class factories. WINDOWS_PACKAGE_MANAGER_API WindowsPackageManagerServerModuleUnregister(); + // Reports the hresult from WIL back to the Windows Package Manager dll for logging; + void WINDOWS_PACKAGE_MANAGER_API_CALLING_CONVENTION WindowsPackageManagerServerLogWilResult(const wil::FailureInfo& info) noexcept; + // Creates an out-of-proc instance for manual activation scenarios. WINDOWS_PACKAGE_MANAGER_API WindowsPackageManagerServerCreateInstance(const CLSID* clsid, const IID* iid, void** out); diff --git a/src/WindowsPackageManager/WindowsPackageManager.vcxproj b/src/WindowsPackageManager/WindowsPackageManager.vcxproj index 345dc4753d..ea3d8f96c7 100644 --- a/src/WindowsPackageManager/WindowsPackageManager.vcxproj +++ b/src/WindowsPackageManager/WindowsPackageManager.vcxproj @@ -166,9 +166,9 @@ Disabled _DEBUG;%(PreprocessorDefinitions) - $(ProjectDir);$(ProjectDir)..\AppInstallerCLICore\Public\;$(ProjectDir)..\AppInstallerCommonCore;$(ProjectDir)..\AppInstallerRepositoryCore;$(ProjectDir)..\AppInstallerCommonCore\Public;$(ProjectDir)..\JsonCppLib\json;$(ProjectDir)..\Microsoft.Management.Deployment\Public;%(AdditionalIncludeDirectories) - $(ProjectDir);$(ProjectDir)..\AppInstallerCLICore\Public\;$(ProjectDir)..\AppInstallerCommonCore;$(ProjectDir)..\AppInstallerRepositoryCore;$(ProjectDir)..\AppInstallerCommonCore\Public;$(ProjectDir)..\JsonCppLib\json;$(ProjectDir)..\Microsoft.Management.Deployment\Public;%(AdditionalIncludeDirectories) - $(ProjectDir);$(ProjectDir)..\AppInstallerCLICore\Public\;$(ProjectDir)..\AppInstallerCommonCore;$(ProjectDir)..\AppInstallerRepositoryCore;$(ProjectDir)..\AppInstallerCommonCore\Public;$(ProjectDir)..\JsonCppLib\json;$(ProjectDir)..\Microsoft.Management.Deployment\Public;%(AdditionalIncludeDirectories) + $(ProjectDir);$(ProjectDir)..\AppInstallerCLICore\Public\;$(ProjectDir)..\AppInstallerCommonCore\Public;$(ProjectDir)..\AppInstallerRepositoryCore;$(ProjectDir)..\AppInstallerCommonCore\Public;$(ProjectDir)..\JsonCppLib\json;$(ProjectDir)..\Microsoft.Management.Deployment\Public;%(AdditionalIncludeDirectories) + $(ProjectDir);$(ProjectDir)..\AppInstallerCLICore\Public\;$(ProjectDir)..\AppInstallerCommonCore\Public;$(ProjectDir)..\AppInstallerRepositoryCore;$(ProjectDir)..\AppInstallerCommonCore\Public;$(ProjectDir)..\JsonCppLib\json;$(ProjectDir)..\Microsoft.Management.Deployment\Public;%(AdditionalIncludeDirectories) + $(ProjectDir);$(ProjectDir)..\AppInstallerCLICore\Public\;$(ProjectDir)..\AppInstallerCommonCore\Public;$(ProjectDir)..\AppInstallerRepositoryCore;$(ProjectDir)..\AppInstallerCommonCore\Public;$(ProjectDir)..\JsonCppLib\json;$(ProjectDir)..\Microsoft.Management.Deployment\Public;%(AdditionalIncludeDirectories) true true true @@ -210,7 +210,7 @@ WIN32;%(PreprocessorDefinitions) - $(ProjectDir);$(ProjectDir)..\AppInstallerCLICore\Public\;$(ProjectDir)..\AppInstallerCommonCore;$(ProjectDir)..\AppInstallerRepositoryCore;$(ProjectDir)..\AppInstallerCommonCore\Public;$(ProjectDir)..\JsonCppLib\json;$(ProjectDir)..\Microsoft.Management.Deployment\Public;%(AdditionalIncludeDirectories) + $(ProjectDir);$(ProjectDir)..\AppInstallerCLICore\Public\;$(ProjectDir)..\AppInstallerCommonCore\Public;$(ProjectDir)..\AppInstallerRepositoryCore;$(ProjectDir)..\AppInstallerCommonCore\Public;$(ProjectDir)..\JsonCppLib\json;$(ProjectDir)..\Microsoft.Management.Deployment\Public;%(AdditionalIncludeDirectories) true false stdcpp17 @@ -227,10 +227,10 @@ true true NDEBUG;%(PreprocessorDefinitions) - $(ProjectDir);$(ProjectDir)..\AppInstallerCLICore\Public\;$(ProjectDir)..\AppInstallerCommonCore;$(ProjectDir)..\AppInstallerRepositoryCore;$(ProjectDir)..\AppInstallerCommonCore\Public;$(ProjectDir)..\Microsoft.Management.Deployment\Public;%(AdditionalIncludeDirectories) - $(ProjectDir);$(ProjectDir)..\AppInstallerCLICore\Public\;$(ProjectDir)..\AppInstallerCommonCore;$(ProjectDir)..\AppInstallerRepositoryCore;$(ProjectDir)..\AppInstallerCommonCore\Public;$(ProjectDir)..\Microsoft.Management.Deployment\Public;%(AdditionalIncludeDirectories) - $(ProjectDir);$(ProjectDir)..\AppInstallerCLICore\Public\;$(ProjectDir)..\AppInstallerCommonCore;$(ProjectDir)..\AppInstallerRepositoryCore;$(ProjectDir)..\AppInstallerCommonCore\Public;$(ProjectDir)..\Microsoft.Management.Deployment\Public;%(AdditionalIncludeDirectories) - $(ProjectDir);$(ProjectDir)..\AppInstallerCLICore\Public\;$(ProjectDir)..\AppInstallerCommonCore;$(ProjectDir)..\AppInstallerRepositoryCore;$(ProjectDir)..\AppInstallerCommonCore\Public;$(ProjectDir)..\Microsoft.Management.Deployment\Public;%(AdditionalIncludeDirectories) + $(ProjectDir);$(ProjectDir)..\AppInstallerCLICore\Public\;$(ProjectDir)..\AppInstallerCommonCore\Public;$(ProjectDir)..\AppInstallerRepositoryCore;$(ProjectDir)..\AppInstallerCommonCore\Public;$(ProjectDir)..\Microsoft.Management.Deployment\Public;%(AdditionalIncludeDirectories) + $(ProjectDir);$(ProjectDir)..\AppInstallerCLICore\Public\;$(ProjectDir)..\AppInstallerCommonCore\Public;$(ProjectDir)..\AppInstallerRepositoryCore;$(ProjectDir)..\AppInstallerCommonCore\Public;$(ProjectDir)..\Microsoft.Management.Deployment\Public;%(AdditionalIncludeDirectories) + $(ProjectDir);$(ProjectDir)..\AppInstallerCLICore\Public\;$(ProjectDir)..\AppInstallerCommonCore\Public;$(ProjectDir)..\AppInstallerRepositoryCore;$(ProjectDir)..\AppInstallerCommonCore\Public;$(ProjectDir)..\Microsoft.Management.Deployment\Public;%(AdditionalIncludeDirectories) + $(ProjectDir);$(ProjectDir)..\AppInstallerCLICore\Public\;$(ProjectDir)..\AppInstallerCommonCore\Public;$(ProjectDir)..\AppInstallerRepositoryCore;$(ProjectDir)..\AppInstallerCommonCore\Public;$(ProjectDir)..\Microsoft.Management.Deployment\Public;%(AdditionalIncludeDirectories) true true true diff --git a/src/WindowsPackageManager/main.cpp b/src/WindowsPackageManager/main.cpp index dfc7ecc221..36e3b0a93f 100644 --- a/src/WindowsPackageManager/main.cpp +++ b/src/WindowsPackageManager/main.cpp @@ -10,6 +10,8 @@ #include "WindowsPackageManager.h" #include +#include +#include #include using namespace winrt::Microsoft::Management::Deployment; @@ -58,6 +60,16 @@ extern "C" } CATCH_RETURN(); + void WINDOWS_PACKAGE_MANAGER_API_CALLING_CONVENTION WindowsPackageManagerServerLogWilResult(const wil::FailureInfo& failure) noexcept try + { + AICLI_LOG(Fail, Error, << [&]() { + wchar_t message[2048]; + wil::GetFailureLogString(message, ARRAYSIZE(message), failure); + return AppInstaller::Utility::ConvertToUTF8(message); + }()); + } + CATCH_LOG(); + WINDOWS_PACKAGE_MANAGER_API WindowsPackageManagerServerCreateInstance(const CLSID* clsid, const IID* iid, void** out) try { RETURN_HR_IF_NULL(E_POINTER, clsid); From 0809143f9e741ab62079f39630528afd75374740 Mon Sep 17 00:00:00 2001 From: Ryan Fu Date: Mon, 14 Nov 2022 10:41:13 -0800 Subject: [PATCH 26/49] try different order --- azure-pipelines.yml | 78 +++++++++++++-------------------------------- 1 file changed, 22 insertions(+), 56 deletions(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 4ca0799342..6e3acd7473 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -135,12 +135,6 @@ jobs: Add-AppxPackage AppInstallerCLIPackage_0.0.2.0_Test\Dependencies\$(buildPlatform)\Microsoft.VCLibs.$(buildPlatform).14.00.Desktop.appx workingDirectory: $(appxPackageDir) - - task: PublishPipelineArtifact@1 - displayName: Publish powershell artifacts - inputs: - targetPath: '$(appxPackageDir)' - condition: always() - - task: VisualStudioTestPlatformInstaller@1 displayName: Prepare VSTest for E2E Tests inputs: @@ -219,40 +213,6 @@ jobs: CleanTargetFolder: false OverWrite: true - - task: PowerShell@2 - displayName: Run wpf for com trace logging - inputs: - targetType: 'inline' - script: | - wpr -start $(Build.SourcesDirectory)\src\PowerShell\ComTrace.wprp -filemode - pwsh: true - errorActionPreference: continue - workingDirectory: '$(buildOutDir)\PowerShell\' - condition: always() - - - template: templates/e2e-test.template.yml - parameters: - title: "E2E Tests Packaged" - isPackaged: true - filter: "TestCategory!=InProcess&TestCategory!=OutOfProcess" - - - task: PowerShell@2 - displayName: Run wpf for com trace logging - inputs: - targetType: 'inline' - script: | - wpr -stop .\comtrace.etl - pwsh: true - errorActionPreference: continue - workingDirectory: '$(buildOutDir)\PowerShell\' - condition: always() - - - task: PublishPipelineArtifact@1 - displayName: Publish powershell artifacts - inputs: - targetPath: '$(buildOutDir)\PowerShell\' - condition: always() - - task: PowerShell@2 displayName: 'Set program files directory' inputs: @@ -272,12 +232,6 @@ jobs: TargetFolder: '$(platformProgramFiles)\dotnet' Contents: resources.pri - - template: templates/e2e-test.template.yml - parameters: - title: "COM API E2E Tests (In-process)" - isPackaged: false - filter: "TestCategory=InProcess" - # Winmd accessed by test runner process (dotnet.exe) - task: CopyFiles@2 displayName: 'Copy winmd to dotnet directory' @@ -296,16 +250,9 @@ jobs: - template: templates/e2e-test.template.yml parameters: - title: "COM API E2E Tests (Out-of-process)" + title: "E2E Tests Packaged" isPackaged: true - filter: "TestCategory=OutOfProcess" - - - task: CopyFiles@2 - displayName: 'Copy E2E Tests Package Log to artifacts folder' - inputs: - SourceFolder: '$(temp)\E2ETestLogs' - TargetFolder: '$(artifactsDir)\E2ETestsPackagedLog' - condition: succeededOrFailed() + filter: "TestCategory!=InProcess&TestCategory!=OutOfProcess" - task: PowerShell@2 displayName: 'Run powershell module' @@ -315,10 +262,29 @@ jobs: # Import PowerShell Module ipmo 'D:\a\1\s\src\x64\Release\PowerShell\Microsoft.WinGet.Client.psd1' # Run Basic powershell commands - Get-WinGetVersion Get-WinGetSource Find-WinGetPackage pwsh: true + condition: always() + + - template: templates/e2e-test.template.yml + parameters: + title: "COM API E2E Tests (In-process)" + isPackaged: false + filter: "TestCategory=InProcess" + + - template: templates/e2e-test.template.yml + parameters: + title: "COM API E2E Tests (Out-of-process)" + isPackaged: true + filter: "TestCategory=OutOfProcess" + + - task: CopyFiles@2 + displayName: 'Copy E2E Tests Package Log to artifacts folder' + inputs: + SourceFolder: '$(temp)\E2ETestLogs' + TargetFolder: '$(artifactsDir)\E2ETestsPackagedLog' + condition: succeededOrFailed() - task: CopyFiles@2 displayName: 'Copy Files: WinGetUtilInterop.UnitTests' From 1ca4064f59254bd96c8d400f023987ed4b0434ba Mon Sep 17 00:00:00 2001 From: Ryan Fu Date: Mon, 14 Nov 2022 11:19:46 -0800 Subject: [PATCH 27/49] remove explicity fail error --- src/WinGetServer/WinMain.cpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/WinGetServer/WinMain.cpp b/src/WinGetServer/WinMain.cpp index 15af38b78f..c6be0fa4fb 100644 --- a/src/WinGetServer/WinMain.cpp +++ b/src/WinGetServer/WinMain.cpp @@ -119,11 +119,6 @@ int __stdcall wWinMain(_In_ HINSTANCE, _In_opt_ HINSTANCE, _In_ LPWSTR cmdLine, RETURN_IF_FAILED(WindowsPackageManagerServerInitialize()); - if (true) - { - RETURN_HR(E_FAIL); - } - // Command line parsing int argc = 0; LPWSTR* argv = CommandLineToArgvW(cmdLine, &argc); From 5075f5bbca605753ca717969466c5d63c04ac0fa Mon Sep 17 00:00:00 2001 From: Ryan Fu Date: Mon, 14 Nov 2022 11:50:45 -0800 Subject: [PATCH 28/49] try again --- src/WinGetServer/WinMain.cpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/WinGetServer/WinMain.cpp b/src/WinGetServer/WinMain.cpp index c6be0fa4fb..716971013c 100644 --- a/src/WinGetServer/WinMain.cpp +++ b/src/WinGetServer/WinMain.cpp @@ -29,11 +29,6 @@ static void _releaseNotifier() noexcept HRESULT WindowsPackageManagerServerInitializeRPCServer() { - if (true) - { - RETURN_HR(E_FAIL); - } - std::string userSID = GetUserSID(); std::string endpoint = "\\pipe\\WinGetServerManualActivation_" + userSID; RPC_STATUS status = RpcServerUseProtseqEpA(GetUCharString("ncacn_np"), RPC_C_PROTSEQ_MAX_REQS_DEFAULT, GetUCharString(endpoint), nullptr); From 8a9b95633eda6e27a05ea6ca9cceccf004f173c2 Mon Sep 17 00:00:00 2001 From: Ryan Fu Date: Mon, 14 Nov 2022 13:54:10 -0800 Subject: [PATCH 29/49] revert all changes --- azure-pipelines.yml | 69 +- .../FeaturesCommand.cs | 4 +- src/AppInstallerCLIE2ETests/GroupPolicy.cs | 20 +- src/AppInstallerCLIE2ETests/HashCommand.cs | 8 +- src/AppInstallerCLIE2ETests/ImportCommand.cs | 266 +++--- src/AppInstallerCLIE2ETests/InstallCommand.cs | 892 +++++++++--------- src/AppInstallerCLIE2ETests/ListCommand.cs | 222 ++--- .../PowerShell/PowerShellModule.cs | 37 +- src/AppInstallerCLIE2ETests/SearchCommand.cs | 310 +++--- src/AppInstallerCLIE2ETests/ShowCommand.cs | 168 ++-- src/AppInstallerCLIE2ETests/SourceCommand.cs | 278 +++--- .../UninstallCommand.cs | 290 +++--- src/AppInstallerCLIE2ETests/UpgradeCommand.cs | 274 +++--- .../ValidateCommand.cs | 74 +- src/PowerShell/ComTrace.wprp | 35 - .../Helpers/ComObjectFactory.cs | 17 +- .../Microsoft.WinGet.Client.csproj | 6 - .../Microsoft.WinGet.Client.psd1 | 160 ---- src/WinGetServer/WinMain.cpp | 2 +- src/WindowsPackageManager/Source.def | 2 +- .../WindowsPackageManager.h | 2 +- src/WindowsPackageManager/main.cpp | 2 +- templates/e2e-test.template.yml | 2 - 23 files changed, 1473 insertions(+), 1667 deletions(-) delete mode 100644 src/PowerShell/ComTrace.wprp delete mode 100644 src/PowerShell/Microsoft.WinGet.Client/ModuleManifest-x86/Microsoft.WinGet.Client.psd1 diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 6e3acd7473..902c76957c 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -140,34 +140,34 @@ jobs: inputs: packageFeedSelector: 'nugetOrg' - # - task: DownloadSecureFile@1 - # name: PsExec - # displayName: 'Download PsExec.exe' - # inputs: - # secureFile: 'PsExec.exe' - - # - task: CmdLine@2 - # displayName: Run Unit Tests Unpackaged Under System Context - # inputs: - # script: | - # $(PsExec.secureFilePath) -accepteula -s -i $(buildOutDir)\AppInstallerCLITests\AppInstallerCLITests.exe -logto $(artifactsDir)\AICLI-Unpackaged-System.log -s -r junit -o $(artifactsDir)\TEST-AppInstallerCLI-Unpackaged-System.xml - # workingDirectory: '$(buildOutDir)\AppInstallerCLITests' - # continueOnError: true - - # - task: PowerShell@2 - # displayName: Run Unit Tests Packaged - # inputs: - # filePath: 'src\AppInstallerCLITests\Run-TestsInPackage.ps1' - # arguments: '-Args "~[pips]" -BuildRoot $(buildOutDir) -PackageRoot AppInstallerCLIPackage\bin\$(buildPlatform)\$(buildConfiguration) -LogTarget $(artifactsDir)\AICLI-Packaged.log -TestResultsTarget $(artifactsDir)\TEST-AppInstallerCLI-Packaged.xml -ScriptWait' - # workingDirectory: 'src' - # continueOnError: true - - # - task: PublishTestResults@2 - # displayName: Publish Unit Test Results - # inputs: - # testResultsFormat: 'JUnit' - # testResultsFiles: '$(artifactsDir)\TEST-*.xml' - # failTaskOnFailedTests: true + - task: DownloadSecureFile@1 + name: PsExec + displayName: 'Download PsExec.exe' + inputs: + secureFile: 'PsExec.exe' + + - task: CmdLine@2 + displayName: Run Unit Tests Unpackaged Under System Context + inputs: + script: | + $(PsExec.secureFilePath) -accepteula -s -i $(buildOutDir)\AppInstallerCLITests\AppInstallerCLITests.exe -logto $(artifactsDir)\AICLI-Unpackaged-System.log -s -r junit -o $(artifactsDir)\TEST-AppInstallerCLI-Unpackaged-System.xml + workingDirectory: '$(buildOutDir)\AppInstallerCLITests' + continueOnError: true + + - task: PowerShell@2 + displayName: Run Unit Tests Packaged + inputs: + filePath: 'src\AppInstallerCLITests\Run-TestsInPackage.ps1' + arguments: '-Args "~[pips]" -BuildRoot $(buildOutDir) -PackageRoot AppInstallerCLIPackage\bin\$(buildPlatform)\$(buildConfiguration) -LogTarget $(artifactsDir)\AICLI-Packaged.log -TestResultsTarget $(artifactsDir)\TEST-AppInstallerCLI-Packaged.xml -ScriptWait' + workingDirectory: 'src' + continueOnError: true + + - task: PublishTestResults@2 + displayName: Publish Unit Test Results + inputs: + testResultsFormat: 'JUnit' + testResultsFiles: '$(artifactsDir)\TEST-*.xml' + failTaskOnFailedTests: true - task: DownloadSecureFile@1 name: AppInstallerTest @@ -254,19 +254,6 @@ jobs: isPackaged: true filter: "TestCategory!=InProcess&TestCategory!=OutOfProcess" - - task: PowerShell@2 - displayName: 'Run powershell module' - inputs: - targetType: 'inline' - script: | - # Import PowerShell Module - ipmo 'D:\a\1\s\src\x64\Release\PowerShell\Microsoft.WinGet.Client.psd1' - # Run Basic powershell commands - Get-WinGetSource - Find-WinGetPackage - pwsh: true - condition: always() - - template: templates/e2e-test.template.yml parameters: title: "COM API E2E Tests (In-process)" diff --git a/src/AppInstallerCLIE2ETests/FeaturesCommand.cs b/src/AppInstallerCLIE2ETests/FeaturesCommand.cs index ab8e00a607..52551dc4df 100644 --- a/src/AppInstallerCLIE2ETests/FeaturesCommand.cs +++ b/src/AppInstallerCLIE2ETests/FeaturesCommand.cs @@ -19,7 +19,7 @@ public void TearDown() InitializeAllFeatures(false); } - //[Test] + [Test] public void DisplayFeatures() { var result = TestCommon.RunAICLICommand("features", ""); @@ -28,7 +28,7 @@ public void DisplayFeatures() Assert.False(result.StdOut.Contains("Enabled")); } - //[Test] + [Test] public void EnableExperimentalFeatures() { ConfigureFeature("experimentalArg", true); diff --git a/src/AppInstallerCLIE2ETests/GroupPolicy.cs b/src/AppInstallerCLIE2ETests/GroupPolicy.cs index 0d3488b011..b869960802 100644 --- a/src/AppInstallerCLIE2ETests/GroupPolicy.cs +++ b/src/AppInstallerCLIE2ETests/GroupPolicy.cs @@ -25,7 +25,7 @@ public void TearDown() GroupPolicyHelper.DeleteExistingPolicies(); } - //[Test] + [Test] public void PolicyEnableWinget() { GroupPolicyHelper.EnableWinget.Disable(); @@ -33,7 +33,7 @@ public void PolicyEnableWinget() Assert.AreEqual(Constants.ErrorCode.ERROR_BLOCKED_BY_POLICY, result.ExitCode); } - //[Test] + [Test] public void EnableSettings() { GroupPolicyHelper.EnableSettings.Disable(); @@ -41,7 +41,7 @@ public void EnableSettings() Assert.AreEqual(Constants.ErrorCode.ERROR_BLOCKED_BY_POLICY, result.ExitCode); } - //[Test] + [Test] public void EnableExperimentalFeatures() { ConfigureFeature("experimentalCmd", true); @@ -55,7 +55,7 @@ public void EnableExperimentalFeatures() Assert.AreEqual(Constants.ErrorCode.ERROR_INVALID_CL_ARGUMENTS, result.ExitCode); } - //[Test] + [Test] public void EnableLocalManifests() { GroupPolicyHelper.EnableLocalManifests.Disable(); @@ -63,7 +63,7 @@ public void EnableLocalManifests() Assert.AreEqual(Constants.ErrorCode.ERROR_BLOCKED_BY_POLICY, result.ExitCode); } - //[Test] + [Test] public void EnableHashOverride() { GroupPolicyHelper.EnableHashOverride.Disable(); @@ -71,7 +71,7 @@ public void EnableHashOverride() Assert.AreEqual(Constants.ErrorCode.ERROR_BLOCKED_BY_POLICY, result.ExitCode); } - //[Test] + [Test] public void EnableDefaultSource() { // Default sources are disabled during setup so they are missing. @@ -83,7 +83,7 @@ public void EnableDefaultSource() Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); } - //[Test] + [Test] public void EnableMicrosoftStoreSource() { // Default sources are disabled during setup so they are missing. @@ -95,7 +95,7 @@ public void EnableMicrosoftStoreSource() Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); } - //[Test] + [Test] public void EnableAdditionalSources() { // Remove the test source, then add it with policy. @@ -112,7 +112,7 @@ public void EnableAdditionalSources() Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); } - //[Test] + [Test] public void EnableAllowedSources() { // Try listing the test source. We should only see it if it is allowed. @@ -140,7 +140,7 @@ public void EnableAllowedSources() Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); } - //[Test] + [Test] public void SourceAutoUpdateInterval() { // Test this policy by inspecting the result of --info diff --git a/src/AppInstallerCLIE2ETests/HashCommand.cs b/src/AppInstallerCLIE2ETests/HashCommand.cs index 0806dc2845..f8525ed3ba 100644 --- a/src/AppInstallerCLIE2ETests/HashCommand.cs +++ b/src/AppInstallerCLIE2ETests/HashCommand.cs @@ -8,7 +8,7 @@ namespace AppInstallerCLIE2ETests public class HashCommand : BaseCommand { - //[Test] + [Test] public void HashFile() { var result = TestCommon.RunAICLICommand("hash", TestCommon.GetTestDataFile("AppInstallerTest.cer")); @@ -16,7 +16,7 @@ public void HashFile() Assert.True(result.StdOut.Contains("9b4c49ad7e47afd97d2e666e93347745e1647c55f1a7ebba6d31b7dd5f69ee68")); } - //[Test] + [Test] public void HashMSIX() { var result = TestCommon.RunAICLICommand("hash", TestCommon.GetTestDataFile(Constants.TestPackage) + " -m"); @@ -25,7 +25,7 @@ public void HashMSIX() Assert.True(result.StdOut.Contains("223b318c4b1154a1fb72b1bc23422810faa5ce899a8e774ba2a02834b2058f00")); } - //[Test] + [Test] public void HashInvalidMSIX() { var result = TestCommon.RunAICLICommand("hash", TestCommon.GetTestDataFile("AppInstallerTest.cer") + " -m"); @@ -34,7 +34,7 @@ public void HashInvalidMSIX() Assert.True(result.StdOut.Contains("Please verify that the input file is a valid, signed MSIX.")); } - //[Test] + [Test] public void HashFileNotFound() { var result = TestCommon.RunAICLICommand("hash", TestCommon.GetTestDataFile("DoesNot.Exist")); diff --git a/src/AppInstallerCLIE2ETests/ImportCommand.cs b/src/AppInstallerCLIE2ETests/ImportCommand.cs index 716f48f203..4f60fed0fc 100644 --- a/src/AppInstallerCLIE2ETests/ImportCommand.cs +++ b/src/AppInstallerCLIE2ETests/ImportCommand.cs @@ -1,133 +1,133 @@ -//// Copyright (c) Microsoft Corporation. -//// Licensed under the MIT License. - -//namespace AppInstallerCLIE2ETests -//{ -// using System.IO; -// using NUnit.Framework; - -// public class ImportCommand : BaseCommand -// { -// [SetUp] -// public void Setup() -// { -// CleanupTestExe(); -// } - -// [Test] -// public void ImportSuccessful_1_0() -// { -// var result = TestCommon.RunAICLICommand("import", GetTestImportFile("ImportFile-Good.1.0.json")); -// Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); -// Assert.True(VerifyTestExeInstalled()); -// UninstallTestExe(); -// } - -// [Test] -// public void ImportSuccessful_2_0() -// { -// var result = TestCommon.RunAICLICommand("import", GetTestImportFile("ImportFile-Good.2.0.json")); -// Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); -// Assert.True(VerifyTestExeInstalled()); -// UninstallTestExe(); -// } - -// // Ignore while we don't have schema validation -// [Test] -// public void ImportInvalidFile() -// { -// // Verify failure when trying to import with an invalid file -// var result = TestCommon.RunAICLICommand("import", GetTestImportFile("ImportFile-Bad-Invalid.json")); -// Assert.AreEqual(Constants.ErrorCode.ERROR_JSON_INVALID_FILE, result.ExitCode); -// Assert.True(result.StdOut.Contains("JSON file is not valid")); -// } - -// [Test] -// public void ImportUnknownSource() -// { -// // Verify failure when trying to import from an unknown source -// var result = TestCommon.RunAICLICommand("import", GetTestImportFile("ImportFile-Bad-UnknownSource.json")); -// Assert.AreEqual(Constants.ErrorCode.ERROR_SOURCE_NAME_DOES_NOT_EXIST, result.ExitCode); -// Assert.True(result.StdOut.Contains("Source required for import is not installed")); -// } - -// [Test] -// public void ImportUnavailablePackage() -// { -// // Verify failure when trying to import an unavailable package -// var result = TestCommon.RunAICLICommand("import", GetTestImportFile("ImportFile-Bad-UnknownPackage.json")); -// Assert.AreEqual(Constants.ErrorCode.ERROR_NOT_ALL_PACKAGES_FOUND, result.ExitCode); -// Assert.True(result.StdOut.Contains("Package not found for import")); -// } - -// [Test] -// public void ImportUnavailableVersion() -// { -// // Verify failure when trying to import an unavailable package -// var result = TestCommon.RunAICLICommand("import", GetTestImportFile("ImportFile-Bad-UnknownPackageVersion.json")); -// Assert.AreEqual(Constants.ErrorCode.ERROR_NOT_ALL_PACKAGES_FOUND, result.ExitCode); -// Assert.True(result.StdOut.Contains("Package not found for import")); -// } - -// [Test] -// public void ImportAlreadyInstalled() -// { -// // Verify success with message when trying to import a package that is already installed -// var installDir = TestCommon.GetRandomTestDir(); -// TestCommon.RunAICLICommand("install", $"AppInstallerTest.TestExeInstaller -l {installDir}"); -// var result = TestCommon.RunAICLICommand("import", $"{GetTestImportFile("ImportFile-Good.1.0.json")}"); -// Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); -// Assert.True(result.StdOut.Contains("Package is already installed")); -// Assert.False(VerifyTestExeInstalled()); -// UninstallTestExe(); -// } - -// [Test] -// public void ImportExportedFile() -// { -// // Verify success when importing an exported list of packages. -// // First install the test package to ensure it is exported. -// TestCommon.RunAICLICommand("install", Constants.ExeInstallerPackageId); - -// var jsonFile = TestCommon.GetRandomTestFile(".json"); -// TestCommon.RunAICLICommand("export", $"{jsonFile} -s TestSource"); - -// // Uninstall the package to ensure we can install it again -// UninstallTestExe(); - -// // Import the file -// var result = TestCommon.RunAICLICommand("import", jsonFile); -// Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); -// Assert.True(VerifyTestExeInstalled()); -// UninstallTestExe(); -// } - -// private string GetTestImportFile(string importFileName) -// { -// return TestCommon.GetTestDataFile(Path.Combine("ImportFiles", importFileName)); -// } - -// private bool VerifyTestExeInstalled(string installDir = null) -// { -// if (string.IsNullOrEmpty(installDir)) -// { -// // Default location used by installer -// installDir = Path.GetTempPath(); -// } - -// return File.Exists(Path.Combine(installDir, Constants.TestExeInstalledFileName)); -// } - -// private void UninstallTestExe() -// { -// TestCommon.RunAICLICommand("uninstall", Constants.ExeInstallerPackageId); -// } - -// private void CleanupTestExe() -// { -// UninstallTestExe(); -// File.Delete(Path.Combine(Path.GetTempPath(), Constants.TestExeInstalledFileName)); -// File.Delete(Path.Combine(Path.GetTempPath(), Constants.TestExeUninstallerFileName)); -// } -// } -//} \ No newline at end of file +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +namespace AppInstallerCLIE2ETests +{ + using System.IO; + using NUnit.Framework; + + public class ImportCommand : BaseCommand + { + [SetUp] + public void Setup() + { + CleanupTestExe(); + } + + [Test] + public void ImportSuccessful_1_0() + { + var result = TestCommon.RunAICLICommand("import", GetTestImportFile("ImportFile-Good.1.0.json")); + Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); + Assert.True(VerifyTestExeInstalled()); + UninstallTestExe(); + } + + [Test] + public void ImportSuccessful_2_0() + { + var result = TestCommon.RunAICLICommand("import", GetTestImportFile("ImportFile-Good.2.0.json")); + Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); + Assert.True(VerifyTestExeInstalled()); + UninstallTestExe(); + } + + // Ignore while we don't have schema validation + [Test] + public void ImportInvalidFile() + { + // Verify failure when trying to import with an invalid file + var result = TestCommon.RunAICLICommand("import", GetTestImportFile("ImportFile-Bad-Invalid.json")); + Assert.AreEqual(Constants.ErrorCode.ERROR_JSON_INVALID_FILE, result.ExitCode); + Assert.True(result.StdOut.Contains("JSON file is not valid")); + } + + [Test] + public void ImportUnknownSource() + { + // Verify failure when trying to import from an unknown source + var result = TestCommon.RunAICLICommand("import", GetTestImportFile("ImportFile-Bad-UnknownSource.json")); + Assert.AreEqual(Constants.ErrorCode.ERROR_SOURCE_NAME_DOES_NOT_EXIST, result.ExitCode); + Assert.True(result.StdOut.Contains("Source required for import is not installed")); + } + + [Test] + public void ImportUnavailablePackage() + { + // Verify failure when trying to import an unavailable package + var result = TestCommon.RunAICLICommand("import", GetTestImportFile("ImportFile-Bad-UnknownPackage.json")); + Assert.AreEqual(Constants.ErrorCode.ERROR_NOT_ALL_PACKAGES_FOUND, result.ExitCode); + Assert.True(result.StdOut.Contains("Package not found for import")); + } + + [Test] + public void ImportUnavailableVersion() + { + // Verify failure when trying to import an unavailable package + var result = TestCommon.RunAICLICommand("import", GetTestImportFile("ImportFile-Bad-UnknownPackageVersion.json")); + Assert.AreEqual(Constants.ErrorCode.ERROR_NOT_ALL_PACKAGES_FOUND, result.ExitCode); + Assert.True(result.StdOut.Contains("Package not found for import")); + } + + [Test] + public void ImportAlreadyInstalled() + { + // Verify success with message when trying to import a package that is already installed + var installDir = TestCommon.GetRandomTestDir(); + TestCommon.RunAICLICommand("install", $"AppInstallerTest.TestExeInstaller -l {installDir}"); + var result = TestCommon.RunAICLICommand("import", $"{GetTestImportFile("ImportFile-Good.1.0.json")}"); + Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); + Assert.True(result.StdOut.Contains("Package is already installed")); + Assert.False(VerifyTestExeInstalled()); + UninstallTestExe(); + } + + [Test] + public void ImportExportedFile() + { + // Verify success when importing an exported list of packages. + // First install the test package to ensure it is exported. + TestCommon.RunAICLICommand("install", Constants.ExeInstallerPackageId); + + var jsonFile = TestCommon.GetRandomTestFile(".json"); + TestCommon.RunAICLICommand("export", $"{jsonFile} -s TestSource"); + + // Uninstall the package to ensure we can install it again + UninstallTestExe(); + + // Import the file + var result = TestCommon.RunAICLICommand("import", jsonFile); + Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); + Assert.True(VerifyTestExeInstalled()); + UninstallTestExe(); + } + + private string GetTestImportFile(string importFileName) + { + return TestCommon.GetTestDataFile(Path.Combine("ImportFiles", importFileName)); + } + + private bool VerifyTestExeInstalled(string installDir = null) + { + if (string.IsNullOrEmpty(installDir)) + { + // Default location used by installer + installDir = Path.GetTempPath(); + } + + return File.Exists(Path.Combine(installDir, Constants.TestExeInstalledFileName)); + } + + private void UninstallTestExe() + { + TestCommon.RunAICLICommand("uninstall", Constants.ExeInstallerPackageId); + } + + private void CleanupTestExe() + { + UninstallTestExe(); + File.Delete(Path.Combine(Path.GetTempPath(), Constants.TestExeInstalledFileName)); + File.Delete(Path.Combine(Path.GetTempPath(), Constants.TestExeUninstallerFileName)); + } + } +} \ No newline at end of file diff --git a/src/AppInstallerCLIE2ETests/InstallCommand.cs b/src/AppInstallerCLIE2ETests/InstallCommand.cs index 245c3c7d0a..595dab05a1 100644 --- a/src/AppInstallerCLIE2ETests/InstallCommand.cs +++ b/src/AppInstallerCLIE2ETests/InstallCommand.cs @@ -1,446 +1,446 @@ -//// Copyright (c) Microsoft Corporation. -//// Licensed under the MIT License. - -//namespace AppInstallerCLIE2ETests -//{ -// using NUnit.Framework; -// using System.IO; - -// public class InstallCommand : BaseCommand -// { -// [OneTimeSetUp] -// public void OneTimeSetup() -// { -// ConfigureFeature("zipInstall", true); -// } - -// [SetUp] -// public void Setup() -// { -// // Try clean up TestExeInstaller for failure cases where cleanup is not successful -// TestCommon.RunAICLICommand("uninstall", "AppInstallerTest.TestExeInstaller"); -// } - -// [Test] -// public void InstallAppDoesNotExist() -// { -// var result = TestCommon.RunAICLICommand("install", "DoesNotExist"); -// Assert.AreEqual(Constants.ErrorCode.ERROR_NO_APPLICATIONS_FOUND, result.ExitCode); -// Assert.True(result.StdOut.Contains("No package found matching input criteria.")); -// } - -// [Test] -// public void InstallWithMultipleAppsMatchingQuery() -// { -// var result = TestCommon.RunAICLICommand("install", "TestExeInstaller"); -// Assert.AreEqual(Constants.ErrorCode.ERROR_MULTIPLE_APPLICATIONS_FOUND, result.ExitCode); -// Assert.True(result.StdOut.Contains("Multiple packages found matching input criteria. Please refine the input.")); -// } - -// [Test] -// public void InstallExe() -// { -// var installDir = TestCommon.GetRandomTestDir(); -// var result = TestCommon.RunAICLICommand("install", $"AppInstallerTest.TestExeInstaller --silent -l {installDir}"); -// Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); -// Assert.True(result.StdOut.Contains("Successfully installed")); -// Assert.True(TestCommon.VerifyTestExeInstalledAndCleanup(installDir, "/execustom")); -// } - -// [Test] -// public void InstallExeWithInsufficientMinOsVersion() -// { -// var installDir = TestCommon.GetRandomTestDir(); -// var result = TestCommon.RunAICLICommand("install", $"InapplicableOsVersion --silent -l {installDir}"); -// // MinOSVersion is moved to installer level, the check is performed during installer selection -// Assert.AreEqual(Constants.ErrorCode.ERROR_NO_APPLICABLE_INSTALLER, result.ExitCode); -// Assert.False(TestCommon.VerifyTestExeInstalledAndCleanup(installDir)); -// } - -// [Test] -// public void InstallExeWithHashMismatch() -// { -// var installDir = TestCommon.GetRandomTestDir(); -// var result = TestCommon.RunAICLICommand("install", $"TestExeSha256Mismatch --silent -l {installDir}"); -// Assert.AreEqual(Constants.ErrorCode.ERROR_INSTALLER_HASH_MISMATCH, result.ExitCode); -// Assert.True(result.StdOut.Contains("Installer hash does not match")); -// Assert.False(TestCommon.VerifyTestExeInstalledAndCleanup(installDir)); -// } - -// [Test] -// public void InstallWithInno() -// { -// // Install test inno, manifest does not provide silent switch, we should be populating the default -// var installDir = TestCommon.GetRandomTestDir(); -// var result = TestCommon.RunAICLICommand("install", $"TestInnoInstaller --silent -l {installDir}"); -// Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); -// Assert.True(result.StdOut.Contains("Successfully installed")); -// Assert.True(TestCommon.VerifyTestExeInstalledAndCleanup(installDir, "/VERYSILENT")); -// } - -// [Test] -// public void InstallBurn() -// { -// // Install test burn, manifest does not provide silent switch, we should be populating the default -// var installDir = TestCommon.GetRandomTestDir(); -// var result = TestCommon.RunAICLICommand("install", $"TestBurnInstaller --silent -l {installDir}"); -// Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); -// Assert.True(result.StdOut.Contains("Successfully installed")); -// Assert.True(TestCommon.VerifyTestExeInstalledAndCleanup(installDir, "/quiet")); -// } - -// [Test] -// public void InstallNullSoft() -// { -// // Install test Nullsoft, manifest does not provide silent switch, we should be populating the default -// var installDir = TestCommon.GetRandomTestDir(); -// var result = TestCommon.RunAICLICommand("install", $"TestNullsoftInstaller --silent -l {installDir}"); -// Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); -// Assert.True(result.StdOut.Contains("Successfully installed")); -// Assert.True(TestCommon.VerifyTestExeInstalledAndCleanup(installDir, "/S")); -// } - -// [Test] -// public void InstallMSI() -// { -// var installDir = TestCommon.GetRandomTestDir(); -// var result = TestCommon.RunAICLICommand("install", $"TestMsiInstaller --silent -l {installDir}"); -// Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); -// Assert.True(result.StdOut.Contains("Successfully installed")); -// Assert.True(TestCommon.VerifyTestMsiInstalledAndCleanup(installDir)); -// } - -// [Test] -// public void InstallMSIX() -// { -// var result = TestCommon.RunAICLICommand("install", $"TestMsixInstaller"); -// Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); -// Assert.True(result.StdOut.Contains("Successfully installed")); -// Assert.True(TestCommon.VerifyTestMsixInstalledAndCleanup()); -// } - -// [Test] -// public void InstallMSIXWithSignature() -// { -// var installDir = TestCommon.GetRandomTestDir(); -// var result = TestCommon.RunAICLICommand("install", $"TestMsixWithSignatureHash --silent -l {installDir}"); -// Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); -// Assert.True(result.StdOut.Contains("Successfully installed")); -// Assert.True(TestCommon.VerifyTestMsixInstalledAndCleanup()); -// } - -// [Test] -// public void InstallMSIXWithSignatureHashMismatch() -// { -// var result = TestCommon.RunAICLICommand("install", $"TestMsixSignatureHashMismatch"); -// Assert.AreEqual(Constants.ErrorCode.ERROR_INSTALLER_HASH_MISMATCH, result.ExitCode); -// Assert.True(result.StdOut.Contains("Installer hash does not match")); -// Assert.False(TestCommon.VerifyTestMsixInstalledAndCleanup()); -// } - -// [Test] -// public void InstallExeWithAlternateSourceFailure() -// { -// TestCommon.RunAICLICommand("source add", "failSearch \"{ \"\"SearchHR\"\": \"\"0x80070002\"\" }\" Microsoft.Test.Configurable --header \"{}\""); - -// try -// { -// var installDir = TestCommon.GetRandomTestDir(); -// var result = TestCommon.RunAICLICommand("install", $"AppInstallerTest.TestExeInstaller --silent -l {installDir}"); -// Assert.AreEqual(unchecked((int)0x80070002), result.ExitCode); -// Assert.True(result.StdOut.Contains("Failed when searching source: failSearch")); -// Assert.True(result.StdOut.Contains("AppInstallerTest.TestExeInstaller")); -// Assert.False(result.StdOut.Contains("Successfully installed")); -// Assert.False(TestCommon.VerifyTestExeInstalledAndCleanup(installDir)); -// } -// finally -// { -// ResetTestSource(); -// } -// } - -// [Test] -// public void InstallPortableExe() -// { -// string installDir = TestCommon.GetPortablePackagesDirectory(); -// string packageId, commandAlias, fileName, packageDirName, productCode; -// packageId = "AppInstallerTest.TestPortableExe"; -// packageDirName = productCode = packageId + "_" + Constants.TestSourceIdentifier; -// commandAlias = fileName = "AppInstallerTestExeInstaller.exe"; - -// var result = TestCommon.RunAICLICommand("install", $"{packageId}"); -// Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); -// Assert.True(result.StdOut.Contains("Successfully installed")); -// // If no location specified, default behavior is to create a package directory with the name "{packageId}_{sourceId}" -// TestCommon.VerifyPortablePackage(Path.Combine(installDir, packageDirName), commandAlias, fileName, productCode, true); -// } - -// [Test] -// public void InstallPortableExeWithCommand() -// { -// var installDir = TestCommon.GetRandomTestDir(); -// string packageId, commandAlias, fileName, productCode; -// packageId = "AppInstallerTest.TestPortableExeWithCommand"; -// productCode = packageId + "_" + Constants.TestSourceIdentifier; -// fileName = "AppInstallerTestExeInstaller.exe"; -// commandAlias = "testCommand.exe"; - -// var result = TestCommon.RunAICLICommand("install", $"{packageId} -l {installDir}"); -// Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); -// Assert.True(result.StdOut.Contains("Successfully installed")); -// TestCommon.VerifyPortablePackage(installDir, commandAlias, fileName, productCode, true); -// } - -// [Test] -// public void InstallPortableExeWithRename() -// { -// var installDir = TestCommon.GetRandomTestDir(); -// string packageId, productCode, renameArgValue; -// packageId = "AppInstallerTest.TestPortableExeWithCommand"; -// productCode = packageId + "_" + Constants.TestSourceIdentifier; -// renameArgValue = "testRename.exe"; - -// var result = TestCommon.RunAICLICommand("install", $"{packageId} -l {installDir} --rename {renameArgValue}"); -// Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); -// Assert.True(result.StdOut.Contains("Successfully installed")); -// TestCommon.VerifyPortablePackage(installDir, renameArgValue, renameArgValue, productCode, true); -// } - -// [Test] -// public void InstallPortableInvalidRename() -// { -// var installDir = TestCommon.GetRandomTestDir(); -// string packageId, renameArgValue; -// packageId = "AppInstallerTest.TestPortableExeWithCommand"; -// renameArgValue = "test?"; - -// var result = TestCommon.RunAICLICommand("install", $"{packageId} -l {installDir} --rename {renameArgValue}"); -// Assert.AreNotEqual(Constants.ErrorCode.S_OK, result.ExitCode); -// Assert.True(result.StdOut.Contains("The specified filename is not a valid filename")); -// } - -// [Test] -// public void InstallPortableReservedNames() -// { -// var installDir = TestCommon.GetRandomTestDir(); -// string packageId, renameArgValue; -// packageId = "AppInstallerTest.TestPortableExeWithCommand"; -// renameArgValue = "CON"; - -// var result = TestCommon.RunAICLICommand("install", $"{packageId} -l {installDir} --rename {renameArgValue}"); -// Assert.AreNotEqual(Constants.ErrorCode.S_OK, result.ExitCode); -// Assert.True(result.StdOut.Contains("The specified filename is not a valid filename")); -// } - -// [Test] -// public void InstallPortableToExistingDirectory() -// { -// var installDir = TestCommon.GetRandomTestDir(); -// var existingDir = Path.Combine(installDir, "testDirectory"); -// Directory.CreateDirectory(existingDir); - -// string packageId, commandAlias, fileName, productCode; -// packageId = "AppInstallerTest.TestPortableExe"; -// productCode = packageId + "_" + Constants.TestSourceIdentifier; -// commandAlias = fileName = "AppInstallerTestExeInstaller.exe"; - -// var result = TestCommon.RunAICLICommand("install", $"{packageId} -l {existingDir}"); -// Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); -// Assert.True(result.StdOut.Contains("Successfully installed")); -// TestCommon.VerifyPortablePackage(existingDir, commandAlias, fileName, productCode, true); -// } - -// [Test] -// public void InstallPortableFailsWithCleanup() -// { -// string packageId, commandAlias; -// packageId = "AppInstallerTest.TestPortableExe"; -// commandAlias = "AppInstallerTestExeInstaller.exe"; - -// // Create a directory with the same name as the symlink in order to cause install to fail. -// string symlinkDirectory = TestCommon.GetPortableSymlinkDirectory(TestCommon.Scope.User); -// string conflictDirectory = Path.Combine(symlinkDirectory, commandAlias); - -// Directory.CreateDirectory(conflictDirectory); - -// var result = TestCommon.RunAICLICommand("install", $"{packageId}"); - -// // Remove directory prior to assertions as this will impact other tests if assertions fail. -// Directory.Delete(conflictDirectory, true); - -// Assert.AreNotEqual(Constants.ErrorCode.S_OK, result.ExitCode); -// Assert.True(result.StdOut.Contains("Unable to create symlink, path points to a directory.")); -// } - -// [Test] -// public void ReinstallPortable() -// { -// string installDir = TestCommon.GetPortablePackagesDirectory(); -// string packageId, commandAlias, fileName, packageDirName, productCode; -// packageId = "AppInstallerTest.TestPortableExe"; -// packageDirName = productCode = packageId + "_" + Constants.TestSourceIdentifier; -// commandAlias = fileName = "AppInstallerTestExeInstaller.exe"; - -// var result = TestCommon.RunAICLICommand("install", $"{packageId}"); -// Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); - -// string symlinkDirectory = TestCommon.GetPortableSymlinkDirectory(TestCommon.Scope.User); -// string symlinkPath = Path.Combine(symlinkDirectory, commandAlias); - -// // Clean first install should not display file overwrite message. -// Assert.True(result.StdOut.Contains("Successfully installed")); -// Assert.False(result.StdOut.Contains($"Overwriting existing file: {symlinkPath}")); - -// // Perform second install and verify that file overwrite message is displayed. -// var result2 = TestCommon.RunAICLICommand("install", $"{packageId} --force"); -// Assert.AreEqual(Constants.ErrorCode.S_OK, result2.ExitCode); -// Assert.True(result2.StdOut.Contains("Successfully installed")); - -// TestCommon.VerifyPortablePackage(Path.Combine(installDir, packageDirName), commandAlias, fileName, productCode, true); -// } - -// [Test] -// public void InstallPortable_UserScope() -// { -// string installDir = TestCommon.GetRandomTestDir(); -// ConfigureInstallBehavior(Constants.PortablePackageUserRoot, installDir); - -// string packageId, commandAlias, fileName, packageDirName, productCode; -// packageId = "AppInstallerTest.TestPortableExe"; -// packageDirName = productCode = packageId + "_" + Constants.TestSourceIdentifier; -// commandAlias = fileName = "AppInstallerTestExeInstaller.exe"; - -// var result = TestCommon.RunAICLICommand("install", $"{packageId} --scope user"); -// ConfigureInstallBehavior(Constants.PortablePackageUserRoot, string.Empty); -// Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); -// Assert.True(result.StdOut.Contains("Successfully installed")); -// TestCommon.VerifyPortablePackage(Path.Combine(installDir, packageDirName), commandAlias, fileName, productCode, true); -// } - -// [Test] -// public void InstallPortable_MachineScope() -// { -// string installDir = TestCommon.GetRandomTestDir(); -// ConfigureInstallBehavior(Constants.PortablePackageMachineRoot, installDir); - -// string packageId, commandAlias, fileName, packageDirName, productCode; -// packageId = "AppInstallerTest.TestPortableExe"; -// packageDirName = productCode = packageId + "_" + Constants.TestSourceIdentifier; -// commandAlias = fileName = "AppInstallerTestExeInstaller.exe"; - -// var result = TestCommon.RunAICLICommand("install", $"{packageId} --scope machine"); -// ConfigureInstallBehavior(Constants.PortablePackageMachineRoot, string.Empty); -// Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); -// Assert.True(result.StdOut.Contains("Successfully installed")); -// TestCommon.VerifyPortablePackage(Path.Combine(installDir, packageDirName), commandAlias, fileName, productCode, true, TestCommon.Scope.Machine); -// } - -// [Test] -// public void InstallZip_Exe() -// { -// var installDir = TestCommon.GetRandomTestDir(); -// var result = TestCommon.RunAICLICommand("install", $"AppInstallerTest.TestZipInstallerWithExe --silent -l {installDir}"); -// Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); -// Assert.True(result.StdOut.Contains("Successfully installed")); -// Assert.True(TestCommon.VerifyTestExeInstalledAndCleanup(installDir, "/execustom")); -// } - -// [Test] -// public void InstallZip_Portable() -// { -// string installDir = TestCommon.GetPortablePackagesDirectory(); -// string packageId, commandAlias, fileName, packageDirName, productCode; -// packageId = "AppInstallerTest.TestZipInstallerWithPortable"; -// packageDirName = productCode = packageId + "_" + Constants.TestSourceIdentifier; -// commandAlias = "TestPortable.exe"; -// fileName = "AppInstallerTestExeInstaller.exe"; - -// var result = TestCommon.RunAICLICommand("install", $"{packageId}"); -// Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); -// Assert.True(result.StdOut.Contains("Successfully installed")); -// TestCommon.VerifyPortablePackage(Path.Combine(installDir, packageDirName), commandAlias, fileName, productCode, true, TestCommon.Scope.User); -// } - -// [Test] -// public void InstallZipWithInvalidRelativeFilePath() -// { -// var result = TestCommon.RunAICLICommand("install", $"AppInstallerTest.TestZipInvalidRelativePath"); -// Assert.AreNotEqual(Constants.ErrorCode.S_OK, result.ExitCode); -// Assert.True(result.StdOut.Contains("Invalid relative file path to the nested installer; path points to a location outside of the install directory")); -// } - -// [Test] -// public void InstallZipWithMsi() -// { -// var installDir = TestCommon.GetRandomTestDir(); -// var result = TestCommon.RunAICLICommand("install", $"AppInstallerTest.TestZipInstallerWithMsi --silent -l {installDir}"); -// Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); -// Assert.True(result.StdOut.Contains("Successfully installed")); -// Assert.True(TestCommon.VerifyTestMsiInstalledAndCleanup(installDir)); -// } - -// [Test] -// public void InstallZipWithMsix() -// { -// var result = TestCommon.RunAICLICommand("install", $"AppInstallerTest.TestZipInstallerWithMsix"); -// Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); -// Assert.True(result.StdOut.Contains("Successfully installed")); -// Assert.True(TestCommon.VerifyTestMsixInstalledAndCleanup()); -// } - -// [Test] -// public void InstallExeFoundExistingConvertToUpgrade() -// { -// var baseDir = TestCommon.GetRandomTestDir(); -// var baseResult = TestCommon.RunAICLICommand("install", $"AppInstallerTest.TestExeInstaller -v 1.0.0.0 --silent -l {baseDir}"); -// Assert.AreEqual(Constants.ErrorCode.S_OK, baseResult.ExitCode); -// Assert.True(baseResult.StdOut.Contains("Successfully installed")); - -// // Install will convert to upgrade -// var upgradeDir = TestCommon.GetRandomTestDir(); -// var upgradeResult = TestCommon.RunAICLICommand("install", $"AppInstallerTest.TestExeInstaller --silent -l {upgradeDir}"); -// Assert.AreEqual(Constants.ErrorCode.S_OK, upgradeResult.ExitCode); -// Assert.True(upgradeResult.StdOut.Contains("Trying to upgrade the installed package...")); -// Assert.True(upgradeResult.StdOut.Contains("Successfully installed")); - -// Assert.True(TestCommon.VerifyTestExeInstalledAndCleanup(baseDir)); -// Assert.True(TestCommon.VerifyTestExeInstalledAndCleanup(upgradeDir, "/Version 2.0.0.0")); -// } - -// [Test] -// public void InstallExeFoundExistingConvertToUpgradeNoAvailableUpgrade() -// { -// var baseDir = TestCommon.GetRandomTestDir(); -// var baseResult = TestCommon.RunAICLICommand("install", $"AppInstallerTest.TestExeInstaller -v 2.0.0.0 --silent -l {baseDir}"); -// Assert.AreEqual(Constants.ErrorCode.S_OK, baseResult.ExitCode); -// Assert.True(baseResult.StdOut.Contains("Successfully installed")); - -// // Install will convert to upgrade -// var upgradeDir = TestCommon.GetRandomTestDir(); -// var upgradeResult = TestCommon.RunAICLICommand("install", $"AppInstallerTest.TestExeInstaller --silent -l {upgradeDir}"); -// Assert.AreEqual(Constants.ErrorCode.ERROR_UPDATE_NOT_APPLICABLE, upgradeResult.ExitCode); -// Assert.True(upgradeResult.StdOut.Contains("Trying to upgrade the installed package...")); -// Assert.True(upgradeResult.StdOut.Contains("No applicable upgrade")); - -// Assert.True(TestCommon.VerifyTestExeInstalledAndCleanup(baseDir)); -// } - -// [Test] -// public void InstallExeWithLatestInstalledWithForce() -// { -// var baseDir = TestCommon.GetRandomTestDir(); -// var baseResult = TestCommon.RunAICLICommand("install", $"AppInstallerTest.TestExeInstaller -v 2.0.0.0 --silent -l {baseDir}"); -// Assert.AreEqual(Constants.ErrorCode.S_OK, baseResult.ExitCode); -// Assert.True(baseResult.StdOut.Contains("Successfully installed")); - -// // Install will not convert to upgrade -// var installDir = TestCommon.GetRandomTestDir(); -// var installResult = TestCommon.RunAICLICommand("install", $"AppInstallerTest.TestExeInstaller -v 1.0.0.0 --silent -l {installDir} --force"); -// Assert.AreEqual(Constants.ErrorCode.S_OK, installResult.ExitCode); -// Assert.True(installResult.StdOut.Contains("Successfully installed")); - -// Assert.True(TestCommon.VerifyTestExeInstalledAndCleanup(baseDir)); -// Assert.True(TestCommon.VerifyTestExeInstalledAndCleanup(installDir, "/execustom")); -// } -// } -//} \ No newline at end of file +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +namespace AppInstallerCLIE2ETests +{ + using NUnit.Framework; + using System.IO; + + public class InstallCommand : BaseCommand + { + [OneTimeSetUp] + public void OneTimeSetup() + { + ConfigureFeature("zipInstall", true); + } + + [SetUp] + public void Setup() + { + // Try clean up TestExeInstaller for failure cases where cleanup is not successful + TestCommon.RunAICLICommand("uninstall", "AppInstallerTest.TestExeInstaller"); + } + + [Test] + public void InstallAppDoesNotExist() + { + var result = TestCommon.RunAICLICommand("install", "DoesNotExist"); + Assert.AreEqual(Constants.ErrorCode.ERROR_NO_APPLICATIONS_FOUND, result.ExitCode); + Assert.True(result.StdOut.Contains("No package found matching input criteria.")); + } + + [Test] + public void InstallWithMultipleAppsMatchingQuery() + { + var result = TestCommon.RunAICLICommand("install", "TestExeInstaller"); + Assert.AreEqual(Constants.ErrorCode.ERROR_MULTIPLE_APPLICATIONS_FOUND, result.ExitCode); + Assert.True(result.StdOut.Contains("Multiple packages found matching input criteria. Please refine the input.")); + } + + [Test] + public void InstallExe() + { + var installDir = TestCommon.GetRandomTestDir(); + var result = TestCommon.RunAICLICommand("install", $"AppInstallerTest.TestExeInstaller --silent -l {installDir}"); + Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); + Assert.True(result.StdOut.Contains("Successfully installed")); + Assert.True(TestCommon.VerifyTestExeInstalledAndCleanup(installDir, "/execustom")); + } + + [Test] + public void InstallExeWithInsufficientMinOsVersion() + { + var installDir = TestCommon.GetRandomTestDir(); + var result = TestCommon.RunAICLICommand("install", $"InapplicableOsVersion --silent -l {installDir}"); + // MinOSVersion is moved to installer level, the check is performed during installer selection + Assert.AreEqual(Constants.ErrorCode.ERROR_NO_APPLICABLE_INSTALLER, result.ExitCode); + Assert.False(TestCommon.VerifyTestExeInstalledAndCleanup(installDir)); + } + + [Test] + public void InstallExeWithHashMismatch() + { + var installDir = TestCommon.GetRandomTestDir(); + var result = TestCommon.RunAICLICommand("install", $"TestExeSha256Mismatch --silent -l {installDir}"); + Assert.AreEqual(Constants.ErrorCode.ERROR_INSTALLER_HASH_MISMATCH, result.ExitCode); + Assert.True(result.StdOut.Contains("Installer hash does not match")); + Assert.False(TestCommon.VerifyTestExeInstalledAndCleanup(installDir)); + } + + [Test] + public void InstallWithInno() + { + // Install test inno, manifest does not provide silent switch, we should be populating the default + var installDir = TestCommon.GetRandomTestDir(); + var result = TestCommon.RunAICLICommand("install", $"TestInnoInstaller --silent -l {installDir}"); + Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); + Assert.True(result.StdOut.Contains("Successfully installed")); + Assert.True(TestCommon.VerifyTestExeInstalledAndCleanup(installDir, "/VERYSILENT")); + } + + [Test] + public void InstallBurn() + { + // Install test burn, manifest does not provide silent switch, we should be populating the default + var installDir = TestCommon.GetRandomTestDir(); + var result = TestCommon.RunAICLICommand("install", $"TestBurnInstaller --silent -l {installDir}"); + Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); + Assert.True(result.StdOut.Contains("Successfully installed")); + Assert.True(TestCommon.VerifyTestExeInstalledAndCleanup(installDir, "/quiet")); + } + + [Test] + public void InstallNullSoft() + { + // Install test Nullsoft, manifest does not provide silent switch, we should be populating the default + var installDir = TestCommon.GetRandomTestDir(); + var result = TestCommon.RunAICLICommand("install", $"TestNullsoftInstaller --silent -l {installDir}"); + Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); + Assert.True(result.StdOut.Contains("Successfully installed")); + Assert.True(TestCommon.VerifyTestExeInstalledAndCleanup(installDir, "/S")); + } + + [Test] + public void InstallMSI() + { + var installDir = TestCommon.GetRandomTestDir(); + var result = TestCommon.RunAICLICommand("install", $"TestMsiInstaller --silent -l {installDir}"); + Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); + Assert.True(result.StdOut.Contains("Successfully installed")); + Assert.True(TestCommon.VerifyTestMsiInstalledAndCleanup(installDir)); + } + + [Test] + public void InstallMSIX() + { + var result = TestCommon.RunAICLICommand("install", $"TestMsixInstaller"); + Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); + Assert.True(result.StdOut.Contains("Successfully installed")); + Assert.True(TestCommon.VerifyTestMsixInstalledAndCleanup()); + } + + [Test] + public void InstallMSIXWithSignature() + { + var installDir = TestCommon.GetRandomTestDir(); + var result = TestCommon.RunAICLICommand("install", $"TestMsixWithSignatureHash --silent -l {installDir}"); + Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); + Assert.True(result.StdOut.Contains("Successfully installed")); + Assert.True(TestCommon.VerifyTestMsixInstalledAndCleanup()); + } + + [Test] + public void InstallMSIXWithSignatureHashMismatch() + { + var result = TestCommon.RunAICLICommand("install", $"TestMsixSignatureHashMismatch"); + Assert.AreEqual(Constants.ErrorCode.ERROR_INSTALLER_HASH_MISMATCH, result.ExitCode); + Assert.True(result.StdOut.Contains("Installer hash does not match")); + Assert.False(TestCommon.VerifyTestMsixInstalledAndCleanup()); + } + + [Test] + public void InstallExeWithAlternateSourceFailure() + { + TestCommon.RunAICLICommand("source add", "failSearch \"{ \"\"SearchHR\"\": \"\"0x80070002\"\" }\" Microsoft.Test.Configurable --header \"{}\""); + + try + { + var installDir = TestCommon.GetRandomTestDir(); + var result = TestCommon.RunAICLICommand("install", $"AppInstallerTest.TestExeInstaller --silent -l {installDir}"); + Assert.AreEqual(unchecked((int)0x80070002), result.ExitCode); + Assert.True(result.StdOut.Contains("Failed when searching source: failSearch")); + Assert.True(result.StdOut.Contains("AppInstallerTest.TestExeInstaller")); + Assert.False(result.StdOut.Contains("Successfully installed")); + Assert.False(TestCommon.VerifyTestExeInstalledAndCleanup(installDir)); + } + finally + { + ResetTestSource(); + } + } + + [Test] + public void InstallPortableExe() + { + string installDir = TestCommon.GetPortablePackagesDirectory(); + string packageId, commandAlias, fileName, packageDirName, productCode; + packageId = "AppInstallerTest.TestPortableExe"; + packageDirName = productCode = packageId + "_" + Constants.TestSourceIdentifier; + commandAlias = fileName = "AppInstallerTestExeInstaller.exe"; + + var result = TestCommon.RunAICLICommand("install", $"{packageId}"); + Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); + Assert.True(result.StdOut.Contains("Successfully installed")); + // If no location specified, default behavior is to create a package directory with the name "{packageId}_{sourceId}" + TestCommon.VerifyPortablePackage(Path.Combine(installDir, packageDirName), commandAlias, fileName, productCode, true); + } + + [Test] + public void InstallPortableExeWithCommand() + { + var installDir = TestCommon.GetRandomTestDir(); + string packageId, commandAlias, fileName, productCode; + packageId = "AppInstallerTest.TestPortableExeWithCommand"; + productCode = packageId + "_" + Constants.TestSourceIdentifier; + fileName = "AppInstallerTestExeInstaller.exe"; + commandAlias = "testCommand.exe"; + + var result = TestCommon.RunAICLICommand("install", $"{packageId} -l {installDir}"); + Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); + Assert.True(result.StdOut.Contains("Successfully installed")); + TestCommon.VerifyPortablePackage(installDir, commandAlias, fileName, productCode, true); + } + + [Test] + public void InstallPortableExeWithRename() + { + var installDir = TestCommon.GetRandomTestDir(); + string packageId, productCode, renameArgValue; + packageId = "AppInstallerTest.TestPortableExeWithCommand"; + productCode = packageId + "_" + Constants.TestSourceIdentifier; + renameArgValue = "testRename.exe"; + + var result = TestCommon.RunAICLICommand("install", $"{packageId} -l {installDir} --rename {renameArgValue}"); + Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); + Assert.True(result.StdOut.Contains("Successfully installed")); + TestCommon.VerifyPortablePackage(installDir, renameArgValue, renameArgValue, productCode, true); + } + + [Test] + public void InstallPortableInvalidRename() + { + var installDir = TestCommon.GetRandomTestDir(); + string packageId, renameArgValue; + packageId = "AppInstallerTest.TestPortableExeWithCommand"; + renameArgValue = "test?"; + + var result = TestCommon.RunAICLICommand("install", $"{packageId} -l {installDir} --rename {renameArgValue}"); + Assert.AreNotEqual(Constants.ErrorCode.S_OK, result.ExitCode); + Assert.True(result.StdOut.Contains("The specified filename is not a valid filename")); + } + + [Test] + public void InstallPortableReservedNames() + { + var installDir = TestCommon.GetRandomTestDir(); + string packageId, renameArgValue; + packageId = "AppInstallerTest.TestPortableExeWithCommand"; + renameArgValue = "CON"; + + var result = TestCommon.RunAICLICommand("install", $"{packageId} -l {installDir} --rename {renameArgValue}"); + Assert.AreNotEqual(Constants.ErrorCode.S_OK, result.ExitCode); + Assert.True(result.StdOut.Contains("The specified filename is not a valid filename")); + } + + [Test] + public void InstallPortableToExistingDirectory() + { + var installDir = TestCommon.GetRandomTestDir(); + var existingDir = Path.Combine(installDir, "testDirectory"); + Directory.CreateDirectory(existingDir); + + string packageId, commandAlias, fileName, productCode; + packageId = "AppInstallerTest.TestPortableExe"; + productCode = packageId + "_" + Constants.TestSourceIdentifier; + commandAlias = fileName = "AppInstallerTestExeInstaller.exe"; + + var result = TestCommon.RunAICLICommand("install", $"{packageId} -l {existingDir}"); + Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); + Assert.True(result.StdOut.Contains("Successfully installed")); + TestCommon.VerifyPortablePackage(existingDir, commandAlias, fileName, productCode, true); + } + + [Test] + public void InstallPortableFailsWithCleanup() + { + string packageId, commandAlias; + packageId = "AppInstallerTest.TestPortableExe"; + commandAlias = "AppInstallerTestExeInstaller.exe"; + + // Create a directory with the same name as the symlink in order to cause install to fail. + string symlinkDirectory = TestCommon.GetPortableSymlinkDirectory(TestCommon.Scope.User); + string conflictDirectory = Path.Combine(symlinkDirectory, commandAlias); + + Directory.CreateDirectory(conflictDirectory); + + var result = TestCommon.RunAICLICommand("install", $"{packageId}"); + + // Remove directory prior to assertions as this will impact other tests if assertions fail. + Directory.Delete(conflictDirectory, true); + + Assert.AreNotEqual(Constants.ErrorCode.S_OK, result.ExitCode); + Assert.True(result.StdOut.Contains("Unable to create symlink, path points to a directory.")); + } + + [Test] + public void ReinstallPortable() + { + string installDir = TestCommon.GetPortablePackagesDirectory(); + string packageId, commandAlias, fileName, packageDirName, productCode; + packageId = "AppInstallerTest.TestPortableExe"; + packageDirName = productCode = packageId + "_" + Constants.TestSourceIdentifier; + commandAlias = fileName = "AppInstallerTestExeInstaller.exe"; + + var result = TestCommon.RunAICLICommand("install", $"{packageId}"); + Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); + + string symlinkDirectory = TestCommon.GetPortableSymlinkDirectory(TestCommon.Scope.User); + string symlinkPath = Path.Combine(symlinkDirectory, commandAlias); + + // Clean first install should not display file overwrite message. + Assert.True(result.StdOut.Contains("Successfully installed")); + Assert.False(result.StdOut.Contains($"Overwriting existing file: {symlinkPath}")); + + // Perform second install and verify that file overwrite message is displayed. + var result2 = TestCommon.RunAICLICommand("install", $"{packageId} --force"); + Assert.AreEqual(Constants.ErrorCode.S_OK, result2.ExitCode); + Assert.True(result2.StdOut.Contains("Successfully installed")); + + TestCommon.VerifyPortablePackage(Path.Combine(installDir, packageDirName), commandAlias, fileName, productCode, true); + } + + [Test] + public void InstallPortable_UserScope() + { + string installDir = TestCommon.GetRandomTestDir(); + ConfigureInstallBehavior(Constants.PortablePackageUserRoot, installDir); + + string packageId, commandAlias, fileName, packageDirName, productCode; + packageId = "AppInstallerTest.TestPortableExe"; + packageDirName = productCode = packageId + "_" + Constants.TestSourceIdentifier; + commandAlias = fileName = "AppInstallerTestExeInstaller.exe"; + + var result = TestCommon.RunAICLICommand("install", $"{packageId} --scope user"); + ConfigureInstallBehavior(Constants.PortablePackageUserRoot, string.Empty); + Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); + Assert.True(result.StdOut.Contains("Successfully installed")); + TestCommon.VerifyPortablePackage(Path.Combine(installDir, packageDirName), commandAlias, fileName, productCode, true); + } + + [Test] + public void InstallPortable_MachineScope() + { + string installDir = TestCommon.GetRandomTestDir(); + ConfigureInstallBehavior(Constants.PortablePackageMachineRoot, installDir); + + string packageId, commandAlias, fileName, packageDirName, productCode; + packageId = "AppInstallerTest.TestPortableExe"; + packageDirName = productCode = packageId + "_" + Constants.TestSourceIdentifier; + commandAlias = fileName = "AppInstallerTestExeInstaller.exe"; + + var result = TestCommon.RunAICLICommand("install", $"{packageId} --scope machine"); + ConfigureInstallBehavior(Constants.PortablePackageMachineRoot, string.Empty); + Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); + Assert.True(result.StdOut.Contains("Successfully installed")); + TestCommon.VerifyPortablePackage(Path.Combine(installDir, packageDirName), commandAlias, fileName, productCode, true, TestCommon.Scope.Machine); + } + + [Test] + public void InstallZip_Exe() + { + var installDir = TestCommon.GetRandomTestDir(); + var result = TestCommon.RunAICLICommand("install", $"AppInstallerTest.TestZipInstallerWithExe --silent -l {installDir}"); + Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); + Assert.True(result.StdOut.Contains("Successfully installed")); + Assert.True(TestCommon.VerifyTestExeInstalledAndCleanup(installDir, "/execustom")); + } + + [Test] + public void InstallZip_Portable() + { + string installDir = TestCommon.GetPortablePackagesDirectory(); + string packageId, commandAlias, fileName, packageDirName, productCode; + packageId = "AppInstallerTest.TestZipInstallerWithPortable"; + packageDirName = productCode = packageId + "_" + Constants.TestSourceIdentifier; + commandAlias = "TestPortable.exe"; + fileName = "AppInstallerTestExeInstaller.exe"; + + var result = TestCommon.RunAICLICommand("install", $"{packageId}"); + Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); + Assert.True(result.StdOut.Contains("Successfully installed")); + TestCommon.VerifyPortablePackage(Path.Combine(installDir, packageDirName), commandAlias, fileName, productCode, true, TestCommon.Scope.User); + } + + [Test] + public void InstallZipWithInvalidRelativeFilePath() + { + var result = TestCommon.RunAICLICommand("install", $"AppInstallerTest.TestZipInvalidRelativePath"); + Assert.AreNotEqual(Constants.ErrorCode.S_OK, result.ExitCode); + Assert.True(result.StdOut.Contains("Invalid relative file path to the nested installer; path points to a location outside of the install directory")); + } + + [Test] + public void InstallZipWithMsi() + { + var installDir = TestCommon.GetRandomTestDir(); + var result = TestCommon.RunAICLICommand("install", $"AppInstallerTest.TestZipInstallerWithMsi --silent -l {installDir}"); + Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); + Assert.True(result.StdOut.Contains("Successfully installed")); + Assert.True(TestCommon.VerifyTestMsiInstalledAndCleanup(installDir)); + } + + [Test] + public void InstallZipWithMsix() + { + var result = TestCommon.RunAICLICommand("install", $"AppInstallerTest.TestZipInstallerWithMsix"); + Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); + Assert.True(result.StdOut.Contains("Successfully installed")); + Assert.True(TestCommon.VerifyTestMsixInstalledAndCleanup()); + } + + [Test] + public void InstallExeFoundExistingConvertToUpgrade() + { + var baseDir = TestCommon.GetRandomTestDir(); + var baseResult = TestCommon.RunAICLICommand("install", $"AppInstallerTest.TestExeInstaller -v 1.0.0.0 --silent -l {baseDir}"); + Assert.AreEqual(Constants.ErrorCode.S_OK, baseResult.ExitCode); + Assert.True(baseResult.StdOut.Contains("Successfully installed")); + + // Install will convert to upgrade + var upgradeDir = TestCommon.GetRandomTestDir(); + var upgradeResult = TestCommon.RunAICLICommand("install", $"AppInstallerTest.TestExeInstaller --silent -l {upgradeDir}"); + Assert.AreEqual(Constants.ErrorCode.S_OK, upgradeResult.ExitCode); + Assert.True(upgradeResult.StdOut.Contains("Trying to upgrade the installed package...")); + Assert.True(upgradeResult.StdOut.Contains("Successfully installed")); + + Assert.True(TestCommon.VerifyTestExeInstalledAndCleanup(baseDir)); + Assert.True(TestCommon.VerifyTestExeInstalledAndCleanup(upgradeDir, "/Version 2.0.0.0")); + } + + [Test] + public void InstallExeFoundExistingConvertToUpgradeNoAvailableUpgrade() + { + var baseDir = TestCommon.GetRandomTestDir(); + var baseResult = TestCommon.RunAICLICommand("install", $"AppInstallerTest.TestExeInstaller -v 2.0.0.0 --silent -l {baseDir}"); + Assert.AreEqual(Constants.ErrorCode.S_OK, baseResult.ExitCode); + Assert.True(baseResult.StdOut.Contains("Successfully installed")); + + // Install will convert to upgrade + var upgradeDir = TestCommon.GetRandomTestDir(); + var upgradeResult = TestCommon.RunAICLICommand("install", $"AppInstallerTest.TestExeInstaller --silent -l {upgradeDir}"); + Assert.AreEqual(Constants.ErrorCode.ERROR_UPDATE_NOT_APPLICABLE, upgradeResult.ExitCode); + Assert.True(upgradeResult.StdOut.Contains("Trying to upgrade the installed package...")); + Assert.True(upgradeResult.StdOut.Contains("No applicable upgrade")); + + Assert.True(TestCommon.VerifyTestExeInstalledAndCleanup(baseDir)); + } + + [Test] + public void InstallExeWithLatestInstalledWithForce() + { + var baseDir = TestCommon.GetRandomTestDir(); + var baseResult = TestCommon.RunAICLICommand("install", $"AppInstallerTest.TestExeInstaller -v 2.0.0.0 --silent -l {baseDir}"); + Assert.AreEqual(Constants.ErrorCode.S_OK, baseResult.ExitCode); + Assert.True(baseResult.StdOut.Contains("Successfully installed")); + + // Install will not convert to upgrade + var installDir = TestCommon.GetRandomTestDir(); + var installResult = TestCommon.RunAICLICommand("install", $"AppInstallerTest.TestExeInstaller -v 1.0.0.0 --silent -l {installDir} --force"); + Assert.AreEqual(Constants.ErrorCode.S_OK, installResult.ExitCode); + Assert.True(installResult.StdOut.Contains("Successfully installed")); + + Assert.True(TestCommon.VerifyTestExeInstalledAndCleanup(baseDir)); + Assert.True(TestCommon.VerifyTestExeInstalledAndCleanup(installDir, "/execustom")); + } + } +} \ No newline at end of file diff --git a/src/AppInstallerCLIE2ETests/ListCommand.cs b/src/AppInstallerCLIE2ETests/ListCommand.cs index d314e87a7e..0115ab814e 100644 --- a/src/AppInstallerCLIE2ETests/ListCommand.cs +++ b/src/AppInstallerCLIE2ETests/ListCommand.cs @@ -1,111 +1,111 @@ -//// Copyright (c) Microsoft Corporation. -//// Licensed under the MIT License. - -//namespace AppInstallerCLIE2ETests -//{ -// using NUnit.Framework; -// using System.IO; - -// public class ListCommand : BaseCommand -// { -// [Test] -// public void ListSelf() -// { -// var result = TestCommon.RunAICLICommand("list", Constants.AICLIPackageFamilyName); -// Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); -// Assert.True(result.StdOut.Contains(Constants.AICLIPackageFamilyName)); -// } - -// [Test] -// public void ListAfterInstall() -// { -// System.Guid guid = System.Guid.NewGuid(); -// string productCode = guid.ToString(); -// var installDir = TestCommon.GetRandomTestDir(); - -// // DisplayName must be set to avoid conflicts with other packages that use the same exe installer. -// string displayName = "TestExeInstaller"; -// string localAppDataPath = System.Environment.GetEnvironmentVariable(Constants.LocalAppData); -// string logFilePath = System.IO.Path.Combine(localAppDataPath, Constants.E2ETestLogsPathPackaged); -// logFilePath = System.IO.Path.Combine(logFilePath, "ListAfterInstall-" + System.IO.Path.GetRandomFileName() + ".log"); - -// var result = TestCommon.RunAICLICommand("list", productCode); -// Assert.AreEqual(Constants.ErrorCode.ERROR_NO_APPLICATIONS_FOUND, result.ExitCode); - -// result = TestCommon.RunAICLICommand("install", $"AppInstallerTest.TestExeInstaller --override \"/InstallDir {installDir} /ProductID {productCode} /LogFile {logFilePath} /DisplayName {displayName}\""); -// Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); - -// result = TestCommon.RunAICLICommand("list", productCode); -// Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); -// Assert.True(result.StdOut.Contains("AppInstallerTest.TestExeInstaller")); -// Assert.True(result.StdOut.Contains("1.0.0.0")); -// Assert.True(result.StdOut.Contains("2.0.0.0")); -// } - -// [Test] -// public void ListWithArpVersionMapping() -// { -// // No mapping performed -// ArpVersionMappingTest("AppInstallerTest.TestArpVersionSameVersion", "TestArpVersionSameVersion", "0.5", "0.5", "< 1.0"); - -// // Partial mapping performed(i.e. only if version falls within arp version range) -// ArpVersionMappingTest("AppInstallerTest.TestArpVersionOppositeOrder", "TestArpVersionOppositeOrder", "10.1", "1.0", "10.1"); -// ArpVersionMappingTest("AppInstallerTest.TestArpVersionOppositeOrder", "TestArpVersionOppositeOrder", "9.9", "9.9", "> 2.0"); - -// // Full mapping performed -// ArpVersionMappingTest("AppInstallerTest.TestArpVersionSameOrder", "TestArpVersionSameOrder", "7.0", "< 1.0", "7.0"); -// ArpVersionMappingTest("AppInstallerTest.TestArpVersionSameOrder", "TestArpVersionSameOrder", "10.1", "1.0", "10.1"); -// ArpVersionMappingTest("AppInstallerTest.TestArpVersionSameOrder", "TestArpVersionSameOrder", "10.7", "< 2.0", "10.7"); -// ArpVersionMappingTest("AppInstallerTest.TestArpVersionSameOrder", "TestArpVersionSameOrder", "11.1", "2.0", "11.1"); -// ArpVersionMappingTest("AppInstallerTest.TestArpVersionSameOrder", "TestArpVersionSameOrder", "12.0", "> 2.0", "12.0"); -// } - -// [Test] -// public void ListWithUpgradeCode() -// { -// // Installs the MSI installer using the TestMsiInstaller package. -// // Then tries listing the TestMsiInstallerUpgradeCode package, which should -// // be correlated to it by the UpgradeCode. -// if (string.IsNullOrEmpty(TestCommon.MsiInstallerPath)) -// { -// Assert.Ignore("MSI installer not available"); -// } - -// var installDir = TestCommon.GetRandomTestDir(); -// Assert.AreEqual(Constants.ErrorCode.S_OK, TestCommon.RunAICLICommand("install", $"TestMsiInstaller --silent -l {installDir}").ExitCode); - -// var result = TestCommon.RunAICLICommand("list", "TestMsiInstallerUpgradeCode"); -// Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); -// Assert.True(result.StdOut.Contains("AppInstallerTest.TestMsiInstallerUpgradeCode")); -// } - -// private void ArpVersionMappingTest(string packageIdentifier, string displayNameOverride, string displayVersionOverride, string expectedListVersion, string notExpectedListVersion = "") -// { -// System.Guid guid = System.Guid.NewGuid(); -// string productCode = guid.ToString(); -// var installDir = TestCommon.GetRandomTestDir(); - -// var result = TestCommon.RunAICLICommand("list", productCode); -// Assert.AreEqual(Constants.ErrorCode.ERROR_NO_APPLICATIONS_FOUND, result.ExitCode); - -// result = TestCommon.RunAICLICommand("install", $"{packageIdentifier} --override \"/InstallDir {installDir} /ProductID {productCode} /DisplayName {displayNameOverride} /Version {displayVersionOverride}\""); -// Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); - -// result = TestCommon.RunAICLICommand("list", productCode); -// Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); - -// Assert.True(result.StdOut.Contains(packageIdentifier)); -// Assert.True(result.StdOut.Contains(expectedListVersion)); -// if (!string.IsNullOrEmpty(notExpectedListVersion)) -// { -// Assert.False(result.StdOut.Contains(notExpectedListVersion)); -// } - -// // Try clean up -// if (File.Exists(Path.Combine(installDir, Constants.TestExeInstalledFileName))) -// { -// TestCommon.RunCommand(Path.Combine(installDir, Constants.TestExeUninstallerFileName)); -// } -// } -// } -//} +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +namespace AppInstallerCLIE2ETests +{ + using NUnit.Framework; + using System.IO; + + public class ListCommand : BaseCommand + { + [Test] + public void ListSelf() + { + var result = TestCommon.RunAICLICommand("list", Constants.AICLIPackageFamilyName); + Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); + Assert.True(result.StdOut.Contains(Constants.AICLIPackageFamilyName)); + } + + [Test] + public void ListAfterInstall() + { + System.Guid guid = System.Guid.NewGuid(); + string productCode = guid.ToString(); + var installDir = TestCommon.GetRandomTestDir(); + + // DisplayName must be set to avoid conflicts with other packages that use the same exe installer. + string displayName = "TestExeInstaller"; + string localAppDataPath = System.Environment.GetEnvironmentVariable(Constants.LocalAppData); + string logFilePath = System.IO.Path.Combine(localAppDataPath, Constants.E2ETestLogsPathPackaged); + logFilePath = System.IO.Path.Combine(logFilePath, "ListAfterInstall-" + System.IO.Path.GetRandomFileName() + ".log"); + + var result = TestCommon.RunAICLICommand("list", productCode); + Assert.AreEqual(Constants.ErrorCode.ERROR_NO_APPLICATIONS_FOUND, result.ExitCode); + + result = TestCommon.RunAICLICommand("install", $"AppInstallerTest.TestExeInstaller --override \"/InstallDir {installDir} /ProductID {productCode} /LogFile {logFilePath} /DisplayName {displayName}\""); + Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); + + result = TestCommon.RunAICLICommand("list", productCode); + Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); + Assert.True(result.StdOut.Contains("AppInstallerTest.TestExeInstaller")); + Assert.True(result.StdOut.Contains("1.0.0.0")); + Assert.True(result.StdOut.Contains("2.0.0.0")); + } + + [Test] + public void ListWithArpVersionMapping() + { + // No mapping performed + ArpVersionMappingTest("AppInstallerTest.TestArpVersionSameVersion", "TestArpVersionSameVersion", "0.5", "0.5", "< 1.0"); + + // Partial mapping performed(i.e. only if version falls within arp version range) + ArpVersionMappingTest("AppInstallerTest.TestArpVersionOppositeOrder", "TestArpVersionOppositeOrder", "10.1", "1.0", "10.1"); + ArpVersionMappingTest("AppInstallerTest.TestArpVersionOppositeOrder", "TestArpVersionOppositeOrder", "9.9", "9.9", "> 2.0"); + + // Full mapping performed + ArpVersionMappingTest("AppInstallerTest.TestArpVersionSameOrder", "TestArpVersionSameOrder", "7.0", "< 1.0", "7.0"); + ArpVersionMappingTest("AppInstallerTest.TestArpVersionSameOrder", "TestArpVersionSameOrder", "10.1", "1.0", "10.1"); + ArpVersionMappingTest("AppInstallerTest.TestArpVersionSameOrder", "TestArpVersionSameOrder", "10.7", "< 2.0", "10.7"); + ArpVersionMappingTest("AppInstallerTest.TestArpVersionSameOrder", "TestArpVersionSameOrder", "11.1", "2.0", "11.1"); + ArpVersionMappingTest("AppInstallerTest.TestArpVersionSameOrder", "TestArpVersionSameOrder", "12.0", "> 2.0", "12.0"); + } + + [Test] + public void ListWithUpgradeCode() + { + // Installs the MSI installer using the TestMsiInstaller package. + // Then tries listing the TestMsiInstallerUpgradeCode package, which should + // be correlated to it by the UpgradeCode. + if (string.IsNullOrEmpty(TestCommon.MsiInstallerPath)) + { + Assert.Ignore("MSI installer not available"); + } + + var installDir = TestCommon.GetRandomTestDir(); + Assert.AreEqual(Constants.ErrorCode.S_OK, TestCommon.RunAICLICommand("install", $"TestMsiInstaller --silent -l {installDir}").ExitCode); + + var result = TestCommon.RunAICLICommand("list", "TestMsiInstallerUpgradeCode"); + Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); + Assert.True(result.StdOut.Contains("AppInstallerTest.TestMsiInstallerUpgradeCode")); + } + + private void ArpVersionMappingTest(string packageIdentifier, string displayNameOverride, string displayVersionOverride, string expectedListVersion, string notExpectedListVersion = "") + { + System.Guid guid = System.Guid.NewGuid(); + string productCode = guid.ToString(); + var installDir = TestCommon.GetRandomTestDir(); + + var result = TestCommon.RunAICLICommand("list", productCode); + Assert.AreEqual(Constants.ErrorCode.ERROR_NO_APPLICATIONS_FOUND, result.ExitCode); + + result = TestCommon.RunAICLICommand("install", $"{packageIdentifier} --override \"/InstallDir {installDir} /ProductID {productCode} /DisplayName {displayNameOverride} /Version {displayVersionOverride}\""); + Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); + + result = TestCommon.RunAICLICommand("list", productCode); + Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); + + Assert.True(result.StdOut.Contains(packageIdentifier)); + Assert.True(result.StdOut.Contains(expectedListVersion)); + if (!string.IsNullOrEmpty(notExpectedListVersion)) + { + Assert.False(result.StdOut.Contains(notExpectedListVersion)); + } + + // Try clean up + if (File.Exists(Path.Combine(installDir, Constants.TestExeInstalledFileName))) + { + TestCommon.RunCommand(Path.Combine(installDir, Constants.TestExeUninstallerFileName)); + } + } + } +} diff --git a/src/AppInstallerCLIE2ETests/PowerShell/PowerShellModule.cs b/src/AppInstallerCLIE2ETests/PowerShell/PowerShellModule.cs index 2fca0e0b4a..36c3b66acf 100644 --- a/src/AppInstallerCLIE2ETests/PowerShell/PowerShellModule.cs +++ b/src/AppInstallerCLIE2ETests/PowerShell/PowerShellModule.cs @@ -4,11 +4,12 @@ namespace AppInstallerCLIE2ETests { using NUnit.Framework; + using System; /// /// Basic E2E tests for verifying that behavior of the PowerShell module cmdlets. /// - public class APowerShellModule + public class PowerShellModule { [OneTimeSetUp] public void Setup() @@ -27,22 +28,38 @@ public void TearDown() [Test] public void GetWinGetSource() { + // Running the x86 PowerShell Module requires PowerShell Core (x86). The tests currently only target PowerShell Core (x64) + if (!Environment.Is64BitProcess) + { + return; + } + var getSourceResult = TestCommon.RunPowerShellCommandWithResult(Constants.GetSourceCmdlet, $"-Name {Constants.TestSourceName}"); Assert.IsTrue(getSourceResult.ExitCode == 0, $"ExitCode: {getSourceResult.ExitCode} Failed with the following output: {getSourceResult.StdOut}, {getSourceResult.StdErr}"); Assert.IsTrue(getSourceResult.StdOut.Contains($"{Constants.TestSourceName}")); } - //[Test] + [Test] public void FindWinGetPackage() { + if (!Environment.Is64BitProcess) + { + return; + } + var result = TestCommon.RunPowerShellCommandWithResult(Constants.FindCmdlet, $"-Id {Constants.ExeInstallerPackageId}"); Assert.IsTrue(result.ExitCode == 0, $"ExitCode: {result.ExitCode} Failed with the following output: {result.StdOut}; {result.StdErr}"); Assert.IsTrue(result.StdOut.Contains("TestExeInstaller")); } - //[Test] + [Test] public void GetWinGetPackage() { + if (!Environment.Is64BitProcess) + { + return; + } + var installResult = TestCommon.RunPowerShellCommandWithResult(Constants.InstallCmdlet, $"-Id {Constants.MsiInstallerPackageId}"); var getResult = TestCommon.RunPowerShellCommandWithResult(Constants.GetCmdlet, $"-Id {Constants.MsiInstallerPackageId}"); var uninstallResult = TestCommon.RunPowerShellCommandWithResult(Constants.UninstallCmdlet, $"-Id {Constants.MsiInstallerPackageId}"); @@ -56,9 +73,14 @@ public void GetWinGetPackage() Assert.IsTrue(!string.IsNullOrEmpty(uninstallResult.StdOut)); } - //[Test] + [Test] public void InstallWinGetPackage() { + if (!Environment.Is64BitProcess) + { + return; + } + var installResult = TestCommon.RunPowerShellCommandWithResult(Constants.InstallCmdlet, $"-Id {Constants.ExeInstallerPackageId}"); var uninstallResult = TestCommon.RunPowerShellCommandWithResult(Constants.UninstallCmdlet, $"-Id {Constants.ExeInstallerPackageId}"); @@ -69,9 +91,14 @@ public void InstallWinGetPackage() Assert.IsTrue(!string.IsNullOrEmpty(uninstallResult.StdOut)); } - //[Test] + [Test] public void UpdateWinGetPackage() { + if (!Environment.Is64BitProcess) + { + return; + } + var installResult = TestCommon.RunPowerShellCommandWithResult(Constants.InstallCmdlet, $"-Id {Constants.ExeInstallerPackageId} -Version 1.0.0.0"); var updateResult = TestCommon.RunPowerShellCommandWithResult(Constants.UpdateCmdlet, $"-Id {Constants.ExeInstallerPackageId}"); var getResult = TestCommon.RunPowerShellCommandWithResult(Constants.GetCmdlet, $"-Id {Constants.ExeInstallerPackageId}"); diff --git a/src/AppInstallerCLIE2ETests/SearchCommand.cs b/src/AppInstallerCLIE2ETests/SearchCommand.cs index 955151aeb5..aca227fca3 100644 --- a/src/AppInstallerCLIE2ETests/SearchCommand.cs +++ b/src/AppInstallerCLIE2ETests/SearchCommand.cs @@ -1,170 +1,170 @@ -//// Copyright (c) Microsoft Corporation. -//// Licensed under the MIT License. +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. -//namespace AppInstallerCLIE2ETests -//{ -// using NUnit.Framework; +namespace AppInstallerCLIE2ETests +{ + using NUnit.Framework; -// public class SearchCommand : BaseCommand -// { -// [Test] -// public void SearchWithoutArgs() -// { -// var result = TestCommon.RunAICLICommand("search", ""); -// Assert.AreEqual(Constants.ErrorCode.ERROR_INVALID_CL_ARGUMENTS, result.ExitCode); -// } + public class SearchCommand : BaseCommand + { + [Test] + public void SearchWithoutArgs() + { + var result = TestCommon.RunAICLICommand("search", ""); + Assert.AreEqual(Constants.ErrorCode.ERROR_INVALID_CL_ARGUMENTS, result.ExitCode); + } -// [Test] -// public void SearchQuery() -// { -// var result = TestCommon.RunAICLICommand("search", "TestExampleInstaller"); -// Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); -// Assert.True(result.StdOut.Contains("TestExampleInstaller")); -// Assert.True(result.StdOut.Contains("AppInstallerTest.TestExampleInstaller")); -// } + [Test] + public void SearchQuery() + { + var result = TestCommon.RunAICLICommand("search", "TestExampleInstaller"); + Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); + Assert.True(result.StdOut.Contains("TestExampleInstaller")); + Assert.True(result.StdOut.Contains("AppInstallerTest.TestExampleInstaller")); + } -// public void SearchUsingAlias() -// { -// var result = TestCommon.RunAICLICommand("find", "TestExampleInstaller"); -// Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); -// Assert.True(result.StdOut.Contains("TestExampleInstaller")); -// Assert.True(result.StdOut.Contains("AppInstallerTest.TestExampleInstaller")); -// } + public void SearchUsingAlias() + { + var result = TestCommon.RunAICLICommand("find", "TestExampleInstaller"); + Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); + Assert.True(result.StdOut.Contains("TestExampleInstaller")); + Assert.True(result.StdOut.Contains("AppInstallerTest.TestExampleInstaller")); + } -// [Test] -// public void SearchWithName() -// { -// var result = TestCommon.RunAICLICommand("search", "--name testexampleinstaller"); -// Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); -// Assert.True(result.StdOut.Contains("TestExampleInstaller")); -// Assert.True(result.StdOut.Contains("AppInstallerTest.TestExampleInstaller")); -// } + [Test] + public void SearchWithName() + { + var result = TestCommon.RunAICLICommand("search", "--name testexampleinstaller"); + Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); + Assert.True(result.StdOut.Contains("TestExampleInstaller")); + Assert.True(result.StdOut.Contains("AppInstallerTest.TestExampleInstaller")); + } -// [Test] -// public void SearchWithID() -// { -// var result = TestCommon.RunAICLICommand("search", "--id appinstallertest.testexampleinstaller"); -// Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); -// Assert.True(result.StdOut.Contains("TestExampleInstaller")); -// Assert.True(result.StdOut.Contains("AppInstallerTest.TestExampleInstaller")); -// } + [Test] + public void SearchWithID() + { + var result = TestCommon.RunAICLICommand("search", "--id appinstallertest.testexampleinstaller"); + Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); + Assert.True(result.StdOut.Contains("TestExampleInstaller")); + Assert.True(result.StdOut.Contains("AppInstallerTest.TestExampleInstaller")); + } -// [Test] -// public void SearchWithInvalidName() -// { -// var result = TestCommon.RunAICLICommand("search", "--name InvalidName"); -// Assert.AreEqual(Constants.ErrorCode.ERROR_NO_APPLICATIONS_FOUND, result.ExitCode); -// Assert.True(result.StdOut.Contains("No package found matching input criteria.")); -// } + [Test] + public void SearchWithInvalidName() + { + var result = TestCommon.RunAICLICommand("search", "--name InvalidName"); + Assert.AreEqual(Constants.ErrorCode.ERROR_NO_APPLICATIONS_FOUND, result.ExitCode); + Assert.True(result.StdOut.Contains("No package found matching input criteria.")); + } -// [Test] -// public void SearchReturnsMultiple() -// { -// // Search Microsoft should return multiple -// var result = TestCommon.RunAICLICommand("search", "AppInstallerTest"); -// Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); -// Assert.True(result.StdOut.Contains("AppInstallerTest.TestExeInstaller")); -// Assert.True(result.StdOut.Contains("AppInstallerTest.TestBurnInstaller")); -// Assert.True(result.StdOut.Contains("AppInstallerTest.TestExampleInstaller")); -// } + [Test] + public void SearchReturnsMultiple() + { + // Search Microsoft should return multiple + var result = TestCommon.RunAICLICommand("search", "AppInstallerTest"); + Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); + Assert.True(result.StdOut.Contains("AppInstallerTest.TestExeInstaller")); + Assert.True(result.StdOut.Contains("AppInstallerTest.TestBurnInstaller")); + Assert.True(result.StdOut.Contains("AppInstallerTest.TestExampleInstaller")); + } -// [Test] -// public void SearchWithExactName() -// { -// var result = TestCommon.RunAICLICommand("search", "--exact TestExampleInstaller"); -// Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); -// Assert.True(result.StdOut.Contains("TestExampleInstaller")); -// Assert.True(result.StdOut.Contains("AppInstallerTest.TestExampleInstaller")); -// } + [Test] + public void SearchWithExactName() + { + var result = TestCommon.RunAICLICommand("search", "--exact TestExampleInstaller"); + Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); + Assert.True(result.StdOut.Contains("TestExampleInstaller")); + Assert.True(result.StdOut.Contains("AppInstallerTest.TestExampleInstaller")); + } -// [Test] -// public void SearchWithExactID() -// { -// var result = TestCommon.RunAICLICommand("search", "--exact AppInstallerTest.TestExampleInstaller"); -// Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); -// Assert.True(result.StdOut.Contains("TestExampleInstaller")); -// Assert.True(result.StdOut.Contains("AppInstallerTest.TestExampleInstaller")); -// } + [Test] + public void SearchWithExactID() + { + var result = TestCommon.RunAICLICommand("search", "--exact AppInstallerTest.TestExampleInstaller"); + Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); + Assert.True(result.StdOut.Contains("TestExampleInstaller")); + Assert.True(result.StdOut.Contains("AppInstallerTest.TestExampleInstaller")); + } -// [Test] -// public void SearchWithExactArgCaseSensitivity() -// { -// var result = TestCommon.RunAICLICommand("search", "--exact testexampleinstaller"); -// Assert.AreEqual(Constants.ErrorCode.ERROR_NO_APPLICATIONS_FOUND, result.ExitCode); -// Assert.True(result.StdOut.Contains("No package found matching input criteria.")); -// } + [Test] + public void SearchWithExactArgCaseSensitivity() + { + var result = TestCommon.RunAICLICommand("search", "--exact testexampleinstaller"); + Assert.AreEqual(Constants.ErrorCode.ERROR_NO_APPLICATIONS_FOUND, result.ExitCode); + Assert.True(result.StdOut.Contains("No package found matching input criteria.")); + } -// [Test] -// public void SearchWithSingleSourceFailure() -// { -// TestCommon.RunAICLICommand("source add", "failSearch \"{ \"\"OpenHR\"\": \"\"0x80070002\"\" }\" Microsoft.Test.Configurable --header \"{}\""); + [Test] + public void SearchWithSingleSourceFailure() + { + TestCommon.RunAICLICommand("source add", "failSearch \"{ \"\"OpenHR\"\": \"\"0x80070002\"\" }\" Microsoft.Test.Configurable --header \"{}\""); -// try -// { -// var result = TestCommon.RunAICLICommand("search", "--exact AppInstallerTest.TestExampleInstaller"); -// Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); -// Assert.True(result.StdOut.Contains("Failed when searching source; results will not be included: failSearch")); -// Assert.True(result.StdOut.Contains("TestExampleInstaller")); -// Assert.True(result.StdOut.Contains("AppInstallerTest.TestExampleInstaller")); -// } -// finally -// { -// ResetTestSource(); -// } -// } + try + { + var result = TestCommon.RunAICLICommand("search", "--exact AppInstallerTest.TestExampleInstaller"); + Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); + Assert.True(result.StdOut.Contains("Failed when searching source; results will not be included: failSearch")); + Assert.True(result.StdOut.Contains("TestExampleInstaller")); + Assert.True(result.StdOut.Contains("AppInstallerTest.TestExampleInstaller")); + } + finally + { + ResetTestSource(); + } + } -// [Test] -// public void SearchStoreWithBadPin() -// { -// // Configure as close as possible to the real chain but use the test cert for everything -// // This will at least force the public key to be checked rather than simply failing based on chain length -// GroupPolicyHelper.EnableAdditionalSources.SetEnabledList(new GroupPolicySource[] -// { -// new GroupPolicySource -// { -// Name = Constants.TestAlternateSourceName, -// Arg = Constants.DefaultMSStoreSourceUrl, -// Type = Constants.DefaultMSStoreSourceType, -// Data = "", -// Identifier = Constants.DefaultMSStoreSourceIdentifier, -// CertificatePinning = new GroupPolicyCertificatePinning -// { -// Chains = new GroupPolicyCertificatePinningChain[] { -// new GroupPolicyCertificatePinningChain -// { -// Chain = new GroupPolicyCertificatePinningDetails[] -// { -// new GroupPolicyCertificatePinningDetails -// { -// Validation = new string[] { "publickey" }, -// EmbeddedCertificate = TestCommon.GetTestServerCertificateHexString() -// }, -// new GroupPolicyCertificatePinningDetails -// { -// Validation = new string[] { "subject", "issuer" }, -// EmbeddedCertificate = TestCommon.GetTestServerCertificateHexString() -// }, -// new GroupPolicyCertificatePinningDetails -// { -// Validation = new string[] { "subject", "issuer" }, -// EmbeddedCertificate = TestCommon.GetTestServerCertificateHexString() -// } -// } -// } -// } -// } -// } -// }); + [Test] + public void SearchStoreWithBadPin() + { + // Configure as close as possible to the real chain but use the test cert for everything + // This will at least force the public key to be checked rather than simply failing based on chain length + GroupPolicyHelper.EnableAdditionalSources.SetEnabledList(new GroupPolicySource[] + { + new GroupPolicySource + { + Name = Constants.TestAlternateSourceName, + Arg = Constants.DefaultMSStoreSourceUrl, + Type = Constants.DefaultMSStoreSourceType, + Data = "", + Identifier = Constants.DefaultMSStoreSourceIdentifier, + CertificatePinning = new GroupPolicyCertificatePinning + { + Chains = new GroupPolicyCertificatePinningChain[] { + new GroupPolicyCertificatePinningChain + { + Chain = new GroupPolicyCertificatePinningDetails[] + { + new GroupPolicyCertificatePinningDetails + { + Validation = new string[] { "publickey" }, + EmbeddedCertificate = TestCommon.GetTestServerCertificateHexString() + }, + new GroupPolicyCertificatePinningDetails + { + Validation = new string[] { "subject", "issuer" }, + EmbeddedCertificate = TestCommon.GetTestServerCertificateHexString() + }, + new GroupPolicyCertificatePinningDetails + { + Validation = new string[] { "subject", "issuer" }, + EmbeddedCertificate = TestCommon.GetTestServerCertificateHexString() + } + } + } + } + } + } + }); -// try -// { -// var result = TestCommon.RunAICLICommand("search", $"-s {Constants.TestAlternateSourceName} foo --verbose-logs"); -// Assert.AreEqual(Constants.ErrorCode.ERROR_PINNED_CERTIFICATE_MISMATCH, result.ExitCode); -// } -// finally -// { -// ResetTestSource(); -// } -// } -// } -//} + try + { + var result = TestCommon.RunAICLICommand("search", $"-s {Constants.TestAlternateSourceName} foo --verbose-logs"); + Assert.AreEqual(Constants.ErrorCode.ERROR_PINNED_CERTIFICATE_MISMATCH, result.ExitCode); + } + finally + { + ResetTestSource(); + } + } + } +} diff --git a/src/AppInstallerCLIE2ETests/ShowCommand.cs b/src/AppInstallerCLIE2ETests/ShowCommand.cs index 575e3d1847..614d57e8ba 100644 --- a/src/AppInstallerCLIE2ETests/ShowCommand.cs +++ b/src/AppInstallerCLIE2ETests/ShowCommand.cs @@ -1,94 +1,94 @@ -//// Copyright (c) Microsoft Corporation. -//// Licensed under the MIT License. +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. -//namespace AppInstallerCLIE2ETests -//{ -// using NUnit.Framework; +namespace AppInstallerCLIE2ETests +{ + using NUnit.Framework; -// public class ShowCommand : BaseCommand -// { -// [Test] -// public void ShowWithNoArgs() -// { -// var result = TestCommon.RunAICLICommand("show", ""); -// Assert.AreEqual(Constants.ErrorCode.ERROR_INVALID_CL_ARGUMENTS, result.ExitCode); -// } + public class ShowCommand : BaseCommand + { + [Test] + public void ShowWithNoArgs() + { + var result = TestCommon.RunAICLICommand("show", ""); + Assert.AreEqual(Constants.ErrorCode.ERROR_INVALID_CL_ARGUMENTS, result.ExitCode); + } -// [Test] -// public void ShowWithNoMatches() -// { -// // Show with 0 search match shows a "please refine input" -// var result = TestCommon.RunAICLICommand("show", $"DoesNotExist"); -// Assert.AreEqual(Constants.ErrorCode.ERROR_NO_APPLICATIONS_FOUND, result.ExitCode); -// Assert.True(result.StdOut.Contains("No package found matching input criteria.")); -// } + [Test] + public void ShowWithNoMatches() + { + // Show with 0 search match shows a "please refine input" + var result = TestCommon.RunAICLICommand("show", $"DoesNotExist"); + Assert.AreEqual(Constants.ErrorCode.ERROR_NO_APPLICATIONS_FOUND, result.ExitCode); + Assert.True(result.StdOut.Contains("No package found matching input criteria.")); + } -// [Test] -// public void ShowWithSubstringMatch() -// { -// // Show with a substring match still returns 0 results -// var result = TestCommon.RunAICLICommand("show", $"AppInstallerTest"); -// Assert.AreEqual(Constants.ErrorCode.ERROR_NO_APPLICATIONS_FOUND, result.ExitCode); -// Assert.True(result.StdOut.Contains("No package found matching input criteria.")); -// } + [Test] + public void ShowWithSubstringMatch() + { + // Show with a substring match still returns 0 results + var result = TestCommon.RunAICLICommand("show", $"AppInstallerTest"); + Assert.AreEqual(Constants.ErrorCode.ERROR_NO_APPLICATIONS_FOUND, result.ExitCode); + Assert.True(result.StdOut.Contains("No package found matching input criteria.")); + } -// [Test] -// public void ShowWithNameMatch() -// { -// var result = TestCommon.RunAICLICommand("show", $"--name testexampleinstaller"); -// Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); -// Assert.True(result.StdOut.Contains("Found TestExampleInstaller [AppInstallerTest.TestExampleInstaller]")); -// Assert.True(result.StdOut.Contains("TestExampleInstaller")); -// Assert.True(result.StdOut.Contains("AppInstallerTest.TestExampleInstaller")); -// } + [Test] + public void ShowWithNameMatch() + { + var result = TestCommon.RunAICLICommand("show", $"--name testexampleinstaller"); + Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); + Assert.True(result.StdOut.Contains("Found TestExampleInstaller [AppInstallerTest.TestExampleInstaller]")); + Assert.True(result.StdOut.Contains("TestExampleInstaller")); + Assert.True(result.StdOut.Contains("AppInstallerTest.TestExampleInstaller")); + } -// [Test] -// public void ShowWithIDMatch() -// { -// var result = TestCommon.RunAICLICommand("show", $"--id appinstallertest.testexampleinstaller"); -// Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); -// Assert.True(result.StdOut.Contains("Found TestExampleInstaller [AppInstallerTest.TestExampleInstaller]")); -// Assert.True(result.StdOut.Contains("TestExampleInstaller")); -// Assert.True(result.StdOut.Contains("AppInstallerTest.TestExampleInstaller")); -// } + [Test] + public void ShowWithIDMatch() + { + var result = TestCommon.RunAICLICommand("show", $"--id appinstallertest.testexampleinstaller"); + Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); + Assert.True(result.StdOut.Contains("Found TestExampleInstaller [AppInstallerTest.TestExampleInstaller]")); + Assert.True(result.StdOut.Contains("TestExampleInstaller")); + Assert.True(result.StdOut.Contains("AppInstallerTest.TestExampleInstaller")); + } -// [Test] -// public void ShowWithVersions() -// { -// // Show with --versions list the versions -// var result = TestCommon.RunAICLICommand("show", $"TestExampleInstaller --versions"); -// Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); -// Assert.True(result.StdOut.Contains("TestExampleInstaller")); -// Assert.True(result.StdOut.Contains("AppInstallerTest.TestExampleInstaller")); -// Assert.True(result.StdOut.Contains("1.2.3.4")); -// } + [Test] + public void ShowWithVersions() + { + // Show with --versions list the versions + var result = TestCommon.RunAICLICommand("show", $"TestExampleInstaller --versions"); + Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); + Assert.True(result.StdOut.Contains("TestExampleInstaller")); + Assert.True(result.StdOut.Contains("AppInstallerTest.TestExampleInstaller")); + Assert.True(result.StdOut.Contains("1.2.3.4")); + } -// [Test] -// public void ShowWithExactName() -// { -// var result = TestCommon.RunAICLICommand("show", $"--exact TestExampleInstaller"); -// Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); -// Assert.True(result.StdOut.Contains("Found TestExampleInstaller [AppInstallerTest.TestExampleInstaller]")); -// Assert.True(result.StdOut.Contains("TestExampleInstaller")); -// Assert.True(result.StdOut.Contains("AppInstallerTest.TestExampleInstaller")); -// } + [Test] + public void ShowWithExactName() + { + var result = TestCommon.RunAICLICommand("show", $"--exact TestExampleInstaller"); + Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); + Assert.True(result.StdOut.Contains("Found TestExampleInstaller [AppInstallerTest.TestExampleInstaller]")); + Assert.True(result.StdOut.Contains("TestExampleInstaller")); + Assert.True(result.StdOut.Contains("AppInstallerTest.TestExampleInstaller")); + } -// [Test] -// public void ShowWithExactID() -// { -// var result = TestCommon.RunAICLICommand("show", $"--exact AppInstallerTest.TestExampleInstaller"); -// Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); -// Assert.True(result.StdOut.Contains("Found TestExampleInstaller [AppInstallerTest.TestExampleInstaller]")); -// Assert.True(result.StdOut.Contains("TestExampleInstaller")); -// Assert.True(result.StdOut.Contains("AppInstallerTest.TestExampleInstaller")); -// } + [Test] + public void ShowWithExactID() + { + var result = TestCommon.RunAICLICommand("show", $"--exact AppInstallerTest.TestExampleInstaller"); + Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); + Assert.True(result.StdOut.Contains("Found TestExampleInstaller [AppInstallerTest.TestExampleInstaller]")); + Assert.True(result.StdOut.Contains("TestExampleInstaller")); + Assert.True(result.StdOut.Contains("AppInstallerTest.TestExampleInstaller")); + } -// [Test] -// public void ShowWithExactArgCaseSensitivity() -// { -// var result = TestCommon.RunAICLICommand("show", $"--exact testexampleinstaller"); -// Assert.AreEqual(Constants.ErrorCode.ERROR_NO_APPLICATIONS_FOUND, result.ExitCode); -// Assert.True(result.StdOut.Contains("No package found matching input criteria.")); -// } -// } -//} \ No newline at end of file + [Test] + public void ShowWithExactArgCaseSensitivity() + { + var result = TestCommon.RunAICLICommand("show", $"--exact testexampleinstaller"); + Assert.AreEqual(Constants.ErrorCode.ERROR_NO_APPLICATIONS_FOUND, result.ExitCode); + Assert.True(result.StdOut.Contains("No package found matching input criteria.")); + } + } +} \ No newline at end of file diff --git a/src/AppInstallerCLIE2ETests/SourceCommand.cs b/src/AppInstallerCLIE2ETests/SourceCommand.cs index b13f2c00ba..e2cc644589 100644 --- a/src/AppInstallerCLIE2ETests/SourceCommand.cs +++ b/src/AppInstallerCLIE2ETests/SourceCommand.cs @@ -1,139 +1,139 @@ -//// Copyright (c) Microsoft Corporation. -//// Licensed under the MIT License. - -//namespace AppInstallerCLIE2ETests -//{ -// using NUnit.Framework; - -// public class SourceCommand : BaseCommand -// { -// [SetUp] -// public void Setup() -// { -// ResetTestSource(false); -// } - -// [Test] -// public void SourceAdd() -// { -// var result = TestCommon.RunAICLICommand("source add", $"SourceTest {Constants.TestSourceUrl}"); -// Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); -// Assert.True(result.StdOut.Contains("Done")); -// TestCommon.RunAICLICommand("source remove", $"-n SourceTest"); -// } - -// [Test] -// public void SourceAddWithDuplicateName() -// { -// // Add source with duplicate name should fail -// var result = TestCommon.RunAICLICommand("source add", $"{Constants.TestSourceName} https://microsoft.com"); -// Assert.AreEqual(Constants.ErrorCode.ERROR_SOURCE_NAME_ALREADY_EXISTS, result.ExitCode); -// Assert.True(result.StdOut.Contains("A source with the given name already exists and refers to a different location")); -// } - -// [Test] -// public void SourceAddWithInvalidURL() -// { -// // Add source with invalid url should fail -// var result = TestCommon.RunAICLICommand("source add", $"AnotherSource {Constants.TestSourceUrl}/Invalid/Directory/Dont/Add/Me"); -// Assert.AreEqual(Constants.ErrorCode.HTTP_E_STATUS_NOT_FOUND, result.ExitCode); -// Assert.True(result.StdOut.Contains("An unexpected error occurred while executing the command")); -// } - - -// [Test] -// public void SourceAddWithHttpURL() -// { -// // Add source with an HTTP url should fail -// var result = TestCommon.RunAICLICommand("source add", "Insecure http://microsoft.com"); -// Assert.AreEqual(Constants.ErrorCode.ERROR_SOURCE_NOT_SECURE, result.ExitCode); -// Assert.True(result.StdOut.Contains("error occurred while executing the command")); -// } - -// [Test] -// public void SourceListWithNoArgs() -// { -// // List with no args should list all available sources -// var result = TestCommon.RunAICLICommand("source list", ""); -// Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); -// Assert.True(result.StdOut.Contains(Constants.TestSourceUrl)); -// } - -// [Test] -// public void SourceListWithName() -// { -// var result = TestCommon.RunAICLICommand("source list", $"-n {Constants.TestSourceName}"); -// Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); -// Assert.True(result.StdOut.Contains(Constants.TestSourceName)); -// Assert.True(result.StdOut.Contains(Constants.TestSourceUrl)); -// Assert.True(result.StdOut.Contains("Microsoft.PreIndexed.Package")); -// Assert.True(result.StdOut.Contains("Updated")); -// } - -// [Test] -// public void SourceListNameMismatch() -// { -// var result = TestCommon.RunAICLICommand("source list", "-n UnknownName"); -// Assert.AreEqual(Constants.ErrorCode.ERROR_SOURCE_NAME_DOES_NOT_EXIST, result.ExitCode); -// Assert.True(result.StdOut.Contains("Did not find a source named")); -// } - -// [Test] -// public void SourceUpdate() -// { -// var result = TestCommon.RunAICLICommand("source update", $"-n {Constants.TestSourceName}"); -// Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); -// Assert.True(result.StdOut.Contains("Done")); -// } - -// [Test] -// public void SourceUpdateWithInvalidName() -// { -// var result = TestCommon.RunAICLICommand("source update", "-n UnknownName"); -// Assert.AreEqual(Constants.ErrorCode.ERROR_SOURCE_NAME_DOES_NOT_EXIST, result.ExitCode); -// Assert.True(result.StdOut.Contains("Did not find a source named: UnknownName")); -// } - -// [Test] -// public void SourceRemoveValidName() -// { -// var result = TestCommon.RunAICLICommand("source remove", $"-n {Constants.TestSourceName}"); -// Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); -// Assert.True(result.StdOut.Contains("Done")); -// ResetTestSource(false); -// } - -// [Test] -// public void SourceRemoveInvalidName() -// { -// var result = TestCommon.RunAICLICommand("source remove", "-n UnknownName"); -// Assert.AreEqual(Constants.ErrorCode.ERROR_SOURCE_NAME_DOES_NOT_EXIST, result.ExitCode); -// Assert.True(result.StdOut.Contains("Did not find a source named: UnknownName")); -// } - -// [Test] -// public void SourceReset() -// { -// var result = TestCommon.RunAICLICommand("source reset", ""); -// Assert.True(result.StdOut.Contains("The following sources will be reset if the --force option is given:")); -// Assert.True(result.StdOut.Contains(Constants.TestSourceName)); -// Assert.True(result.StdOut.Contains(Constants.TestSourceUrl)); -// } - -// [Test] -// public void SourceForceReset() -// { -// // Force Reset Sources -// var result = TestCommon.RunAICLICommand("source reset", "--force"); -// Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); -// Assert.True(result.StdOut.Contains("Resetting all sources...Done")); - -// //Verify sources have been reset -// result = TestCommon.RunAICLICommand("source list", ""); -// Assert.True(result.StdOut.Contains("winget")); -// Assert.True(result.StdOut.Contains("https://cdn.winget.microsoft.com/cache")); -// Assert.False(result.StdOut.Contains(Constants.TestSourceName)); -// Assert.False(result.StdOut.Contains(Constants.TestSourceUrl)); -// } -// } -//} \ No newline at end of file +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +namespace AppInstallerCLIE2ETests +{ + using NUnit.Framework; + + public class SourceCommand : BaseCommand + { + [SetUp] + public void Setup() + { + ResetTestSource(false); + } + + [Test] + public void SourceAdd() + { + var result = TestCommon.RunAICLICommand("source add", $"SourceTest {Constants.TestSourceUrl}"); + Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); + Assert.True(result.StdOut.Contains("Done")); + TestCommon.RunAICLICommand("source remove", $"-n SourceTest"); + } + + [Test] + public void SourceAddWithDuplicateName() + { + // Add source with duplicate name should fail + var result = TestCommon.RunAICLICommand("source add", $"{Constants.TestSourceName} https://microsoft.com"); + Assert.AreEqual(Constants.ErrorCode.ERROR_SOURCE_NAME_ALREADY_EXISTS, result.ExitCode); + Assert.True(result.StdOut.Contains("A source with the given name already exists and refers to a different location")); + } + + [Test] + public void SourceAddWithInvalidURL() + { + // Add source with invalid url should fail + var result = TestCommon.RunAICLICommand("source add", $"AnotherSource {Constants.TestSourceUrl}/Invalid/Directory/Dont/Add/Me"); + Assert.AreEqual(Constants.ErrorCode.HTTP_E_STATUS_NOT_FOUND, result.ExitCode); + Assert.True(result.StdOut.Contains("An unexpected error occurred while executing the command")); + } + + + [Test] + public void SourceAddWithHttpURL() + { + // Add source with an HTTP url should fail + var result = TestCommon.RunAICLICommand("source add", "Insecure http://microsoft.com"); + Assert.AreEqual(Constants.ErrorCode.ERROR_SOURCE_NOT_SECURE, result.ExitCode); + Assert.True(result.StdOut.Contains("error occurred while executing the command")); + } + + [Test] + public void SourceListWithNoArgs() + { + // List with no args should list all available sources + var result = TestCommon.RunAICLICommand("source list", ""); + Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); + Assert.True(result.StdOut.Contains(Constants.TestSourceUrl)); + } + + [Test] + public void SourceListWithName() + { + var result = TestCommon.RunAICLICommand("source list", $"-n {Constants.TestSourceName}"); + Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); + Assert.True(result.StdOut.Contains(Constants.TestSourceName)); + Assert.True(result.StdOut.Contains(Constants.TestSourceUrl)); + Assert.True(result.StdOut.Contains("Microsoft.PreIndexed.Package")); + Assert.True(result.StdOut.Contains("Updated")); + } + + [Test] + public void SourceListNameMismatch() + { + var result = TestCommon.RunAICLICommand("source list", "-n UnknownName"); + Assert.AreEqual(Constants.ErrorCode.ERROR_SOURCE_NAME_DOES_NOT_EXIST, result.ExitCode); + Assert.True(result.StdOut.Contains("Did not find a source named")); + } + + [Test] + public void SourceUpdate() + { + var result = TestCommon.RunAICLICommand("source update", $"-n {Constants.TestSourceName}"); + Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); + Assert.True(result.StdOut.Contains("Done")); + } + + [Test] + public void SourceUpdateWithInvalidName() + { + var result = TestCommon.RunAICLICommand("source update", "-n UnknownName"); + Assert.AreEqual(Constants.ErrorCode.ERROR_SOURCE_NAME_DOES_NOT_EXIST, result.ExitCode); + Assert.True(result.StdOut.Contains("Did not find a source named: UnknownName")); + } + + [Test] + public void SourceRemoveValidName() + { + var result = TestCommon.RunAICLICommand("source remove", $"-n {Constants.TestSourceName}"); + Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); + Assert.True(result.StdOut.Contains("Done")); + ResetTestSource(false); + } + + [Test] + public void SourceRemoveInvalidName() + { + var result = TestCommon.RunAICLICommand("source remove", "-n UnknownName"); + Assert.AreEqual(Constants.ErrorCode.ERROR_SOURCE_NAME_DOES_NOT_EXIST, result.ExitCode); + Assert.True(result.StdOut.Contains("Did not find a source named: UnknownName")); + } + + [Test] + public void SourceReset() + { + var result = TestCommon.RunAICLICommand("source reset", ""); + Assert.True(result.StdOut.Contains("The following sources will be reset if the --force option is given:")); + Assert.True(result.StdOut.Contains(Constants.TestSourceName)); + Assert.True(result.StdOut.Contains(Constants.TestSourceUrl)); + } + + [Test] + public void SourceForceReset() + { + // Force Reset Sources + var result = TestCommon.RunAICLICommand("source reset", "--force"); + Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); + Assert.True(result.StdOut.Contains("Resetting all sources...Done")); + + //Verify sources have been reset + result = TestCommon.RunAICLICommand("source list", ""); + Assert.True(result.StdOut.Contains("winget")); + Assert.True(result.StdOut.Contains("https://cdn.winget.microsoft.com/cache")); + Assert.False(result.StdOut.Contains(Constants.TestSourceName)); + Assert.False(result.StdOut.Contains(Constants.TestSourceUrl)); + } + } +} \ No newline at end of file diff --git a/src/AppInstallerCLIE2ETests/UninstallCommand.cs b/src/AppInstallerCLIE2ETests/UninstallCommand.cs index 3ef0fb229c..61a15dacbb 100644 --- a/src/AppInstallerCLIE2ETests/UninstallCommand.cs +++ b/src/AppInstallerCLIE2ETests/UninstallCommand.cs @@ -1,170 +1,170 @@ -//// Copyright (c) Microsoft Corporation. -//// Licensed under the MIT License. +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. -//namespace AppInstallerCLIE2ETests -//{ -// using NUnit.Framework; -// using System.IO; +namespace AppInstallerCLIE2ETests +{ + using NUnit.Framework; + using System.IO; -// public class UninstallCommand : BaseCommand -// { -// // Custom product code for overriding the default in the test exe -// private const string CustomProductCode = "{f08fc03c-0b7e-4fca-9b3c-3a384d18a9f3}"; + public class UninstallCommand : BaseCommand + { + // Custom product code for overriding the default in the test exe + private const string CustomProductCode = "{f08fc03c-0b7e-4fca-9b3c-3a384d18a9f3}"; -// // File written when uninstalling the test exe -// private const string UninstallTestExeUninstalledFile = "TestExeUninstalled.txt"; + // File written when uninstalling the test exe + private const string UninstallTestExeUninstalledFile = "TestExeUninstalled.txt"; -// // Name of a file installed by the MSI that will be removed during uninstall -// private const string UninstallTestMsiInstalledFile = "AppInstallerTestExeInstaller.exe"; + // Name of a file installed by the MSI that will be removed during uninstall + private const string UninstallTestMsiInstalledFile = "AppInstallerTestExeInstaller.exe"; -// // Package name of the test MSIX package -// private const string UninstallTestMsixName = "6c6338fe-41b7-46ca-8ba6-b5ad5312bb0e"; + // Package name of the test MSIX package + private const string UninstallTestMsixName = "6c6338fe-41b7-46ca-8ba6-b5ad5312bb0e"; -// [Test] -// public void UninstallTestExe() -// { -// // Uninstall an Exe -// var installDir = TestCommon.GetRandomTestDir(); -// TestCommon.RunAICLICommand("install", $"{Constants.ExeInstallerPackageId} --silent -l {installDir}"); -// var result = TestCommon.RunAICLICommand("uninstall", Constants.ExeInstallerPackageId); -// Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); -// Assert.True(result.StdOut.Contains("Successfully uninstalled")); -// Assert.True(TestCommon.VerifyTestExeUninstalled(installDir)); -// } + [Test] + public void UninstallTestExe() + { + // Uninstall an Exe + var installDir = TestCommon.GetRandomTestDir(); + TestCommon.RunAICLICommand("install", $"{Constants.ExeInstallerPackageId} --silent -l {installDir}"); + var result = TestCommon.RunAICLICommand("uninstall", Constants.ExeInstallerPackageId); + Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); + Assert.True(result.StdOut.Contains("Successfully uninstalled")); + Assert.True(TestCommon.VerifyTestExeUninstalled(installDir)); + } -// [Test] -// public void UninstallTestMsi() -// { -// if (string.IsNullOrEmpty(TestCommon.MsiInstallerPath)) -// { -// Assert.Ignore("MSI installer not available"); -// } + [Test] + public void UninstallTestMsi() + { + if (string.IsNullOrEmpty(TestCommon.MsiInstallerPath)) + { + Assert.Ignore("MSI installer not available"); + } -// // Uninstall an MSI -// var installDir = TestCommon.GetRandomTestDir(); -// TestCommon.RunAICLICommand("install", $"{Constants.MsiInstallerPackageId} -l {installDir}"); -// var result = TestCommon.RunAICLICommand("uninstall", Constants.MsiInstallerPackageId); -// Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); -// Assert.True(result.StdOut.Contains("Successfully uninstalled")); -// Assert.True(TestCommon.VerifyTestMsiUninstalled(installDir)); -// } + // Uninstall an MSI + var installDir = TestCommon.GetRandomTestDir(); + TestCommon.RunAICLICommand("install", $"{Constants.MsiInstallerPackageId} -l {installDir}"); + var result = TestCommon.RunAICLICommand("uninstall", Constants.MsiInstallerPackageId); + Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); + Assert.True(result.StdOut.Contains("Successfully uninstalled")); + Assert.True(TestCommon.VerifyTestMsiUninstalled(installDir)); + } -// [Test] -// public void UninstallTestMsix() -// { -// // Uninstall an MSIX -// TestCommon.RunAICLICommand("install", Constants.MsixInstallerPackageId); -// var result = TestCommon.RunAICLICommand("uninstall", Constants.MsixInstallerPackageId); -// Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); -// Assert.True(result.StdOut.Contains("Successfully uninstalled")); -// Assert.True(TestCommon.VerifyTestMsixUninstalled()); -// } + [Test] + public void UninstallTestMsix() + { + // Uninstall an MSIX + TestCommon.RunAICLICommand("install", Constants.MsixInstallerPackageId); + var result = TestCommon.RunAICLICommand("uninstall", Constants.MsixInstallerPackageId); + Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); + Assert.True(result.StdOut.Contains("Successfully uninstalled")); + Assert.True(TestCommon.VerifyTestMsixUninstalled()); + } -// [Test] -// public void UninstallPortable() -// { -// // Uninstall a Portable -// string installDir = Path.Combine(System.Environment.GetEnvironmentVariable("LocalAppData"), "Microsoft", "WinGet", "Packages"); -// string packageId, commandAlias, fileName, packageDirName, productCode; -// packageId = "AppInstallerTest.TestPortableExe"; -// packageDirName = productCode = packageId + "_" + Constants.TestSourceIdentifier; -// commandAlias = fileName = "AppInstallerTestExeInstaller.exe"; + [Test] + public void UninstallPortable() + { + // Uninstall a Portable + string installDir = Path.Combine(System.Environment.GetEnvironmentVariable("LocalAppData"), "Microsoft", "WinGet", "Packages"); + string packageId, commandAlias, fileName, packageDirName, productCode; + packageId = "AppInstallerTest.TestPortableExe"; + packageDirName = productCode = packageId + "_" + Constants.TestSourceIdentifier; + commandAlias = fileName = "AppInstallerTestExeInstaller.exe"; -// TestCommon.RunAICLICommand("install", $"{packageId}"); -// var result = TestCommon.RunAICLICommand("uninstall", $"{packageId}"); -// Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); -// Assert.True(result.StdOut.Contains("Successfully uninstalled")); -// TestCommon.VerifyPortablePackage(Path.Combine(installDir, packageDirName), commandAlias, fileName, productCode, false); -// } + TestCommon.RunAICLICommand("install", $"{packageId}"); + var result = TestCommon.RunAICLICommand("uninstall", $"{packageId}"); + Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); + Assert.True(result.StdOut.Contains("Successfully uninstalled")); + TestCommon.VerifyPortablePackage(Path.Combine(installDir, packageDirName), commandAlias, fileName, productCode, false); + } -// [Test] -// public void UninstallPortableWithProductCode() -// { -// // Uninstall a Portable with ProductCode -// string installDir = TestCommon.GetPortablePackagesDirectory(); -// string packageId, commandAlias, fileName, packageDirName, productCode; -// packageId = "AppInstallerTest.TestPortableExe"; -// packageDirName = productCode = packageId + "_" + Constants.TestSourceIdentifier; -// commandAlias = fileName = "AppInstallerTestExeInstaller.exe"; + [Test] + public void UninstallPortableWithProductCode() + { + // Uninstall a Portable with ProductCode + string installDir = TestCommon.GetPortablePackagesDirectory(); + string packageId, commandAlias, fileName, packageDirName, productCode; + packageId = "AppInstallerTest.TestPortableExe"; + packageDirName = productCode = packageId + "_" + Constants.TestSourceIdentifier; + commandAlias = fileName = "AppInstallerTestExeInstaller.exe"; -// TestCommon.RunAICLICommand("install", $"{packageId}"); -// var result = TestCommon.RunAICLICommand("uninstall", $"--product-code {productCode}"); -// Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); -// Assert.True(result.StdOut.Contains("Successfully uninstalled")); -// TestCommon.VerifyPortablePackage(Path.Combine(installDir, packageDirName), commandAlias, fileName, productCode, false); -// } + TestCommon.RunAICLICommand("install", $"{packageId}"); + var result = TestCommon.RunAICLICommand("uninstall", $"--product-code {productCode}"); + Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); + Assert.True(result.StdOut.Contains("Successfully uninstalled")); + TestCommon.VerifyPortablePackage(Path.Combine(installDir, packageDirName), commandAlias, fileName, productCode, false); + } -// [Test] -// public void UninstallPortableModifiedSymlink() -// { -// string installDir = TestCommon.GetPortablePackagesDirectory(); -// string packageId, commandAlias, fileName, packageDirName, productCode; -// packageId = "AppInstallerTest.TestPortableExe"; -// packageDirName = productCode = packageId + "_" + Constants.TestSourceIdentifier; -// commandAlias = fileName = "AppInstallerTestExeInstaller.exe"; + [Test] + public void UninstallPortableModifiedSymlink() + { + string installDir = TestCommon.GetPortablePackagesDirectory(); + string packageId, commandAlias, fileName, packageDirName, productCode; + packageId = "AppInstallerTest.TestPortableExe"; + packageDirName = productCode = packageId + "_" + Constants.TestSourceIdentifier; + commandAlias = fileName = "AppInstallerTestExeInstaller.exe"; -// TestCommon.RunAICLICommand("install", $"{packageId}"); + TestCommon.RunAICLICommand("install", $"{packageId}"); -// string symlinkDirectory = TestCommon.GetPortableSymlinkDirectory(TestCommon.Scope.User); -// string symlinkPath = Path.Combine(symlinkDirectory, commandAlias); + string symlinkDirectory = TestCommon.GetPortableSymlinkDirectory(TestCommon.Scope.User); + string symlinkPath = Path.Combine(symlinkDirectory, commandAlias); -// // Replace symlink with modified symlink -// File.Delete(symlinkPath); -// FileSystemInfo modifiedSymlinkInfo = File.CreateSymbolicLink(symlinkPath, "fakeTargetExe"); + // Replace symlink with modified symlink + File.Delete(symlinkPath); + FileSystemInfo modifiedSymlinkInfo = File.CreateSymbolicLink(symlinkPath, "fakeTargetExe"); -// var result = TestCommon.RunAICLICommand("uninstall", $"{packageId}"); -// Assert.AreEqual(Constants.ErrorCode.ERROR_PORTABLE_UNINSTALL_FAILED, result.ExitCode); -// Assert.True(result.StdOut.Contains("Unable to remove Portable package as it has been modified; to override this check use --force")); -// Assert.True(modifiedSymlinkInfo.Exists, "Modified symlink should still exist"); + var result = TestCommon.RunAICLICommand("uninstall", $"{packageId}"); + Assert.AreEqual(Constants.ErrorCode.ERROR_PORTABLE_UNINSTALL_FAILED, result.ExitCode); + Assert.True(result.StdOut.Contains("Unable to remove Portable package as it has been modified; to override this check use --force")); + Assert.True(modifiedSymlinkInfo.Exists, "Modified symlink should still exist"); -// // Try again with --force -// var result2 = TestCommon.RunAICLICommand("uninstall", $"{packageId} --force"); -// Assert.AreEqual(Constants.ErrorCode.S_OK, result2.ExitCode); -// Assert.True(result2.StdOut.Contains("Portable package has been modified; proceeding due to --force")); -// Assert.True(result2.StdOut.Contains("Successfully uninstalled")); + // Try again with --force + var result2 = TestCommon.RunAICLICommand("uninstall", $"{packageId} --force"); + Assert.AreEqual(Constants.ErrorCode.S_OK, result2.ExitCode); + Assert.True(result2.StdOut.Contains("Portable package has been modified; proceeding due to --force")); + Assert.True(result2.StdOut.Contains("Successfully uninstalled")); -// TestCommon.VerifyPortablePackage(Path.Combine(installDir, packageDirName), commandAlias, fileName, productCode, false); -// } + TestCommon.VerifyPortablePackage(Path.Combine(installDir, packageDirName), commandAlias, fileName, productCode, false); + } -// [Test] -// public void UninstallZip_Portable() -// { -// string installDir = TestCommon.GetPortablePackagesDirectory(); -// string packageId, commandAlias, fileName, packageDirName, productCode; -// packageId = "AppInstallerTest.TestZipInstallerWithPortable"; -// packageDirName = productCode = packageId + "_" + Constants.TestSourceIdentifier; -// commandAlias = "TestPortable.exe"; -// fileName = "AppInstallerTestExeInstaller.exe"; + [Test] + public void UninstallZip_Portable() + { + string installDir = TestCommon.GetPortablePackagesDirectory(); + string packageId, commandAlias, fileName, packageDirName, productCode; + packageId = "AppInstallerTest.TestZipInstallerWithPortable"; + packageDirName = productCode = packageId + "_" + Constants.TestSourceIdentifier; + commandAlias = "TestPortable.exe"; + fileName = "AppInstallerTestExeInstaller.exe"; -// var testreuslt = TestCommon.RunAICLICommand("install", $"{packageId}"); -// var result = TestCommon.RunAICLICommand("uninstall", $"{packageId}"); -// Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); -// Assert.True(result.StdOut.Contains("Successfully uninstalled")); -// TestCommon.VerifyPortablePackage(Path.Combine(installDir, packageDirName), commandAlias, fileName, productCode, false); -// } + var testreuslt = TestCommon.RunAICLICommand("install", $"{packageId}"); + var result = TestCommon.RunAICLICommand("uninstall", $"{packageId}"); + Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); + Assert.True(result.StdOut.Contains("Successfully uninstalled")); + TestCommon.VerifyPortablePackage(Path.Combine(installDir, packageDirName), commandAlias, fileName, productCode, false); + } -// [Test] -// public void UninstallNotIndexed() -// { -// // Uninstalls a package found with ARP not matching any known manifest. -// // Install the test EXE providing a custom Product Code so that it cannot be mapped -// // back to its manifest, then uninstall it using its Product Code -// var installDir = TestCommon.GetRandomTestDir(); -// TestCommon.RunAICLICommand("install", $"{Constants.ExeInstallerPackageId} --override \"/ProductID {CustomProductCode} /InstallDir {installDir}"); -// var result = TestCommon.RunAICLICommand("uninstall", CustomProductCode); -// Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); -// Assert.True(result.StdOut.Contains("Successfully uninstalled")); -// Assert.True(TestCommon.VerifyTestExeUninstalled(installDir)); -// } + [Test] + public void UninstallNotIndexed() + { + // Uninstalls a package found with ARP not matching any known manifest. + // Install the test EXE providing a custom Product Code so that it cannot be mapped + // back to its manifest, then uninstall it using its Product Code + var installDir = TestCommon.GetRandomTestDir(); + TestCommon.RunAICLICommand("install", $"{Constants.ExeInstallerPackageId} --override \"/ProductID {CustomProductCode} /InstallDir {installDir}"); + var result = TestCommon.RunAICLICommand("uninstall", CustomProductCode); + Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); + Assert.True(result.StdOut.Contains("Successfully uninstalled")); + Assert.True(TestCommon.VerifyTestExeUninstalled(installDir)); + } -// [Test] -// public void UninstallAppNotInstalled() -// { -// // Verify failure when trying to uninstall an app that is not installed. -// var result = TestCommon.RunAICLICommand("uninstall", $"TestMsixInstaller"); -// Assert.AreEqual(Constants.ErrorCode.ERROR_NO_APPLICATIONS_FOUND, result.ExitCode); -// Assert.True(result.StdOut.Contains("No installed package found matching input criteria.")); -// } -// } -//} + [Test] + public void UninstallAppNotInstalled() + { + // Verify failure when trying to uninstall an app that is not installed. + var result = TestCommon.RunAICLICommand("uninstall", $"TestMsixInstaller"); + Assert.AreEqual(Constants.ErrorCode.ERROR_NO_APPLICATIONS_FOUND, result.ExitCode); + Assert.True(result.StdOut.Contains("No installed package found matching input criteria.")); + } + } +} diff --git a/src/AppInstallerCLIE2ETests/UpgradeCommand.cs b/src/AppInstallerCLIE2ETests/UpgradeCommand.cs index c63b454b72..095017ee37 100644 --- a/src/AppInstallerCLIE2ETests/UpgradeCommand.cs +++ b/src/AppInstallerCLIE2ETests/UpgradeCommand.cs @@ -1,137 +1,137 @@ -//// Copyright (c) Microsoft Corporation. -//// Licensed under the MIT License. - -//namespace AppInstallerCLIE2ETests -//{ -// using NUnit.Framework; -// using System.IO; - -// public class UpgradeCommand : BaseCommand -// { -// [Test] -// public void UpgradePortable() -// { -// string installDir = TestCommon.GetPortablePackagesDirectory(); -// string packageId, commandAlias, fileName, packageDirName, productCode; -// packageId = "AppInstallerTest.TestPortableExe"; -// packageDirName = productCode = packageId + "_" + Constants.TestSourceIdentifier; -// commandAlias = fileName = "AppInstallerTestExeInstaller.exe"; - -// var result = TestCommon.RunAICLICommand("install", "AppInstallerTest.TestPortableExe -v 1.0.0.0"); -// Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); -// Assert.True(result.StdOut.Contains("Successfully installed")); - -// var result2 = TestCommon.RunAICLICommand("upgrade", $"{packageId} -v 2.0.0.0"); -// Assert.AreEqual(Constants.ErrorCode.S_OK, result2.ExitCode); -// Assert.True(result2.StdOut.Contains("Successfully installed")); -// TestCommon.VerifyPortablePackage(Path.Combine(installDir, packageDirName), commandAlias, fileName, productCode, true); -// } - -// [Test] -// public void UpgradePortableARPMismatch() -// { -// string packageId = "AppInstallerTest.TestPortableExe"; -// string productCode = packageId + "_" + Constants.TestSourceIdentifier; - -// var installResult = TestCommon.RunAICLICommand("install", "AppInstallerTest.TestPortableExe -v 1.0.0.0"); -// Assert.AreEqual(Constants.ErrorCode.S_OK, installResult.ExitCode); -// Assert.True(installResult.StdOut.Contains("Successfully installed")); - -// // Modify packageId to cause mismatch. -// TestCommon.ModifyPortableARPEntryValue(productCode, Constants.WinGetPackageIdentifier, "testPackageId"); - -// var upgradeResult = TestCommon.RunAICLICommand("upgrade", $"{packageId} -v 2.0.0.0"); - -// // Reset and perform uninstall cleanup -// TestCommon.ModifyPortableARPEntryValue(productCode, Constants.WinGetPackageIdentifier, packageId); -// TestCommon.RunAICLICommand("uninstall", $"--product-code {productCode}"); - -// Assert.AreNotEqual(Constants.ErrorCode.S_OK, upgradeResult.ExitCode); -// Assert.True(upgradeResult.StdOut.Contains("Portable package from a different source already exists")); -// } - -// [Test] -// public void UpgradePortableForcedOverride() -// { -// string installDir = TestCommon.GetPortablePackagesDirectory(); -// string packageId, commandAlias, fileName, packageDirName, productCode; -// packageId = "AppInstallerTest.TestPortableExe"; -// packageDirName = productCode = packageId + "_" + Constants.TestSourceIdentifier; -// commandAlias = fileName = "AppInstallerTestExeInstaller.exe"; - -// var installResult = TestCommon.RunAICLICommand("install", "AppInstallerTest.TestPortableExe -v 1.0.0.0"); -// Assert.AreEqual(Constants.ErrorCode.S_OK, installResult.ExitCode); -// Assert.True(installResult.StdOut.Contains("Successfully installed")); - -// // Modify packageId and sourceId to cause mismatch. -// TestCommon.ModifyPortableARPEntryValue(productCode, Constants.WinGetPackageIdentifier, "testPackageId"); -// TestCommon.ModifyPortableARPEntryValue(productCode, Constants.WinGetSourceIdentifier, "testSourceId"); - -// var upgradeResult = TestCommon.RunAICLICommand("upgrade", $"{packageId} -v 2.0.0.0 --force"); -// Assert.AreEqual(Constants.ErrorCode.S_OK, upgradeResult.ExitCode); -// Assert.True(upgradeResult.StdOut.Contains("Successfully installed")); -// TestCommon.VerifyPortablePackage(Path.Combine(installDir, packageDirName), commandAlias, fileName, productCode, true); -// } - -// [Test] -// public void UpgradePortableUninstallPrevious() -// { -// string installDir = TestCommon.GetPortablePackagesDirectory(); -// string packageId, commandAlias, fileName, packageDirName, productCode; -// packageId = "AppInstallerTest.TestPortableExe"; -// packageDirName = productCode = packageId + "_" + Constants.TestSourceIdentifier; -// commandAlias = fileName = "AppInstallerTestExeInstaller.exe"; - -// var result = TestCommon.RunAICLICommand("install", $"{packageId} -v 1.0.0.0"); -// Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); -// Assert.True(result.StdOut.Contains("Successfully installed")); - -// var result2 = TestCommon.RunAICLICommand("upgrade", $"{packageId} -v 3.0.0.0"); -// Assert.AreEqual(Constants.ErrorCode.S_OK, result2.ExitCode); -// Assert.True(result2.StdOut.Contains("Successfully installed")); -// TestCommon.VerifyPortablePackage(Path.Combine(installDir, packageDirName), commandAlias, fileName, productCode, true); -// } - -// [Test] -// public void UpgradePortableMachineScope() -// { -// string installDir = TestCommon.GetRandomTestDir(); -// ConfigureInstallBehavior(Constants.PortablePackageMachineRoot, installDir); - -// string packageId, commandAlias, fileName, packageDirName, productCode; -// packageId = "AppInstallerTest.TestPortableExe"; -// packageDirName = productCode = packageId + "_" + Constants.TestSourceIdentifier; -// commandAlias = fileName = "AppInstallerTestExeInstaller.exe"; - -// var result = TestCommon.RunAICLICommand("install", $"{packageId} -v 1.0.0.0 --scope machine"); -// Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); -// Assert.True(result.StdOut.Contains("Successfully installed")); - -// var result2 = TestCommon.RunAICLICommand("upgrade", $"{packageId} -v 2.0.0.0"); -// ConfigureInstallBehavior(Constants.PortablePackageMachineRoot, string.Empty); -// Assert.AreEqual(Constants.ErrorCode.S_OK, result2.ExitCode); -// Assert.True(result2.StdOut.Contains("Successfully installed")); -// TestCommon.VerifyPortablePackage(Path.Combine(installDir, packageDirName), commandAlias, fileName, productCode, true, TestCommon.Scope.Machine); -// } - -// [Test] -// public void UpgradeZip_Portable() -// { -// string installDir = TestCommon.GetPortablePackagesDirectory(); -// string packageId, commandAlias, fileName, packageDirName, productCode; -// packageId = "AppInstallerTest.TestZipInstallerWithPortable"; -// packageDirName = productCode = packageId + "_" + Constants.TestSourceIdentifier; -// commandAlias = "TestPortable.exe"; -// fileName = "AppInstallerTestExeInstaller.exe"; - -// var result = TestCommon.RunAICLICommand("install", $"AppInstallerTest.TestZipInstallerWithPortable -v 1.0.0.0"); -// Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); -// Assert.True(result.StdOut.Contains("Successfully installed")); - -// var result2 = TestCommon.RunAICLICommand("upgrade", $"{packageId} -v 2.0.0.0"); -// Assert.AreEqual(Constants.ErrorCode.S_OK, result2.ExitCode); -// Assert.True(result2.StdOut.Contains("Successfully installed")); -// TestCommon.VerifyPortablePackage(Path.Combine(installDir, packageDirName), commandAlias, fileName, productCode, true, TestCommon.Scope.User); -// } -// } -//} +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +namespace AppInstallerCLIE2ETests +{ + using NUnit.Framework; + using System.IO; + + public class UpgradeCommand : BaseCommand + { + [Test] + public void UpgradePortable() + { + string installDir = TestCommon.GetPortablePackagesDirectory(); + string packageId, commandAlias, fileName, packageDirName, productCode; + packageId = "AppInstallerTest.TestPortableExe"; + packageDirName = productCode = packageId + "_" + Constants.TestSourceIdentifier; + commandAlias = fileName = "AppInstallerTestExeInstaller.exe"; + + var result = TestCommon.RunAICLICommand("install", "AppInstallerTest.TestPortableExe -v 1.0.0.0"); + Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); + Assert.True(result.StdOut.Contains("Successfully installed")); + + var result2 = TestCommon.RunAICLICommand("upgrade", $"{packageId} -v 2.0.0.0"); + Assert.AreEqual(Constants.ErrorCode.S_OK, result2.ExitCode); + Assert.True(result2.StdOut.Contains("Successfully installed")); + TestCommon.VerifyPortablePackage(Path.Combine(installDir, packageDirName), commandAlias, fileName, productCode, true); + } + + [Test] + public void UpgradePortableARPMismatch() + { + string packageId = "AppInstallerTest.TestPortableExe"; + string productCode = packageId + "_" + Constants.TestSourceIdentifier; + + var installResult = TestCommon.RunAICLICommand("install", "AppInstallerTest.TestPortableExe -v 1.0.0.0"); + Assert.AreEqual(Constants.ErrorCode.S_OK, installResult.ExitCode); + Assert.True(installResult.StdOut.Contains("Successfully installed")); + + // Modify packageId to cause mismatch. + TestCommon.ModifyPortableARPEntryValue(productCode, Constants.WinGetPackageIdentifier, "testPackageId"); + + var upgradeResult = TestCommon.RunAICLICommand("upgrade", $"{packageId} -v 2.0.0.0"); + + // Reset and perform uninstall cleanup + TestCommon.ModifyPortableARPEntryValue(productCode, Constants.WinGetPackageIdentifier, packageId); + TestCommon.RunAICLICommand("uninstall", $"--product-code {productCode}"); + + Assert.AreNotEqual(Constants.ErrorCode.S_OK, upgradeResult.ExitCode); + Assert.True(upgradeResult.StdOut.Contains("Portable package from a different source already exists")); + } + + [Test] + public void UpgradePortableForcedOverride() + { + string installDir = TestCommon.GetPortablePackagesDirectory(); + string packageId, commandAlias, fileName, packageDirName, productCode; + packageId = "AppInstallerTest.TestPortableExe"; + packageDirName = productCode = packageId + "_" + Constants.TestSourceIdentifier; + commandAlias = fileName = "AppInstallerTestExeInstaller.exe"; + + var installResult = TestCommon.RunAICLICommand("install", "AppInstallerTest.TestPortableExe -v 1.0.0.0"); + Assert.AreEqual(Constants.ErrorCode.S_OK, installResult.ExitCode); + Assert.True(installResult.StdOut.Contains("Successfully installed")); + + // Modify packageId and sourceId to cause mismatch. + TestCommon.ModifyPortableARPEntryValue(productCode, Constants.WinGetPackageIdentifier, "testPackageId"); + TestCommon.ModifyPortableARPEntryValue(productCode, Constants.WinGetSourceIdentifier, "testSourceId"); + + var upgradeResult = TestCommon.RunAICLICommand("upgrade", $"{packageId} -v 2.0.0.0 --force"); + Assert.AreEqual(Constants.ErrorCode.S_OK, upgradeResult.ExitCode); + Assert.True(upgradeResult.StdOut.Contains("Successfully installed")); + TestCommon.VerifyPortablePackage(Path.Combine(installDir, packageDirName), commandAlias, fileName, productCode, true); + } + + [Test] + public void UpgradePortableUninstallPrevious() + { + string installDir = TestCommon.GetPortablePackagesDirectory(); + string packageId, commandAlias, fileName, packageDirName, productCode; + packageId = "AppInstallerTest.TestPortableExe"; + packageDirName = productCode = packageId + "_" + Constants.TestSourceIdentifier; + commandAlias = fileName = "AppInstallerTestExeInstaller.exe"; + + var result = TestCommon.RunAICLICommand("install", $"{packageId} -v 1.0.0.0"); + Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); + Assert.True(result.StdOut.Contains("Successfully installed")); + + var result2 = TestCommon.RunAICLICommand("upgrade", $"{packageId} -v 3.0.0.0"); + Assert.AreEqual(Constants.ErrorCode.S_OK, result2.ExitCode); + Assert.True(result2.StdOut.Contains("Successfully installed")); + TestCommon.VerifyPortablePackage(Path.Combine(installDir, packageDirName), commandAlias, fileName, productCode, true); + } + + [Test] + public void UpgradePortableMachineScope() + { + string installDir = TestCommon.GetRandomTestDir(); + ConfigureInstallBehavior(Constants.PortablePackageMachineRoot, installDir); + + string packageId, commandAlias, fileName, packageDirName, productCode; + packageId = "AppInstallerTest.TestPortableExe"; + packageDirName = productCode = packageId + "_" + Constants.TestSourceIdentifier; + commandAlias = fileName = "AppInstallerTestExeInstaller.exe"; + + var result = TestCommon.RunAICLICommand("install", $"{packageId} -v 1.0.0.0 --scope machine"); + Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); + Assert.True(result.StdOut.Contains("Successfully installed")); + + var result2 = TestCommon.RunAICLICommand("upgrade", $"{packageId} -v 2.0.0.0"); + ConfigureInstallBehavior(Constants.PortablePackageMachineRoot, string.Empty); + Assert.AreEqual(Constants.ErrorCode.S_OK, result2.ExitCode); + Assert.True(result2.StdOut.Contains("Successfully installed")); + TestCommon.VerifyPortablePackage(Path.Combine(installDir, packageDirName), commandAlias, fileName, productCode, true, TestCommon.Scope.Machine); + } + + [Test] + public void UpgradeZip_Portable() + { + string installDir = TestCommon.GetPortablePackagesDirectory(); + string packageId, commandAlias, fileName, packageDirName, productCode; + packageId = "AppInstallerTest.TestZipInstallerWithPortable"; + packageDirName = productCode = packageId + "_" + Constants.TestSourceIdentifier; + commandAlias = "TestPortable.exe"; + fileName = "AppInstallerTestExeInstaller.exe"; + + var result = TestCommon.RunAICLICommand("install", $"AppInstallerTest.TestZipInstallerWithPortable -v 1.0.0.0"); + Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); + Assert.True(result.StdOut.Contains("Successfully installed")); + + var result2 = TestCommon.RunAICLICommand("upgrade", $"{packageId} -v 2.0.0.0"); + Assert.AreEqual(Constants.ErrorCode.S_OK, result2.ExitCode); + Assert.True(result2.StdOut.Contains("Successfully installed")); + TestCommon.VerifyPortablePackage(Path.Combine(installDir, packageDirName), commandAlias, fileName, productCode, true, TestCommon.Scope.User); + } + } +} diff --git a/src/AppInstallerCLIE2ETests/ValidateCommand.cs b/src/AppInstallerCLIE2ETests/ValidateCommand.cs index 744188004d..0873892d60 100644 --- a/src/AppInstallerCLIE2ETests/ValidateCommand.cs +++ b/src/AppInstallerCLIE2ETests/ValidateCommand.cs @@ -1,42 +1,42 @@ -//// Copyright (c) Microsoft Corporation. -//// Licensed under the MIT License. +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. -//namespace AppInstallerCLIE2ETests -//{ -// using NUnit.Framework; +namespace AppInstallerCLIE2ETests +{ + using NUnit.Framework; -// public class ValidateCommand : BaseCommand -// { -// [Test] -// public void ValidateManifest() -// { -// var result = TestCommon.RunAICLICommand("validate", TestCommon.GetTestDataFile("Manifests\\TestValidManifest.yaml")); -// Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); -// Assert.True(result.StdOut.Contains("Manifest validation succeeded.")); -// } + public class ValidateCommand : BaseCommand + { + [Test] + public void ValidateManifest() + { + var result = TestCommon.RunAICLICommand("validate", TestCommon.GetTestDataFile("Manifests\\TestValidManifest.yaml")); + Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); + Assert.True(result.StdOut.Contains("Manifest validation succeeded.")); + } -// [Test] -// public void ValidateManifestWithExtendedCharacter() -// { -// var result = TestCommon.RunAICLICommand("validate", TestCommon.GetTestDataFile("Manifests\\TëstExeInstaller.yaml")); -// Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); -// Assert.True(result.StdOut.Contains("Manifest validation succeeded.")); -// } + [Test] + public void ValidateManifestWithExtendedCharacter() + { + var result = TestCommon.RunAICLICommand("validate", TestCommon.GetTestDataFile("Manifests\\TëstExeInstaller.yaml")); + Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); + Assert.True(result.StdOut.Contains("Manifest validation succeeded.")); + } -// [Test] -// public void ValidateInvalidManifest() -// { -// var result = TestCommon.RunAICLICommand("validate", TestCommon.GetTestDataFile("Manifests\\TestInvalidManifest.yaml")); -// Assert.AreEqual(Constants.ErrorCode.ERROR_MANIFEST_VALIDATION_FAILURE, result.ExitCode); -// Assert.True(result.StdOut.Contains("Manifest validation failed.")); -// } + [Test] + public void ValidateInvalidManifest() + { + var result = TestCommon.RunAICLICommand("validate", TestCommon.GetTestDataFile("Manifests\\TestInvalidManifest.yaml")); + Assert.AreEqual(Constants.ErrorCode.ERROR_MANIFEST_VALIDATION_FAILURE, result.ExitCode); + Assert.True(result.StdOut.Contains("Manifest validation failed.")); + } -// [Test] -// public void ValidateManifestDoesNotExist() -// { -// var result = TestCommon.RunAICLICommand("validate", TestCommon.GetTestDataFile("Manifests\\DoesNotExist")); -// Assert.AreEqual(Constants.ErrorCode.ERROR_PATH_NOT_FOUND, result.ExitCode); -// Assert.True(result.StdOut.Contains("Path does not exist")); -// } -// } -//} \ No newline at end of file + [Test] + public void ValidateManifestDoesNotExist() + { + var result = TestCommon.RunAICLICommand("validate", TestCommon.GetTestDataFile("Manifests\\DoesNotExist")); + Assert.AreEqual(Constants.ErrorCode.ERROR_PATH_NOT_FOUND, result.ExitCode); + Assert.True(result.StdOut.Contains("Path does not exist")); + } + } +} \ No newline at end of file diff --git a/src/PowerShell/ComTrace.wprp b/src/PowerShell/ComTrace.wprp deleted file mode 100644 index b7f3c9d700..0000000000 --- a/src/PowerShell/ComTrace.wprp +++ /dev/null @@ -1,35 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/PowerShell/Microsoft.WinGet.Client/Helpers/ComObjectFactory.cs b/src/PowerShell/Microsoft.WinGet.Client/Helpers/ComObjectFactory.cs index 5e72f8a184..a774ece544 100644 --- a/src/PowerShell/Microsoft.WinGet.Client/Helpers/ComObjectFactory.cs +++ b/src/PowerShell/Microsoft.WinGet.Client/Helpers/ComObjectFactory.cs @@ -114,19 +114,14 @@ private static T Create(Type type, in Guid iid) int hr = WinGetServerManualActivation_CreateInstance(type.GUID, iid, 0, out instance); - if (hr != 0) + if (hr == ErrorCode.ERROR_FILE_NOT_FOUND) { - throw new COMException($"Failed with error code {hr}.", hr); + throw new Exception(Utilities.ResourceManager.GetString("WinGetPackageNotInstalled")); + } + else if (hr != 0) + { + throw new COMException($"Failed to create instance: {hr}", hr); } - //if (hr == ErrorCode.ERROR_FILE_NOT_FOUND) - //{ - // throw new Exception(Utilities.ResourceManager.GetString("WinGetPackageNotInstalled")); - //} - //else if (hr != 0) - //{ - // Console.WriteLine($"Error code: {hr}"); - // throw new COMException("Failed to create instance.", hr); - //} } else { diff --git a/src/PowerShell/Microsoft.WinGet.Client/Microsoft.WinGet.Client.csproj b/src/PowerShell/Microsoft.WinGet.Client/Microsoft.WinGet.Client.csproj index 0b889169d8..1451df7710 100644 --- a/src/PowerShell/Microsoft.WinGet.Client/Microsoft.WinGet.Client.csproj +++ b/src/PowerShell/Microsoft.WinGet.Client/Microsoft.WinGet.Client.csproj @@ -102,12 +102,6 @@ - - - - - - diff --git a/src/PowerShell/Microsoft.WinGet.Client/ModuleManifest-x86/Microsoft.WinGet.Client.psd1 b/src/PowerShell/Microsoft.WinGet.Client/ModuleManifest-x86/Microsoft.WinGet.Client.psd1 deleted file mode 100644 index 8719d66290..0000000000 --- a/src/PowerShell/Microsoft.WinGet.Client/ModuleManifest-x86/Microsoft.WinGet.Client.psd1 +++ /dev/null @@ -1,160 +0,0 @@ -# NOTE: This module manifest is only used for explicitly targeting the x86 powershell module and should not be used in production. -# -# 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 = "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/WinGetServer/WinMain.cpp b/src/WinGetServer/WinMain.cpp index 716971013c..a3e44a1fd1 100644 --- a/src/WinGetServer/WinMain.cpp +++ b/src/WinGetServer/WinMain.cpp @@ -101,7 +101,7 @@ extern "C" HRESULT CreateInstance( int __stdcall wWinMain(_In_ HINSTANCE, _In_opt_ HINSTANCE, _In_ LPWSTR cmdLine, _In_ int) { - wil::SetResultLoggingCallback(&WindowsPackageManagerServerLogWilResult); + wil::SetResultLoggingCallback(&WindowsPackageManagerServerWilResultCallback); RETURN_IF_FAILED(CoInitializeEx(nullptr, COINIT_MULTITHREADED)); diff --git a/src/WindowsPackageManager/Source.def b/src/WindowsPackageManager/Source.def index f8f1d2c4db..c1505a638b 100644 --- a/src/WindowsPackageManager/Source.def +++ b/src/WindowsPackageManager/Source.def @@ -5,7 +5,7 @@ EXPORTS WindowsPackageManagerServerModuleCreate WindowsPackageManagerServerModuleRegister WindowsPackageManagerServerModuleUnregister - WindowsPackageManagerServerLogWilResult + WindowsPackageManagerServerWilResultCallback WindowsPackageManagerServerCreateInstance WindowsPackageManagerInProcModuleInitialize WindowsPackageManagerInProcModuleTerminate diff --git a/src/WindowsPackageManager/WindowsPackageManager.h b/src/WindowsPackageManager/WindowsPackageManager.h index 3112107801..e9b47f77c7 100644 --- a/src/WindowsPackageManager/WindowsPackageManager.h +++ b/src/WindowsPackageManager/WindowsPackageManager.h @@ -29,7 +29,7 @@ extern "C" WINDOWS_PACKAGE_MANAGER_API WindowsPackageManagerServerModuleUnregister(); // Reports the hresult from WIL back to the Windows Package Manager dll for logging; - void WINDOWS_PACKAGE_MANAGER_API_CALLING_CONVENTION WindowsPackageManagerServerLogWilResult(const wil::FailureInfo& info) noexcept; + void WINDOWS_PACKAGE_MANAGER_API_CALLING_CONVENTION WindowsPackageManagerServerWilResultCallback(const wil::FailureInfo& info) noexcept; // Creates an out-of-proc instance for manual activation scenarios. WINDOWS_PACKAGE_MANAGER_API WindowsPackageManagerServerCreateInstance(const CLSID* clsid, const IID* iid, void** out); diff --git a/src/WindowsPackageManager/main.cpp b/src/WindowsPackageManager/main.cpp index 36e3b0a93f..a0835fc4b9 100644 --- a/src/WindowsPackageManager/main.cpp +++ b/src/WindowsPackageManager/main.cpp @@ -60,7 +60,7 @@ extern "C" } CATCH_RETURN(); - void WINDOWS_PACKAGE_MANAGER_API_CALLING_CONVENTION WindowsPackageManagerServerLogWilResult(const wil::FailureInfo& failure) noexcept try + void WINDOWS_PACKAGE_MANAGER_API_CALLING_CONVENTION WindowsPackageManagerServerWilResultCallback(const wil::FailureInfo& failure) noexcept try { AICLI_LOG(Fail, Error, << [&]() { wchar_t message[2048]; diff --git a/templates/e2e-test.template.yml b/templates/e2e-test.template.yml index 510cffe76d..8b36c84506 100644 --- a/templates/e2e-test.template.yml +++ b/templates/e2e-test.template.yml @@ -19,7 +19,6 @@ steps: overrideTestrunParameters: '-PackagedContext true -AICLIPackagePath $(System.DefaultWorkingDirectory)\src\AppInstallerCLIPackage\bin\$(buildPlatform)\$(buildConfiguration) -AICLIPath AppInstallerCLI\winget.exe - -VerboseLogging true -LooseFileRegistration true -InvokeCommandInDesktopPackage true -StaticFileRootPath $(Agent.TempDirectory)\TestLocalIndex @@ -31,7 +30,6 @@ steps: ${{ else }}: overrideTestrunParameters: '-PackagedContext false -AICLIPath $(System.DefaultWorkingDirectory)\src\AppInstallerCLIPackage\bin\$(buildPlatform)\$(buildConfiguration)\AppInstallerCLI\winget.exe - -VerboseLogging true -InvokeCommandInDesktopPackage false -StaticFileRootPath $(Agent.TempDirectory)\TestLocalIndex -MsiTestInstallerPath $(System.DefaultWorkingDirectory)\src\AppInstallerCLIE2ETests\TestData\AppInstallerTestMsiInstaller.msi From 8f68d4dc0533e5d8b3be01bbae6261a63b65dccf Mon Sep 17 00:00:00 2001 From: Ryan Fu Date: Mon, 14 Nov 2022 13:57:33 -0800 Subject: [PATCH 30/49] uncomment tests --- .../WinGetUtil/WinGetUtilCompareVersions.cs | 62 ++-- .../WinGetUtil/WinGetUtilDownload.cs | 46 +-- .../WinGetUtilInstallerMetadataCollection.cs | 130 ++++---- .../WinGetUtil/WinGetUtilLog.cs | 2 +- .../WinGetUtil/WinGetUtilManifest.cs | 116 +++---- .../WinGetUtil/WinGetUtilSQLiteIndex.cs | 284 +++++++++--------- 6 files changed, 320 insertions(+), 320 deletions(-) diff --git a/src/AppInstallerCLIE2ETests/WinGetUtil/WinGetUtilCompareVersions.cs b/src/AppInstallerCLIE2ETests/WinGetUtil/WinGetUtilCompareVersions.cs index 2dd1b577d9..84abc1825b 100644 --- a/src/AppInstallerCLIE2ETests/WinGetUtil/WinGetUtilCompareVersions.cs +++ b/src/AppInstallerCLIE2ETests/WinGetUtil/WinGetUtilCompareVersions.cs @@ -1,33 +1,33 @@ -//// Copyright (c) Microsoft Corporation. -//// Licensed under the MIT License. +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. -//namespace AppInstallerCLIE2ETests.WinGetUtil -//{ -// using NUnit.Framework; +namespace AppInstallerCLIE2ETests.WinGetUtil +{ + using NUnit.Framework; -// public class WinGetUtilCompareVersions -// { -// [Test] -// // V1 = V2 -// [TestCase("1.0.0.0", "1.0.0.0", 0)] -// [TestCase("1.0.0", "1.0.0.0", 0)] -// [TestCase("1.0", "1.0.0.0", 0)] -// [TestCase("1", "1.0.0.0", 0)] -// // V1 > V2 -// [TestCase("1.0.0.1", "1.0.0.0", 1)] -// [TestCase("1.0.1.0", "1.0.0.0", 1)] -// [TestCase("1.1.0.0", "1.0.0.0", 1)] -// [TestCase("2.0.0.0", "1.0.0.0", 1)] -// // V1 < V2 -// [TestCase("1.0.0.0", "1.0.0.1", -1)] -// [TestCase("1.0.0.0", "1.0.1.0", -1)] -// [TestCase("1.0.0.0", "1.1.0.0", -1)] -// [TestCase("1.0.0.0", "2.0.0.0", -1)] -// public void WinGetUtil_CompareVersions(string version1, string version2, int expectedResult) -// { -// // Compare versions -// WinGetUtilWrapper.WinGetCompareVersions(version1, version2, out int result); -// Assert.AreEqual(expectedResult, result); -// } -// } -//} + public class WinGetUtilCompareVersions + { + [Test] + // V1 = V2 + [TestCase("1.0.0.0", "1.0.0.0", 0)] + [TestCase("1.0.0", "1.0.0.0", 0)] + [TestCase("1.0", "1.0.0.0", 0)] + [TestCase("1", "1.0.0.0", 0)] + // V1 > V2 + [TestCase("1.0.0.1", "1.0.0.0", 1)] + [TestCase("1.0.1.0", "1.0.0.0", 1)] + [TestCase("1.1.0.0", "1.0.0.0", 1)] + [TestCase("2.0.0.0", "1.0.0.0", 1)] + // V1 < V2 + [TestCase("1.0.0.0", "1.0.0.1", -1)] + [TestCase("1.0.0.0", "1.0.1.0", -1)] + [TestCase("1.0.0.0", "1.1.0.0", -1)] + [TestCase("1.0.0.0", "2.0.0.0", -1)] + public void WinGetUtil_CompareVersions(string version1, string version2, int expectedResult) + { + // Compare versions + WinGetUtilWrapper.WinGetCompareVersions(version1, version2, out int result); + Assert.AreEqual(expectedResult, result); + } + } +} diff --git a/src/AppInstallerCLIE2ETests/WinGetUtil/WinGetUtilDownload.cs b/src/AppInstallerCLIE2ETests/WinGetUtil/WinGetUtilDownload.cs index 1ac94f5015..d31a6073a1 100644 --- a/src/AppInstallerCLIE2ETests/WinGetUtil/WinGetUtilDownload.cs +++ b/src/AppInstallerCLIE2ETests/WinGetUtil/WinGetUtilDownload.cs @@ -1,27 +1,27 @@ -//// Copyright (c) Microsoft Corporation. -//// Licensed under the MIT License. +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. -//namespace AppInstallerCLIE2ETests.WinGetUtil -//{ -// using System.IO; -// using System.Linq; -// using NUnit.Framework; +namespace AppInstallerCLIE2ETests.WinGetUtil +{ + using System.IO; + using System.Linq; + using NUnit.Framework; -// public class WinGetUtilDownload -// { -// [Test] -// public void WinGetUtil_Download() -// { -// uint hashSize = 32; -// byte[] sha256Hash = new byte[hashSize]; -// string installerUrl = @"https://localhost:5001/TestKit/AppInstallerTestExeInstaller/AppInstallerTestExeInstaller.exe"; -// string filePath = TestCommon.GetRandomTestFile(".exe"); + public class WinGetUtilDownload + { + [Test] + public void WinGetUtil_Download() + { + uint hashSize = 32; + byte[] sha256Hash = new byte[hashSize]; + string installerUrl = @"https://localhost:5001/TestKit/AppInstallerTestExeInstaller/AppInstallerTestExeInstaller.exe"; + string filePath = TestCommon.GetRandomTestFile(".exe"); -// // Download -// WinGetUtilWrapper.WinGetDownload(installerUrl, filePath, sha256Hash, hashSize); + // Download + WinGetUtilWrapper.WinGetDownload(installerUrl, filePath, sha256Hash, hashSize); -// Assert.True(File.Exists(filePath)); -// Assert.False(sha256Hash.All(byteVal => byteVal == 0)); -// } -// } -//} + Assert.True(File.Exists(filePath)); + Assert.False(sha256Hash.All(byteVal => byteVal == 0)); + } + } +} diff --git a/src/AppInstallerCLIE2ETests/WinGetUtil/WinGetUtilInstallerMetadataCollection.cs b/src/AppInstallerCLIE2ETests/WinGetUtil/WinGetUtilInstallerMetadataCollection.cs index 6f71bd72e0..d11c11128f 100644 --- a/src/AppInstallerCLIE2ETests/WinGetUtil/WinGetUtilInstallerMetadataCollection.cs +++ b/src/AppInstallerCLIE2ETests/WinGetUtil/WinGetUtilInstallerMetadataCollection.cs @@ -1,77 +1,77 @@ -//// Copyright (c) Microsoft Corporation. -//// Licensed under the MIT License. +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. -//namespace AppInstallerCLIE2ETests.WinGetUtil -//{ -// using Newtonsoft.Json; -// using NUnit.Framework; -// using System; -// using System.IO; -// using System.Runtime.InteropServices; +namespace AppInstallerCLIE2ETests.WinGetUtil +{ + using Newtonsoft.Json; + using NUnit.Framework; + using System; + using System.IO; + using System.Runtime.InteropServices; -// public class WinGetUtilInstallerMetadataCollection -// { -// [Test] -// public void WinGetUtil_BeginCompleteInstallerMetadataCollection() -// { -// string logFilePath = TestCommon.GetRandomTestFile(".log"); -// string inputJson = TestCommon.GetTestDataFile(@"WinGetUtil\InstallerMetadata\Minimal.json"); -// string outputFilePath = TestCommon.GetRandomTestFile(".json"); + public class WinGetUtilInstallerMetadataCollection + { + [Test] + public void WinGetUtil_BeginCompleteInstallerMetadataCollection() + { + string logFilePath = TestCommon.GetRandomTestFile(".log"); + string inputJson = TestCommon.GetTestDataFile(@"WinGetUtil\InstallerMetadata\Minimal.json"); + string outputFilePath = TestCommon.GetRandomTestFile(".json"); -// WinGetUtilWrapper.WinGetBeginInstallerMetadataCollection( -// inputJson, -// logFilePath, -// WinGetUtilWrapper.WinGetBeginInstallerMetadataCollectionOptions.WinGetBeginInstallerMetadataCollectionOption_InputIsFilePath, -// out IntPtr collectionHandle); + WinGetUtilWrapper.WinGetBeginInstallerMetadataCollection( + inputJson, + logFilePath, + WinGetUtilWrapper.WinGetBeginInstallerMetadataCollectionOptions.WinGetBeginInstallerMetadataCollectionOption_InputIsFilePath, + out IntPtr collectionHandle); -// Assert.AreNotEqual(IntPtr.Zero, collectionHandle); -// Assert.True(File.Exists(logFilePath)); + Assert.AreNotEqual(IntPtr.Zero, collectionHandle); + Assert.True(File.Exists(logFilePath)); -// WinGetUtilWrapper.WinGetCompleteInstallerMetadataCollection( -// collectionHandle, -// outputFilePath, -// WinGetUtilWrapper.WinGetCompleteInstallerMetadataCollectionOptions.WinGetCompleteInstallerMetadataCollectionOption_None); + WinGetUtilWrapper.WinGetCompleteInstallerMetadataCollection( + collectionHandle, + outputFilePath, + WinGetUtilWrapper.WinGetCompleteInstallerMetadataCollectionOptions.WinGetCompleteInstallerMetadataCollectionOption_None); -// string outputJson = File.ReadAllText(outputFilePath); -// Assert.IsNotEmpty(JsonConvert.DeserializeObject(outputJson).ToString()); -// } + string outputJson = File.ReadAllText(outputFilePath); + Assert.IsNotEmpty(JsonConvert.DeserializeObject(outputJson).ToString()); + } -// [Test] -// public void WinGetUtil_MergeInstallerMetadata_Success() -// { -// string logFilePath = TestCommon.GetRandomTestFile(".log"); -// string inputJsonPath = TestCommon.GetTestDataFile(@"WinGetUtil\InstallerMetadata\MergeValid.json"); -// string inputJson = File.ReadAllText(inputJsonPath); + [Test] + public void WinGetUtil_MergeInstallerMetadata_Success() + { + string logFilePath = TestCommon.GetRandomTestFile(".log"); + string inputJsonPath = TestCommon.GetTestDataFile(@"WinGetUtil\InstallerMetadata\MergeValid.json"); + string inputJson = File.ReadAllText(inputJsonPath); -// WinGetUtilWrapper.WinGetMergeInstallerMetadata( -// inputJson, -// out string outputJson, -// 0, -// logFilePath, -// WinGetUtilWrapper.WinGetMergeInstallerMetadataOptions.WinGetMergeInstallerMetadataOptions_None); + WinGetUtilWrapper.WinGetMergeInstallerMetadata( + inputJson, + out string outputJson, + 0, + logFilePath, + WinGetUtilWrapper.WinGetMergeInstallerMetadataOptions.WinGetMergeInstallerMetadataOptions_None); -// Assert.True(File.Exists(logFilePath)); -// Assert.IsNotEmpty(JsonConvert.DeserializeObject(outputJson).ToString()); -// } + Assert.True(File.Exists(logFilePath)); + Assert.IsNotEmpty(JsonConvert.DeserializeObject(outputJson).ToString()); + } -// [Test] -// public void WinGetUtil_MergeInstallerMetadata_Fail_SubmissionMismatch() -// { -// string logFilePath = TestCommon.GetRandomTestFile(".log"); -// string inputJsonPath = TestCommon.GetTestDataFile(@"WinGetUtil\InstallerMetadata\MergeSubmissionMismatch.json"); -// string inputJson = File.ReadAllText(inputJsonPath); + [Test] + public void WinGetUtil_MergeInstallerMetadata_Fail_SubmissionMismatch() + { + string logFilePath = TestCommon.GetRandomTestFile(".log"); + string inputJsonPath = TestCommon.GetTestDataFile(@"WinGetUtil\InstallerMetadata\MergeSubmissionMismatch.json"); + string inputJson = File.ReadAllText(inputJsonPath); -// Assert.Throws(() => -// { -// WinGetUtilWrapper.WinGetMergeInstallerMetadata( -// inputJson, -// out string outputJson, -// 0, -// logFilePath, -// WinGetUtilWrapper.WinGetMergeInstallerMetadataOptions.WinGetMergeInstallerMetadataOptions_None); -// }); + Assert.Throws(() => + { + WinGetUtilWrapper.WinGetMergeInstallerMetadata( + inputJson, + out string outputJson, + 0, + logFilePath, + WinGetUtilWrapper.WinGetMergeInstallerMetadataOptions.WinGetMergeInstallerMetadataOptions_None); + }); -// Assert.True(File.Exists(logFilePath)); -// } -// } -//} + Assert.True(File.Exists(logFilePath)); + } + } +} diff --git a/src/AppInstallerCLIE2ETests/WinGetUtil/WinGetUtilLog.cs b/src/AppInstallerCLIE2ETests/WinGetUtil/WinGetUtilLog.cs index 2eac3d132b..635f3a4af4 100644 --- a/src/AppInstallerCLIE2ETests/WinGetUtil/WinGetUtilLog.cs +++ b/src/AppInstallerCLIE2ETests/WinGetUtil/WinGetUtilLog.cs @@ -8,7 +8,7 @@ namespace AppInstallerCLIE2ETests.WinGetUtil public class WinGetUtilLog { - //[Test] + [Test] public void WinGetUtil_Logging() { string filePath = TestCommon.GetRandomTestFile(".log"); diff --git a/src/AppInstallerCLIE2ETests/WinGetUtil/WinGetUtilManifest.cs b/src/AppInstallerCLIE2ETests/WinGetUtil/WinGetUtilManifest.cs index 2d42f09f7d..8dee02baaf 100644 --- a/src/AppInstallerCLIE2ETests/WinGetUtil/WinGetUtilManifest.cs +++ b/src/AppInstallerCLIE2ETests/WinGetUtil/WinGetUtilManifest.cs @@ -1,68 +1,68 @@ -//// Copyright (c) Microsoft Corporation. -//// Licensed under the MIT License. +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. -//namespace AppInstallerCLIE2ETests.WinGetUtil -//{ -// using System; -// using System.IO; -// using NUnit.Framework; +namespace AppInstallerCLIE2ETests.WinGetUtil +{ + using System; + using System.IO; + using NUnit.Framework; -// public class WinGetUtilManifest -// { -// private IntPtr indexHandle; + public class WinGetUtilManifest + { + private IntPtr indexHandle; -// [SetUp] -// public void SetUp() -// { -// this.indexHandle = IntPtr.Zero; -// var sqliteFile = TestCommon.GetRandomTestFile(".db"); -// uint majorVersion = 1; -// uint minorVersion = 2; -// WinGetUtilWrapper.WinGetSQLiteIndexCreate(sqliteFile, majorVersion, minorVersion, out this.indexHandle); ; -// } + [SetUp] + public void SetUp() + { + this.indexHandle = IntPtr.Zero; + var sqliteFile = TestCommon.GetRandomTestFile(".db"); + uint majorVersion = 1; + uint minorVersion = 2; + WinGetUtilWrapper.WinGetSQLiteIndexCreate(sqliteFile, majorVersion, minorVersion, out this.indexHandle); ; + } -// [TearDown] -// public void TearDown() -// { -// WinGetUtilWrapper.WinGetSQLiteIndexClose(this.indexHandle); -// } + [TearDown] + public void TearDown() + { + WinGetUtilWrapper.WinGetSQLiteIndexClose(this.indexHandle); + } -// [Test] -// [TestCase(WinGetUtilWrapper.CreateManifestOption.NoValidation)] -// [TestCase(WinGetUtilWrapper.CreateManifestOption.SchemaAndSemanticValidation)] -// public void WinGetUtil_ValidateManifest_Success(WinGetUtilWrapper.CreateManifestOption createManifestOption) -// { -// string manifestsDir = TestCommon.GetTestDataFile(@"WinGetUtil\Manifests\Unmerged\ValidateManifest"); -// string mergedManifestPath = TestCommon.GetRandomTestFile(".yaml"); + [Test] + [TestCase(WinGetUtilWrapper.CreateManifestOption.NoValidation)] + [TestCase(WinGetUtilWrapper.CreateManifestOption.SchemaAndSemanticValidation)] + public void WinGetUtil_ValidateManifest_Success(WinGetUtilWrapper.CreateManifestOption createManifestOption) + { + string manifestsDir = TestCommon.GetTestDataFile(@"WinGetUtil\Manifests\Unmerged\ValidateManifest"); + string mergedManifestPath = TestCommon.GetRandomTestFile(".yaml"); -// // Create manifest -// WinGetUtilWrapper.WinGetCreateManifest( -// manifestsDir, -// out bool succeeded, -// out IntPtr manifestHandle, -// out string createFailureMessage, -// mergedManifestPath, -// createManifestOption); + // Create manifest + WinGetUtilWrapper.WinGetCreateManifest( + manifestsDir, + out bool succeeded, + out IntPtr manifestHandle, + out string createFailureMessage, + mergedManifestPath, + createManifestOption); -// Assert.True(succeeded); -// Assert.AreNotEqual(IntPtr.Zero, manifestHandle); -// Assert.IsNull(createFailureMessage); -// Assert.True(File.Exists(mergedManifestPath)); + Assert.True(succeeded); + Assert.AreNotEqual(IntPtr.Zero, manifestHandle); + Assert.IsNull(createFailureMessage); + Assert.True(File.Exists(mergedManifestPath)); -// // Validate manifest -// WinGetUtilWrapper.WinGetValidateManifestV3( -// manifestHandle, -// indexHandle, -// out WinGetUtilWrapper.ValidateManifestResultCode resultCode, -// out string validateFailureMessage, -// WinGetUtilWrapper.ValidateManifestOptionV2.ArpVersionValidation, -// WinGetUtilWrapper.ValidateManifestOperationType.Add); + // Validate manifest + WinGetUtilWrapper.WinGetValidateManifestV3( + manifestHandle, + indexHandle, + out WinGetUtilWrapper.ValidateManifestResultCode resultCode, + out string validateFailureMessage, + WinGetUtilWrapper.ValidateManifestOptionV2.ArpVersionValidation, + WinGetUtilWrapper.ValidateManifestOperationType.Add); -// Assert.AreEqual(WinGetUtilWrapper.ValidateManifestResultCode.Success, resultCode); -// Assert.IsEmpty(validateFailureMessage); + Assert.AreEqual(WinGetUtilWrapper.ValidateManifestResultCode.Success, resultCode); + Assert.IsEmpty(validateFailureMessage); -// // Close manifest -// WinGetUtilWrapper.WinGetCloseManifest(manifestHandle); -// } -// } -//} + // Close manifest + WinGetUtilWrapper.WinGetCloseManifest(manifestHandle); + } + } +} diff --git a/src/AppInstallerCLIE2ETests/WinGetUtil/WinGetUtilSQLiteIndex.cs b/src/AppInstallerCLIE2ETests/WinGetUtil/WinGetUtilSQLiteIndex.cs index 36d764f2b9..2be18fbe78 100644 --- a/src/AppInstallerCLIE2ETests/WinGetUtil/WinGetUtilSQLiteIndex.cs +++ b/src/AppInstallerCLIE2ETests/WinGetUtil/WinGetUtilSQLiteIndex.cs @@ -1,142 +1,142 @@ -//// Copyright (c) Microsoft Corporation. -//// Licensed under the MIT License. - -//namespace AppInstallerCLIE2ETests.WinGetUtil -//{ -// using System; -// using System.IO; -// using System.Runtime.InteropServices; -// using NUnit.Framework; - -// public class WinGetUtilSQLiteIndex -// { -// private string sqlitePath; -// private readonly uint majorVersion = 1; -// private readonly uint minorVersion = 2; - -// // Manifest example 1 -// private readonly string addManifestsFile_1 = TestCommon.GetTestDataFile(@"WinGetUtil\Manifests\Merged\WinGetUtilTest.Add.yaml"); -// private readonly string updateManifestsFile_1 = TestCommon.GetTestDataFile(@"WinGetUtil\Manifests\Merged\WinGetUtilTest.Update.yaml"); -// private readonly string relativePath_1 = @"manifests\a\AppInstallerTest\WinGetUtilTest\1.0.0.0\WinGetTest.yaml"; - -// [SetUp] -// public void SetUp() -// { -// this.sqlitePath = TestCommon.GetRandomTestFile(".sql"); -// } - -// [Test] -// public void WinGetUtil_SQLiteIndex_AddManifest() -// { -// SQLiteIndex((indexHandle) => -// { -// // Add manifest -// WinGetUtilWrapper.WinGetSQLiteIndexAddManifest(indexHandle, addManifestsFile_1, relativePath_1); -// }); -// } - -// [Test] -// public void WinGetUtil_SQLiteIndex_UpdateManifest_Success() -// { -// SQLiteIndex((indexHandle) => -// { -// // Add manifest -// WinGetUtilWrapper.WinGetSQLiteIndexAddManifest(indexHandle, addManifestsFile_1, relativePath_1); - -// // Update manifest -// WinGetUtilWrapper.WinGetSQLiteIndexUpdateManifest(indexHandle, updateManifestsFile_1, relativePath_1, out bool indexModified); -// Assert.True(indexModified); -// }); -// } - -// [Test] -// public void WinGetUtil_SQLiteIndex_UpdateManifest_Fail_NotFound() -// { -// SQLiteIndex((indexHandle) => -// { -// // Update non-existing manifest -// Assert.Throws(() => -// { -// WinGetUtilWrapper.WinGetSQLiteIndexUpdateManifest(indexHandle, updateManifestsFile_1, relativePath_1, out bool indexModified); -// }); -// }); -// } - -// [Test] -// public void WinGetUtil_SQLiteIndex_RemoveManifest_Success() -// { -// SQLiteIndex((indexHandle) => -// { -// // Add manifest -// WinGetUtilWrapper.WinGetSQLiteIndexAddManifest(indexHandle, addManifestsFile_1, relativePath_1); - -// // Remove manifest -// WinGetUtilWrapper.WinGetSQLiteIndexRemoveManifest(indexHandle, addManifestsFile_1, relativePath_1); -// }); -// } - -// [Test] -// public void WinGetUtil_SQLiteIndex_RemoveManifest_Fail_NotFound() -// { -// SQLiteIndex((indexHandle) => -// { -// // Remove non-existing manifest -// Assert.Throws(() => -// { -// WinGetUtilWrapper.WinGetSQLiteIndexRemoveManifest(indexHandle, addManifestsFile_1, relativePath_1); -// }); -// }); -// } - -// [Test] -// public void WinGetUtil_SQLiteIndex_OpenClose() -// { -// SQLiteIndex((_) => -// { -// // Open -// WinGetUtilWrapper.WinGetSQLiteIndexOpen(sqlitePath, out IntPtr indexHandle); - -// // Add manifest -// WinGetUtilWrapper.WinGetSQLiteIndexAddManifest(indexHandle, addManifestsFile_1, relativePath_1); - -// // Close -// WinGetUtilWrapper.WinGetSQLiteIndexClose(indexHandle); -// }); -// } - -// [Test] -// public void WinGetUtil_SQLiteIndex_CheckConsistency() -// { -// SQLiteIndex((indexHandle) => -// { -// // Add manifest -// WinGetUtilWrapper.WinGetSQLiteIndexAddManifest(indexHandle, addManifestsFile_1, relativePath_1); - -// // Prepare for packaging -// WinGetUtilWrapper.WinGetSQLiteIndexPrepareForPackaging(indexHandle); - -// // Check consistency -// WinGetUtilWrapper.WinGetSQLiteIndexCheckConsistency(indexHandle, out bool succeeded); -// Assert.True(succeeded); -// }); -// } - -// /// -// /// Create and close an sqlite index file. -// /// -// /// Function to execute. -// private void SQLiteIndex(Action Execute) -// { -// // Create -// WinGetUtilWrapper.WinGetSQLiteIndexCreate(sqlitePath, majorVersion, minorVersion, out IntPtr indexHandle); -// Assert.True(File.Exists(sqlitePath)); -// Assert.AreNotEqual(IntPtr.Zero, indexHandle); - -// // Execute provided function -// Execute(indexHandle); - -// // Close -// WinGetUtilWrapper.WinGetSQLiteIndexClose(indexHandle); -// } -// } -//} +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +namespace AppInstallerCLIE2ETests.WinGetUtil +{ + using System; + using System.IO; + using System.Runtime.InteropServices; + using NUnit.Framework; + + public class WinGetUtilSQLiteIndex + { + private string sqlitePath; + private readonly uint majorVersion = 1; + private readonly uint minorVersion = 2; + + // Manifest example 1 + private readonly string addManifestsFile_1 = TestCommon.GetTestDataFile(@"WinGetUtil\Manifests\Merged\WinGetUtilTest.Add.yaml"); + private readonly string updateManifestsFile_1 = TestCommon.GetTestDataFile(@"WinGetUtil\Manifests\Merged\WinGetUtilTest.Update.yaml"); + private readonly string relativePath_1 = @"manifests\a\AppInstallerTest\WinGetUtilTest\1.0.0.0\WinGetTest.yaml"; + + [SetUp] + public void SetUp() + { + this.sqlitePath = TestCommon.GetRandomTestFile(".sql"); + } + + [Test] + public void WinGetUtil_SQLiteIndex_AddManifest() + { + SQLiteIndex((indexHandle) => + { + // Add manifest + WinGetUtilWrapper.WinGetSQLiteIndexAddManifest(indexHandle, addManifestsFile_1, relativePath_1); + }); + } + + [Test] + public void WinGetUtil_SQLiteIndex_UpdateManifest_Success() + { + SQLiteIndex((indexHandle) => + { + // Add manifest + WinGetUtilWrapper.WinGetSQLiteIndexAddManifest(indexHandle, addManifestsFile_1, relativePath_1); + + // Update manifest + WinGetUtilWrapper.WinGetSQLiteIndexUpdateManifest(indexHandle, updateManifestsFile_1, relativePath_1, out bool indexModified); + Assert.True(indexModified); + }); + } + + [Test] + public void WinGetUtil_SQLiteIndex_UpdateManifest_Fail_NotFound() + { + SQLiteIndex((indexHandle) => + { + // Update non-existing manifest + Assert.Throws(() => + { + WinGetUtilWrapper.WinGetSQLiteIndexUpdateManifest(indexHandle, updateManifestsFile_1, relativePath_1, out bool indexModified); + }); + }); + } + + [Test] + public void WinGetUtil_SQLiteIndex_RemoveManifest_Success() + { + SQLiteIndex((indexHandle) => + { + // Add manifest + WinGetUtilWrapper.WinGetSQLiteIndexAddManifest(indexHandle, addManifestsFile_1, relativePath_1); + + // Remove manifest + WinGetUtilWrapper.WinGetSQLiteIndexRemoveManifest(indexHandle, addManifestsFile_1, relativePath_1); + }); + } + + [Test] + public void WinGetUtil_SQLiteIndex_RemoveManifest_Fail_NotFound() + { + SQLiteIndex((indexHandle) => + { + // Remove non-existing manifest + Assert.Throws(() => + { + WinGetUtilWrapper.WinGetSQLiteIndexRemoveManifest(indexHandle, addManifestsFile_1, relativePath_1); + }); + }); + } + + [Test] + public void WinGetUtil_SQLiteIndex_OpenClose() + { + SQLiteIndex((_) => + { + // Open + WinGetUtilWrapper.WinGetSQLiteIndexOpen(sqlitePath, out IntPtr indexHandle); + + // Add manifest + WinGetUtilWrapper.WinGetSQLiteIndexAddManifest(indexHandle, addManifestsFile_1, relativePath_1); + + // Close + WinGetUtilWrapper.WinGetSQLiteIndexClose(indexHandle); + }); + } + + [Test] + public void WinGetUtil_SQLiteIndex_CheckConsistency() + { + SQLiteIndex((indexHandle) => + { + // Add manifest + WinGetUtilWrapper.WinGetSQLiteIndexAddManifest(indexHandle, addManifestsFile_1, relativePath_1); + + // Prepare for packaging + WinGetUtilWrapper.WinGetSQLiteIndexPrepareForPackaging(indexHandle); + + // Check consistency + WinGetUtilWrapper.WinGetSQLiteIndexCheckConsistency(indexHandle, out bool succeeded); + Assert.True(succeeded); + }); + } + + /// + /// Create and close an sqlite index file. + /// + /// Function to execute. + private void SQLiteIndex(Action Execute) + { + // Create + WinGetUtilWrapper.WinGetSQLiteIndexCreate(sqlitePath, majorVersion, minorVersion, out IntPtr indexHandle); + Assert.True(File.Exists(sqlitePath)); + Assert.AreNotEqual(IntPtr.Zero, indexHandle); + + // Execute provided function + Execute(indexHandle); + + // Close + WinGetUtilWrapper.WinGetSQLiteIndexClose(indexHandle); + } + } +} From cf5a0ef1e3bde12f78757bcae3178a7d3035dbc2 Mon Sep 17 00:00:00 2001 From: Ryan Fu Date: Mon, 14 Nov 2022 14:52:10 -0800 Subject: [PATCH 31/49] remove teardown form powershell module test --- src/AppInstallerCLIE2ETests/PowerShell/PowerShellModule.cs | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/AppInstallerCLIE2ETests/PowerShell/PowerShellModule.cs b/src/AppInstallerCLIE2ETests/PowerShell/PowerShellModule.cs index 36c3b66acf..86294f4d9c 100644 --- a/src/AppInstallerCLIE2ETests/PowerShell/PowerShellModule.cs +++ b/src/AppInstallerCLIE2ETests/PowerShell/PowerShellModule.cs @@ -18,13 +18,6 @@ public void Setup() TestCommon.RunAICLICommand("source add", $"-n {Constants.TestSourceName} {Constants.TestSourceUrl}"); } - [OneTimeTearDown] - public void TearDown() - { - // Remove-WinGetPackage is a function and not a cmdlet that uses COM. Remove source from WinGetDev directory to ensure clean state. - TestCommon.RunAICLICommand("source remove", $"-n {Constants.TestSourceName}"); - } - [Test] public void GetWinGetSource() { From b149685fa9ec529d95f7e2e13c7494c516492b30 Mon Sep 17 00:00:00 2001 From: Ryan Fu Date: Mon, 14 Nov 2022 15:03:36 -0800 Subject: [PATCH 32/49] remove unnecessary changes --- src/AppInstallerCLIE2ETests/ShowCommand.cs | 2 +- src/AppInstallerCLIE2ETests/UpgradeCommand.cs | 2 +- .../ValidateCommand.cs | 2 +- .../WinGetUtil/WinGetUtilSQLiteIndex.cs | 22 +++++++++---------- .../AppInstallerCLIPackage.wapproj | 2 +- src/WinGetServer/WinGetServer.vcxproj | 2 +- .../WindowsPackageManager.h | 2 +- 7 files changed, 17 insertions(+), 17 deletions(-) diff --git a/src/AppInstallerCLIE2ETests/ShowCommand.cs b/src/AppInstallerCLIE2ETests/ShowCommand.cs index 614d57e8ba..69a65e6043 100644 --- a/src/AppInstallerCLIE2ETests/ShowCommand.cs +++ b/src/AppInstallerCLIE2ETests/ShowCommand.cs @@ -44,7 +44,7 @@ public void ShowWithNameMatch() [Test] public void ShowWithIDMatch() - { + { var result = TestCommon.RunAICLICommand("show", $"--id appinstallertest.testexampleinstaller"); Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); Assert.True(result.StdOut.Contains("Found TestExampleInstaller [AppInstallerTest.TestExampleInstaller]")); diff --git a/src/AppInstallerCLIE2ETests/UpgradeCommand.cs b/src/AppInstallerCLIE2ETests/UpgradeCommand.cs index 095017ee37..293fdc18b0 100644 --- a/src/AppInstallerCLIE2ETests/UpgradeCommand.cs +++ b/src/AppInstallerCLIE2ETests/UpgradeCommand.cs @@ -20,7 +20,7 @@ public void UpgradePortable() var result = TestCommon.RunAICLICommand("install", "AppInstallerTest.TestPortableExe -v 1.0.0.0"); Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode); Assert.True(result.StdOut.Contains("Successfully installed")); - + var result2 = TestCommon.RunAICLICommand("upgrade", $"{packageId} -v 2.0.0.0"); Assert.AreEqual(Constants.ErrorCode.S_OK, result2.ExitCode); Assert.True(result2.StdOut.Contains("Successfully installed")); diff --git a/src/AppInstallerCLIE2ETests/ValidateCommand.cs b/src/AppInstallerCLIE2ETests/ValidateCommand.cs index 0873892d60..1a8e45e54d 100644 --- a/src/AppInstallerCLIE2ETests/ValidateCommand.cs +++ b/src/AppInstallerCLIE2ETests/ValidateCommand.cs @@ -7,7 +7,7 @@ namespace AppInstallerCLIE2ETests public class ValidateCommand : BaseCommand { - [Test] + [Test] public void ValidateManifest() { var result = TestCommon.RunAICLICommand("validate", TestCommon.GetTestDataFile("Manifests\\TestValidManifest.yaml")); diff --git a/src/AppInstallerCLIE2ETests/WinGetUtil/WinGetUtilSQLiteIndex.cs b/src/AppInstallerCLIE2ETests/WinGetUtil/WinGetUtilSQLiteIndex.cs index 2be18fbe78..652d04ad97 100644 --- a/src/AppInstallerCLIE2ETests/WinGetUtil/WinGetUtilSQLiteIndex.cs +++ b/src/AppInstallerCLIE2ETests/WinGetUtil/WinGetUtilSQLiteIndex.cs @@ -21,8 +21,8 @@ public class WinGetUtilSQLiteIndex [SetUp] public void SetUp() - { - this.sqlitePath = TestCommon.GetRandomTestFile(".sql"); + { + this.sqlitePath = TestCommon.GetRandomTestFile(".sql"); } [Test] @@ -41,9 +41,9 @@ public void WinGetUtil_SQLiteIndex_UpdateManifest_Success() SQLiteIndex((indexHandle) => { // Add manifest - WinGetUtilWrapper.WinGetSQLiteIndexAddManifest(indexHandle, addManifestsFile_1, relativePath_1); - - // Update manifest + WinGetUtilWrapper.WinGetSQLiteIndexAddManifest(indexHandle, addManifestsFile_1, relativePath_1); + + // Update manifest WinGetUtilWrapper.WinGetSQLiteIndexUpdateManifest(indexHandle, updateManifestsFile_1, relativePath_1, out bool indexModified); Assert.True(indexModified); }); @@ -68,9 +68,9 @@ public void WinGetUtil_SQLiteIndex_RemoveManifest_Success() SQLiteIndex((indexHandle) => { // Add manifest - WinGetUtilWrapper.WinGetSQLiteIndexAddManifest(indexHandle, addManifestsFile_1, relativePath_1); - - // Remove manifest + WinGetUtilWrapper.WinGetSQLiteIndexAddManifest(indexHandle, addManifestsFile_1, relativePath_1); + + // Remove manifest WinGetUtilWrapper.WinGetSQLiteIndexRemoveManifest(indexHandle, addManifestsFile_1, relativePath_1); }); } @@ -130,9 +130,9 @@ private void SQLiteIndex(Action Execute) // Create WinGetUtilWrapper.WinGetSQLiteIndexCreate(sqlitePath, majorVersion, minorVersion, out IntPtr indexHandle); Assert.True(File.Exists(sqlitePath)); - Assert.AreNotEqual(IntPtr.Zero, indexHandle); - - // Execute provided function + Assert.AreNotEqual(IntPtr.Zero, indexHandle); + + // Execute provided function Execute(indexHandle); // Close diff --git a/src/AppInstallerCLIPackage/AppInstallerCLIPackage.wapproj b/src/AppInstallerCLIPackage/AppInstallerCLIPackage.wapproj index ee9c9e72b8..d659efee6b 100644 --- a/src/AppInstallerCLIPackage/AppInstallerCLIPackage.wapproj +++ b/src/AppInstallerCLIPackage/AppInstallerCLIPackage.wapproj @@ -54,7 +54,7 @@ 10.0.22000.0 10.0.17763.0 en-US - False + false ..\AppInstallerCLI\AppInstallerCLI.vcxproj diff --git a/src/WinGetServer/WinGetServer.vcxproj b/src/WinGetServer/WinGetServer.vcxproj index 14e3cdda59..e2bb9192f1 100644 --- a/src/WinGetServer/WinGetServer.vcxproj +++ b/src/WinGetServer/WinGetServer.vcxproj @@ -100,7 +100,7 @@ true true true - $(ProjectDir)..\WindowsPackageManager;$(ProjectDir)..\AppInstallerCommonCore;%(AdditionalIncludeDirectories); + $(ProjectDir)..\WindowsPackageManager;%(AdditionalIncludeDirectories) Windows diff --git a/src/WindowsPackageManager/WindowsPackageManager.h b/src/WindowsPackageManager/WindowsPackageManager.h index e9b47f77c7..bfef2841b8 100644 --- a/src/WindowsPackageManager/WindowsPackageManager.h +++ b/src/WindowsPackageManager/WindowsPackageManager.h @@ -28,7 +28,7 @@ extern "C" // Unregisters the server module class factories. WINDOWS_PACKAGE_MANAGER_API WindowsPackageManagerServerModuleUnregister(); - // Reports the hresult from WIL back to the Windows Package Manager dll for logging; + // Callback for logging the WIL result reported from the server. void WINDOWS_PACKAGE_MANAGER_API_CALLING_CONVENTION WindowsPackageManagerServerWilResultCallback(const wil::FailureInfo& info) noexcept; // Creates an out-of-proc instance for manual activation scenarios. From eabc286bd9e90c8c34e46f90687c419db9a610df Mon Sep 17 00:00:00 2001 From: Ryan Fu Date: Mon, 14 Nov 2022 17:37:54 -0800 Subject: [PATCH 33/49] fix powershell module e2e test --- src/AppInstallerCLIE2ETests/PowerShell/PowerShellModule.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/AppInstallerCLIE2ETests/PowerShell/PowerShellModule.cs b/src/AppInstallerCLIE2ETests/PowerShell/PowerShellModule.cs index 86294f4d9c..ff4bb06c69 100644 --- a/src/AppInstallerCLIE2ETests/PowerShell/PowerShellModule.cs +++ b/src/AppInstallerCLIE2ETests/PowerShell/PowerShellModule.cs @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. -namespace AppInstallerCLIE2ETests +namespace AppInstallerCLIE2ETests.PowerShell { using NUnit.Framework; using System; @@ -14,7 +14,6 @@ public class PowerShellModule [OneTimeSetUp] public void Setup() { - // Add-WinGetPackage is a function and not a cmdlet that uses COM. Add source to WinGetDev directly to ensure test source exists. TestCommon.RunAICLICommand("source add", $"-n {Constants.TestSourceName} {Constants.TestSourceUrl}"); } From d4c466f57cd54ed21e2002117a862dd4de8034e0 Mon Sep 17 00:00:00 2001 From: Ryan Fu Date: Tue, 15 Nov 2022 08:32:35 -0800 Subject: [PATCH 34/49] separate powershell tests --- azure-pipelines.yml | 8 +++++++- .../PowerShell/PowerShellModule.cs | 1 + 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 902c76957c..89ab288c80 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -252,7 +252,7 @@ jobs: parameters: title: "E2E Tests Packaged" isPackaged: true - filter: "TestCategory!=InProcess&TestCategory!=OutOfProcess" + filter: "TestCategory!=InProcess&TestCategory!=OutOfProcess&TestCategory!=PowerShell" - template: templates/e2e-test.template.yml parameters: @@ -266,6 +266,12 @@ jobs: isPackaged: true filter: "TestCategory=OutOfProcess" + - template: templates/e2e-test.template.yml + parameters: + title: "PowerShell Module E2E Tests" + isPackaged: false + filter: "TestCategory=PowerShell" + - task: CopyFiles@2 displayName: 'Copy E2E Tests Package Log to artifacts folder' inputs: diff --git a/src/AppInstallerCLIE2ETests/PowerShell/PowerShellModule.cs b/src/AppInstallerCLIE2ETests/PowerShell/PowerShellModule.cs index ff4bb06c69..16c72b4627 100644 --- a/src/AppInstallerCLIE2ETests/PowerShell/PowerShellModule.cs +++ b/src/AppInstallerCLIE2ETests/PowerShell/PowerShellModule.cs @@ -9,6 +9,7 @@ namespace AppInstallerCLIE2ETests.PowerShell /// /// Basic E2E tests for verifying that behavior of the PowerShell module cmdlets. /// + [Category("PowerShell")] public class PowerShellModule { [OneTimeSetUp] From 38a20af9d5b3c8a92fcc43062507cbf7f01d4663 Mon Sep 17 00:00:00 2001 From: Ryan Fu Date: Tue, 15 Nov 2022 14:36:14 -0800 Subject: [PATCH 35/49] Fix E2E tests --- azure-pipelines.yml | 1 + src/AppInstallerCLIE2ETests/Constants.cs | 2 + .../PowerShell/PowerShellModule.cs | 38 +++++++++++++++++++ src/AppInstallerCLIE2ETests/SetUpFixture.cs | 1 - 4 files changed, 41 insertions(+), 1 deletion(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 89ab288c80..ac4e1c9430 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -311,6 +311,7 @@ jobs: inputs: filePath: 'src\PowerShell\Microsoft.WinGet.Client\Copy-PlatformBinaries.ps1' arguments: '-Platform $(buildPlatform) -Configuration $(buildConfiguration) -OutDir $(artifactsDir)\PowerShell' + condition: always() - task: PublishPipelineArtifact@1 displayName: Publish Pipeline Artifacts diff --git a/src/AppInstallerCLIE2ETests/Constants.cs b/src/AppInstallerCLIE2ETests/Constants.cs index 9ac4f1e03c..6f9c467723 100644 --- a/src/AppInstallerCLIE2ETests/Constants.cs +++ b/src/AppInstallerCLIE2ETests/Constants.cs @@ -83,6 +83,8 @@ public class Constants public const string UninstallCmdlet = "Uninstall-WinGetPackage"; public const string UpdateCmdlet = "Update-WinGetPackage"; + public const string WinGetServerExeName = "WindowsPackageManagerServer"; + // Locations public const string LocalAppData = "LocalAppData"; diff --git a/src/AppInstallerCLIE2ETests/PowerShell/PowerShellModule.cs b/src/AppInstallerCLIE2ETests/PowerShell/PowerShellModule.cs index 16c72b4627..2af935c32a 100644 --- a/src/AppInstallerCLIE2ETests/PowerShell/PowerShellModule.cs +++ b/src/AppInstallerCLIE2ETests/PowerShell/PowerShellModule.cs @@ -5,6 +5,9 @@ namespace AppInstallerCLIE2ETests.PowerShell { using NUnit.Framework; using System; + using System.Diagnostics; + using System.Linq; + using System.Threading; /// /// Basic E2E tests for verifying that behavior of the PowerShell module cmdlets. @@ -18,6 +21,36 @@ public void Setup() TestCommon.RunAICLICommand("source add", $"-n {Constants.TestSourceName} {Constants.TestSourceUrl}"); } + [OneTimeTearDown] + public void TearDown() + { + // TODO: This is a workaround to an issue where the server takes longer than expected to terminate when + // running from the E2E tests. This can cause other E2E tests to fail when attempting to reset the test source. + if (IsRunning(Constants.WinGetServerExeName)) + { + // There should only be one WinGetServer process running at a time. + Process serverProcess = Process.GetProcessesByName(Constants.WinGetServerExeName).First(); + serverProcess.Kill(); + } + + TestCommon.RunAICLICommand("source remove", $"{Constants.TestSourceName}"); + } + + [Test] + public void AssertServerShutdownAfterExecution() + { + if (!Environment.Is64BitProcess) + { + return; + } + + TestCommon.RunPowerShellCommandWithResult(Constants.GetSourceCmdlet, $"-Name {Constants.TestSourceName}"); + + // Wait for 15 seconds and verify that WingetServer process is no longer running. + Thread.Sleep(15000); + Assert.IsTrue(!IsRunning(Constants.WinGetServerExeName), $"{Constants.WinGetServerExeName} failed to terminate after creating COM object."); + } + [Test] public void GetWinGetSource() { @@ -107,5 +140,10 @@ public void UpdateWinGetPackage() Assert.IsTrue(getResult.StdOut.Contains("2.0.0.0")); Assert.IsTrue(!string.IsNullOrEmpty(uninstallResult.StdOut)); } + + private bool IsRunning(string processName) + { + return Process.GetProcessesByName(processName).Length > 0; + } } } \ No newline at end of file diff --git a/src/AppInstallerCLIE2ETests/SetUpFixture.cs b/src/AppInstallerCLIE2ETests/SetUpFixture.cs index 583ab838f4..c73d2ebfa0 100644 --- a/src/AppInstallerCLIE2ETests/SetUpFixture.cs +++ b/src/AppInstallerCLIE2ETests/SetUpFixture.cs @@ -5,7 +5,6 @@ namespace AppInstallerCLIE2ETests { using Microsoft.Win32; using Newtonsoft.Json; - using Newtonsoft.Json.Linq; using NUnit.Framework; using System; using System.IO; From 6918fb9a699f7ea355947b1b3ff06e5b9a83c22b Mon Sep 17 00:00:00 2001 From: Ryan Fu Date: Tue, 15 Nov 2022 14:45:36 -0800 Subject: [PATCH 36/49] rejoin powershell tests --- azure-pipelines.yml | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index ac4e1c9430..1c25202102 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -252,7 +252,7 @@ jobs: parameters: title: "E2E Tests Packaged" isPackaged: true - filter: "TestCategory!=InProcess&TestCategory!=OutOfProcess&TestCategory!=PowerShell" + filter: "TestCategory!=InProcess&TestCategory!=OutOfProcess" - template: templates/e2e-test.template.yml parameters: @@ -266,12 +266,6 @@ jobs: isPackaged: true filter: "TestCategory=OutOfProcess" - - template: templates/e2e-test.template.yml - parameters: - title: "PowerShell Module E2E Tests" - isPackaged: false - filter: "TestCategory=PowerShell" - - task: CopyFiles@2 displayName: 'Copy E2E Tests Package Log to artifacts folder' inputs: From 3ff22d1f4713f65fda5811dd61d0fa751fe37c89 Mon Sep 17 00:00:00 2001 From: Ryan Fu Date: Wed, 16 Nov 2022 11:14:57 -0800 Subject: [PATCH 37/49] fix binskim --- .../PowerShell/PowerShellModule.cs | 34 ++++++++++++++++--- src/PureLib/PureLib.vcxproj | 12 +++++++ 2 files changed, 42 insertions(+), 4 deletions(-) diff --git a/src/AppInstallerCLIE2ETests/PowerShell/PowerShellModule.cs b/src/AppInstallerCLIE2ETests/PowerShell/PowerShellModule.cs index 2af935c32a..5e74c2cbd1 100644 --- a/src/AppInstallerCLIE2ETests/PowerShell/PowerShellModule.cs +++ b/src/AppInstallerCLIE2ETests/PowerShell/PowerShellModule.cs @@ -45,10 +45,13 @@ public void AssertServerShutdownAfterExecution() } TestCommon.RunPowerShellCommandWithResult(Constants.GetSourceCmdlet, $"-Name {Constants.TestSourceName}"); - - // Wait for 15 seconds and verify that WingetServer process is no longer running. - Thread.Sleep(15000); - Assert.IsTrue(!IsRunning(Constants.WinGetServerExeName), $"{Constants.WinGetServerExeName} failed to terminate after creating COM object."); + + Assert.IsTrue(IsRunning(Constants.WinGetServerExeName), $"{Constants.WinGetServerExeName} is not running."); + Process serverProcess = Process.GetProcessesByName(Constants.WinGetServerExeName).First(); + + // Wait a maximum of 30 seconds for the server process to exit. + bool serverProcessExit = serverProcess.WaitForExit(30000); + Assert.IsTrue(serverProcessExit, $"{Constants.WinGetServerExeName} failed to terminate after creating COM object."); } [Test] @@ -141,6 +144,29 @@ public void UpdateWinGetPackage() Assert.IsTrue(!string.IsNullOrEmpty(uninstallResult.StdOut)); } + /// + /// There is a known issue where the server takes an abnormally long time to terminate after the E2E test pwsh processes finish execution. + /// This test verifies that the server does indeed terminate within 5 minutes after running all of the cmdlets. + /// Commented out to reduce the overall duration of the build pipeline. + /// + // [Test] + public void VerifyServerTermination() + { + TestCommon.RunPowerShellCommandWithResult(Constants.GetSourceCmdlet, $"-Name {Constants.TestSourceName}"); + TestCommon.RunPowerShellCommandWithResult(Constants.FindCmdlet, $"-Id {Constants.ExeInstallerPackageId}"); + TestCommon.RunPowerShellCommandWithResult(Constants.InstallCmdlet, $"-Id {Constants.ExeInstallerPackageId} -Version 1.0.0.0"); + TestCommon.RunPowerShellCommandWithResult(Constants.UpdateCmdlet, $"-Id {Constants.ExeInstallerPackageId}"); + TestCommon.RunPowerShellCommandWithResult(Constants.GetCmdlet, $"-Id {Constants.ExeInstallerPackageId}"); + TestCommon.RunPowerShellCommandWithResult(Constants.UninstallCmdlet, $"-Id {Constants.ExeInstallerPackageId}"); + + Assert.IsTrue(IsRunning(Constants.WinGetServerExeName), $"{Constants.WinGetServerExeName} is not running."); + Process serverProcess = Process.GetProcessesByName(Constants.WinGetServerExeName).First(); + + // Wait a maximum of 5 minutes for the server process to exit. + bool serverProcessExit = serverProcess.WaitForExit(300000); + Assert.IsTrue(serverProcessExit, $"{Constants.WinGetServerExeName} failed to terminate after creating COM object."); + } + private bool IsRunning(string processName) { return Process.GetProcessesByName(processName).Length > 0; diff --git a/src/PureLib/PureLib.vcxproj b/src/PureLib/PureLib.vcxproj index ac61fa317d..e9eadaf33e 100644 --- a/src/PureLib/PureLib.vcxproj +++ b/src/PureLib/PureLib.vcxproj @@ -52,6 +52,18 @@ v143 Unicode + + Spectre + + + Spectre + + + Spectre + + + Spectre + From b66ebb72cd04f28b8f46f99697f7df2984354006 Mon Sep 17 00:00:00 2001 From: Ryan Fu Date: Tue, 22 Nov 2022 11:50:53 -0800 Subject: [PATCH 38/49] Address PR comments --- .../PowerShell/PowerShellModule.cs | 4 +- .../WinGetServerManualActivation_Client.cpp | 64 +++++++++++-------- src/WinGetServer/WinMain.cpp | 11 +++- src/WindowsPackageManager/main.cpp | 7 +- 4 files changed, 54 insertions(+), 32 deletions(-) diff --git a/src/AppInstallerCLIE2ETests/PowerShell/PowerShellModule.cs b/src/AppInstallerCLIE2ETests/PowerShell/PowerShellModule.cs index 5e74c2cbd1..22b4161c44 100644 --- a/src/AppInstallerCLIE2ETests/PowerShell/PowerShellModule.cs +++ b/src/AppInstallerCLIE2ETests/PowerShell/PowerShellModule.cs @@ -10,11 +10,13 @@ namespace AppInstallerCLIE2ETests.PowerShell using System.Threading; /// - /// Basic E2E tests for verifying that behavior of the PowerShell module cmdlets. + /// Basic E2E smoke tests for verifying the behavior of the PowerShell module cmdlets. /// [Category("PowerShell")] public class PowerShellModule { + // TODO: Consider using Pester framework for conducting more extensive PowerShell module tests. + [OneTimeSetUp] public void Setup() { diff --git a/src/WinGetServer/WinGetServerManualActivation_Client.cpp b/src/WinGetServer/WinGetServerManualActivation_Client.cpp index 65f85749a3..b0a844724c 100644 --- a/src/WinGetServer/WinGetServerManualActivation_Client.cpp +++ b/src/WinGetServer/WinGetServerManualActivation_Client.cpp @@ -15,9 +15,9 @@ #include #if USE_PROD_WINGET_SERVER -const std::wstring_view s_ServerExePath = L"\\Microsoft\\WindowsApps\\Microsoft.DesktopAppInstaller_8wekyb3d8bbwe\\WindowsPackageManagerServer.exe"; +const std::wstring_view s_ServerExePath = L"Microsoft\\WindowsApps\\Microsoft.DesktopAppInstaller_8wekyb3d8bbwe\\WindowsPackageManagerServer.exe"; #else -const std::wstring_view s_ServerExePath = L"\\Microsoft\\WindowsApps\\WinGetDevCLI_8wekyb3d8bbwe\\WindowsPackageManagerServerDev.exe"; +const std::wstring_view s_ServerExePath = L"Microsoft\\WindowsApps\\WinGetDevCLI_8wekyb3d8bbwe\\WindowsPackageManagerServerDev.exe"; #endif _Must_inspect_result_ @@ -67,21 +67,29 @@ void InitializeRpcBinding() HRESULT LaunchWinGetServerWithManualActivation() { const std::filesystem::path& localAppDataPath = GetKnownFolderPath(FOLDERID_LocalAppData); - std::wstring serverExePath = std::wstring{ localAppDataPath } + std::wstring{ s_ServerExePath } + L" --manualActivation"; + const std::filesystem::path& serverExePath = localAppDataPath / s_ServerExePath; + std::wstring commandLineInput = std::wstring{ serverExePath } + L" --manualActivation"; STARTUPINFO info = { sizeof(info) }; PROCESS_INFORMATION processInfo; - if (CreateProcessW(NULL, &serverExePath[0], NULL, NULL, FALSE, 0, NULL, NULL, &info, &processInfo)) + if (!CreateProcessW(NULL, &commandLineInput[0], NULL, NULL, FALSE, 0, NULL, NULL, &info, &processInfo)) { - WaitForSingleObject(processInfo.hThread, 500); - CloseHandle(processInfo.hProcess); - CloseHandle(processInfo.hThread); - return S_OK; + return HRESULT_FROM_WIN32(GetLastError()); } - else + + // Wait for manual reset event from server before proceeding with COM activation. + HANDLE eventHandle = CreateEventW(NULL, TRUE, FALSE, L"WinGetServerStartEvent"); + RETURN_HR_IF_NULL(PEER_E_EVENT_HANDLE_NOT_FOUND, eventHandle); + + DWORD waitResult = WaitForSingleObject(eventHandle, INFINITE); + if (waitResult != 0) { - return HRESULT_FROM_WIN32(GetLastError()); + return ERROR_SERVICE_NEVER_STARTED; } + + CloseHandle(processInfo.hProcess); + CloseHandle(processInfo.hThread); + return S_OK; } HRESULT CallCreateInstance(const CLSID* clsid, const IID* iid, UINT32 flags, UINT32* bufferByteCount, BYTE** buffer) @@ -99,13 +107,12 @@ HRESULT CallCreateInstance(const CLSID* clsid, const IID* iid, UINT32 flags, UIN return S_OK; } -HRESULT LaunchServerAndCreateInstance(const CLSID* clsid, const IID* iid, UINT32 flags, void** out) +HRESULT CreateComInstance(const CLSID* clsid, const IID* iid, UINT32 flags, void** out) { UINT32 bufferByteCount = 0; BYTE* buffer = nullptr; UniqueMidl bufferPtr; - RETURN_IF_FAILED(LaunchWinGetServerWithManualActivation()); RETURN_IF_FAILED(CallCreateInstance(clsid, iid, flags, &bufferByteCount, &buffer)); bufferPtr.reset(buffer); @@ -127,24 +134,31 @@ extern "C" HRESULT WinGetServerManualActivation_CreateInstance(const CLSID* clsi RETURN_HR_IF_NULL(E_POINTER, iid); RETURN_HR_IF_NULL(E_POINTER, out); - if (WinGetServerManualActivation_IfHandle == NULL) + static std::once_flag rpcBindingOnce; + try { - static std::once_flag rpcBindingOnce; - try - { - std::call_once(rpcBindingOnce, InitializeRpcBinding); - } - CATCH_RETURN(); + std::call_once(rpcBindingOnce, InitializeRpcBinding); } + CATCH_RETURN(); - HRESULT result; - - for (int i = 0; i < 3; i++) + HRESULT result = CreateComInstance(clsid, iid, flags, out); + if (FAILED(result)) { - result = LaunchServerAndCreateInstance(clsid, iid, flags, out); - if (SUCCEEDED(result) || result == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)) + for (int i = 0; i < 3; i++) { - break; + result = LaunchWinGetServerWithManualActivation(); + if (result == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)) + { + break; + } + + result = CreateComInstance(clsid, iid, flags, out); + if (SUCCEEDED(result)) + { + break; + } + + Sleep(200); } } diff --git a/src/WinGetServer/WinMain.cpp b/src/WinGetServer/WinMain.cpp index a3e44a1fd1..30261461ea 100644 --- a/src/WinGetServer/WinMain.cpp +++ b/src/WinGetServer/WinMain.cpp @@ -34,6 +34,9 @@ HRESULT WindowsPackageManagerServerInitializeRPCServer() RPC_STATUS status = RpcServerUseProtseqEpA(GetUCharString("ncacn_np"), RPC_C_PROTSEQ_MAX_REQS_DEFAULT, GetUCharString(endpoint), nullptr); RETURN_HR_IF(HRESULT_FROM_WIN32(status), status != RPC_S_OK); + // The goal of this security descriptor is to restrict RPC server access only to the user in admin mode. + // (ML;;NW;;;HI) specifies a high mandatory integrity level (requires admin). + // (A;;GA;;;UserSID) specifies access only for the user with the user SID (i.e. self). wil::unique_hlocal_security_descriptor securityDescriptor; std::string securityDescriptorString = "S:(ML;;NW;;;HI)D:(A;;GA;;;" + userSID + ")"; RETURN_LAST_ERROR_IF(!ConvertStringSecurityDescriptorToSecurityDescriptorA(securityDescriptorString.c_str(), SDDL_REVISION_1, &securityDescriptor, nullptr)); @@ -148,9 +151,15 @@ int __stdcall wWinMain(_In_ HINSTANCE, _In_opt_ HINSTANCE, _In_ LPWSTR cmdLine, RETURN_IF_FAILED(WindowsPackageManagerServerInitializeRPCServer()); } - _comServerExitEvent.wait(); + // Manual reset event to notify the client that the server is available. + HANDLE eventHandle = CreateEventW(NULL, TRUE, FALSE, L"WinGetServerStartEvent"); + RETURN_HR_IF_NULL(PEER_E_EVENT_HANDLE_NOT_FOUND, eventHandle); + SetEvent(eventHandle); + + _comServerExitEvent.wait(); RETURN_IF_FAILED(WindowsPackageManagerServerModuleUnregister()); + ResetEvent(eventHandle); } CATCH_RETURN() diff --git a/src/WindowsPackageManager/main.cpp b/src/WindowsPackageManager/main.cpp index a0835fc4b9..b0f4185d9f 100644 --- a/src/WindowsPackageManager/main.cpp +++ b/src/WindowsPackageManager/main.cpp @@ -12,6 +12,7 @@ #include #include #include +#include #include using namespace winrt::Microsoft::Management::Deployment; @@ -62,11 +63,7 @@ extern "C" void WINDOWS_PACKAGE_MANAGER_API_CALLING_CONVENTION WindowsPackageManagerServerWilResultCallback(const wil::FailureInfo& failure) noexcept try { - AICLI_LOG(Fail, Error, << [&]() { - wchar_t message[2048]; - wil::GetFailureLogString(message, ARRAYSIZE(message), failure); - return AppInstaller::Utility::ConvertToUTF8(message); - }()); + AppInstaller::Logging::Telemetry().LogFailure(failure); } CATCH_LOG(); From 6f4885b85f27fa715d8a34b742f6c7be41cfea71 Mon Sep 17 00:00:00 2001 From: Ryan Fu Date: Tue, 22 Nov 2022 13:03:39 -0800 Subject: [PATCH 39/49] fix path in project file --- .../UndockedRegFreeWinRT.vcxproj | 20 +++++++++---------- .../UndockedRegFreeWinRT.vcxproj.filters | 8 ++++---- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/Xlang/UndockedRegFreeWinRT/src/UndockedRegFreeWinRT/UndockedRegFreeWinRT/UndockedRegFreeWinRT.vcxproj b/src/Xlang/UndockedRegFreeWinRT/src/UndockedRegFreeWinRT/UndockedRegFreeWinRT/UndockedRegFreeWinRT.vcxproj index 3c8aec0245..d29cb977e5 100644 --- a/src/Xlang/UndockedRegFreeWinRT/src/UndockedRegFreeWinRT/UndockedRegFreeWinRT/UndockedRegFreeWinRT.vcxproj +++ b/src/Xlang/UndockedRegFreeWinRT/src/UndockedRegFreeWinRT/UndockedRegFreeWinRT/UndockedRegFreeWinRT.vcxproj @@ -109,7 +109,7 @@ Windows true false - comsuppw.lib;shlwapi.lib;xmllite.lib;runtimeobject.lib;Pathcch.lib;Rometadata.lib;Rpcrt4.lib;Shell32.lib;Advapi32.lib + comsuppw.lib;shlwapi.lib;xmllite.lib;runtimeobject.lib;Pathcch.lib;Rometadata.lib;Rpcrt4.lib;Shell32.lib;Advapi32.lib winrtact.def @@ -123,14 +123,14 @@ pch.h $(PorjectDir)\..\detours\include;%(AdditionalUsingDirectories) stdcpp17 - - + + Windows true false - comsuppw.lib;shlwapi.lib;xmllite.lib;runtimeobject.lib;Pathcch.lib;Rometadata.lib;Rpcrt4.lib;Shell32.lib;Advapi32.lib + comsuppw.lib;shlwapi.lib;xmllite.lib;runtimeobject.lib;Pathcch.lib;Rometadata.lib;Rpcrt4.lib;Shell32.lib;Advapi32.lib winrtact.def @@ -153,7 +153,7 @@ true true false - comsuppw.lib;shlwapi.lib;xmllite.lib;runtimeobject.lib;Pathcch.lib;Rometadata.lib;Rpcrt4.lib;Shell32.lib;Advapi32.lib + comsuppw.lib;shlwapi.lib;xmllite.lib;runtimeobject.lib;Pathcch.lib;Rometadata.lib;Rpcrt4.lib;Shell32.lib;Advapi32.lib winrtact.def @@ -176,7 +176,7 @@ true true false - comsuppw.lib;shlwapi.lib;xmllite.lib;runtimeobject.lib;Pathcch.lib;Rometadata.lib;Rpcrt4.lib;Shell32.lib;Advapi32.lib + comsuppw.lib;shlwapi.lib;xmllite.lib;runtimeobject.lib;Pathcch.lib;Rometadata.lib;Rpcrt4.lib;Shell32.lib;Advapi32.lib winrtact.def @@ -186,10 +186,10 @@ - - - - + + + + diff --git a/src/Xlang/UndockedRegFreeWinRT/src/UndockedRegFreeWinRT/UndockedRegFreeWinRT/UndockedRegFreeWinRT.vcxproj.filters b/src/Xlang/UndockedRegFreeWinRT/src/UndockedRegFreeWinRT/UndockedRegFreeWinRT/UndockedRegFreeWinRT.vcxproj.filters index 1c48914b19..6062b1002e 100644 --- a/src/Xlang/UndockedRegFreeWinRT/src/UndockedRegFreeWinRT/UndockedRegFreeWinRT/UndockedRegFreeWinRT.vcxproj.filters +++ b/src/Xlang/UndockedRegFreeWinRT/src/UndockedRegFreeWinRT/UndockedRegFreeWinRT/UndockedRegFreeWinRT.vcxproj.filters @@ -34,13 +34,13 @@ Source Files - + Source Files - + Source Files - + Source Files @@ -51,7 +51,7 @@ Header Files - + Header Files From 3c1980281fe9ab99fa4ce632d6d7c3a4b7c5d2ba Mon Sep 17 00:00:00 2001 From: Ryan Fu Date: Mon, 28 Nov 2022 11:28:41 -0800 Subject: [PATCH 40/49] respond to PR feedback --- src/AppInstallerCLIE2ETests/Constants.cs | 2 +- .../PowerShell/PowerShellModule.cs | 40 +++---- .../Common/ErrorCode.cs | 2 +- .../Helpers/ComObjectFactory.cs | 6 +- src/WinGetServer/Utils.cpp | 4 +- src/WinGetServer/WinGetServer.idl | 1 - src/WinGetServer/WinGetServer.vcxproj | 108 +----------------- .../WinGetServerManualActivation_Client.cpp | 39 +++---- src/WinGetServer/WinMain.cpp | 21 ++-- src/WindowsPackageManager/Source.def | 2 +- .../WindowsPackageManager.h | 4 +- .../WindowsPackageManager.vcxproj | 16 +-- src/WindowsPackageManager/main.cpp | 10 +- .../UndockedRegFreeWinRT.vcxproj | 2 - 14 files changed, 68 insertions(+), 189 deletions(-) diff --git a/src/AppInstallerCLIE2ETests/Constants.cs b/src/AppInstallerCLIE2ETests/Constants.cs index 95dc46779b..6cd28185c0 100644 --- a/src/AppInstallerCLIE2ETests/Constants.cs +++ b/src/AppInstallerCLIE2ETests/Constants.cs @@ -83,7 +83,7 @@ public class Constants public const string UninstallCmdlet = "Uninstall-WinGetPackage"; public const string UpdateCmdlet = "Update-WinGetPackage"; - public const string WinGetServerExeName = "WindowsPackageManagerServer"; + public const string WindowsPackageManagerServer = "WindowsPackageManagerServer"; // Locations public const string LocalAppData = "LocalAppData"; diff --git a/src/AppInstallerCLIE2ETests/PowerShell/PowerShellModule.cs b/src/AppInstallerCLIE2ETests/PowerShell/PowerShellModule.cs index 22b4161c44..a45eb99239 100644 --- a/src/AppInstallerCLIE2ETests/PowerShell/PowerShellModule.cs +++ b/src/AppInstallerCLIE2ETests/PowerShell/PowerShellModule.cs @@ -11,6 +11,7 @@ namespace AppInstallerCLIE2ETests.PowerShell /// /// Basic E2E smoke tests for verifying the behavior of the PowerShell module cmdlets. + /// Running the x86 PowerShell Module requires PowerShell Core (x86). These tests currently only target PowerShell Core (x64) /// [Category("PowerShell")] public class PowerShellModule @@ -28,10 +29,10 @@ public void TearDown() { // TODO: This is a workaround to an issue where the server takes longer than expected to terminate when // running from the E2E tests. This can cause other E2E tests to fail when attempting to reset the test source. - if (IsRunning(Constants.WinGetServerExeName)) + if (IsRunning(Constants.WindowsPackageManagerServer)) { // There should only be one WinGetServer process running at a time. - Process serverProcess = Process.GetProcessesByName(Constants.WinGetServerExeName).First(); + Process serverProcess = Process.GetProcessesByName(Constants.WindowsPackageManagerServer).First(); serverProcess.Kill(); } @@ -48,25 +49,24 @@ public void AssertServerShutdownAfterExecution() TestCommon.RunPowerShellCommandWithResult(Constants.GetSourceCmdlet, $"-Name {Constants.TestSourceName}"); - Assert.IsTrue(IsRunning(Constants.WinGetServerExeName), $"{Constants.WinGetServerExeName} is not running."); - Process serverProcess = Process.GetProcessesByName(Constants.WinGetServerExeName).First(); + Assert.IsTrue(IsRunning(Constants.WindowsPackageManagerServer), $"{Constants.WindowsPackageManagerServer} is not running."); + Process serverProcess = Process.GetProcessesByName(Constants.WindowsPackageManagerServer).First(); // Wait a maximum of 30 seconds for the server process to exit. bool serverProcessExit = serverProcess.WaitForExit(30000); - Assert.IsTrue(serverProcessExit, $"{Constants.WinGetServerExeName} failed to terminate after creating COM object."); + Assert.IsTrue(serverProcessExit, $"{Constants.WindowsPackageManagerServer} failed to terminate after creating COM object."); } [Test] public void GetWinGetSource() { - // Running the x86 PowerShell Module requires PowerShell Core (x86). The tests currently only target PowerShell Core (x64) if (!Environment.Is64BitProcess) { return; } var getSourceResult = TestCommon.RunPowerShellCommandWithResult(Constants.GetSourceCmdlet, $"-Name {Constants.TestSourceName}"); - Assert.IsTrue(getSourceResult.ExitCode == 0, $"ExitCode: {getSourceResult.ExitCode} Failed with the following output: {getSourceResult.StdOut}, {getSourceResult.StdErr}"); + Assert.AreEqual(Constants.ErrorCode.S_OK, getSourceResult.ExitCode, $"ExitCode: {getSourceResult.ExitCode} Failed with the following output: {getSourceResult.StdOut}, {getSourceResult.StdErr}"); Assert.IsTrue(getSourceResult.StdOut.Contains($"{Constants.TestSourceName}")); } @@ -79,7 +79,7 @@ public void FindWinGetPackage() } var result = TestCommon.RunPowerShellCommandWithResult(Constants.FindCmdlet, $"-Id {Constants.ExeInstallerPackageId}"); - Assert.IsTrue(result.ExitCode == 0, $"ExitCode: {result.ExitCode} Failed with the following output: {result.StdOut}; {result.StdErr}"); + Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode, $"ExitCode: {result.ExitCode} Failed with the following output: {result.StdOut}; {result.StdErr}"); Assert.IsTrue(result.StdOut.Contains("TestExeInstaller")); } @@ -95,9 +95,9 @@ public void GetWinGetPackage() var getResult = TestCommon.RunPowerShellCommandWithResult(Constants.GetCmdlet, $"-Id {Constants.MsiInstallerPackageId}"); var uninstallResult = TestCommon.RunPowerShellCommandWithResult(Constants.UninstallCmdlet, $"-Id {Constants.MsiInstallerPackageId}"); - Assert.IsTrue(installResult.ExitCode == 0, $"ExitCode: {installResult.ExitCode}; Failed with the following output: {installResult.StdOut}; {installResult.StdErr}"); - Assert.IsTrue(getResult.ExitCode == 0, $"Failed with the following output: {getResult.StdOut}"); - Assert.IsTrue(uninstallResult.ExitCode == 0, $"Failed with the following output: {uninstallResult.StdOut}"); + Assert.AreEqual(Constants.ErrorCode.S_OK, installResult.ExitCode, $"ExitCode: {installResult.ExitCode}; Failed with the following output: {installResult.StdOut}; {installResult.StdErr}"); + Assert.AreEqual(Constants.ErrorCode.S_OK, getResult.ExitCode, $"Failed with the following output: {getResult.StdOut}"); + Assert.AreEqual(Constants.ErrorCode.S_OK, uninstallResult.ExitCode, $"Failed with the following output: {uninstallResult.StdOut}"); Assert.IsTrue(!string.IsNullOrEmpty(installResult.StdOut)); Assert.IsTrue(getResult.StdOut.Contains("TestMsiInstaller")); @@ -115,8 +115,8 @@ public void InstallWinGetPackage() var installResult = TestCommon.RunPowerShellCommandWithResult(Constants.InstallCmdlet, $"-Id {Constants.ExeInstallerPackageId}"); var uninstallResult = TestCommon.RunPowerShellCommandWithResult(Constants.UninstallCmdlet, $"-Id {Constants.ExeInstallerPackageId}"); - Assert.IsTrue(installResult.ExitCode == 0, $"ExitCode: {installResult.ExitCode}; Failed with the following output: {installResult.StdOut}; {installResult.StdErr}"); - Assert.IsTrue(uninstallResult.ExitCode == 0, $"Failed with the following output: {uninstallResult.StdOut}"); + Assert.AreEqual(Constants.ErrorCode.S_OK, installResult.ExitCode, $"ExitCode: {installResult.ExitCode}; Failed with the following output: {installResult.StdOut}; {installResult.StdErr}"); + Assert.AreEqual(Constants.ErrorCode.S_OK, uninstallResult.ExitCode, $"Failed with the following output: {uninstallResult.StdOut}"); Assert.IsTrue(!string.IsNullOrEmpty(installResult.StdOut)); Assert.IsTrue(!string.IsNullOrEmpty(uninstallResult.StdOut)); @@ -135,10 +135,10 @@ public void UpdateWinGetPackage() var getResult = TestCommon.RunPowerShellCommandWithResult(Constants.GetCmdlet, $"-Id {Constants.ExeInstallerPackageId}"); var uninstallResult = TestCommon.RunPowerShellCommandWithResult(Constants.UninstallCmdlet, $"-Id {Constants.ExeInstallerPackageId}"); - Assert.IsTrue(installResult.ExitCode == 0, $"Failed with the following output: {installResult.StdOut}"); - Assert.IsTrue(updateResult.ExitCode == 0, $"Failed with the following output: {updateResult.StdOut}"); - Assert.IsTrue(getResult.ExitCode == 0, $"Failed with the following output: {getResult.StdOut}"); - Assert.IsTrue(uninstallResult.ExitCode == 0, $"Failed with the following output: {uninstallResult.StdOut}"); + Assert.AreEqual(Constants.ErrorCode.S_OK, installResult.ExitCode, $"Failed with the following output: {installResult.StdOut}"); + Assert.AreEqual(Constants.ErrorCode.S_OK, updateResult.ExitCode, $"Failed with the following output: {updateResult.StdOut}"); + Assert.AreEqual(Constants.ErrorCode.S_OK, getResult.ExitCode, $"Failed with the following output: {getResult.StdOut}"); + Assert.AreEqual(Constants.ErrorCode.S_OK, uninstallResult.ExitCode, $"Failed with the following output: {uninstallResult.StdOut}"); Assert.IsTrue(!string.IsNullOrEmpty(installResult.StdOut)); Assert.IsTrue(!string.IsNullOrEmpty(updateResult.StdOut)); @@ -161,12 +161,12 @@ public void VerifyServerTermination() TestCommon.RunPowerShellCommandWithResult(Constants.GetCmdlet, $"-Id {Constants.ExeInstallerPackageId}"); TestCommon.RunPowerShellCommandWithResult(Constants.UninstallCmdlet, $"-Id {Constants.ExeInstallerPackageId}"); - Assert.IsTrue(IsRunning(Constants.WinGetServerExeName), $"{Constants.WinGetServerExeName} is not running."); - Process serverProcess = Process.GetProcessesByName(Constants.WinGetServerExeName).First(); + Assert.IsTrue(IsRunning(Constants.WindowsPackageManagerServer), $"{Constants.WindowsPackageManagerServer} is not running."); + Process serverProcess = Process.GetProcessesByName(Constants.WindowsPackageManagerServer).First(); // Wait a maximum of 5 minutes for the server process to exit. bool serverProcessExit = serverProcess.WaitForExit(300000); - Assert.IsTrue(serverProcessExit, $"{Constants.WinGetServerExeName} failed to terminate after creating COM object."); + Assert.IsTrue(serverProcessExit, $"{Constants.WindowsPackageManagerServer} failed to terminate after creating COM object."); } private bool IsRunning(string processName) diff --git a/src/PowerShell/Microsoft.WinGet.Client/Common/ErrorCode.cs b/src/PowerShell/Microsoft.WinGet.Client/Common/ErrorCode.cs index 09cdd61e9e..9ee0793871 100644 --- a/src/PowerShell/Microsoft.WinGet.Client/Common/ErrorCode.cs +++ b/src/PowerShell/Microsoft.WinGet.Client/Common/ErrorCode.cs @@ -11,6 +11,6 @@ namespace Microsoft.WinGet.Client.Common /// public class ErrorCode { - public const int ERROR_FILE_NOT_FOUND = unchecked((int)0x80070002); + public const int FILE_NOT_FOUND = unchecked((int)0x80070002); } } diff --git a/src/PowerShell/Microsoft.WinGet.Client/Helpers/ComObjectFactory.cs b/src/PowerShell/Microsoft.WinGet.Client/Helpers/ComObjectFactory.cs index a774ece544..35d80c9070 100644 --- a/src/PowerShell/Microsoft.WinGet.Client/Helpers/ComObjectFactory.cs +++ b/src/PowerShell/Microsoft.WinGet.Client/Helpers/ComObjectFactory.cs @@ -106,15 +106,13 @@ public virtual PackageMatchFilter CreatePackageMatchFilter() private static T Create(Type type, in Guid iid) { - object instance; + object instance = null; if (Utilities.ExecutingAsAdministrator) { - instance = null; - int hr = WinGetServerManualActivation_CreateInstance(type.GUID, iid, 0, out instance); - if (hr == ErrorCode.ERROR_FILE_NOT_FOUND) + if (hr == ErrorCode.FILE_NOT_FOUND) { throw new Exception(Utilities.ResourceManager.GetString("WinGetPackageNotInstalled")); } diff --git a/src/WinGetServer/Utils.cpp b/src/WinGetServer/Utils.cpp index 044f5b272a..57af9414d8 100644 --- a/src/WinGetServer/Utils.cpp +++ b/src/WinGetServer/Utils.cpp @@ -27,9 +27,9 @@ std::string GetUserSID() PTOKEN_USER pTokenUser = reinterpret_cast(&buffer[0]); THROW_LAST_ERROR_IF(!GetTokenInformation(hToken, TokenUser, pTokenUser, dwBufferSize, &dwBufferSize)); - THROW_LAST_ERROR_IF(!IsValidSid(pTokenUser->User.Sid)); + THROW_HR_IF(CO_E_INVALIDSID, !IsValidSid(pTokenUser->User.Sid)); LPSTR pszSID = NULL; - ConvertSidToStringSidA(pTokenUser->User.Sid, &pszSID); + THROW_LAST_ERROR_IF(!ConvertSidToStringSidA(pTokenUser->User.Sid, &pszSID)); return std::string{ pszSID }; } \ No newline at end of file diff --git a/src/WinGetServer/WinGetServer.idl b/src/WinGetServer/WinGetServer.idl index 87f8a7a42c..b96ea9617f 100644 --- a/src/WinGetServer/WinGetServer.idl +++ b/src/WinGetServer/WinGetServer.idl @@ -10,7 +10,6 @@ interface WinGetServerManualActivation HRESULT CreateInstance( [in] GUID clsid, [in] GUID iid, - [in] UINT32 flags, [out, ref] UINT32* pcbBuffer, [out, ref, size_is(, *pcbBuffer)] BYTE** ppBuffer ); diff --git a/src/WinGetServer/WinGetServer.vcxproj b/src/WinGetServer/WinGetServer.vcxproj index e2bb9192f1..c2b7f54932 100644 --- a/src/WinGetServer/WinGetServer.vcxproj +++ b/src/WinGetServer/WinGetServer.vcxproj @@ -152,14 +152,7 @@ - true - true - true - true - true - true - true - true + true @@ -177,102 +170,9 @@ - false - false - false - false - false - false - false - false - Stub - Stub - Stub - Stub - Stub - Stub - Stub - Stub - Stub - Stub - Stub - Stub - Stub - Stub - Stub - Stub - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - true - true - true - true - true - true - true - true + false + Stub + true diff --git a/src/WinGetServer/WinGetServerManualActivation_Client.cpp b/src/WinGetServer/WinGetServerManualActivation_Client.cpp index b0a844724c..b08577143e 100644 --- a/src/WinGetServer/WinGetServerManualActivation_Client.cpp +++ b/src/WinGetServer/WinGetServerManualActivation_Client.cpp @@ -72,33 +72,24 @@ HRESULT LaunchWinGetServerWithManualActivation() STARTUPINFO info = { sizeof(info) }; PROCESS_INFORMATION processInfo; - if (!CreateProcessW(NULL, &commandLineInput[0], NULL, NULL, FALSE, 0, NULL, NULL, &info, &processInfo)) - { - return HRESULT_FROM_WIN32(GetLastError()); - } + RETURN_LAST_ERROR_IF(!CreateProcessW(NULL, &commandLineInput[0], NULL, NULL, FALSE, 0, NULL, NULL, &info, &processInfo)); // Wait for manual reset event from server before proceeding with COM activation. - HANDLE eventHandle = CreateEventW(NULL, TRUE, FALSE, L"WinGetServerStartEvent"); - RETURN_HR_IF_NULL(PEER_E_EVENT_HANDLE_NOT_FOUND, eventHandle); - - DWORD waitResult = WaitForSingleObject(eventHandle, INFINITE); - if (waitResult != 0) - { - return ERROR_SERVICE_NEVER_STARTED; - } + wil::unique_event_watcher eventWatcher; + wil::unique_event manualResetEvent; + manualResetEvent.open(L"WinGetServerStartEvent"); + manualResetEvent.wait(); - CloseHandle(processInfo.hProcess); - CloseHandle(processInfo.hThread); return S_OK; } -HRESULT CallCreateInstance(const CLSID* clsid, const IID* iid, UINT32 flags, UINT32* bufferByteCount, BYTE** buffer) +HRESULT CallCreateInstance(REFCLSID rclsid, REFIID riid, UINT32* bufferByteCount, BYTE** buffer) { RpcTryExcept { - RETURN_IF_FAILED(CreateInstance(*clsid, *iid, flags, bufferByteCount, buffer)); + RETURN_IF_FAILED(CreateInstance(rclsid, riid, bufferByteCount, buffer)); } - RpcExcept(1) + RpcExcept(1) { return HRESULT_FROM_WIN32(RpcExceptionCode()); } @@ -107,13 +98,13 @@ HRESULT CallCreateInstance(const CLSID* clsid, const IID* iid, UINT32 flags, UIN return S_OK; } -HRESULT CreateComInstance(const CLSID* clsid, const IID* iid, UINT32 flags, void** out) +HRESULT CreateComInstance(REFCLSID rclsid, REFIID riid, void** out) { UINT32 bufferByteCount = 0; BYTE* buffer = nullptr; UniqueMidl bufferPtr; - RETURN_IF_FAILED(CallCreateInstance(clsid, iid, flags, &bufferByteCount, &buffer)); + RETURN_IF_FAILED(CallCreateInstance(rclsid, riid, &bufferByteCount, &buffer)); bufferPtr.reset(buffer); @@ -123,15 +114,13 @@ HRESULT CreateComInstance(const CLSID* clsid, const IID* iid, UINT32 flags, void RETURN_IF_FAILED(stream->Seek({}, STREAM_SEEK_SET, nullptr)); wil::com_ptr output; - RETURN_IF_FAILED(CoUnmarshalInterface(stream.get(), *iid, reinterpret_cast(&output))); + RETURN_IF_FAILED(CoUnmarshalInterface(stream.get(), riid, reinterpret_cast(&output))); *out = output.detach(); return S_OK; } -extern "C" HRESULT WinGetServerManualActivation_CreateInstance(const CLSID* clsid, const IID* iid, UINT32 flags, void** out) +extern "C" HRESULT WinGetServerManualActivation_CreateInstance(REFCLSID rclsid, REFIID riid, void** out) { - RETURN_HR_IF_NULL(E_POINTER, clsid); - RETURN_HR_IF_NULL(E_POINTER, iid); RETURN_HR_IF_NULL(E_POINTER, out); static std::once_flag rpcBindingOnce; @@ -141,7 +130,7 @@ extern "C" HRESULT WinGetServerManualActivation_CreateInstance(const CLSID* clsi } CATCH_RETURN(); - HRESULT result = CreateComInstance(clsid, iid, flags, out); + HRESULT result = CreateComInstance(rclsid, riid, out); if (FAILED(result)) { for (int i = 0; i < 3; i++) @@ -152,7 +141,7 @@ extern "C" HRESULT WinGetServerManualActivation_CreateInstance(const CLSID* clsi break; } - result = CreateComInstance(clsid, iid, flags, out); + result = CreateComInstance(rclsid, riid, out); if (SUCCEEDED(result)) { break; diff --git a/src/WinGetServer/WinMain.cpp b/src/WinGetServer/WinMain.cpp index 30261461ea..83a0ee3258 100644 --- a/src/WinGetServer/WinMain.cpp +++ b/src/WinGetServer/WinMain.cpp @@ -65,12 +65,9 @@ void __RPC_USER MIDL_user_free(_Pre_maybenull_ _Post_invalid_ void* ptr) extern "C" HRESULT CreateInstance( /* [in] */ GUID clsid, /* [in] */ GUID iid, - /* [in] */ UINT32 flags, /* [ref][out] */ UINT32 * pcbBuffer, /* [size_is][size_is][ref][out] */ BYTE * *ppBuffer) { - UNREFERENCED_PARAMETER(flags); - RETURN_HR_IF_NULL(E_POINTER, pcbBuffer); RETURN_HR_IF_NULL(E_POINTER, ppBuffer); @@ -78,7 +75,7 @@ extern "C" HRESULT CreateInstance( RETURN_IF_FAILED(CreateStreamOnHGlobal(nullptr, TRUE, &stream)); wil::com_ptr instance; - RETURN_IF_FAILED(WindowsPackageManagerServerCreateInstance(&clsid, &iid, reinterpret_cast(&instance))); + RETURN_IF_FAILED(WindowsPackageManagerServerCreateInstance(clsid, iid, reinterpret_cast(&instance))); RETURN_IF_FAILED(CoMarshalInterface(stream.get(), iid, instance.get(), MSHCTX_LOCAL, nullptr, MSHLFLAGS_NORMAL)); @@ -104,7 +101,7 @@ extern "C" HRESULT CreateInstance( int __stdcall wWinMain(_In_ HINSTANCE, _In_opt_ HINSTANCE, _In_ LPWSTR cmdLine, _In_ int) { - wil::SetResultLoggingCallback(&WindowsPackageManagerServerWilResultCallback); + wil::SetResultLoggingCallback(&WindowsPackageManagerServerWilResultLoggingCallback); RETURN_IF_FAILED(CoInitializeEx(nullptr, COINIT_MULTITHREADED)); @@ -141,25 +138,25 @@ int __stdcall wWinMain(_In_ HINSTANCE, _In_opt_ HINSTANCE, _In_ LPWSTR cmdLine, { HANDLE hMutex = NULL; hMutex = CreateMutex(NULL, FALSE, TEXT("WinGetServerMutex")); - RETURN_HR_IF_NULL(OSS_MUTEX_NOT_CREATED, hMutex); + RETURN_LAST_ERROR_IF_NULL(hMutex); DWORD waitResult = WaitForSingleObject(hMutex, 0); - if (waitResult != 0 && waitResult != WAIT_ABANDONED) + if (waitResult != WAIT_OBJECT_0 && waitResult != WAIT_ABANDONED) { - return ERROR_SERVICE_ALREADY_RUNNING; + return HRESULT_FROM_WIN32(ERROR_SERVICE_ALREADY_RUNNING); } RETURN_IF_FAILED(WindowsPackageManagerServerInitializeRPCServer()); } // Manual reset event to notify the client that the server is available. - HANDLE eventHandle = CreateEventW(NULL, TRUE, FALSE, L"WinGetServerStartEvent"); - RETURN_HR_IF_NULL(PEER_E_EVENT_HANDLE_NOT_FOUND, eventHandle); - SetEvent(eventHandle); + wil::unique_event manualResetEvent; + manualResetEvent.create(wil::EventOptions::ManualReset, L"WinGetServerStartEvent"); + manualResetEvent.SetEvent(); _comServerExitEvent.wait(); + manualResetEvent.ResetEvent(); RETURN_IF_FAILED(WindowsPackageManagerServerModuleUnregister()); - ResetEvent(eventHandle); } CATCH_RETURN() diff --git a/src/WindowsPackageManager/Source.def b/src/WindowsPackageManager/Source.def index c1505a638b..816849baae 100644 --- a/src/WindowsPackageManager/Source.def +++ b/src/WindowsPackageManager/Source.def @@ -5,7 +5,7 @@ EXPORTS WindowsPackageManagerServerModuleCreate WindowsPackageManagerServerModuleRegister WindowsPackageManagerServerModuleUnregister - WindowsPackageManagerServerWilResultCallback + WindowsPackageManagerServerWilResultLoggingCallback WindowsPackageManagerServerCreateInstance WindowsPackageManagerInProcModuleInitialize WindowsPackageManagerInProcModuleTerminate diff --git a/src/WindowsPackageManager/WindowsPackageManager.h b/src/WindowsPackageManager/WindowsPackageManager.h index bfef2841b8..1842e27b8c 100644 --- a/src/WindowsPackageManager/WindowsPackageManager.h +++ b/src/WindowsPackageManager/WindowsPackageManager.h @@ -29,10 +29,10 @@ extern "C" WINDOWS_PACKAGE_MANAGER_API WindowsPackageManagerServerModuleUnregister(); // Callback for logging the WIL result reported from the server. - void WINDOWS_PACKAGE_MANAGER_API_CALLING_CONVENTION WindowsPackageManagerServerWilResultCallback(const wil::FailureInfo& info) noexcept; + void WINDOWS_PACKAGE_MANAGER_API_CALLING_CONVENTION WindowsPackageManagerServerWilResultLoggingCallback(const wil::FailureInfo& info) noexcept; // Creates an out-of-proc instance for manual activation scenarios. - WINDOWS_PACKAGE_MANAGER_API WindowsPackageManagerServerCreateInstance(const CLSID* clsid, const IID* iid, void** out); + WINDOWS_PACKAGE_MANAGER_API WindowsPackageManagerServerCreateInstance(REFCLSID rclsid, REFIID riid, void** out); // Creates module for in-proc COM invocation. WINDOWS_PACKAGE_MANAGER_API WindowsPackageManagerInProcModuleInitialize(); diff --git a/src/WindowsPackageManager/WindowsPackageManager.vcxproj b/src/WindowsPackageManager/WindowsPackageManager.vcxproj index ea3d8f96c7..42389b3043 100644 --- a/src/WindowsPackageManager/WindowsPackageManager.vcxproj +++ b/src/WindowsPackageManager/WindowsPackageManager.vcxproj @@ -166,9 +166,9 @@ Disabled _DEBUG;%(PreprocessorDefinitions) - $(ProjectDir);$(ProjectDir)..\AppInstallerCLICore\Public\;$(ProjectDir)..\AppInstallerCommonCore\Public;$(ProjectDir)..\AppInstallerRepositoryCore;$(ProjectDir)..\AppInstallerCommonCore\Public;$(ProjectDir)..\JsonCppLib\json;$(ProjectDir)..\Microsoft.Management.Deployment\Public;%(AdditionalIncludeDirectories) - $(ProjectDir);$(ProjectDir)..\AppInstallerCLICore\Public\;$(ProjectDir)..\AppInstallerCommonCore\Public;$(ProjectDir)..\AppInstallerRepositoryCore;$(ProjectDir)..\AppInstallerCommonCore\Public;$(ProjectDir)..\JsonCppLib\json;$(ProjectDir)..\Microsoft.Management.Deployment\Public;%(AdditionalIncludeDirectories) - $(ProjectDir);$(ProjectDir)..\AppInstallerCLICore\Public\;$(ProjectDir)..\AppInstallerCommonCore\Public;$(ProjectDir)..\AppInstallerRepositoryCore;$(ProjectDir)..\AppInstallerCommonCore\Public;$(ProjectDir)..\JsonCppLib\json;$(ProjectDir)..\Microsoft.Management.Deployment\Public;%(AdditionalIncludeDirectories) + $(ProjectDir);$(ProjectDir)..\AppInstallerCLICore\Public\;$(ProjectDir)..\AppInstallerRepositoryCore;$(ProjectDir)..\AppInstallerCommonCore\Public;$(ProjectDir)..\JsonCppLib\json;$(ProjectDir)..\Microsoft.Management.Deployment\Public;%(AdditionalIncludeDirectories) + $(ProjectDir);$(ProjectDir)..\AppInstallerCLICore\Public\;$(ProjectDir)..\AppInstallerRepositoryCore;$(ProjectDir)..\AppInstallerCommonCore\Public;$(ProjectDir)..\JsonCppLib\json;$(ProjectDir)..\Microsoft.Management.Deployment\Public;%(AdditionalIncludeDirectories) + $(ProjectDir);$(ProjectDir)..\AppInstallerCLICore\Public\;$(ProjectDir)..\AppInstallerRepositoryCore;$(ProjectDir)..\AppInstallerCommonCore\Public;$(ProjectDir)..\JsonCppLib\json;$(ProjectDir)..\Microsoft.Management.Deployment\Public;%(AdditionalIncludeDirectories) true true true @@ -210,7 +210,7 @@ WIN32;%(PreprocessorDefinitions) - $(ProjectDir);$(ProjectDir)..\AppInstallerCLICore\Public\;$(ProjectDir)..\AppInstallerCommonCore\Public;$(ProjectDir)..\AppInstallerRepositoryCore;$(ProjectDir)..\AppInstallerCommonCore\Public;$(ProjectDir)..\JsonCppLib\json;$(ProjectDir)..\Microsoft.Management.Deployment\Public;%(AdditionalIncludeDirectories) + $(ProjectDir);$(ProjectDir)..\AppInstallerCLICore\Public\;$(ProjectDir)..\AppInstallerRepositoryCore;$(ProjectDir)..\AppInstallerCommonCore\Public;$(ProjectDir)..\JsonCppLib\json;$(ProjectDir)..\Microsoft.Management.Deployment\Public;%(AdditionalIncludeDirectories) true false stdcpp17 @@ -227,10 +227,10 @@ true true NDEBUG;%(PreprocessorDefinitions) - $(ProjectDir);$(ProjectDir)..\AppInstallerCLICore\Public\;$(ProjectDir)..\AppInstallerCommonCore\Public;$(ProjectDir)..\AppInstallerRepositoryCore;$(ProjectDir)..\AppInstallerCommonCore\Public;$(ProjectDir)..\Microsoft.Management.Deployment\Public;%(AdditionalIncludeDirectories) - $(ProjectDir);$(ProjectDir)..\AppInstallerCLICore\Public\;$(ProjectDir)..\AppInstallerCommonCore\Public;$(ProjectDir)..\AppInstallerRepositoryCore;$(ProjectDir)..\AppInstallerCommonCore\Public;$(ProjectDir)..\Microsoft.Management.Deployment\Public;%(AdditionalIncludeDirectories) - $(ProjectDir);$(ProjectDir)..\AppInstallerCLICore\Public\;$(ProjectDir)..\AppInstallerCommonCore\Public;$(ProjectDir)..\AppInstallerRepositoryCore;$(ProjectDir)..\AppInstallerCommonCore\Public;$(ProjectDir)..\Microsoft.Management.Deployment\Public;%(AdditionalIncludeDirectories) - $(ProjectDir);$(ProjectDir)..\AppInstallerCLICore\Public\;$(ProjectDir)..\AppInstallerCommonCore\Public;$(ProjectDir)..\AppInstallerRepositoryCore;$(ProjectDir)..\AppInstallerCommonCore\Public;$(ProjectDir)..\Microsoft.Management.Deployment\Public;%(AdditionalIncludeDirectories) + $(ProjectDir);$(ProjectDir)..\AppInstallerCLICore\Public\;$(ProjectDir)..\AppInstallerRepositoryCore;$(ProjectDir)..\AppInstallerCommonCore\Public;$(ProjectDir)..\Microsoft.Management.Deployment\Public;%(AdditionalIncludeDirectories) + $(ProjectDir);$(ProjectDir)..\AppInstallerCLICore\Public\;$(ProjectDir)..\AppInstallerRepositoryCore;$(ProjectDir)..\AppInstallerCommonCore\Public;$(ProjectDir)..\Microsoft.Management.Deployment\Public;%(AdditionalIncludeDirectories) + $(ProjectDir);$(ProjectDir)..\AppInstallerCLICore\Public\;$(ProjectDir)..\AppInstallerRepositoryCore;$(ProjectDir)..\AppInstallerCommonCore\Public;$(ProjectDir)..\Microsoft.Management.Deployment\Public;%(AdditionalIncludeDirectories) + $(ProjectDir);$(ProjectDir)..\AppInstallerCLICore\Public\;$(ProjectDir)..\AppInstallerRepositoryCore;$(ProjectDir)..\AppInstallerCommonCore\Public;$(ProjectDir)..\Microsoft.Management.Deployment\Public;%(AdditionalIncludeDirectories) true true true diff --git a/src/WindowsPackageManager/main.cpp b/src/WindowsPackageManager/main.cpp index b0f4185d9f..8ee8a3bc52 100644 --- a/src/WindowsPackageManager/main.cpp +++ b/src/WindowsPackageManager/main.cpp @@ -61,20 +61,18 @@ extern "C" } CATCH_RETURN(); - void WINDOWS_PACKAGE_MANAGER_API_CALLING_CONVENTION WindowsPackageManagerServerWilResultCallback(const wil::FailureInfo& failure) noexcept try + void WINDOWS_PACKAGE_MANAGER_API_CALLING_CONVENTION WindowsPackageManagerServerWilResultLoggingCallback(const wil::FailureInfo& failure) noexcept try { AppInstaller::Logging::Telemetry().LogFailure(failure); } CATCH_LOG(); - WINDOWS_PACKAGE_MANAGER_API WindowsPackageManagerServerCreateInstance(const CLSID* clsid, const IID* iid, void** out) try + WINDOWS_PACKAGE_MANAGER_API WindowsPackageManagerServerCreateInstance(REFCLSID rclsid, REFIID riid, void** out) try { - RETURN_HR_IF_NULL(E_POINTER, clsid); - RETURN_HR_IF_NULL(E_POINTER, iid); RETURN_HR_IF_NULL(E_POINTER, out); ::Microsoft::WRL::ComPtr factory; - RETURN_IF_FAILED(::Microsoft::WRL::Module<::Microsoft::WRL::ModuleType::OutOfProc>::GetModule().GetClassObject(*clsid, IID_PPV_ARGS(&factory))); - RETURN_HR(factory->CreateInstance(nullptr, *iid, out)); + RETURN_IF_FAILED(::Microsoft::WRL::Module<::Microsoft::WRL::ModuleType::OutOfProc>::GetModule().GetClassObject(rclsid, IID_PPV_ARGS(&factory))); + RETURN_HR(factory->CreateInstance(nullptr, riid, out)); } CATCH_RETURN(); diff --git a/src/Xlang/UndockedRegFreeWinRT/src/UndockedRegFreeWinRT/UndockedRegFreeWinRT/UndockedRegFreeWinRT.vcxproj b/src/Xlang/UndockedRegFreeWinRT/src/UndockedRegFreeWinRT/UndockedRegFreeWinRT/UndockedRegFreeWinRT.vcxproj index d29cb977e5..0e2bd2328a 100644 --- a/src/Xlang/UndockedRegFreeWinRT/src/UndockedRegFreeWinRT/UndockedRegFreeWinRT/UndockedRegFreeWinRT.vcxproj +++ b/src/Xlang/UndockedRegFreeWinRT/src/UndockedRegFreeWinRT/UndockedRegFreeWinRT/UndockedRegFreeWinRT.vcxproj @@ -123,8 +123,6 @@ pch.h $(PorjectDir)\..\detours\include;%(AdditionalUsingDirectories) stdcpp17 - - Windows From 9957cd88ac5ee2c7efc5d79fb4163b76551a15a5 Mon Sep 17 00:00:00 2001 From: Ryan Fu Date: Mon, 28 Nov 2022 14:27:55 -0800 Subject: [PATCH 41/49] fix build dependencies --- src/AppInstallerCLI.sln | 13 ++++++++----- .../Helpers/ComObjectFactory.cs | 3 +-- src/WinGetServer/WinGetServer.vcxproj | 2 ++ 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/AppInstallerCLI.sln b/src/AppInstallerCLI.sln index d1908080b3..c2a7b0b72f 100644 --- a/src/AppInstallerCLI.sln +++ b/src/AppInstallerCLI.sln @@ -4,8 +4,8 @@ VisualStudioVersion = 17.2.32630.192 MinimumVisualStudioVersion = 10.0.40219.1 Project("{C7167F0D-BC9F-4E6E-AFE1-012C56B48DB5}") = "AppInstallerCLIPackage", "AppInstallerCLIPackage\AppInstallerCLIPackage.wapproj", "{6AA3791A-0713-4548-A357-87A323E7AC3A}" ProjectSection(ProjectDependencies) = postProject - {2B00D362-AC92-41F3-A8D2-5B1599BDCA01} = {2B00D362-AC92-41F3-A8D2-5B1599BDCA01} {1CC41A9A-AE66-459D-9210-1E572DD7BE69} = {1CC41A9A-AE66-459D-9210-1E572DD7BE69} + {2B00D362-AC92-41F3-A8D2-5B1599BDCA01} = {2B00D362-AC92-41F3-A8D2-5B1599BDCA01} {5B6F90DF-FD19-4BAE-83D9-24DAD128E777} = {5B6F90DF-FD19-4BAE-83D9-24DAD128E777} EndProjectSection EndProject @@ -50,9 +50,9 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "binver", "binver\binver.vcx EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AppInstallerCLIE2ETests", "AppInstallerCLIE2ETests\AppInstallerCLIE2ETests.csproj", "{3C0269FA-E582-4CA7-9E33-3881A005CA0C}" ProjectSection(ProjectDependencies) = postProject - {C1624B2F-2BF6-4E28-92FA-1BF85C6B62A8} = {C1624B2F-2BF6-4E28-92FA-1BF85C6B62A8} {3E2CBA31-CEBA-4D63-BF52-49C0718E19EA} = {3E2CBA31-CEBA-4D63-BF52-49C0718E19EA} {6CB84692-5994-407D-B9BD-9216AF77FE83} = {6CB84692-5994-407D-B9BD-9216AF77FE83} + {C1624B2F-2BF6-4E28-92FA-1BF85C6B62A8} = {C1624B2F-2BF6-4E28-92FA-1BF85C6B62A8} EndProjectSection EndProject Project("{C7167F0D-BC9F-4E6E-AFE1-012C56B48DB5}") = "AppInstallerTestMsixInstaller", "AppInstallerTestMsixInstaller\AppInstallerTestMsixInstaller.wapproj", "{3E2CBA31-CEBA-4D63-BF52-49C0718E19EA}" @@ -100,12 +100,12 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Microsoft.Management.Deployment", "Microsoft.Management.Deployment\Microsoft.Management.Deployment.vcxproj", "{1CC41A9A-AE66-459D-9210-1E572DD7BE69}" ProjectSection(ProjectDependencies) = postProject - {866C3F06-636F-4BE8-BC24-5F86ECC606A1} = {866C3F06-636F-4BE8-BC24-5F86ECC606A1} {1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D} = {1C6E0108-2860-4B17-9F7E-FA5C6C1F3D3D} + {5890D6ED-7C3B-40F3-B436-B54F640D9E65} = {5890D6ED-7C3B-40F3-B436-B54F640D9E65} {5EB88068-5FB9-4E69-89B2-72DBC5E068F9} = {5EB88068-5FB9-4E69-89B2-72DBC5E068F9} - {8BB94BB8-374F-4294-BCA1-C7811514A6B7} = {8BB94BB8-374F-4294-BCA1-C7811514A6B7} {82B39FDA-E86B-4713-A873-9D56DE00247A} = {82B39FDA-E86B-4713-A873-9D56DE00247A} - {5890D6ED-7C3B-40F3-B436-B54F640D9E65} = {5890D6ED-7C3B-40F3-B436-B54F640D9E65} + {866C3F06-636F-4BE8-BC24-5F86ECC606A1} = {866C3F06-636F-4BE8-BC24-5F86ECC606A1} + {8BB94BB8-374F-4294-BCA1-C7811514A6B7} = {8BB94BB8-374F-4294-BCA1-C7811514A6B7} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "WinGetServer", "WinGetServer\WinGetServer.vcxproj", "{2B00D362-AC92-41F3-A8D2-5B1599BDCA01}" @@ -132,6 +132,9 @@ 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", "Xlang\UndockedRegFreeWinRT\src\UndockedRegFreeWinRT\UndockedRegFreeWinRT\UndockedRegFreeWinRT.vcxproj", "{31ED69A8-5310-45A9-953F-56C351D2C3E1}" + ProjectSection(ProjectDependencies) = postProject + {2B00D362-AC92-41F3-A8D2-5B1599BDCA01} = {2B00D362-AC92-41F3-A8D2-5B1599BDCA01} + EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Detours", "Xlang\UndockedRegFreeWinRT\src\UndockedRegFreeWinRT\detours\detours.vcxproj", "{787EC629-C0FB-4BA9-9746-4A82CD06B73E}" EndProject diff --git a/src/PowerShell/Microsoft.WinGet.Client/Helpers/ComObjectFactory.cs b/src/PowerShell/Microsoft.WinGet.Client/Helpers/ComObjectFactory.cs index 35d80c9070..ed7556e3e6 100644 --- a/src/PowerShell/Microsoft.WinGet.Client/Helpers/ComObjectFactory.cs +++ b/src/PowerShell/Microsoft.WinGet.Client/Helpers/ComObjectFactory.cs @@ -110,7 +110,7 @@ private static T Create(Type type, in Guid iid) if (Utilities.ExecutingAsAdministrator) { - int hr = WinGetServerManualActivation_CreateInstance(type.GUID, iid, 0, out instance); + int hr = WinGetServerManualActivation_CreateInstance(type.GUID, iid, out instance); if (hr == ErrorCode.FILE_NOT_FOUND) { @@ -138,7 +138,6 @@ private static T Create(Type type, in Guid iid) private static extern int WinGetServerManualActivation_CreateInstance( [In, MarshalAs(UnmanagedType.LPStruct)] Guid clsid, [In, MarshalAs(UnmanagedType.LPStruct)] Guid iid, - uint flags, [Out, MarshalAs(UnmanagedType.IUnknown)] out object instance); } } diff --git a/src/WinGetServer/WinGetServer.vcxproj b/src/WinGetServer/WinGetServer.vcxproj index c2b7f54932..731d3c8afd 100644 --- a/src/WinGetServer/WinGetServer.vcxproj +++ b/src/WinGetServer/WinGetServer.vcxproj @@ -172,7 +172,9 @@ false Stub + Stub true + From 190a6b9398c44ac13231bd5e5e8423963eb47aa2 Mon Sep 17 00:00:00 2001 From: Ryan Fu Date: Wed, 30 Nov 2022 13:52:33 -0800 Subject: [PATCH 42/49] fix manual reset event --- .../Helpers/ComObjectFactory.cs | 15 +++++++++------ src/WinGetServer/WinGetServer.vcxproj | 2 +- .../WinGetServerManualActivation_Client.cpp | 6 +++--- src/WinGetServer/WinMain.cpp | 3 ++- 4 files changed, 15 insertions(+), 11 deletions(-) diff --git a/src/PowerShell/Microsoft.WinGet.Client/Helpers/ComObjectFactory.cs b/src/PowerShell/Microsoft.WinGet.Client/Helpers/ComObjectFactory.cs index ed7556e3e6..d339c37f62 100644 --- a/src/PowerShell/Microsoft.WinGet.Client/Helpers/ComObjectFactory.cs +++ b/src/PowerShell/Microsoft.WinGet.Client/Helpers/ComObjectFactory.cs @@ -112,13 +112,16 @@ private static T Create(Type type, in Guid iid) { int hr = WinGetServerManualActivation_CreateInstance(type.GUID, iid, out instance); - if (hr == ErrorCode.FILE_NOT_FOUND) + if (hr < 0) { - throw new Exception(Utilities.ResourceManager.GetString("WinGetPackageNotInstalled")); - } - else if (hr != 0) - { - throw new COMException($"Failed to create instance: {hr}", hr); + if (hr == ErrorCode.FILE_NOT_FOUND) + { + throw new Exception(Utilities.ResourceManager.GetString("WinGetPackageNotInstalled")); + } + else + { + throw new COMException($"Failed to create instance: {hr}", hr); + } } } else diff --git a/src/WinGetServer/WinGetServer.vcxproj b/src/WinGetServer/WinGetServer.vcxproj index 731d3c8afd..3df54e74ba 100644 --- a/src/WinGetServer/WinGetServer.vcxproj +++ b/src/WinGetServer/WinGetServer.vcxproj @@ -174,7 +174,7 @@ Stub Stub true - + WinGetServer.h diff --git a/src/WinGetServer/WinGetServerManualActivation_Client.cpp b/src/WinGetServer/WinGetServerManualActivation_Client.cpp index b08577143e..54b7ad90bd 100644 --- a/src/WinGetServer/WinGetServerManualActivation_Client.cpp +++ b/src/WinGetServer/WinGetServerManualActivation_Client.cpp @@ -71,11 +71,11 @@ HRESULT LaunchWinGetServerWithManualActivation() std::wstring commandLineInput = std::wstring{ serverExePath } + L" --manualActivation"; STARTUPINFO info = { sizeof(info) }; - PROCESS_INFORMATION processInfo; - RETURN_LAST_ERROR_IF(!CreateProcessW(NULL, &commandLineInput[0], NULL, NULL, FALSE, 0, NULL, NULL, &info, &processInfo)); + wil::unique_process_information process; + + RETURN_LAST_ERROR_IF(!CreateProcessW(NULL, &commandLineInput[0], NULL, NULL, FALSE, 0, NULL, NULL, &info, &process)); // Wait for manual reset event from server before proceeding with COM activation. - wil::unique_event_watcher eventWatcher; wil::unique_event manualResetEvent; manualResetEvent.open(L"WinGetServerStartEvent"); manualResetEvent.wait(); diff --git a/src/WinGetServer/WinMain.cpp b/src/WinGetServer/WinMain.cpp index 83a0ee3258..dc05d8d4dc 100644 --- a/src/WinGetServer/WinMain.cpp +++ b/src/WinGetServer/WinMain.cpp @@ -155,7 +155,8 @@ int __stdcall wWinMain(_In_ HINSTANCE, _In_opt_ HINSTANCE, _In_ LPWSTR cmdLine, manualResetEvent.SetEvent(); _comServerExitEvent.wait(); - manualResetEvent.ResetEvent(); + + manualResetEvent.reset(); RETURN_IF_FAILED(WindowsPackageManagerServerModuleUnregister()); } CATCH_RETURN() From a305bab3c22748ba5c0b0aa5de90e08d19ea6aa0 Mon Sep 17 00:00:00 2001 From: Ryan Fu Date: Wed, 30 Nov 2022 16:17:52 -0800 Subject: [PATCH 43/49] fix build warnings and errors --- src/AppInstallerCLIE2ETests/PowerShell/PowerShellModule.cs | 4 ++-- src/PowerShell/Microsoft.WinGet.Client/Common/ErrorCode.cs | 5 ++++- .../Microsoft.WinGet.Client/Helpers/ComObjectFactory.cs | 2 +- .../Microsoft.WinGet.Client/Microsoft.WinGet.Client.csproj | 2 +- src/WinGetServer/WinGetServerManualActivation_Client.cpp | 7 +++++-- src/WinGetServer/WinMain.cpp | 6 +++++- 6 files changed, 18 insertions(+), 8 deletions(-) diff --git a/src/AppInstallerCLIE2ETests/PowerShell/PowerShellModule.cs b/src/AppInstallerCLIE2ETests/PowerShell/PowerShellModule.cs index a45eb99239..e3eda5af2a 100644 --- a/src/AppInstallerCLIE2ETests/PowerShell/PowerShellModule.cs +++ b/src/AppInstallerCLIE2ETests/PowerShell/PowerShellModule.cs @@ -7,7 +7,6 @@ namespace AppInstallerCLIE2ETests.PowerShell using System; using System.Diagnostics; using System.Linq; - using System.Threading; /// /// Basic E2E smoke tests for verifying the behavior of the PowerShell module cmdlets. @@ -47,7 +46,8 @@ public void AssertServerShutdownAfterExecution() return; } - TestCommon.RunPowerShellCommandWithResult(Constants.GetSourceCmdlet, $"-Name {Constants.TestSourceName}"); + var result = TestCommon.RunPowerShellCommandWithResult(Constants.GetSourceCmdlet, $"-Name {Constants.TestSourceName}"); + Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode, $"ExitCode: {result.ExitCode} Failed with the following output: {result.StdOut}, {result.StdErr}"); Assert.IsTrue(IsRunning(Constants.WindowsPackageManagerServer), $"{Constants.WindowsPackageManagerServer} is not running."); Process serverProcess = Process.GetProcessesByName(Constants.WindowsPackageManagerServer).First(); diff --git a/src/PowerShell/Microsoft.WinGet.Client/Common/ErrorCode.cs b/src/PowerShell/Microsoft.WinGet.Client/Common/ErrorCode.cs index 9ee0793871..ec0ab97a3a 100644 --- a/src/PowerShell/Microsoft.WinGet.Client/Common/ErrorCode.cs +++ b/src/PowerShell/Microsoft.WinGet.Client/Common/ErrorCode.cs @@ -11,6 +11,9 @@ namespace Microsoft.WinGet.Client.Common /// public class ErrorCode { - public const int FILE_NOT_FOUND = unchecked((int)0x80070002); + /// + /// Error code for FILENOTFOUND. + /// + public const int FILENOTFOUND = unchecked((int)0x80070002); } } diff --git a/src/PowerShell/Microsoft.WinGet.Client/Helpers/ComObjectFactory.cs b/src/PowerShell/Microsoft.WinGet.Client/Helpers/ComObjectFactory.cs index d339c37f62..40ea93a7a3 100644 --- a/src/PowerShell/Microsoft.WinGet.Client/Helpers/ComObjectFactory.cs +++ b/src/PowerShell/Microsoft.WinGet.Client/Helpers/ComObjectFactory.cs @@ -114,7 +114,7 @@ private static T Create(Type type, in Guid iid) if (hr < 0) { - if (hr == ErrorCode.FILE_NOT_FOUND) + if (hr == ErrorCode.FILENOTFOUND) { throw new Exception(Utilities.ResourceManager.GetString("WinGetPackageNotInstalled")); } diff --git a/src/PowerShell/Microsoft.WinGet.Client/Microsoft.WinGet.Client.csproj b/src/PowerShell/Microsoft.WinGet.Client/Microsoft.WinGet.Client.csproj index 6154f1cda6..18e712151a 100644 --- a/src/PowerShell/Microsoft.WinGet.Client/Microsoft.WinGet.Client.csproj +++ b/src/PowerShell/Microsoft.WinGet.Client/Microsoft.WinGet.Client.csproj @@ -38,7 +38,7 @@ Content Always - + Content Always diff --git a/src/WinGetServer/WinGetServerManualActivation_Client.cpp b/src/WinGetServer/WinGetServerManualActivation_Client.cpp index 54b7ad90bd..d78899bb90 100644 --- a/src/WinGetServer/WinGetServerManualActivation_Client.cpp +++ b/src/WinGetServer/WinGetServerManualActivation_Client.cpp @@ -77,8 +77,11 @@ HRESULT LaunchWinGetServerWithManualActivation() // Wait for manual reset event from server before proceeding with COM activation. wil::unique_event manualResetEvent; - manualResetEvent.open(L"WinGetServerStartEvent"); - manualResetEvent.wait(); + if (manualResetEvent.try_open(L"WinGetServerStartEvent")) + { + manualResetEvent.wait(); + manualResetEvent.ResetEvent(); + } return S_OK; } diff --git a/src/WinGetServer/WinMain.cpp b/src/WinGetServer/WinMain.cpp index dc05d8d4dc..7ced86d402 100644 --- a/src/WinGetServer/WinMain.cpp +++ b/src/WinGetServer/WinMain.cpp @@ -151,7 +151,11 @@ int __stdcall wWinMain(_In_ HINSTANCE, _In_opt_ HINSTANCE, _In_ LPWSTR cmdLine, // Manual reset event to notify the client that the server is available. wil::unique_event manualResetEvent; - manualResetEvent.create(wil::EventOptions::ManualReset, L"WinGetServerStartEvent"); + if (!manualResetEvent.try_create(wil::EventOptions::ManualReset, L"WinGetServerStartEvent")) + { + manualResetEvent.open(L"WinGetServerStartEvent"); + } + manualResetEvent.SetEvent(); _comServerExitEvent.wait(); From 5a9d0a246ac74e2b73a3dcb10d5d2b2cd0468ce3 Mon Sep 17 00:00:00 2001 From: Ryan Fu Date: Fri, 2 Dec 2022 15:53:35 -0800 Subject: [PATCH 44/49] revert flags parameter --- .../Microsoft.WinGet.Client/Common/ErrorCode.cs | 4 ++-- .../Helpers/ComObjectFactory.cs | 5 +++-- src/WinGetServer/WinGetServer.idl | 1 + .../WinGetServerManualActivation_Client.cpp | 14 +++++++------- src/WinGetServer/WinMain.cpp | 1 + 5 files changed, 14 insertions(+), 11 deletions(-) diff --git a/src/PowerShell/Microsoft.WinGet.Client/Common/ErrorCode.cs b/src/PowerShell/Microsoft.WinGet.Client/Common/ErrorCode.cs index ec0ab97a3a..68218ee799 100644 --- a/src/PowerShell/Microsoft.WinGet.Client/Common/ErrorCode.cs +++ b/src/PowerShell/Microsoft.WinGet.Client/Common/ErrorCode.cs @@ -12,8 +12,8 @@ namespace Microsoft.WinGet.Client.Common public class ErrorCode { /// - /// Error code for FILENOTFOUND. + /// Error code for ERROR_FILE_NOT_FOUND. /// - public const int FILENOTFOUND = unchecked((int)0x80070002); + public const int FileNotFound = unchecked((int)0x80070002); } } diff --git a/src/PowerShell/Microsoft.WinGet.Client/Helpers/ComObjectFactory.cs b/src/PowerShell/Microsoft.WinGet.Client/Helpers/ComObjectFactory.cs index 40ea93a7a3..3dc4323ea3 100644 --- a/src/PowerShell/Microsoft.WinGet.Client/Helpers/ComObjectFactory.cs +++ b/src/PowerShell/Microsoft.WinGet.Client/Helpers/ComObjectFactory.cs @@ -110,11 +110,11 @@ private static T Create(Type type, in Guid iid) if (Utilities.ExecutingAsAdministrator) { - int hr = WinGetServerManualActivation_CreateInstance(type.GUID, iid, out instance); + int hr = WinGetServerManualActivation_CreateInstance(type.GUID, iid, 0, out instance); if (hr < 0) { - if (hr == ErrorCode.FILENOTFOUND) + if (hr == ErrorCode.FileNotFound) { throw new Exception(Utilities.ResourceManager.GetString("WinGetPackageNotInstalled")); } @@ -141,6 +141,7 @@ private static T Create(Type type, in Guid iid) private static extern int WinGetServerManualActivation_CreateInstance( [In, MarshalAs(UnmanagedType.LPStruct)] Guid clsid, [In, MarshalAs(UnmanagedType.LPStruct)] Guid iid, + uint flags, [Out, MarshalAs(UnmanagedType.IUnknown)] out object instance); } } diff --git a/src/WinGetServer/WinGetServer.idl b/src/WinGetServer/WinGetServer.idl index b96ea9617f..87f8a7a42c 100644 --- a/src/WinGetServer/WinGetServer.idl +++ b/src/WinGetServer/WinGetServer.idl @@ -10,6 +10,7 @@ interface WinGetServerManualActivation HRESULT CreateInstance( [in] GUID clsid, [in] GUID iid, + [in] UINT32 flags, [out, ref] UINT32* pcbBuffer, [out, ref, size_is(, *pcbBuffer)] BYTE** ppBuffer ); diff --git a/src/WinGetServer/WinGetServerManualActivation_Client.cpp b/src/WinGetServer/WinGetServerManualActivation_Client.cpp index d78899bb90..0b8e9ab647 100644 --- a/src/WinGetServer/WinGetServerManualActivation_Client.cpp +++ b/src/WinGetServer/WinGetServerManualActivation_Client.cpp @@ -86,11 +86,11 @@ HRESULT LaunchWinGetServerWithManualActivation() return S_OK; } -HRESULT CallCreateInstance(REFCLSID rclsid, REFIID riid, UINT32* bufferByteCount, BYTE** buffer) +HRESULT CallCreateInstance(REFCLSID rclsid, REFIID riid, UINT32 flags, UINT32* bufferByteCount, BYTE** buffer) { RpcTryExcept { - RETURN_IF_FAILED(CreateInstance(rclsid, riid, bufferByteCount, buffer)); + RETURN_IF_FAILED(CreateInstance(rclsid, riid, flags, bufferByteCount, buffer)); } RpcExcept(1) { @@ -101,13 +101,13 @@ HRESULT CallCreateInstance(REFCLSID rclsid, REFIID riid, UINT32* bufferByteCount return S_OK; } -HRESULT CreateComInstance(REFCLSID rclsid, REFIID riid, void** out) +HRESULT CreateComInstance(REFCLSID rclsid, REFIID riid, UINT32 flags, void** out) { UINT32 bufferByteCount = 0; BYTE* buffer = nullptr; UniqueMidl bufferPtr; - RETURN_IF_FAILED(CallCreateInstance(rclsid, riid, &bufferByteCount, &buffer)); + RETURN_IF_FAILED(CallCreateInstance(rclsid, riid, flags, &bufferByteCount, &buffer)); bufferPtr.reset(buffer); @@ -122,7 +122,7 @@ HRESULT CreateComInstance(REFCLSID rclsid, REFIID riid, void** out) return S_OK; } -extern "C" HRESULT WinGetServerManualActivation_CreateInstance(REFCLSID rclsid, REFIID riid, void** out) +extern "C" HRESULT WinGetServerManualActivation_CreateInstance(REFCLSID rclsid, REFIID riid, UINT32 flags, void** out) { RETURN_HR_IF_NULL(E_POINTER, out); @@ -133,7 +133,7 @@ extern "C" HRESULT WinGetServerManualActivation_CreateInstance(REFCLSID rclsid, } CATCH_RETURN(); - HRESULT result = CreateComInstance(rclsid, riid, out); + HRESULT result = CreateComInstance(rclsid, riid, flags, out); if (FAILED(result)) { for (int i = 0; i < 3; i++) @@ -144,7 +144,7 @@ extern "C" HRESULT WinGetServerManualActivation_CreateInstance(REFCLSID rclsid, break; } - result = CreateComInstance(rclsid, riid, out); + result = CreateComInstance(rclsid, riid, flags, out); if (SUCCEEDED(result)) { break; diff --git a/src/WinGetServer/WinMain.cpp b/src/WinGetServer/WinMain.cpp index 7ced86d402..1ec630bb95 100644 --- a/src/WinGetServer/WinMain.cpp +++ b/src/WinGetServer/WinMain.cpp @@ -65,6 +65,7 @@ void __RPC_USER MIDL_user_free(_Pre_maybenull_ _Post_invalid_ void* ptr) extern "C" HRESULT CreateInstance( /* [in] */ GUID clsid, /* [in] */ GUID iid, + /* [in] */ UINT32, /* [ref][out] */ UINT32 * pcbBuffer, /* [size_is][size_is][ref][out] */ BYTE * *ppBuffer) { From 7b1362a098c24984a9d864c0af030f976bd6392e Mon Sep 17 00:00:00 2001 From: Ryan Fu Date: Fri, 2 Dec 2022 16:00:21 -0800 Subject: [PATCH 45/49] fix spelling --- .github/actions/spelling/allow.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/actions/spelling/allow.txt b/.github/actions/spelling/allow.txt index 7d1718f3d7..b5963866a2 100644 --- a/.github/actions/spelling/allow.txt +++ b/.github/actions/spelling/allow.txt @@ -249,6 +249,7 @@ INVALIDARG iomanip iostream IPortable +ipmo ISAPPROVEDFOROUTPUT isspace istream @@ -407,6 +408,7 @@ publiccontainer PUCHAR PVOID pwa +pwsh QCol RAII rclsid From 9d587c85079e74940479a8eded1909a1752c8142 Mon Sep 17 00:00:00 2001 From: Ryan Fu Date: Fri, 2 Dec 2022 16:07:09 -0800 Subject: [PATCH 46/49] more spelling --- .github/actions/spelling/allow.txt | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/.github/actions/spelling/allow.txt b/.github/actions/spelling/allow.txt index b5963866a2..78ec6efc97 100644 --- a/.github/actions/spelling/allow.txt +++ b/.github/actions/spelling/allow.txt @@ -202,6 +202,7 @@ hcertstore HCRYPTMSG hfile HGLOBAL +HGlobal HIDECANCEL hinternet HKCU @@ -246,6 +247,7 @@ INSTALLPATH INSTALLUILEVEL interop INVALIDARG +INVALIDSID iomanip iostream IPortable @@ -319,6 +321,7 @@ mutex mutexes namespace namespaces +ncacn Nelon netcoreapp netstandard @@ -396,6 +399,7 @@ preindexed prepareforpackaging PRIMARYKEY prioritization +processthreadsapi PRODUCTNAME PRODUCTVERSION PROGRAMFILES @@ -403,6 +407,7 @@ PROGRESSONLY promptrestart PROPERTYDUMP psz +PTOKEN ptr publiccontainer PUCHAR @@ -475,7 +480,9 @@ SHELLEXEC SHELLEXECUTEINFO SHELLEXECUTEINFOA SHELLEXECUTEINFOW +shlobj Shlwapi +shtypes signtool silentwithprogress simplesave @@ -499,6 +506,7 @@ src srwlock sscanf sstream +STARTUPINFO STATEACTION STATFLAG STATSTG @@ -600,6 +608,7 @@ unicode UNICODESTRING uninstall uninstalling +Unmarshal Unregister Unregisters untimes @@ -671,6 +680,7 @@ WStr wstring wstringstream WTD +wtypesbase www xamarin xaml From 4ff088711bf453341a3275422659bda70279a7b0 Mon Sep 17 00:00:00 2001 From: Ryan Fu Date: Fri, 2 Dec 2022 16:16:50 -0800 Subject: [PATCH 47/49] even more spelling --- .github/actions/spelling/allow.txt | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.github/actions/spelling/allow.txt b/.github/actions/spelling/allow.txt index 78ec6efc97..45190c8548 100644 --- a/.github/actions/spelling/allow.txt +++ b/.github/actions/spelling/allow.txt @@ -37,6 +37,7 @@ aspnet authn authz autocomplete +AUTOLISTEN auxdata azureedge backend @@ -229,6 +230,7 @@ IDX IFACEMETHOD ifdef ifndef +ifspec ifstream IIS impl @@ -314,6 +316,8 @@ msixmgr msixsdk msixsdkx msixtest +MSHCTX +MSHLFLAGS msrc Multifile Multimatch @@ -406,6 +410,8 @@ PROGRAMFILES PROGRESSONLY promptrestart PROPERTYDUMP +PROTSEQ +Protseq psz PTOKEN ptr @@ -445,6 +451,7 @@ RESTSOURCE resw resx rethrowing +REQS roadmap robuffer rowcount @@ -599,6 +606,7 @@ UIA UIF uint Uknown +ULARGE ulong ULONGLONG uncomment From 0d4edb0f9b7c4783e51de7f4f0d89facfda7b8e5 Mon Sep 17 00:00:00 2001 From: Ryan Fu Date: Fri, 2 Dec 2022 17:03:07 -0800 Subject: [PATCH 48/49] remove Reset event --- src/WinGetServer/WinGetServerManualActivation_Client.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/WinGetServer/WinGetServerManualActivation_Client.cpp b/src/WinGetServer/WinGetServerManualActivation_Client.cpp index 0b8e9ab647..dad8385f65 100644 --- a/src/WinGetServer/WinGetServerManualActivation_Client.cpp +++ b/src/WinGetServer/WinGetServerManualActivation_Client.cpp @@ -80,7 +80,6 @@ HRESULT LaunchWinGetServerWithManualActivation() if (manualResetEvent.try_open(L"WinGetServerStartEvent")) { manualResetEvent.wait(); - manualResetEvent.ResetEvent(); } return S_OK; @@ -132,7 +131,7 @@ extern "C" HRESULT WinGetServerManualActivation_CreateInstance(REFCLSID rclsid, std::call_once(rpcBindingOnce, InitializeRpcBinding); } CATCH_RETURN(); - + HRESULT result = CreateComInstance(rclsid, riid, flags, out); if (FAILED(result)) { From bb047051e3599e62757e83b93310501ac9d3aa50 Mon Sep 17 00:00:00 2001 From: Ryan Fu Date: Fri, 2 Dec 2022 17:08:29 -0800 Subject: [PATCH 49/49] fix line spacing --- src/WinGetServer/WinGetServerManualActivation_Client.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/WinGetServer/WinGetServerManualActivation_Client.cpp b/src/WinGetServer/WinGetServerManualActivation_Client.cpp index dad8385f65..b74b8d0fcd 100644 --- a/src/WinGetServer/WinGetServerManualActivation_Client.cpp +++ b/src/WinGetServer/WinGetServerManualActivation_Client.cpp @@ -131,7 +131,7 @@ extern "C" HRESULT WinGetServerManualActivation_CreateInstance(REFCLSID rclsid, std::call_once(rpcBindingOnce, InitializeRpcBinding); } CATCH_RETURN(); - + HRESULT result = CreateComInstance(rclsid, riid, flags, out); if (FAILED(result)) {