Skip to content

Commit

Permalink
Rich information on Bootstrap initalization failure (#2316)
Browse files Browse the repository at this point in the history
* On error in MddBootstrapIntialize log to EventLog and optionally DebugBreak, FailFast and/or prompt to install

* Added ShowUI to C++ auto-initializer.

* Remove hardcoded language tag in URL

Co-authored-by: Rafael Rivera <[email protected]>

* Incorporated feedback

* Update C++ AutoInitializer to use MddBootstrapInitialize2 with options override (for those who don't like the default)

* Add MddBootstrapInitializeOptions_OnPackageIdentity_NOP with tests

* Moar tests. Fixed NOP/NOOP typo. Added C# support for InitializeOptions and use MddBootstrapInitialize2

* Let's try that. C# AutoInitializer options override

* Added build option to control auto-initializer (WindowsAppSDKBootstrapAutoInitialize=false, default=true). Added boolean control over the new options e.g. <WindowsAppSDKBootstrapAutoInitializeOptions_OnNoMatch_ShowUI>true</>

* Minnor reformatting and cleanup

* Changed to use TryInitialize and Exit (instead of throwing Initialize and FailFast) for less misleading error symptoms

* Incorporated feedbacck

* Incorproated feedback. Removed some stale comments

* Removed unnecessary extra checks for WindowsAppSDKBootstrapInitialize

* Renamed Microsoft.WindowsAppSDK.MddCommon.targets to Microsoft.WindowsAppSDK.BootstrapCommon.targets. Mdd==DynamicDependencies, which is a generic facility for any packcage. Bootstrap==specialization of DynamicDependencies, uniquely for WindowsAppSDK's runtime

* Updated reference to MddCommon

Co-authored-by: Rafael Rivera <[email protected]>
  • Loading branch information
DrusTheAxe and riverar authored Apr 1, 2022
1 parent 03a53a2 commit 003df95
Show file tree
Hide file tree
Showing 14 changed files with 589 additions and 54 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -62,15 +62,15 @@ jobs:
Copy-Item -Path "$targetsFilePath\Microsoft.WindowsAppSDK.Foundation.props" -Destination "$fullpackagePath\build\Microsoft.WindowsAppSDK.Foundation.props"
Copy-Item -Path "$targetsFilePath\Microsoft.WindowsAppSDK.Bootstrap.CS.targets" -Destination "$fullpackagePath\build\Microsoft.WindowsAppSDK.Bootstrap.CS.targets"
Copy-Item -Path "$targetsFilePath\WindowsAppSDK-Nuget-Native.Bootstrap.targets" -Destination "$fullpackagePath\build\native\WindowsAppSDK-Nuget-Native.Bootstrap.targets"
Copy-Item -Path "$targetsFilePath\Microsoft.WindowsAppSDK.MddCommon.targets" -Destination "$fullpackagePath\build\Microsoft.WindowsAppSDK.MddCommon.targets"
Copy-Item -Path "$targetsFilePath\Microsoft.WindowsAppSDK.BootstrapCommon.targets" -Destination "$fullpackagePath\build\Microsoft.WindowsAppSDK.BootstrapCommon.targets"
Copy-Item -Path "$targetsFilePath\AppxManifest.xml" -Destination "$fullpackagePath\AppxManifest.xml"
$manifestPath = $fullpackagePath+'\manifests';
New-Item -ItemType Directory -Force -Path $manifestPath;
$xslt = New-Object System.Xml.Xsl.XslCompiledTransform;
$xslt.Load('build\TransformAppxManifest.xslt');
$xslt.Transform($fullpackagePath+'\AppxManifest.xml', $manifestPath+'\Microsoft.WindowsAppSdk.Foundation.manifest');
# - script: |
# dir /s $(Build.SourcesDirectory)

Expand Down
16 changes: 13 additions & 3 deletions build/NuSpecs/Microsoft.WindowsAppSDK.Bootstrap.CS.targets
Original file line number Diff line number Diff line change
@@ -1,7 +1,17 @@
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

<Target Name="GenerateBootstrapCS"
BeforeTargets="BeforeCompile">
<PropertyGroup>
<DefineConstants
<DefineConstants Condition="'$(WindowsAppSDKBootstrapAutoInitializeOptions_Default)'=='true'">$(DefineConstants);MICROSOFT_WINDOWSAPPSDK_BOOTSTRAP_AUTO_INITIALIZE_OPTIONS_DEFAULT</DefineConstants>
<DefineConstants Condition="'$(WindowsAppSDKBootstrapAutoInitializeOptions_None)'=='true'">$(DefineConstants);MICROSOFT_WINDOWSAPPSDK_BOOTSTRAP_AUTO_INITIALIZE_OPTIONS_NONE</DefineConstants>
<DefineConstants Condition="'$(WindowsAppSDKBootstrapAutoInitializeOptions_OnError_DebugBreak)'=='true'">$(DefineConstants);MICROSOFT_WINDOWSAPPSDK_BOOTSTRAP_AUTO_INITIALIZE_OPTIONS_ONERROR_DEBUGBREAK</DefineConstants>
<DefineConstants Condition="'$(WindowsAppSDKBootstrapAutoInitializeOptions_OnError_DebugBreak_IfDebuggerAttached)'=='true'">$(DefineConstants);MICROSOFT_WINDOWSAPPSDK_BOOTSTRAP_AUTO_INITIALIZE_OPTIONS_ONERROR_DEBUGBREAK_IFDEBUGGERATTACHED</DefineConstants>
<DefineConstants Condition="'$(WindowsAppSDKBootstrapAutoInitializeOptions_OnError_FailFast)'=='true'">$(DefineConstants);MICROSOFT_WINDOWSAPPSDK_BOOTSTRAP_AUTO_INITIALIZE_OPTIONS_ONERROR_FAILFAST</DefineConstants>
<DefineConstants Condition="'$(WindowsAppSDKBootstrapAutoInitializeOptions_OnNoMatch_ShowUI)'=='true'">$(DefineConstants);MICROSOFT_WINDOWSAPPSDK_BOOTSTRAP_AUTO_INITIALIZE_OPTIONS_ONNOMATCH_SHOWUI</DefineConstants>
<DefineConstants Condition="'$(WindowsAppSDKBootstrapAutoInitializeOptions_OnPackageIdentity_NoOp)'=='true'">$(DefineConstants);MICROSOFT_WINDOWSAPPSDK_BOOTSTRAP_AUTO_INITIALIZE_OPTIONS_ONPACKAGEIDENTITY_NOOP</DefineConstants>
</PropertyGroup>

<Target Name="GenerateBootstrapCS" BeforeTargets="BeforeCompile">
<ItemGroup>
<Compile Include="$(MSBuildThisFileDirectory)..\include\MddBootstrapAutoInitializer.cs" />
<Compile Include="$(MSBuildThisFileDirectory)..\include\WindowsAppSDK-VersionInfo.cs" />
Expand Down
2 changes: 1 addition & 1 deletion build/NuSpecs/Microsoft.WindowsAppSDK.Foundation.targets
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@
<!-- Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT License. See LICENSE in the project root for license information. -->
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildThisFileDirectory)MrtCore.targets" />
<Import Project="$(MSBuildThisFileDirectory)Microsoft.WindowsAppSDK.MddCommon.targets" />
<Import Project="$(MSBuildThisFileDirectory)Microsoft.WindowsAppSDK.BootstrapCommon.targets" />
<Import Project="$(MSBuildThisFileDirectory)Microsoft.WindowsAppSDK.Bootstrap.CS.targets" Condition="'$(WindowsAppSdkBootstrapInitialize)' == 'true'"/>
</Project>
18 changes: 12 additions & 6 deletions build/NuSpecs/WindowsAppSDK-Nuget-Native.Bootstrap.targets
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

<Target Name="GenerateBootstrapCpp"
BeforeTargets="ClCompile">
<Target Name="GenerateBootstrapCpp" BeforeTargets="ClCompile">
<ItemGroup>
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\include\MddBootstrapAutoInitializer.cpp">
<PrecompiledHeader>NotUsing</PrecompiledHeader>
</ClCompile>
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\include\MddBootstrapAutoInitializer.cpp">
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<PreprocessorDefinitions Condition="'$(WindowsAppSDKBootstrapAutoInitializeOptions_Default)'=='true'">MICROSOFT_WINDOWSAPPSDK_BOOTSTRAP_AUTO_INITIALIZE_OPTIONS_DEFAULT;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions Condition="'$(WindowsAppSDKBootstrapAutoInitializeOptions_None)'=='true'">MICROSOFT_WINDOWSAPPSDK_BOOTSTRAP_AUTO_INITIALIZE_OPTIONS_NONE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions Condition="'$(WindowsAppSDKBootstrapAutoInitializeOptions_OnError_DebugBreak)'=='true'">MICROSOFT_WINDOWSAPPSDK_BOOTSTRAP_AUTO_INITIALIZE_OPTIONS_ONERROR_DEBUGBREAK;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions Condition="'$(WindowsAppSDKBootstrapAutoInitializeOptions_OnError_DebugBreak_IfDebuggerAttached)'=='true'">MICROSOFT_WINDOWSAPPSDK_BOOTSTRAP_AUTO_INITIALIZE_OPTIONS_ONERROR_DEBUGBREAK_IFDEBUGGERATTACHED;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions Condition="'$(WindowsAppSDKBootstrapAutoInitializeOptions_OnError_FailFast)'=='true'">MICROSOFT_WINDOWSAPPSDK_BOOTSTRAP_AUTO_INITIALIZE_OPTIONS_ONERROR_FAILFAST;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions Condition="'$(WindowsAppSDKBootstrapAutoInitializeOptions_OnNoMatch_ShowUI)'=='true'">MICROSOFT_WINDOWSAPPSDK_BOOTSTRAP_AUTO_INITIALIZE_OPTIONS_ONNOMATCH_SHOWUI;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions Condition="'$(WindowsAppSDKBootstrapAutoInitializeOptions_OnPackageIdentity_NoOp)'=='true'">MICROSOFT_WINDOWSAPPSDK_BOOTSTRAP_AUTO_INITIALIZE_OPTIONS_ONPACKAGEIDENTITY_NOOP;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
</ItemGroup>
</Target>

Expand Down
2 changes: 1 addition & 1 deletion build/NuSpecs/WindowsAppSDK-Nuget-Native.targets
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@
</Reference>
</ItemGroup>

<Import Project="$(MSBuildThisFileDirectory)..\Microsoft.WindowsAppSDK.MddCommon.targets" />
<Import Project="$(MSBuildThisFileDirectory)..\Microsoft.WindowsAppSDK.BootstrapCommon.targets" />
<Import Project="$(MSBuildThisFileDirectory)WindowsAppSDK-Nuget-Native.Bootstrap.targets" Condition="'$(WindowsAppSdkBootstrapInitialize)' == 'true'"/>

</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -66,11 +66,11 @@ public override string ToString()

internal static class NativeMethods
{
[DllImport("Microsoft.WindowsAppRuntime.Bootstrap.dll", EntryPoint = "MddBootstrapInitialize", CharSet = CharSet.Unicode, ExactSpelling = true, PreserveSig = false)]
internal static extern void MddBootstrapInitialize_Throw(uint majorMinorVersion, string versionTag, PackageVersion packageVersion);
[DllImport("Microsoft.WindowsAppRuntime.Bootstrap.dll", EntryPoint = "MddBootstrapInitialize2", CharSet = CharSet.Unicode, ExactSpelling = true, PreserveSig = false)]
internal static extern void MddBootstrapInitialize2_Throw(uint majorMinorVersion, string versionTag, PackageVersion packageVersion, Bootstrap.InitializeOptions options);

[DllImport("Microsoft.WindowsAppRuntime.Bootstrap.dll", CharSet = CharSet.Unicode, ExactSpelling = true)]
internal static extern int MddBootstrapInitialize(uint majorMinorVersion, string versionTag, PackageVersion packageVersion);
internal static extern int MddBootstrapInitialize2(uint majorMinorVersion, string versionTag, PackageVersion packageVersion, Bootstrap.InitializeOptions options);

[DllImport("Microsoft.WindowsAppRuntime.Bootstrap.dll", ExactSpelling = true)]
internal static extern void MddBootstrapShutdown();
Expand All @@ -79,17 +79,40 @@ internal static class NativeMethods
// The Windows App SDK bootstrap initialization API.
public class Bootstrap
{
/// Options for Bootstrap initialization APIs.
public enum InitializeOptions : int
{
/// Default behavior
None = 0,

/// If not successful call DebugBreak()
OnError_DebugBreak = 0x0001,

/// If not successful call DebugBreak() if a debugger is attached to the process
OnError_DebugBreak_IfDebuggerAttached = 0x0002,

/// If not successful perform a fail-fast
OnError_FailFast = 0x0004,

/// If a compatible Windows App Runtime framework package is not found show UI
OnNoMatch_ShowUI = 0x0008,

/// Do nothing (do not error) if the process has package identity
OnPackageIdentity_NOOP = 0x0010,
}

/// Initialize the calling process to use Windows App SDK's framework package.
///
/// Find a Windows App SDK framework package meeting the criteria and make it available
/// for use by the current process. If multiple packages meet the criteria the best
/// candidate is selected.
///
/// This is equivalent to `Initialize(majorMinorVersion, null, new PackageVersion())`.
/// This is equivalent to `Initialize(majorMinorVersion, null, new PackageVersion(), InitializeOptions.None)`.
///
/// @param majorMinorVersion major and minor version of Windows App SDK's framework package, encoded as `0xMMMMNNNN` where M=Major, N=Minor (e.g. 1.2 == 0x00010002).
/// @see Initialize(uint, string)
/// @see Initialize(uint, string, PackageVersion)
/// @see Initialize(uint, string, PackageVersion, InitializeOptions)
/// @see Shutdown()
public static void Initialize(uint majorMinorVersion)
{
Expand All @@ -102,12 +125,13 @@ public static void Initialize(uint majorMinorVersion)
/// for use by the current process. If multiple packages meet the criteria the best
/// candidate is selected.
///
/// This is equivalent to `Initialize(majorMinorVersion, versionTag, new PackageVersion())`.
/// This is equivalent to `Initialize(majorMinorVersion, versionTag, new PackageVersion(), InitializeOptions.None)`.
///
/// @param majorMinorVersion major and minor version of Windows App SDK's framework package, encoded as `0xMMMMNNNN` where M=Major, N=Minor (e.g. 1.2 == 0x00010002).
/// @param versionTag version tag (if any), e.g. "preview1".
/// @see Initialize(uint)
/// @see Initialize(uint, string, PackageVersion)
/// @see Initialize(uint, string, PackageVersion, InitializeOptions)
/// @see Shutdown()
public static void Initialize(uint majorMinorVersion, string versionTag)
{
Expand All @@ -120,15 +144,37 @@ public static void Initialize(uint majorMinorVersion, string versionTag)
/// for use by the current process. If multiple packages meet the criteria the best
/// candidate is selected.
///
/// This is equivalent to `Initialize(majorMinorVersion, versionTag, minVersion, InitializeOptions.None)`.
///
/// @param majorMinorVersion major and minor version of Windows App SDK's framework package, encoded as `0xMMMMNNNN` where M=Major, N=Minor (e.g. 1.2 == 0x00010002).
/// @param versionTag version tag (if any), e.g. "preview1".
/// @param minVersion the minimum version to use
/// @param minVersion the minimum version to use.
/// @see Initialize(uint)
/// @see Initialize(uint, string)
/// @see Initialize(uint, string, PackageVersion, InitializeOptions)
/// @see Shutdown()
public static void Initialize(uint majorMinorVersion, string versionTag, PackageVersion minVersion)
{
NativeMethods.MddBootstrapInitialize_Throw(majorMinorVersion, versionTag, minVersion);
NativeMethods.MddBootstrapInitialize2_Throw(majorMinorVersion, versionTag, minVersion, InitializeOptions.None);
}

/// Initialize the calling process to use Windows App SDK's framework package.
///
/// Find a Windows App SDK framework package meeting the criteria and make it available
/// for use by the current process. If multiple packages meet the criteria the best
/// candidate is selected.
///
/// @param majorMinorVersion major and minor version of Windows App SDK's framework package, encoded as `0xMMMMNNNN` where M=Major, N=Minor (e.g. 1.2 == 0x00010002).
/// @param versionTag version tag (if any), e.g. "preview1".
/// @param minVersion the minimum version to use.
/// @param options optional behavior.
/// @see Initialize(uint)
/// @see Initialize(uint, string)
/// @see Initialize(uint, string, PackageVersion)
/// @see Shutdown()
public static void Initialize(uint majorMinorVersion, string versionTag, PackageVersion minVersion, InitializeOptions options)
{
NativeMethods.MddBootstrapInitialize2_Throw(majorMinorVersion, versionTag, minVersion, options);
}

/// Initialize the calling process to use Windows App SDK's framework package.
Expand All @@ -138,12 +184,12 @@ public static void Initialize(uint majorMinorVersion, string versionTag, Package
/// for use by the current process. If multiple packages meet the criteria the best
/// candidate is selected.
///
/// This is equivalent to `TryInitialize(majorMinorVersion, null, new PackageVersion(), hresult)`.
/// This is equivalent to `TryInitialize(majorMinorVersion, null, new PackageVersion(), InitializeOptions.None, hresult)`.
///
/// @param majorMinorVersion major and minor version of Windows App SDK's framework package, encoded as `0xMMMMNNNN` where M=Major, N=Minor (e.g. 1.2 == 0x00010002).
/// @retval true if successful, otherwise false is returned.
/// @see TryInitialize(uint, string, out int)
/// @see TryInitialize(uint, string, PackageVersion, out int)
/// @see TryInitialize(uint, string, PackageVersion, InitializeOptions, out int)
/// @see Shutdown()
public static bool TryInitialize(uint majorMinorVersion, out int hresult)
{
Expand All @@ -157,13 +203,14 @@ public static bool TryInitialize(uint majorMinorVersion, out int hresult)
/// for use by the current process. If multiple packages meet the criteria the best
/// candidate is selected.
///
/// This is equivalent to `TryInitialize(majorMinorVersion, versionTag, new PackageVersion(), hresult)`.
/// This is equivalent to `TryInitialize(majorMinorVersion, versionTag, new PackageVersion(), InitializeOptions.None, hresult)`.
///
/// @param majorMinorVersion major and minor version of Windows App SDK's framework package, encoded as `0xMMMMNNNN` where M=Major, N=Minor (e.g. 1.2 == 0x00010002).
/// @param versionTag version tag (if any), e.g. "preview1".
/// @retval true if successful, otherwise false is returned.
/// @see TryInitialize(uint, out int)
/// @see TryInitialize(uint, string, PackageVersion, out int)
/// @see TryInitialize(uint, string, PackageVersion, InitializeOptions, out int)
/// @see Shutdown()
public static bool TryInitialize(uint majorMinorVersion, string versionTag, out int hresult)
{
Expand All @@ -178,17 +225,43 @@ public static bool TryInitialize(uint majorMinorVersion, string versionTag, out
/// for use by the current process. If multiple packages meet the criteria the best
/// candidate is selected.
///
/// This is equivalent to `TryInitialize(majorMinorVersion, versionTag, minVersion, InitializeOptions.None, hresult)`.
///
/// @param majorMinorVersion major and minor version of Windows App SDK's framework package, encoded as `0xMMMMNNNN` where M=Major, N=Minor (e.g. 1.2 == 0x00010002).
/// @param versionTag version tag (if any), e.g. "preview1".
/// @param minVersion the minimum version to use.
/// @param options optional behavior.
/// @param hresult the error code if an error occurred.
/// @retval true if successful, otherwise false is returned.
/// @see TryInitialize(uint, out int)
/// @see TryInitialize(uint, string, out int)
/// @see TryInitialize(uint, string, PackageVersion, out int)
/// @see Shutdown()
public static bool TryInitialize(uint majorMinorVersion, string versionTag, PackageVersion minVersion, out int hresult)
{
hresult = NativeMethods.MddBootstrapInitialize(majorMinorVersion, versionTag, minVersion);
return TryInitialize(majorMinorVersion, versionTag, minVersion, InitializeOptions.None, out hresult);
}

/// Initialize the calling process to use Windows App SDK's framework package.
/// Failure returns false with the failure HRESULT in the hresult parameter.
///
/// Find a Windows App SDK framework package meeting the criteria and make it available
/// for use by the current process. If multiple packages meet the criteria the best
/// candidate is selected.
///
/// @param majorMinorVersion major and minor version of Windows App SDK's framework package, encoded as `0xMMMMNNNN` where M=Major, N=Minor (e.g. 1.2 == 0x00010002).
/// @param versionTag version tag (if any), e.g. "preview1".
/// @param minVersion the minimum version to use.
/// @param options optional behavior.
/// @param hresult the error code if an error occurred.
/// @retval true if successful, otherwise false is returned.
/// @see TryInitialize(uint, out int)
/// @see TryInitialize(uint, string, out int)
/// @see TryInitialize(uint, string, PackageVersion, out int)
/// @see Shutdown()
public static bool TryInitialize(uint majorMinorVersion, string versionTag, PackageVersion minVersion, InitializeOptions options, out int hresult)
{
hresult = NativeMethods.MddBootstrapInitialize2(majorMinorVersion, versionTag, minVersion, options);
return hresult >= 0;
}

Expand All @@ -199,9 +272,11 @@ public static bool TryInitialize(uint majorMinorVersion, string versionTag, Pack
/// @see Initialize(uint)
/// @see Initialize(uint, string)
/// @see Initialize(uint, string, PackageVersion)
/// @see Initialize(uint, string, PackageVersion, InitializeOptions options)
/// @see TryInitialize(uint, out int)
/// @see TryInitialize(uint, string, out int)
/// @see TryInitialize(uint, string, PackageVersion, out int)
/// @see TryInitialize(uint, string, PackageVersion, InitializeOptions options, out int)
public static void Shutdown()
{
NativeMethods.MddBootstrapShutdown();
Expand Down
Loading

0 comments on commit 003df95

Please sign in to comment.