diff --git a/dev/Deployment/DeploymentManager.cpp b/dev/Deployment/DeploymentManager.cpp index a342ad5757..fdebcf09e5 100644 --- a/dev/Deployment/DeploymentManager.cpp +++ b/dev/Deployment/DeploymentManager.cpp @@ -46,6 +46,26 @@ inline void Initialize_StopSuccessActivity( initializeActivityContext.GetUseExistingPackageIfHigherVersion()); } +inline void GetStatus_StopSuccessActivity( + ::WindowsAppRuntime::Deployment::Activity::Context& activityContext, + const winrt::Microsoft::Windows::ApplicationModel::WindowsAppRuntime::DeploymentStatus& deploymentStatus) +{ + activityContext.GetActivity().StopWithResult( + S_OK, + static_cast(0), + static_cast(nullptr), + static_cast(0), + static_cast(nullptr), + static_cast(nullptr), + static_cast(deploymentStatus), + static_cast(::WindowsAppRuntime::Deployment::Activity::DeploymentStage::None), + static_cast(nullptr), + S_OK, + static_cast(nullptr), + GUID{}, + false /*useExistingPackageIfHigherVersion*/); +} + namespace winrt::Microsoft::Windows::ApplicationModel::WindowsAppRuntime::implementation { static bool s_isInitialized{ false }; @@ -53,8 +73,67 @@ namespace winrt::Microsoft::Windows::ApplicationModel::WindowsAppRuntime::implem winrt::Microsoft::Windows::ApplicationModel::WindowsAppRuntime::DeploymentResult DeploymentManager::GetStatus() { - FAIL_FAST_HR_IF(HRESULT_FROM_WIN32(APPMODEL_ERROR_NO_PACKAGE), !AppModel::Identity::IsPackagedProcess()); - return GetStatus(GetCurrentFrameworkPackageFullName()); + // Start telemetry FIRST so we capture all failures, including unpackaged process errors. + auto& activityContext{ ::WindowsAppRuntime::Deployment::Activity::Context::Get() }; + + // Start activity immediately with safe defaults - the WIL callback will capture any errors. + activityContext.GetActivity().Start( + false /*forceDeployment*/, + Security::IntegrityLevel::IsElevated(), + true /*isPackagedProcess - assume true, we check below*/, + false /*isFullTrustPackage*/, + 0 /*integrityLevel*/, + false /*isRepair*/, + true /*isGetStatus*/); + + // Now check if packaged - errors are captured by telemetry + const bool isPackagedProcess{ AppModel::Identity::IsPackagedProcess() }; + if (!isPackagedProcess) + { + // Stop telemetry and fail fast + activityContext.GetActivity().StopWithResult( + HRESULT_FROM_WIN32(APPMODEL_ERROR_NO_PACKAGE), + static_cast(wil::FailureType::FailFast), + __FILE__, + __LINE__, + L"GetStatus called from unpackaged process", + static_cast(nullptr), + static_cast(winrt::Microsoft::Windows::ApplicationModel::WindowsAppRuntime::DeploymentStatus::Unknown), + static_cast(::WindowsAppRuntime::Deployment::Activity::DeploymentStage::None), + L"IsPackagedProcess", + S_OK, + static_cast(nullptr), + GUID{}, + false); + FAIL_FAST_HR(HRESULT_FROM_WIN32(APPMODEL_ERROR_NO_PACKAGE)); + } + + try + { + auto result = GetStatus(GetCurrentFrameworkPackageFullName()); + GetStatus_StopSuccessActivity(activityContext, result.Status()); + return result; + } + catch (...) + { + // Capture exception in telemetry before re-throwing + const HRESULT hr = wil::ResultFromCaughtException(); + activityContext.GetActivity().StopWithResult( + hr, + static_cast(wil::FailureType::Exception), + static_cast(nullptr), + static_cast(0), + static_cast(nullptr), + static_cast(nullptr), + static_cast(winrt::Microsoft::Windows::ApplicationModel::WindowsAppRuntime::DeploymentStatus::Unknown), + static_cast(::WindowsAppRuntime::Deployment::Activity::DeploymentStage::None), + L"GetStatus", + S_OK, + static_cast(nullptr), + GUID{}, + false); + throw; + } } winrt::Microsoft::Windows::ApplicationModel::WindowsAppRuntime::DeploymentResult DeploymentManager::Initialize() @@ -66,13 +145,88 @@ namespace winrt::Microsoft::Windows::ApplicationModel::WindowsAppRuntime::implem winrt::Microsoft::Windows::ApplicationModel::WindowsAppRuntime::DeploymentResult DeploymentManager::Initialize( winrt::Microsoft::Windows::ApplicationModel::WindowsAppRuntime::DeploymentInitializeOptions const& deploymentInitializeOptions) { - return Initialize(GetCurrentFrameworkPackageFullName(), deploymentInitializeOptions); + // Start telemetry FIRST so we capture all failures, including framework discovery errors. + auto& initializeActivityContext{ ::WindowsAppRuntime::Deployment::Activity::Context::Get() }; + + // Start activity immediately with safe defaults - the WIL callback will capture any errors + // that occur during GetCurrentFrameworkPackageFullName() or subsequent operations. + initializeActivityContext.GetActivity().Start( + deploymentInitializeOptions.ForceDeployment(), + false /*isElevated - actual value determined later*/, + true /*isPackagedProcess - assume true as safe default*/, + false /*isFullTrustPackage - determined later*/, + 0 /*integrityLevel - determined later*/, + false /*isRepair*/, + false /*isGetStatus*/); + + try + { + return Initialize(GetCurrentFrameworkPackageFullName(), deploymentInitializeOptions); + } + catch (...) + { + // Capture exception in telemetry before re-throwing + const HRESULT hr = wil::ResultFromCaughtException(); + initializeActivityContext.GetActivity().StopWithResult( + hr, + static_cast(wil::FailureType::Exception), + static_cast(nullptr), + static_cast(0), + static_cast(nullptr), + static_cast(nullptr), + static_cast(winrt::Microsoft::Windows::ApplicationModel::WindowsAppRuntime::DeploymentStatus::PackageInstallRequired), + static_cast(::WindowsAppRuntime::Deployment::Activity::DeploymentStage::DiscoverFramework), + L"GetCurrentFrameworkPackageFullName", + S_OK, + static_cast(nullptr), + GUID{}, + false); + throw; + } } winrt::Microsoft::Windows::ApplicationModel::WindowsAppRuntime::DeploymentResult DeploymentManager::Repair() { winrt::Microsoft::Windows::ApplicationModel::WindowsAppRuntime::DeploymentInitializeOptions options{}; - return Initialize(GetCurrentFrameworkPackageFullName(), options, true); + + // Start telemetry FIRST so we capture all failures, including framework discovery errors. + auto& initializeActivityContext{ ::WindowsAppRuntime::Deployment::Activity::Context::Get() }; + + // Start activity immediately with safe defaults - the WIL callback will capture any errors + // that occur during GetCurrentFrameworkPackageFullName() or subsequent operations. + initializeActivityContext.GetActivity().Start( + options.ForceDeployment(), + false /*isElevated - actual value determined later*/, + true /*isPackagedProcess - assume true as safe default*/, + false /*isFullTrustPackage - determined later*/, + 0 /*integrityLevel - determined later*/, + true /*isRepair*/, + false /*isGetStatus*/); + + try + { + return Initialize(GetCurrentFrameworkPackageFullName(), options, true); + } + catch (...) + { + // Capture exception in telemetry before re-throwing + const HRESULT hr = wil::ResultFromCaughtException(); + initializeActivityContext.GetActivity().StopWithResult( + hr, + static_cast(wil::FailureType::Exception), + static_cast(nullptr), + static_cast(0), + static_cast(nullptr), + static_cast(nullptr), + static_cast(winrt::Microsoft::Windows::ApplicationModel::WindowsAppRuntime::DeploymentStatus::PackageInstallRequired), + static_cast(::WindowsAppRuntime::Deployment::Activity::DeploymentStage::DiscoverFramework), + L"GetCurrentFrameworkPackageFullName", + S_OK, + static_cast(nullptr), + GUID{}, + false); + throw; + } } std::wstring ExtractFormattedVersionTag(const std::wstring& versionTag) @@ -217,8 +371,12 @@ namespace winrt::Microsoft::Windows::ApplicationModel::WindowsAppRuntime::implem initializeActivityContext.SetIsFullTrustPackage(); } - initializeActivityContext.GetActivity().Start(deploymentInitializeOptions.ForceDeployment(), Security::IntegrityLevel::IsElevated(), - isPackagedProcess, initializeActivityContext.GetIsFullTrustPackage(), integrityLevel, isRepair); + // Only start telemetry if not already running (public APIs start it before calling us). + if (!initializeActivityContext.GetActivity().IsRunning()) + { + initializeActivityContext.GetActivity().Start(deploymentInitializeOptions.ForceDeployment(), Security::IntegrityLevel::IsElevated(), + isPackagedProcess, initializeActivityContext.GetIsFullTrustPackage(), integrityLevel, isRepair); + } // DeploymentManager API requires a packaged process? winrt::Microsoft::Windows::ApplicationModel::WindowsAppRuntime::DeploymentResult deploymentResult{ winrt::Microsoft::Windows::ApplicationModel::WindowsAppRuntime::DeploymentStatus::Unknown, S_OK }; diff --git a/dev/Deployment/DeploymentTraceLogging.h b/dev/Deployment/DeploymentTraceLogging.h index f8f90e79c4..6a8d65149f 100644 --- a/dev/Deployment/DeploymentTraceLogging.h +++ b/dev/Deployment/DeploymentTraceLogging.h @@ -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, bool isFullTrustPackage, DWORD integrityLevel, bool isRepair) + void StartActivity(bool forceDeployment, bool isElevated, bool isPackagedProcess, bool isFullTrustPackage, DWORD integrityLevel, bool isRepair, bool isGetStatus = false) { // Clear the process-wide callback set in Start wil::SetResultLoggingCallback(nullptr); @@ -35,7 +35,8 @@ class WindowsAppRuntimeDeployment_TraceLogger final : public wil::TraceLoggingPr TraceLoggingValue(isPackagedProcess, "isPackagedProcess"), TraceLoggingValue(isFullTrustPackage, "isFullTrustPackage"), TraceLoggingValue(integrityLevel, "integrityLevel"), - TraceLoggingValue(isRepair, "isRepairAPI")); + TraceLoggingValue(isRepair, "isRepairAPI"), + TraceLoggingValue(isGetStatus, "isGetStatusAPI")); } void StopWithResult( HRESULT hresult,