88
99namespace AppInstaller ::Deployment
1010{
11+ using namespace winrt ::Windows::Foundation;
12+ using namespace winrt ::Windows::Management::Deployment;
13+
1114 namespace
1215 {
1316 size_t GetDeploymentOperationId ()
1417 {
1518 static std::atomic_size_t s_deploymentId = 0 ;
1619 return s_deploymentId.fetch_add (1 );
1720 }
21+
22+ void WaitForDeployment (
23+ IAsyncOperationWithProgress<DeploymentResult, DeploymentProgress>& deployOperation,
24+ size_t id,
25+ IProgressCallback& callback)
26+ {
27+ AsyncOperationProgressHandler<DeploymentResult, DeploymentProgress> progressCallback (
28+ [&callback](const IAsyncOperationWithProgress<DeploymentResult, DeploymentProgress>&, DeploymentProgress progress)
29+ {
30+ callback.OnProgress (progress.percentage , 100 , ProgressType::Percent);
31+ }
32+ );
33+
34+ // Set progress callback.
35+ deployOperation.Progress (progressCallback);
36+
37+ auto removeCancel = callback.SetCancellationFunction ([&]() { deployOperation.Cancel (); });
38+ auto deployResult = deployOperation.get ();
39+
40+ if (!SUCCEEDED (deployResult.ExtendedErrorCode ()))
41+ {
42+ AICLI_LOG (Core, Error, << " Deployment failed #" << id << " : " << Utility::ConvertToUTF8 (deployResult.ErrorText ()));
43+
44+ // Note that while the format string is char*, it gets converted to wchar before being used and thus %s needs a wchar.
45+ THROW_HR_MSG (deployResult.ExtendedErrorCode (), " Install failed: %s" , deployResult.ErrorText ().c_str ());
46+ }
47+ else
48+ {
49+ AICLI_LOG (Core, Info, << " Successfully deployed #" << id);
50+ }
51+ }
52+
53+ // Type that exists simply to enabled a fire and forget register call as we exit.
54+ struct DelayRegisterStorage
55+ {
56+ DelayRegisterStorage () = default ;
57+
58+ ~DelayRegisterStorage ()
59+ {
60+ PackageManager packageManager;
61+
62+ for (const auto & fn : m_familyNames)
63+ {
64+ size_t id = GetDeploymentOperationId ();
65+ AICLI_LOG (Core, Info, << " Starting RegisterPackageByFamilyName operation #" << id << " : " << fn);
66+
67+ winrt::hstring familyName = Utility::ConvertToUTF16 (fn).c_str ();
68+ (void )packageManager.RegisterPackageByFamilyNameAsync (
69+ familyName,
70+ nullptr ,
71+ winrt::Windows::Management::Deployment::DeploymentOptions::None,
72+ nullptr ,
73+ nullptr );
74+ }
75+ }
76+
77+ void Add (std::string_view familyName)
78+ {
79+ m_familyNames.emplace_back (familyName);
80+ }
81+
82+ private:
83+ std::vector<std::string> m_familyNames;
84+ };
85+
86+ DelayRegisterStorage s_delayRegisterStorage;
1887 }
1988
2089 void RequestAddPackageAsync (
2190 const winrt::Windows::Foundation::Uri& uri,
2291 winrt::Windows::Management::Deployment::DeploymentOptions options,
2392 IProgressCallback& callback)
2493 {
25- using namespace winrt ::Windows::Foundation;
26- using namespace winrt ::Windows::Management::Deployment;
27-
2894 size_t id = GetDeploymentOperationId ();
2995 AICLI_LOG (Core, Info, << " Starting RequestAddPackage operation #" << id << " : " << Utility::ConvertToUTF8 (uri.AbsoluteUri ().c_str ()));
3096
@@ -39,36 +105,39 @@ namespace AppInstaller::Deployment
39105 nullptr , /* optionalAndRelatedPackageFamilyNames*/
40106 nullptr /* relatedPackageUris*/ );
41107
42- AsyncOperationProgressHandler<DeploymentResult, DeploymentProgress> progressCallback (
43- [&callback](const IAsyncOperationWithProgress<DeploymentResult, DeploymentProgress>&, DeploymentProgress progress)
44- {
45- callback.OnProgress (progress.percentage , 100 , ProgressType::Percent);
46- }
47- );
108+ WaitForDeployment (deployOperation, id, callback);
109+ }
110+
111+ void StageAndDelayRegisterPackageAsync (
112+ std::string_view packageFamilyName,
113+ const winrt::Windows::Foundation::Uri& uri,
114+ winrt::Windows::Management::Deployment::DeploymentOptions stageOptions,
115+ winrt::Windows::Management::Deployment::DeploymentOptions,
116+ IProgressCallback& callback)
117+ {
118+ size_t id = GetDeploymentOperationId ();
119+ AICLI_LOG (Core, Info, << " Starting StagePackage operation #" << id << " : " << Utility::ConvertToUTF8 (uri.AbsoluteUri ().c_str ()));
48120
49- // Set progress callback.
50- deployOperation.Progress (progressCallback);
121+ PackageManager packageManager;
51122
52- auto removeCancel = callback.SetCancellationFunction ([&]() { deployOperation.Cancel (); });
53- auto deployResult = deployOperation.get ();
123+ // RequestAddPackageAsync will invoke smart screen.
124+ auto deployOperation = packageManager.StagePackageAsync (
125+ uri,
126+ nullptr , /* dependencyPackageUris*/
127+ stageOptions,
128+ nullptr , /* targetVolume*/
129+ nullptr , /* optionalAndRelatedPackageFamilyNames*/
130+ nullptr /* relatedPackageUris*/ );
54131
55- if (!SUCCEEDED (deployResult.ExtendedErrorCode ()))
56- {
57- AICLI_LOG (Core, Error, << " Deployment failed #" << id << " : " << Utility::ConvertToUTF8 (deployResult.ErrorText ()));
132+ WaitForDeployment (deployOperation, id, callback);
58133
59- // Note that while the format string is char*, it gets converted to wchar before being used and thus %s needs a wchar.
60- THROW_HR_MSG (deployResult.ExtendedErrorCode (), " Install failed: %s" , deployResult.ErrorText ().c_str ());
61- }
62- else
63- {
64- AICLI_LOG (Core, Info, << " Successfully deployed #" << id);
65- }
134+ s_delayRegisterStorage.Add (packageFamilyName);
66135 }
67136
68- void RemovePackageFireAndForget (winrt::hstring packageFullName)
137+ void RemovePackageFireAndForget (std::string_view packageFullName)
69138 {
70- using namespace winrt ::Windows::Management::Deployment;
71139 PackageManager packageManager;
72- (void )packageManager.RemovePackageAsync (packageFullName, RemovalOptions::None);
140+ winrt::hstring fullName = Utility::ConvertToUTF16 (packageFullName).c_str ();
141+ (void )packageManager.RemovePackageAsync (fullName, RemovalOptions::None);
73142 }
74143}
0 commit comments