Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cherry-Pick "Deployment Manager Repair API (#2954)" #2999

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion dev/Deployment/Deployment.idl
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ namespace Microsoft.Windows.ApplicationModel.WindowsAppRuntime
Ok,
PackageInstallRequired,
PackageInstallFailed,

[contract(DeploymentContract, 3)]
PackageRepairFailed,
};

/// Represents the result of a Deployment Manager method.
Expand All @@ -37,7 +40,7 @@ namespace Microsoft.Windows.ApplicationModel.WindowsAppRuntime
DeploymentInitializeOptions();

/// Gets or sets a value that indicates whether the processes associated with the
/// WindowsAppSDK main and singleton packages will be shut down forcibly if they are
/// WindowsAppSDK Main and Singleton packages will be shut down forcibly if they are
/// currently in use, when registering the WinAppSDK packages.
Boolean ForceDeployment;

Expand All @@ -64,5 +67,10 @@ namespace Microsoft.Windows.ApplicationModel.WindowsAppRuntime
[contract(DeploymentContract, 2)]
[overload("Initialize")]
static DeploymentResult Initialize(Microsoft.Windows.ApplicationModel.WindowsAppRuntime.DeploymentInitializeOptions deploymentInitializeOptions);

/// Checks the status of the WindowsAppRuntime of the current package and attempts to
/// repair already installed WinAppSDK packages.
[contract(DeploymentContract, 3)]
static DeploymentResult Repair();
};
}
1 change: 1 addition & 0 deletions dev/Deployment/DeploymentActivityContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ void WindowsAppRuntime::Deployment::Activity::Context::Reset()
m_deploymentErrorExtendedHresult = S_OK;
m_deploymentErrorText.clear();
m_deploymentErrorActivityId = GUID{};
m_useExistingPackageIfHigherVersion = false;
}

void WindowsAppRuntime::Deployment::Activity::Context::SetDeploymentErrorInfo(
Expand Down
19 changes: 15 additions & 4 deletions dev/Deployment/DeploymentActivityContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ namespace WindowsAppRuntime::Deployment::Activity
GUID m_deploymentErrorActivityId{};
WindowsAppRuntimeDeployment_TraceLogger::Initialize m_activity;
WilFailure m_lastFailure;
bool isFullTrustPackage{};
bool m_isFullTrustPackage{};
bool m_useExistingPackageIfHigherVersion{};

public:
static WindowsAppRuntime::Deployment::Activity::Context& Get();
Expand Down Expand Up @@ -78,9 +79,14 @@ namespace WindowsAppRuntime::Deployment::Activity
return m_lastFailure;
}

const bool& GetIsFullTrustPackage() const
const bool GetIsFullTrustPackage() const
{
return isFullTrustPackage;
return m_isFullTrustPackage;
}

const bool GetUseExistingPackageIfHigherVersion() const
{
return m_useExistingPackageIfHigherVersion;
}

void SetInstallStage(const DeploymentStage& installStage)
Expand Down Expand Up @@ -112,7 +118,12 @@ namespace WindowsAppRuntime::Deployment::Activity

void SetIsFullTrustPackage()
{
isFullTrustPackage = true;
m_isFullTrustPackage = true;
}

void SetUseExistingPackageIfHigherVersion()
{
m_useExistingPackageIfHigherVersion = true;
}
};

Expand Down
168 changes: 113 additions & 55 deletions dev/Deployment/DeploymentManager.cpp

Large diffs are not rendered by default.

14 changes: 9 additions & 5 deletions dev/Deployment/DeploymentManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,26 +18,30 @@ namespace winrt::Microsoft::Windows::ApplicationModel::WindowsAppRuntime::implem
static WindowsAppRuntime::DeploymentResult GetStatus();
static WindowsAppRuntime::DeploymentResult Initialize();
static WindowsAppRuntime::DeploymentResult Initialize(WindowsAppRuntime::DeploymentInitializeOptions const& deploymentInitializeOptions);
static WindowsAppRuntime::DeploymentResult Repair();

