Skip to content

Commit

Permalink
WinUI gallery unpackaged mode working + single project config for bot…
Browse files Browse the repository at this point in the history
…h packaged and unpackaged (microsoft#1329)

Unpackaged mode no longer crashes on launch
The WinUI gallery unpacakged mode was broken and crashed on launch - no matter whether building from msbuild cmd line or VS. It was happening because at some places in the code resource was getting accessed through URI which only makes sense for packaged app and not unpackaged. To remedy this, other parts of the code had separate code under UNPACKAGED which would build a non-URI path for unpackaged app config. This UNPACKAGED constant was not defined anywhere and as a result, that alternative code was not getting accessed. Some places had missing alternative code entirely.

This PR removes dependence on UNPACKAGED compile time variable entirely.
This PR side steps compile time variable for a easier to maintain runtime function which uses Appmodel/GetCurrentPackageId() system api to determine whether an app is running in packaged mode or unpackaged mode during runtime.

Single project configuration
As a need arose for cleaning up the project files for unpackaged winui gallery to work, I used this opportunity to build upon @Scottj1s 's work in unpkg-module branch and get rid of WAP configuration, have single project configuration for building any flavor of WinUI gallery.
As a result, using launch configurations, you can build WinUI gallery in either packaged or unpackaged mode.
I have introduced more solution configurations to aid in that.
image

If you want to build a Packaged winui gallery,
select Packaged launch configuration and choose between Debug or Release solution configs.

If you want to build a Unpackaged winui gallery,
select Unpackaged launch configuration and choose between Debug-Unpackaged or Release-Unpackaged solution configs.

A mix and match config will result in error because that's how Visual Studio works.
  • Loading branch information
pratikone authored Aug 15, 2023
1 parent 1ffc48c commit 81209eb
Show file tree
Hide file tree
Showing 18 changed files with 496 additions and 406 deletions.
23 changes: 16 additions & 7 deletions WinUIGallery/Common/FileLoader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,29 @@
using System.Linq;
using System.Threading.Tasks;
using Windows.Storage;
using AppUIBasics.Helper;
using System.IO;
using System.Reflection;

namespace AppUIBasics.Common
{
internal class FileLoader
{
public static async Task<string> LoadText(string relativeFilePath)
{
#if UNPACKAGED
var sourcePath = Path.GetFullPath(Path.Combine(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location), relativeFilePath));
var file = await StorageFile.GetFileFromPathAsync(sourcePath);
#else
Uri sourceUri = new Uri("ms-appx:///" + relativeFilePath);
var file = await StorageFile.GetFileFromApplicationUriAsync(sourceUri);
#endif
StorageFile file = null;
if (!NativeHelper.IsAppPackaged)
{
var sourcePath = Path.GetFullPath(Path.Combine(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location), relativeFilePath));
file = await StorageFile.GetFileFromPathAsync(sourcePath);

}
else
{
Uri sourceUri = new Uri("ms-appx:///" + relativeFilePath);
file = await StorageFile.GetFileFromApplicationUriAsync(sourceUri);

}
return await FileIO.ReadTextAsync(file);
}

Expand Down
14 changes: 4 additions & 10 deletions WinUIGallery/Common/SuspensionManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
using Windows.Storage.Streams;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using AppUIBasics.Helper;

namespace AppUIBasics.Common
{
Expand Down Expand Up @@ -75,11 +76,7 @@ public static async Task SaveAsync()
serializer.WriteObject(sessionData, _sessionState);

// Get an output stream for the SessionState file and write the state asynchronously
#if !UNPACKAGED
StorageFolder localFolder = ApplicationData.Current.LocalFolder;
#else
StorageFolder localFolder = await StorageFolder.GetFolderFromPathAsync(System.AppContext.BaseDirectory);
#endif
StorageFolder localFolder = WindowHelper.GetAppLocalFolder();
StorageFile file = await localFolder.CreateFileAsync(sessionStateFilename, CreationCollisionOption.ReplaceExisting);
using (Stream fileStream = await file.OpenStreamForWriteAsync())
{
Expand Down Expand Up @@ -109,11 +106,8 @@ public static async Task RestoreAsync()
try
{
// Get the input stream for the SessionState file
#if !UNPACKAGED
StorageFolder localFolder = ApplicationData.Current.LocalFolder;
#else
StorageFolder localFolder = await StorageFolder.GetFolderFromPathAsync(System.AppContext.BaseDirectory);
#endif
StorageFolder localFolder = WindowHelper.GetAppLocalFolder();

StorageFile file = await localFolder.GetFileAsync(sessionStateFilename);
using (IInputStream inStream = await file.OpenSequentialReadAsync())
{
Expand Down
6 changes: 3 additions & 3 deletions WinUIGallery/ControlPages/CreateMultipleWindowsPage.xaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<!--
<!--
//*********************************************************
//
// Copyright (c) Microsoft. All rights reserved.
Expand All @@ -22,8 +22,8 @@

<StackPanel>
<local:ControlExample HeaderText="Create single threaded Multiple Top level Windows(MTW)."
CSharpSource="Window\CreateWindowSample1.txt">
CSharpSource="Window/CreateWindowSample1.txt">
<Button x:Name="Control1" Click="createNewWindow_Click">Create new Window</Button>
</local:ControlExample>
</StackPanel>
</Page>
</Page>
4 changes: 2 additions & 2 deletions WinUIGallery/ControlPages/TitleBarPage.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@

<StackPanel>
<local:ControlExample HeaderText="User defined UIElement as custom titlebar for the window"
CSharpSource="Window\TitleBar\TitleBarSample1.txt">
CSharpSource="Window/TitleBar/TitleBarSample1.txt">
<local:ControlExample.Example>
<StackPanel Orientation="Vertical" Spacing="10">
<TextBlock TextWrapping="WrapWholeWords">
Expand Down Expand Up @@ -112,7 +112,7 @@

</local:ControlExample>
<local:ControlExample HeaderText="Fallback titlebar when no user defined titlebar is set"
CSharpSource="Window\TitleBar\TitleBarSample2.txt">
CSharpSource="Window/TitleBar/TitleBarSample2.txt">
<local:ControlExample.Example>
<StackPanel Orientation="Vertical" Spacing="10">
<TextBlock TextWrapping="WrapWholeWords">
Expand Down
6 changes: 1 addition & 5 deletions WinUIGallery/Controls/ControlExample.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -288,11 +288,7 @@ public async void TakeScreenshotWithDelay()
var manager = AppRecordingManager.GetDefault();
if (manager.GetStatus().CanRecord)
{
#if UNPACKAGED
StorageFolder localFolder = await StorageFolder.GetFolderFromPathAsync(System.AppContext.BaseDirectory);
#else
StorageFolder localFolder = ApplicationData.Current.LocalFolder;
#endif
StorageFolder localFolder = WindowHelper.GetAppLocalFolder();
var result = await manager.SaveScreenshotToFilesAsync(
localFolder,
"appScreenshot",
Expand Down
28 changes: 25 additions & 3 deletions WinUIGallery/Controls/SampleCodePresenter.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Media;
using AppUIBasics.Common;
using System.Reflection;
using System.IO;

namespace AppUIBasics.Controls
{
Expand Down Expand Up @@ -144,6 +147,12 @@ private Uri GetDerivedSource(string sourceRelativePath)
return derivedSource;
}

private string GetDerivedSourceUnpackaged(string sourceRelativePath)
{
string derviedSourceString = "ControlPagesSampleCode\\" + sourceRelativePath;
return derviedSourceString;
}

private void GenerateSyntaxHighlightedContent()
{
var language = SampleType switch
Expand All @@ -166,9 +175,22 @@ private async void FormatAndRenderSampleFromFile(string sourceRelativePath, Cont
{
if (sourceRelativePath != null && sourceRelativePath.EndsWith("txt"))
{
Uri derivedSource = GetDerivedSource(sourceRelativePath);
var file = await StorageFile.GetFileFromApplicationUriAsync(derivedSource);
string sampleString = await FileIO.ReadTextAsync(file);

string sampleString = null;
StorageFile file = null;
if (!NativeHelper.IsAppPackaged)
{
var relativePath = GetDerivedSourceUnpackaged(sourceRelativePath);
var sourcePath = Path.GetFullPath(Path.Combine(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location), relativePath));
file = await StorageFile.GetFileFromPathAsync(sourcePath);
}
else
{
Uri derivedSource = GetDerivedSource(sourceRelativePath);
file = await StorageFile.GetFileFromApplicationUriAsync(derivedSource);
}

sampleString = await FileIO.ReadTextAsync(file);

FormatAndRenderSampleFromString(sampleString, presenter, highlightLanguage);
}
Expand Down
5 changes: 0 additions & 5 deletions WinUIGallery/Directory.Build.targets
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,5 @@
<!-- These are set in Directory.Build.targets because we need to import the publish profile first -->
<AppxPackageName>WinUIGallery.Desktop</AppxPackageName>
</PropertyGroup>
<ItemGroup Condition="'$(WindowsPackageType)' == 'MSIX'">
<AppxManifest Include="Package.$(WindowsPackageType).appxmanifest">
<SubType>Designer</SubType>
</AppxManifest>
</ItemGroup>
<Import Project="net6.override.targets" Condition="'$(MSBuildRuntimeType)' == 'Core'" />
</Project>
47 changes: 47 additions & 0 deletions WinUIGallery/Helper/NativeHelper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
//*********************************************************
//
// Copyright (c) Microsoft. All rights reserved.
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
//
//*********************************************************

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;

namespace AppUIBasics.Helper
{
internal class NativeHelper
{
public const int ERROR_SUCCESS = 0;
public const int ERROR_INSUFFICIENT_BUFFER = 122;
public const int APPMODEL_ERROR_NO_PACKAGE = 15700;

[DllImport("api-ms-win-appmodel-runtime-l1-1-1", SetLastError = true)]
[return: MarshalAs(UnmanagedType.U4)]
internal static extern uint GetCurrentPackageId(ref int pBufferLength, out byte pBuffer);

public static bool IsAppPackaged
{
get
{
int bufferSize = 0;
byte byteBuffer = 0;
uint lastError = NativeHelper.GetCurrentPackageId(ref bufferSize, out byteBuffer);
bool isPackaged = true;

if (lastError == NativeHelper.APPMODEL_ERROR_NO_PACKAGE)
{
isPackaged = false;
}
return isPackaged;
}
}
}
}
38 changes: 21 additions & 17 deletions WinUIGallery/Helper/NavigationOrientationHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,34 +9,37 @@ public static class NavigationOrientationHelper
{

private const string IsLeftModeKey = "NavigationIsOnLeftMode";

#if UNPACKAGED
private static bool _isLeftMode = true;
#endif

public static bool IsLeftMode()
{
#if !UNPACKAGED
var valueFromSettings = ApplicationData.Current.LocalSettings.Values[IsLeftModeKey];
if(valueFromSettings == null)
if (NativeHelper.IsAppPackaged)
{
ApplicationData.Current.LocalSettings.Values[IsLeftModeKey] = true;
valueFromSettings = true;
var valueFromSettings = ApplicationData.Current.LocalSettings.Values[IsLeftModeKey];
if (valueFromSettings == null)
{
ApplicationData.Current.LocalSettings.Values[IsLeftModeKey] = true;
valueFromSettings = true;
}
return (bool)valueFromSettings;
}
else
{
return _isLeftMode;
}
return (bool)valueFromSettings;
#else
return _isLeftMode;
#endif
}

public static void IsLeftModeForElement(bool isLeftMode, UIElement element)
{
UpdateNavigationViewForElement(isLeftMode, element);
#if !UNPACKAGED
ApplicationData.Current.LocalSettings.Values[IsLeftModeKey] = isLeftMode;
#else
_isLeftMode = isLeftMode;
#endif
if (NativeHelper.IsAppPackaged)
{
ApplicationData.Current.LocalSettings.Values[IsLeftModeKey] = isLeftMode;
}
else
{
_isLeftMode = isLeftMode;
}
}

public static void UpdateNavigationViewForElement(bool isLeftMode, UIElement element)
Expand All @@ -53,5 +56,6 @@ public static void UpdateNavigationViewForElement(bool isLeftMode, UIElement ele
Grid.SetRow(_navView, 1);
}
}

}
}
41 changes: 24 additions & 17 deletions WinUIGallery/Helper/ProtocolActivationClipboardHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,33 +12,40 @@ namespace AppUIBasics.Helper
public static class ProtocolActivationClipboardHelper
{
private const string ShowCopyLinkTeachingTipKey = "ShowCopyLinkTeachingTip";

#if UNPACKAGED
private static bool _showCopyLinkTeachingTip = true;
#endif

public static bool ShowCopyLinkTeachingTip
{
get
{
#if !UNPACKAGED
object valueFromSettings = ApplicationData.Current.LocalSettings.Values[ShowCopyLinkTeachingTipKey];
if (valueFromSettings == null)
if (NativeHelper.IsAppPackaged)
{
object valueFromSettings = ApplicationData.Current.LocalSettings.Values[ShowCopyLinkTeachingTipKey];
if (valueFromSettings == null)
{
ApplicationData.Current.LocalSettings.Values[ShowCopyLinkTeachingTipKey] = true;
valueFromSettings = true;
}
return (bool)valueFromSettings;
}
else
{
ApplicationData.Current.LocalSettings.Values[ShowCopyLinkTeachingTipKey] = true;
valueFromSettings = true;
return _showCopyLinkTeachingTip;
}
return (bool)valueFromSettings;
#else
return _showCopyLinkTeachingTip;
#endif
}

#if !UNPACKAGED
set => ApplicationData.Current.LocalSettings.Values[ShowCopyLinkTeachingTipKey] = value;
#else
set => _showCopyLinkTeachingTip = value;
#endif
set
{
if (NativeHelper.IsAppPackaged)
{
ApplicationData.Current.LocalSettings.Values[ShowCopyLinkTeachingTipKey] = value;

}
else
{
_showCopyLinkTeachingTip = value;
}
}
}

public static void Copy(ControlInfoDataItem item)
Expand Down
26 changes: 13 additions & 13 deletions WinUIGallery/Helper/ThemeHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,7 @@ public static class ThemeHelper
{
private const string SelectedAppThemeKey = "SelectedAppTheme";

#if !UNPACKAGED
private static Window CurrentApplicationWindow;
#endif
/// <summary>
/// Gets the current actual theme of the app based on the requested theme of the
/// root element, or if that value is Default, the requested theme of the Application.
Expand Down Expand Up @@ -66,24 +64,26 @@ public static ElementTheme RootTheme
}
}

#if !UNPACKAGED
ApplicationData.Current.LocalSettings.Values[SelectedAppThemeKey] = value.ToString();
#endif
if (NativeHelper.IsAppPackaged)
{
ApplicationData.Current.LocalSettings.Values[SelectedAppThemeKey] = value.ToString();
}
}
}

public static void Initialize()
{
#if !UNPACKAGED
// Save reference as this might be null when the user is in another app
CurrentApplicationWindow = App.StartupWindow;
string savedTheme = ApplicationData.Current.LocalSettings.Values[SelectedAppThemeKey]?.ToString();

if (savedTheme != null)
if (NativeHelper.IsAppPackaged)
{
RootTheme = AppUIBasics.App.GetEnum<ElementTheme>(savedTheme);
// Save reference as this might be null when the user is in another app
CurrentApplicationWindow = App.StartupWindow;
string savedTheme = ApplicationData.Current.LocalSettings.Values[SelectedAppThemeKey]?.ToString();

if (savedTheme != null)
{
RootTheme = AppUIBasics.App.GetEnum<ElementTheme>(savedTheme);
}
}
#endif
}

public static bool IsDarkTheme()
Expand Down
Loading

0 comments on commit 81209eb

Please sign in to comment.