Skip to content

Commit 12dbc22

Browse files
author
Chacón
authored
Split COM install command into download and install stages (microsoft#1528)
1 parent 9799443 commit 12dbc22

16 files changed

Lines changed: 678 additions & 394 deletions

.github/actions/spelling/allow.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -385,6 +385,7 @@ regex
385385
regexp
386386
removemanifest
387387
repolibtest
388+
requeue
388389
rescap
389390
resheader
390391
resmimetype

src/AppInstallerCLICore/AppInstallerCLICore.vcxproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,7 @@
275275
<ClInclude Include="VTSupport.h" />
276276
<ClInclude Include="PackageCollection.h" />
277277
<ClInclude Include="Workflows\CompletionFlow.h" />
278+
<ClInclude Include="Workflows\DownloadFlow.h" />
278279
<ClInclude Include="Workflows\ImportExportFlow.h" />
279280
<ClInclude Include="Workflows\MsiInstallFlow.h" />
280281
<ClInclude Include="Workflows\MSStoreInstallerHandler.h" />
@@ -324,6 +325,7 @@
324325
<ClCompile Include="Resources.cpp" />
325326
<ClCompile Include="VTSupport.cpp" />
326327
<ClCompile Include="Workflows\CompletionFlow.cpp" />
328+
<ClCompile Include="Workflows\DownloadFlow.cpp" />
327329
<ClCompile Include="Workflows\ImportExportFlow.cpp" />
328330
<ClCompile Include="Workflows\MsiInstallFlow.cpp" />
329331
<ClCompile Include="Workflows\MSStoreInstallerHandler.cpp" />

src/AppInstallerCLICore/AppInstallerCLICore.vcxproj.filters

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,9 @@
170170
<ClInclude Include="Workflows\SettingsFlow.h">
171171
<Filter>Workflows</Filter>
172172
</ClInclude>
173+
<ClInclude Include="Workflows\DownloadFlow.h">
174+
<Filter>Workflows</Filter>
175+
</ClInclude>
173176
</ItemGroup>
174177
<ItemGroup>
175178
<ClCompile Include="pch.cpp">
@@ -307,6 +310,9 @@
307310
<ClCompile Include="Workflows\SettingsFlow.cpp">
308311
<Filter>Workflows</Filter>
309312
</ClCompile>
313+
<ClCompile Include="Workflows\DlownloadFlow.cpp">
314+
<Filter>Workflows</Filter>
315+
</ClCompile>
310316
</ItemGroup>
311317
<ItemGroup>
312318
<None Include="PropertySheet.props" />

src/AppInstallerCLICore/Commands/COMInstallCommand.cpp

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// Licensed under the MIT License.
33
#include "pch.h"
44
#include "COMInstallCommand.h"
5+
#include "Workflows/DownloadFlow.h"
56
#include "Workflows/InstallFlow.h"
67
#include "Workflows/WorkflowBase.h"
78

@@ -13,12 +14,21 @@ using namespace AppInstaller::Utility::literals;
1314
namespace AppInstaller::CLI
1415
{
1516
// IMPORTANT: To use this command, the caller should have already retrieved the package manifest (GetManifest()) and added it to the Context Data
16-
void COMInstallCommand::ExecuteInternal(Context& context) const
17+
void COMDownloadCommand::ExecuteInternal(Context& context) const
1718
{
1819
context <<
1920
Workflow::ReportExecutionStage(ExecutionStage::Discovery) <<
2021
Workflow::SelectInstaller <<
2122
Workflow::EnsureApplicableInstaller <<
22-
Workflow::InstallSinglePackage;
23+
Workflow::DownloadSinglePackage;
24+
}
25+
26+
// IMPORTANT: To use this command, the caller should have already executed the COMDownloadCommand
27+
void COMInstallCommand::ExecuteInternal(Context& context) const
28+
{
29+
context <<
30+
Workflow::GetInstallerHash <<
31+
Workflow::VerifyInstallerHash <<
32+
Workflow::InstallPackageInstaller;
2333
}
2434
}

src/AppInstallerCLICore/Commands/COMInstallCommand.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,15 @@
55

66
namespace AppInstaller::CLI
77
{
8+
// IMPORTANT: To use this command, the caller should have already retrieved the package manifest (GetManifest()) and added it to the Context Data
9+
struct COMDownloadCommand final : public Command
10+
{
11+
COMDownloadCommand(std::string_view parent) : Command("download", parent) {}
12+
13+
protected:
14+
void ExecuteInternal(Execution::Context& context) const override;
15+
};
16+
817
// IMPORTANT: To use this command, the caller should have already retrieved the package manifest (GetManifest()) and added it to the Context Data
918
struct COMInstallCommand final : public Command
1019
{

src/AppInstallerCLICore/Commands/RootCommand.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@ namespace AppInstaller::CLI
77
{
88
struct RootCommand final : public Command
99
{
10-
RootCommand() : Command("root", {}) {}
10+
constexpr static std::string_view CommandName = "root"sv;
11+
12+
RootCommand() : Command(CommandName, {}) {}
1113

1214
std::vector<std::unique_ptr<Command>> GetCommands() const override;
1315
std::vector<Argument> GetArguments() const override;

src/AppInstallerCLICore/ContextOrchestrator.cpp

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,13 @@ namespace AppInstaller::CLI::Execution
5959
}
6060
}
6161

62+
void ContextOrchestrator::RequeueItem(OrchestratorQueueItem& item)
63+
{
64+
std::lock_guard<std::mutex> lockQueue{ m_queueLock };
65+
66+
item.SetState(OrchestratorQueueItemState::Queued);
67+
}
68+
6269
void ContextOrchestrator::EnqueueAndRunItem(std::shared_ptr<OrchestratorQueueItem> item)
6370
{
6471
EnqueueItem(item);
@@ -101,11 +108,10 @@ namespace AppInstaller::CLI::Execution
101108
HRESULT terminationHR = S_OK;
102109
try
103110
{
104-
::AppInstaller::CLI::RootCommand rootCommand;
111+
std::unique_ptr<Command> command = item->PopNextCommand();
105112

106113
std::unique_ptr<AppInstaller::ThreadLocalStorage::PreviousThreadGlobals> setThreadGlobalsToPreviousState = item->GetContext().GetThreadGlobals().SetForCurrentThread();
107114

108-
std::unique_ptr<::AppInstaller::CLI::Command> command = std::make_unique<::AppInstaller::CLI::COMInstallCommand>(rootCommand.Name());
109115
item->GetContext().GetThreadGlobals().GetTelemetryLogger().LogCommand(command->FullName());
110116
command->ValidateArguments(item->GetContext().Args);
111117

@@ -123,7 +129,16 @@ namespace AppInstaller::CLI::Execution
123129
item->GetContext().SetTerminationHR(terminationHR);
124130
}
125131

126-
RemoveItemInState(*item, OrchestratorQueueItemState::Running);
132+
item->GetContext().EnableCtrlHandler(false);
133+
134+
if (FAILED(terminationHR) || item->IsComplete())
135+
{
136+
RemoveItemInState(*item, OrchestratorQueueItemState::Running);
137+
}
138+
else
139+
{
140+
RequeueItem(*item);
141+
}
127142

128143
item = GetNextItem();
129144
}
@@ -180,7 +195,10 @@ namespace AppInstaller::CLI::Execution
180195

181196
std::unique_ptr<OrchestratorQueueItem> OrchestratorQueueItemFactory::CreateItemForInstall(std::wstring packageId, std::wstring sourceId, std::unique_ptr<COMContext> context)
182197
{
183-
return std::make_unique<OrchestratorQueueItem>(OrchestratorQueueItemId(std::move(packageId), std::move(sourceId)), std::move(context));
198+
std::unique_ptr<OrchestratorQueueItem> item = std::make_unique<OrchestratorQueueItem>(OrchestratorQueueItemId(std::move(packageId), std::move(sourceId)), std::move(context));
199+
item->AddCommand(std::make_unique<::AppInstaller::CLI::COMDownloadCommand>(RootCommand::CommandName));
200+
item->AddCommand(std::make_unique<::AppInstaller::CLI::COMInstallCommand>(RootCommand::CommandName));
201+
return item;
184202
}
185203

186204
}

src/AppInstallerCLICore/ContextOrchestrator.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include "ExecutionArgs.h"
77
#include "ExecutionContextData.h"
88
#include "CompletionData.h"
9+
#include "Command.h"
910
#include "COMContext.h"
1011

1112
#include <string_view>
@@ -40,11 +41,20 @@ namespace AppInstaller::CLI::Execution
4041
COMContext& GetContext() const { return *m_context; }
4142
const wil::unique_event& GetCompletedEvent() const { return m_completedEvent; }
4243
const OrchestratorQueueItemId& GetId() const { return m_id; }
44+
void AddCommand(std::unique_ptr<Command> command) { m_commands.push_back(std::move(command)); }
45+
std::unique_ptr<Command> PopNextCommand()
46+
{
47+
std::unique_ptr<Command> command = std::move(m_commands.front());
48+
m_commands.pop_front();
49+
return command;
50+
}
51+
bool IsComplete() const { return m_commands.empty(); }
4352
private:
4453
OrchestratorQueueItemState m_state = OrchestratorQueueItemState::NotQueued;
4554
std::unique_ptr<COMContext> m_context;
4655
wil::unique_event m_completedEvent{ wil::EventOptions::ManualReset };
4756
OrchestratorQueueItemId m_id;
57+
std::deque<std::unique_ptr<Command>> m_commands;
4858
};
4959

5060
struct OrchestratorQueueItemFactory
@@ -67,6 +77,7 @@ namespace AppInstaller::CLI::Execution
6777
void RunItems();
6878
std::shared_ptr<OrchestratorQueueItem> GetNextItem();
6979
void EnqueueItem(std::shared_ptr<OrchestratorQueueItem> item);
80+
void RequeueItem(OrchestratorQueueItem& item);
7081
void RemoveItemInState(const OrchestratorQueueItem& item, OrchestratorQueueItemState state);
7182

7283
_Requires_lock_held_(m_queueLock)

0 commit comments

Comments
 (0)