private:
static WindowsAppRuntime::DeploymentResult GetStatus(hstring const& packageFullName);
static WindowsAppRuntime::DeploymentResult Initialize(hstring const& packageFullName);
static WindowsAppRuntime::DeploymentResult Initialize(hstring const& packageFullName, WindowsAppRuntime::DeploymentInitializeOptions const& deploymentInitializeOptions);
static WindowsAppRuntime::DeploymentResult Initialize(hstring const& packageFullName,
WindowsAppRuntime::DeploymentInitializeOptions const& deploymentInitializeOptions,
bool isRepair = false);

private:
static WindowsAppRuntime::DeploymentResult _Initialize(
::WindowsAppRuntime::Deployment::Activity::Context& initializeActivityContext,
hstring const& packageFullName,
WindowsAppRuntime::DeploymentInitializeOptions const& deploymentInitializeOptions);
WindowsAppRuntime::DeploymentInitializeOptions const& deploymentInitializeOptions,
bool isRepair);

private:
static MddCore::PackageInfo GetPackageInfoForPackage(std::wstring const& packageFullName);
static std::vector<std::wstring> FindPackagesByFamily(std::wstring const& packageFamilyName);
static HRESULT VerifyPackage(const std::wstring& packageFamilyName, const PACKAGE_VERSION targetVersion);
static HRESULT VerifyPackage(const std::wstring& packageFamilyName, const PACKAGE_VERSION targetVersion, __out std::wstring& matchedPackageFullName);
static std::wstring GetPackagePath(std::wstring const& packageFullName);
static HRESULT AddPackageInBreakAwayProcess(const std::filesystem::path& packagePath, const bool forceDeployment);
static HRESULT AddOrRegisterPackageInBreakAwayProcess(const std::filesystem::path& packagePath, const bool regiterHigherVersionPackage, const bool forceDeployment);
static std::wstring GenerateDeploymentAgentPath();
static HRESULT AddPackage(const std::filesystem::path& packagePath, const bool forceDeployment);
static HRESULT AddOrRegisterPackage(const std::filesystem::path& package, const bool regiterHigherVersionPackage, const bool forceDeployment);
static HRESULT DeployPackages(const std::wstring& frameworkPackageFullName, const bool forceDeployment);
static HRESULT Deploy(const std::wstring& frameworkPackageFullName, const bool forceDeployment = false);
static HRESULT InstallLicenses(const std::wstring& frameworkPackageFullName);
Expand Down
10 changes: 6 additions & 4 deletions dev/Deployment/DeploymentTraceLogging.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class WindowsAppRuntimeDeployment_TraceLogger final : public wil::TraceLoggingPr
public:

