Skip to content

Commit 0bfac5d

Browse files
authored
Fixes for updating winget from winget (microsoft#5972)
Fixes microsoft#4283 ## Change The primary issue here is that the package update monitoring is too aggressive at shutting down, and I made it listen to signal in more cases. It really isn't a good signal for us to listen to, and was only added for the elevated Store case. The fix is to move it entirely to the Store flow, as if we are installing via MSIX we can just let the deferred registration work and if someone else is updating us then we can just listen to the proper termination signals. I additionally noticed that the dependencies were being installed despite the fact that I definitely already had them up to date. There were a few issues here that I also fixed: - An MSIX nested inside an archive that was expecting to inherit the PackageFamilyName from the root node of the manifest was not doing so if the installer type was also inherited. Inheriting the installer type info before the PFN resolved this (for `Microsoft.VCLibs.14`). - An exe installer that installs an MSIX that was expecting to inherit the PackageFamilyName from the root node of the manifest was not doing so. I allowed the PFN to be inherited when the `AppsAndFeaturesEntries` has an MSIX type (for `Microsoft.WindowsAppRuntime.*`). - MSIX packages were not being allowed to map display versions, so I enabled them. - There was a bug with display version sorting that would not map the sort key of the "first" version when multiple versions are installed. This could lead to the first version in the list not being the latest version per the mapping.
1 parent e90cee1 commit 0bfac5d

18 files changed

Lines changed: 484 additions & 181 deletions

src/AppInstallerCLICore/Commands/TestCommand.cpp

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ namespace AppInstaller::CLI
3131
HRESULT WaitForShutdown(Execution::Context& context)
3232
{
3333
LogAndReport(context, "Waiting for app shutdown event");
34-
if (!ShutdownMonitoring::TerminationSignalHandler::Instance()->WaitForAppShutdownEvent())
34+
if (!ShutdownMonitoring::ServerShutdownSynchronization::WaitForShutdown(300000))
3535
{
3636
LogAndReport(context, "Failed getting app shutdown event");
3737
return APPINSTALLER_CLI_ERROR_INTERNAL_ERROR;
@@ -82,6 +82,21 @@ namespace AppInstaller::CLI
8282
return hr;
8383
}
8484

85+
void AppShutdownTestSystemBlockNewWork(CancelReason reason)
86+
{
87+
AICLI_LOG(CLI, Info, << "AppShutdownTestSystemBlockNewWork :: " << reason);
88+
}
89+
90+
void AppShutdownTestSystemBeginShutdown(CancelReason reason)
91+
{
92+
AICLI_LOG(CLI, Info, << "AppShutdownTestSystemBeginShutdown :: " << reason);
93+
}
94+
95+
void AppShutdownTestSystemWait()
96+
{
97+
AICLI_LOG(CLI, Info, << "AppShutdownTestSystemWait");
98+
}
99+
85100
void EnsureDSCv3Processor(Execution::Context& context)
86101
{
87102
auto& configurationSet = context.Get<Execution::Data::ConfigurationContext>().Set();
@@ -354,6 +369,13 @@ namespace AppInstaller::CLI
354369
{
355370
HRESULT hr = E_FAIL;
356371

372+
ShutdownMonitoring::ServerShutdownSynchronization::ComponentSystem appShutdownTestSystem{};
373+
appShutdownTestSystem.BlockNewWork = AppShutdownTestSystemBlockNewWork;
374+
appShutdownTestSystem.BeginShutdown = AppShutdownTestSystemBeginShutdown;
375+
appShutdownTestSystem.Wait = AppShutdownTestSystemWait;
376+
377+
ShutdownMonitoring::ServerShutdownSynchronization::AddComponent(appShutdownTestSystem);
378+
357379
// Only package context and admin won't create the window message.
358380
if (!Runtime::IsRunningInPackagedContext() || !Runtime::IsRunningAsAdmin())
359381
{

src/AppInstallerCLICore/ExecutionContext.h

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -80,12 +80,6 @@ namespace AppInstaller::CLI::Execution
8080

8181
DEFINE_ENUM_FLAG_OPERATORS(ContextFlag);
8282

83-
#ifndef AICLI_DISABLE_TEST_HOOKS
84-
HWND GetWindowHandle();
85-
86-
bool WaitForAppShutdownEvent();
87-
#endif
88-
8983
// Callback to log data actions.
9084
void ContextEnumBasedVariantMapActionCallback(const void* map, Data data, EnumBasedVariantMapAction action);
9185

src/AppInstallerCLICore/Public/ShutdownMonitoring.h

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@
33
#pragma once
44
#include <Windows.h>
55
#include <AppInstallerProgress.h>
6-
#include <winrt/Windows.ApplicationModel.h>
76
#include <wil/resource.h>
87
#include <memory>
98
#include <mutex>
9+
#include <optional>
1010

1111
namespace AppInstaller::ShutdownMonitoring
1212
{
@@ -39,9 +39,6 @@ namespace AppInstaller::ShutdownMonitoring
3939
#ifndef AICLI_DISABLE_TEST_HOOKS
4040
// Gets the window handle for the message window.
4141
HWND GetWindowHandle() const;
42-
43-
// Waits for the shutdown event.
44-
bool WaitForAppShutdownEvent() const;
4542
#endif
4643

4744
private:
@@ -59,17 +56,11 @@ namespace AppInstaller::ShutdownMonitoring
5956

6057
void CreateWindowAndStartMessageLoop();
6158

62-
#ifndef AICLI_DISABLE_TEST_HOOKS
63-
wil::unique_event m_appShutdownEvent;
64-
#endif
65-
6659
std::mutex m_listenersLock;
6760
std::vector<ICancellable*> m_listeners;
6861
wil::unique_event m_messageQueueReady;
6962
wil::unique_hwnd m_windowHandle;
7063
std::thread m_windowThread;
71-
winrt::Windows::ApplicationModel::PackageCatalog m_catalog = nullptr;
72-
decltype(winrt::Windows::ApplicationModel::PackageCatalog{ nullptr }.PackageUpdating(winrt::auto_revoke, nullptr)) m_updatingEvent;
7364
};
7465

7566
// Coordinates shutdown across server components
@@ -98,7 +89,7 @@ namespace AppInstaller::ShutdownMonitoring
9889
static void AddComponent(const ComponentSystem& component);
9990

10091
// Waits for the shutdown to complete.
101-
static void WaitForShutdown();
92+
static bool WaitForShutdown(std::optional<DWORD> timeout = std::nullopt);
10293

10394
private:
10495
ServerShutdownSynchronization() = default;

src/AppInstallerCLICore/ShutdownMonitoring.cpp

Lines changed: 18 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -75,36 +75,16 @@ namespace AppInstaller::ShutdownMonitoring
7575
{
7676
return m_windowHandle.get();
7777
}
78-
79-
bool TerminationSignalHandler::WaitForAppShutdownEvent() const
80-
{
81-
return m_appShutdownEvent.wait(60000);
82-
}
8378
#endif
8479

8580
TerminationSignalHandler::TerminationSignalHandler()
8681
{
87-
#ifndef AICLI_DISABLE_TEST_HOOKS
88-
m_appShutdownEvent.create();
89-
#endif
90-
9182
if (!s_TerminationSignalHandlerEnabled)
9283
{
9384
AICLI_LOG(CLI, Info, << "TerminationSignalHandler is disabled, skipping creation of signal listeners");
9485
return;
9586
}
9687

97-
if (Runtime::IsRunningInPackagedContext())
98-
{
99-
// Create package update listener
100-
m_catalog = winrt::Windows::ApplicationModel::PackageCatalog::OpenForCurrentPackage();
101-
m_updatingEvent = m_catalog.PackageUpdating(
102-
winrt::auto_revoke, [this](winrt::Windows::ApplicationModel::PackageCatalog, winrt::Windows::ApplicationModel::PackageUpdatingEventArgs)
103-
{
104-
this->StartAppShutdown();
105-
});
106-
}
107-
10888
// Create message only window.
10989
m_messageQueueReady.create();
11090
m_windowThread = std::thread(&TerminationSignalHandler::CreateWindowAndStartMessageLoop, this);
@@ -138,10 +118,6 @@ namespace AppInstaller::ShutdownMonitoring
138118
{
139119
AICLI_LOG(CLI, Info, << "Initiating shutdown procedure");
140120

141-
#ifndef AICLI_DISABLE_TEST_HOOKS
142-
m_appShutdownEvent.SetEvent();
143-
#endif
144-
145121
// Lifetime manager sends CTRL-C after the WM_QUERYENDSESSION is processed.
146122
// If we disable the CTRL-C handler, the default handler will kill us.
147123
InformListeners(CancelReason::AppShutdown, true);
@@ -334,20 +310,27 @@ namespace AppInstaller::ShutdownMonitoring
334310
instance.m_components.push_back(component);
335311
}
336312

337-
void ServerShutdownSynchronization::WaitForShutdown()
313+
bool ServerShutdownSynchronization::WaitForShutdown(std::optional<DWORD> timeout)
338314
{
339315
ServerShutdownSynchronization& instance = Instance();
340316

317+
if (timeout)
318+
{
319+
return instance.m_shutdownComplete.wait(timeout.value());
320+
}
321+
else
341322
{
342-
std::lock_guard<std::mutex> lock{ instance.m_threadLock };
343-
if (!instance.m_shutdownThread.joinable())
344323
{
345-
AICLI_LOG(Core, Warning, << "Attempt to wait for shutdown when shutdown has not been initiated.");
346-
return;
324+
std::lock_guard<std::mutex> lock{ instance.m_threadLock };
325+
if (!instance.m_shutdownThread.joinable())
326+
{
327+
AICLI_LOG(Core, Warning, << "Attempt to wait for shutdown when shutdown has not been initiated.");
328+
return false;
329+
}
347330
}
348-
}
349331

350-
instance.m_shutdownComplete.wait();
332+
return instance.m_shutdownComplete.wait();
333+
}
351334
}
352335

353336
void ServerShutdownSynchronization::Signal(CancelReason reason)
@@ -393,6 +376,7 @@ namespace AppInstaller::ShutdownMonitoring
393376
components = m_components;
394377
}
395378

379+
AICLI_LOG(CLI, Verbose, << "ServerShutdownSynchronization :: BlockNewWork");
396380
for (const auto& component : components)
397381
{
398382
if (component.BlockNewWork)
@@ -401,6 +385,7 @@ namespace AppInstaller::ShutdownMonitoring
401385
}
402386
}
403387

388+
AICLI_LOG(CLI, Verbose, << "ServerShutdownSynchronization :: BeginShutdown");
404389
for (const auto& component : components)
405390
{
406391
if (component.BeginShutdown)
@@ -409,6 +394,7 @@ namespace AppInstaller::ShutdownMonitoring
409394
}
410395
}
411396

397+
AICLI_LOG(CLI, Verbose, << "ServerShutdownSynchronization :: Wait");
412398
for (const auto& component : components)
413399
{
414400
if (component.Wait)
@@ -417,6 +403,7 @@ namespace AppInstaller::ShutdownMonitoring
417403
}
418404
}
419405

406+
AICLI_LOG(CLI, Verbose, << "ServerShutdownSynchronization :: ShutdownCompleteCallback");
420407
ShutdownCompleteCallback callback = m_callback;
421408
if (callback)
422409
{

src/AppInstallerCLIE2ETests/AppShutdownTests.cs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ public class AppShutdownTests
2424
/// Runs winget test appshutdown and register the application to force a WM_QUERYENDSESSION message.
2525
/// </summary>
2626
[Test]
27+
[Ignore("This test relied on a signal to terminate that was determined to be problematic. We may need OS fixes to test it when elevated.")]
2728
public void RegisterApplicationTest()
2829
{
2930
if (!TestSetup.Parameters.PackagedContext)
@@ -95,9 +96,6 @@ public void RegisterApplicationTest()
9596

9697
Task.WaitAll(new Task[] { testCmdTask, registerTask }, 360000);
9798

98-
// Assert.True(registerTask.Result);
99-
TestContext.Out.Write(testCmdTask.Result.StdOut);
100-
10199
// The ctrl-c command terminates the batch file before the exit code file gets created.
102100
// Look for the output.
103101
Assert.True(testCmdTask.Result.StdOut.Contains("Succeeded waiting for app shutdown event"));

src/AppInstallerCLIE2ETests/InprocTestbedTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ public void OneTimeSetup()
9090
[Test]
9191
public void DefaultTest()
9292
{
93-
this.RunInprocTestbed(new TestbedParameters());
93+
this.RunInprocTestbed(new TestbedParameters() { WorkTestSleepInterval = 1000 });
9494
}
9595

9696
/// <summary>

src/AppInstallerCLITests/AppInstallerCLITests.vcxproj

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1049,6 +1049,12 @@
10491049
<CopyFileToFolders Include="TestData\TestFont.ttf">
10501050
<DeploymentContent>true</DeploymentContent>
10511051
</CopyFileToFolders>
1052+
<CopyFileToFolders Include="TestData\Manifest-MSIX-in-AppsAndFeatures.yaml">
1053+
<DeploymentContent>true</DeploymentContent>
1054+
</CopyFileToFolders>
1055+
<CopyFileToFolders Include="TestData\Manifest-MSIX-in-Archive.yaml">
1056+
<DeploymentContent>true</DeploymentContent>
1057+
</CopyFileToFolders>
10521058
</ItemGroup>
10531059
<ItemGroup>
10541060
<ProjectReference Include="..\AppInstallerCLICore\AppInstallerCLICore.vcxproj">
@@ -1080,5 +1086,4 @@
10801086
<Error Condition="!Exists('$(SolutionDir)\packages\Microsoft.Windows.CppWinRT.2.0.250303.1\build\native\Microsoft.Windows.CppWinRT.props')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\packages\Microsoft.Windows.CppWinRT.2.0.250303.1\build\native\Microsoft.Windows.CppWinRT.props'))" />
10811087
<Error Condition="!Exists('$(SolutionDir)\packages\Microsoft.Windows.CppWinRT.2.0.250303.1\build\native\Microsoft.Windows.CppWinRT.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\packages\Microsoft.Windows.CppWinRT.2.0.250303.1\build\native\Microsoft.Windows.CppWinRT.targets'))" />
10821088
</Target>
1083-
</Project>
1084-
1089+
</Project>

0 commit comments

Comments
 (0)