BEGIN_COMPLIANT_CRITICAL_DATA_ACTIVITY_CLASS(Initialize, PDT_ProductAndServicePerformance);
void StartActivity(bool forceDeployment, bool isElevated, bool isPackagedProcess, DWORD integrityLevel)
void StartActivity(bool forceDeployment, bool isElevated, bool isPackagedProcess, bool isFullTrustPackage, DWORD integrityLevel, bool isRepair)
{
// Clear the process-wide callback set in Start
wil::SetResultLoggingCallback(nullptr);
Expand All @@ -33,7 +33,9 @@ class WindowsAppRuntimeDeployment_TraceLogger final : public wil::TraceLoggingPr
TraceLoggingValue(forceDeployment, "forceDeployment"),
TraceLoggingValue(isElevated, "isElevated"),
TraceLoggingValue(isPackagedProcess, "isPackagedProcess"),
TraceLoggingValue(integrityLevel, "integrityLevel"));
TraceLoggingValue(isFullTrustPackage, "isFullTrustPackage"),
TraceLoggingValue(integrityLevel, "integrityLevel"),
TraceLoggingValue(isRepair, "isRepairAPI"));
}
void StopWithResult(
HRESULT hresult,
Expand All @@ -48,7 +50,7 @@ class WindowsAppRuntimeDeployment_TraceLogger final : public wil::TraceLoggingPr
HRESULT deploymentErrorExtendedHResult,
PCWSTR deploymentErrorText,
GUID deploymentErrorActivityId,
bool isFullTrustPackage)
bool useExistingPackageIfHigherVersion)
{
// Set a process-wide callback function for WIL to call each time it logs a failure.
wil::SetResultLoggingCallback(nullptr);
Expand All @@ -69,7 +71,7 @@ class WindowsAppRuntimeDeployment_TraceLogger final : public wil::TraceLoggingPr
TraceLoggingValue(deploymentErrorExtendedHResult, "DeploymentErrorExtendedHResult"),
TraceLoggingValue(deploymentErrorText, "DeploymentErrorText"),
TraceLoggingValue(deploymentErrorActivityId, "DeploymentErrorActivityId"),
TraceLoggingValue(isFullTrustPackage, "isFullTrustPackage"));
TraceLoggingValue(useExistingPackageIfHigherVersion, "useExistingPackageIfHigherVersion"));
}
else
{
Expand Down
4 changes: 4 additions & 0 deletions dev/Deployment/PackageDefinitions.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#define WINDOWSAPPRUNTIME_PACKAGE_SUBTYPENAME_DDLM L"DDLM"
#define WINDOWSAPPRUNTIME_FRAMEWORK_PACKAGE_FOLDER L"MSIX"
#define WINDOWSAPPRUNTIME_FRAMEWORK_PACKAGE_FILE_EXTENSION L".msix"
#define WINDOWSAPPRUNTIME_PACKAGE_MANIFEST_FILE L"AppxManifest.xml"

namespace winrt::Microsoft::Windows::ApplicationModel::WindowsAppRuntime::implementation
{
Expand Down Expand Up @@ -48,4 +49,7 @@ namespace winrt::Microsoft::Windows::ApplicationModel::WindowsAppRuntime::implem
{ WINDOWSAPPRUNTIME_PACKAGE_NAME_MAINPREFIX, WINDOWSAPPRUNTIME_PACKAGE_SUBTYPENAME_MAIN, PackageVersionType::Versioned },
{ WINDOWSAPPRUNTIME_PACKAGE_NAME_SINGLETONPREFIX, WINDOWSAPPRUNTIME_PACKAGE_SUBTYPENAME_SINGLETON, PackageVersionType::Unversioned },
};

// Record existing target package full name(s) to deploy (specifically, re-register) if it's higher version than that of the current framework package version, in this global map.
static std::map<std::wstring, std::wstring> g_existingTargetPackagesIfHigherVersion;
}
52 changes: 37 additions & 15 deletions dev/DeploymentAgent/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@

using namespace winrt::Windows::Foundation;

int APIENTRY wWinMain(HINSTANCE, HINSTANCE, LPWSTR, int)
// argv[1] tells whether to use AddPackageAsync (argv[1] == "0") or RegisterPackageAsync (argv[1] == "1") on the path passed in argv[2].
int APIENTRY wWinMain(HINSTANCE, HINSTANCE, LPWSTR, int) try
{
int argc{};
const std::wstring cmdLine{ GetCommandLineW() };
Expand All @@ -17,22 +18,30 @@ int APIENTRY wWinMain(HINSTANCE, HINSTANCE, LPWSTR, int)
WindowsAppRuntimeDeploymentAgent_TraceLogger::FailedDueToBadArguments(argc);
return HRESULT_FROM_WIN32(ERROR_BAD_ARGUMENTS);
}
std::filesystem::path packagePath{ argv[1] };

bool useExistingPackageIfHigherVersion{};
if (argc >= 2)
{
if (CompareStringOrdinal(argv[1], -1, L"1", -1, TRUE) == CSTR_EQUAL)
{
useExistingPackageIfHigherVersion = true;
}
}

bool forceDeployment{};
if (argc >= 3)
if (argc >= 4)
{
if (CompareStringOrdinal(argv[2], -1, L"1", -1, TRUE) == CSTR_EQUAL)
if (CompareStringOrdinal(argv[3], -1, L"1", -1, TRUE) == CSTR_EQUAL)
{
forceDeployment = true;
}
}

GUID callerActivityId{};
if (argc >= 4)
if (argc >= 5)
{
// Best effort for telemetry purpose and a failure doesn't affect functionality.
std::ignore = CLSIDFromString(argv[3], &callerActivityId);
std::ignore = CLSIDFromString(argv[4], &callerActivityId);
}

winrt::Windows::Management::Deployment::PackageManager packageManager;
Expand All @@ -41,30 +50,43 @@ int APIENTRY wWinMain(HINSTANCE, HINSTANCE, LPWSTR, int)
winrt::Windows::Management::Deployment::DeploymentOptions::ForceTargetApplicationShutdown :
winrt::Windows::Management::Deployment::DeploymentOptions::None };

const auto packagePathUri{ winrt::Windows::Foundation::Uri(packagePath.c_str()) };
const auto deploymentOperation{ packageManager.AddPackageAsync(packagePathUri, nullptr, options) };
winrt::Windows::Foundation::IAsyncOperationWithProgress<winrt::Windows::Management::Deployment::DeploymentResult,
winrt::Windows::Management::Deployment::DeploymentProgress> deploymentOperation;
const auto pathUri{ winrt::Windows::Foundation::Uri(argv[2]) };
if (useExistingPackageIfHigherVersion)
{
deploymentOperation = packageManager.RegisterPackageAsync(pathUri, nullptr, options); }
else
{
deploymentOperation = packageManager.AddPackageAsync(pathUri, nullptr, options);
}

deploymentOperation.get();
const auto deploymentResult{ deploymentOperation.GetResults() };
if (deploymentOperation.Status() != AsyncStatus::Completed)
{
HRESULT hr = static_cast<HRESULT>(deploymentOperation.ErrorCode());
if (FAILED(hr))
HRESULT deploymentOperationHResult = static_cast<HRESULT>(deploymentOperation.ErrorCode());
HRESULT deploymentOperationExtendedHResult = static_cast<HRESULT>(deploymentResult.ExtendedErrorCode());
if (FAILED(deploymentOperationHResult))
{
WindowsAppRuntimeDeploymentAgent_TraceLogger::FailedInDeployment(
hr,
packagePath.wstring().c_str(),
deploymentOperationHResult,
argv[1],
argv[2],
forceDeployment,
callerActivityId,
deploymentResult.ExtendedErrorCode(),
deploymentOperationExtendedHResult,
deploymentResult.ErrorText().c_str(),
deploymentResult.ActivityId());
}
return deploymentResult.ExtendedErrorCode();
return deploymentOperationExtendedHResult ? deploymentOperationExtendedHResult : deploymentOperationHResult;
}

WindowsAppRuntimeDeploymentAgent_TraceLogger::Success(
packagePath.wstring().c_str(),
argv[1],
argv[2],
forceDeployment,
callerActivityId);
return S_OK;
}
CATCH_RETURN()
10 changes: 6 additions & 4 deletions dev/DeploymentAgent/tracelogging.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,11 @@ class WindowsAppRuntimeDeploymentAgent_TraceLogger final : public wil::TraceLogg

public:

DEFINE_COMPLIANT_CRITICAL_DATA_EVENT_PARAM3(
DEFINE_COMPLIANT_CRITICAL_DATA_EVENT_PARAM4(
Success,
PDT_ProductAndServicePerformance,
PCWSTR, packagePath,
bool, useExistingPackageIfHigherVersion,
PCWSTR, path,
bool, forceDeployment,
GUID, callerActivityId);

Expand All @@ -27,11 +28,12 @@ class WindowsAppRuntimeDeploymentAgent_TraceLogger final : public wil::TraceLogg
PDT_ProductAndServicePerformance,
UINT32, argsCount);

DEFINE_COMPLIANT_CRITICAL_DATA_EVENT_PARAM7(
DEFINE_COMPLIANT_CRITICAL_DATA_EVENT_PARAM8(
FailedInDeployment,
PDT_ProductAndServicePerformance,
HRESULT, hresult,
PCWSTR, packagePath,
bool, useExistingPackageIfHigherVersion,
PCWSTR, path,
bool, forceDeployment,
GUID, callerActivityId,
HRESULT, deploymentExtendedError,
Expand Down