Skip to content

Commit 81209eb

Browse files
authored
WinUI gallery unpackaged mode working + single project config for both packaged and unpackaged (#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.
1 parent 1ffc48c commit 81209eb

18 files changed

Lines changed: 496 additions & 406 deletions

WinUIGallery/Common/FileLoader.cs

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,20 +3,29 @@
33
using System.Linq;
44
using System.Threading.Tasks;
55
using Windows.Storage;
6+
using AppUIBasics.Helper;
7+
using System.IO;
8+
using System.Reflection;
69

710
namespace AppUIBasics.Common
811
{
912
internal class FileLoader
1013
{
1114
public static async Task<string> LoadText(string relativeFilePath)
1215
{
13-
#if UNPACKAGED
14-
var sourcePath = Path.GetFullPath(Path.Combine(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location), relativeFilePath));
15-
var file = await StorageFile.GetFileFromPathAsync(sourcePath);
16-
#else
17-
Uri sourceUri = new Uri("ms-appx:///" + relativeFilePath);
18-
var file = await StorageFile.GetFileFromApplicationUriAsync(sourceUri);
19-
#endif
16+
StorageFile file = null;
17+
if (!NativeHelper.IsAppPackaged)
18+
{
19+
var sourcePath = Path.GetFullPath(Path.Combine(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location), relativeFilePath));
20+
file = await StorageFile.GetFileFromPathAsync(sourcePath);
21+
22+
}
23+
else
24+
{
25+
Uri sourceUri = new Uri("ms-appx:///" + relativeFilePath);
26+
file = await StorageFile.GetFileFromApplicationUriAsync(sourceUri);
27+
28+
}
2029
return await FileIO.ReadTextAsync(file);
2130
}
2231

WinUIGallery/Common/SuspensionManager.cs

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
using Windows.Storage.Streams;
1111
using Microsoft.UI.Xaml;
1212
using Microsoft.UI.Xaml.Controls;
13+
using AppUIBasics.Helper;
1314

1415
namespace AppUIBasics.Common
1516
{
@@ -75,11 +76,7 @@ public static async Task SaveAsync()
7576
serializer.WriteObject(sessionData, _sessionState);
7677

7778
// Get an output stream for the SessionState file and write the state asynchronously
78-
#if !UNPACKAGED
79-
StorageFolder localFolder = ApplicationData.Current.LocalFolder;
80-
#else
81-
StorageFolder localFolder = await StorageFolder.GetFolderFromPathAsync(System.AppContext.BaseDirectory);
82-
#endif
79+
StorageFolder localFolder = WindowHelper.GetAppLocalFolder();
8380
StorageFile file = await localFolder.CreateFileAsync(sessionStateFilename, CreationCollisionOption.ReplaceExisting);
8481
using (Stream fileStream = await file.OpenStreamForWriteAsync())
8582
{
@@ -109,11 +106,8 @@ public static async Task RestoreAsync()
109106
try
110107
{
111108
// Get the input stream for the SessionState file
112-
#if !UNPACKAGED
113-
StorageFolder localFolder = ApplicationData.Current.LocalFolder;
114-
#else
115-
StorageFolder localFolder = await StorageFolder.GetFolderFromPathAsync(System.AppContext.BaseDirectory);
116-
#endif
109+
StorageFolder localFolder = WindowHelper.GetAppLocalFolder();
110+
117111
StorageFile file = await localFolder.GetFileAsync(sessionStateFilename);
118112
using (IInputStream inStream = await file.OpenSequentialReadAsync())
119113
{

WinUIGallery/ControlPages/CreateMultipleWindowsPage.xaml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<!--
1+
<!--
22
//*********************************************************
33
//
44
// Copyright (c) Microsoft. All rights reserved.
@@ -22,8 +22,8 @@
2222

2323
<StackPanel>
2424
<local:ControlExample HeaderText="Create single threaded Multiple Top level Windows(MTW)."
25-
CSharpSource="Window\CreateWindowSample1.txt">
25+
CSharpSource="Window/CreateWindowSample1.txt">
2626
<Button x:Name="Control1" Click="createNewWindow_Click">Create new Window</Button>
2727
</local:ControlExample>
2828
</StackPanel>
29-
</Page>
29+
</Page>

WinUIGallery/ControlPages/TitleBarPage.xaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727

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

113113
</local:ControlExample>
114114
<local:ControlExample HeaderText="Fallback titlebar when no user defined titlebar is set"
115-
CSharpSource="Window\TitleBar\TitleBarSample2.txt">
115+
CSharpSource="Window/TitleBar/TitleBarSample2.txt">
116116
<local:ControlExample.Example>
117117
<StackPanel Orientation="Vertical" Spacing="10">
118118
<TextBlock TextWrapping="WrapWholeWords">

WinUIGallery/Controls/ControlExample.xaml.cs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -288,11 +288,7 @@ public async void TakeScreenshotWithDelay()
288288
var manager = AppRecordingManager.GetDefault();
289289
if (manager.GetStatus().CanRecord)
290290
{
291-
#if UNPACKAGED
292-
StorageFolder localFolder = await StorageFolder.GetFolderFromPathAsync(System.AppContext.BaseDirectory);
293-
#else
294-
StorageFolder localFolder = ApplicationData.Current.LocalFolder;
295-
#endif
291+
StorageFolder localFolder = WindowHelper.GetAppLocalFolder();
296292
var result = await manager.SaveScreenshotToFilesAsync(
297293
localFolder,
298294
"appScreenshot",

WinUIGallery/Controls/SampleCodePresenter.xaml.cs

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@
2222
using Microsoft.UI.Xaml;
2323
using Microsoft.UI.Xaml.Controls;
2424
using Microsoft.UI.Xaml.Media;
25+
using AppUIBasics.Common;
26+
using System.Reflection;
27+
using System.IO;
2528

2629
namespace AppUIBasics.Controls
2730
{
@@ -144,6 +147,12 @@ private Uri GetDerivedSource(string sourceRelativePath)
144147
return derivedSource;
145148
}
146149

150+
private string GetDerivedSourceUnpackaged(string sourceRelativePath)
151+
{
152+
string derviedSourceString = "ControlPagesSampleCode\\" + sourceRelativePath;
153+
return derviedSourceString;
154+
}
155+
147156
private void GenerateSyntaxHighlightedContent()
148157
{
149158
var language = SampleType switch
@@ -166,9 +175,22 @@ private async void FormatAndRenderSampleFromFile(string sourceRelativePath, Cont
166175
{
167176
if (sourceRelativePath != null && sourceRelativePath.EndsWith("txt"))
168177
{
169-
Uri derivedSource = GetDerivedSource(sourceRelativePath);
170-
var file = await StorageFile.GetFileFromApplicationUriAsync(derivedSource);
171-
string sampleString = await FileIO.ReadTextAsync(file);
178+
179+
string sampleString = null;
180+
StorageFile file = null;
181+
if (!NativeHelper.IsAppPackaged)
182+
{
183+
var relativePath = GetDerivedSourceUnpackaged(sourceRelativePath);
184+
var sourcePath = Path.GetFullPath(Path.Combine(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location), relativePath));
185+
file = await StorageFile.GetFileFromPathAsync(sourcePath);
186+
}
187+
else
188+
{
189+
Uri derivedSource = GetDerivedSource(sourceRelativePath);
190+
file = await StorageFile.GetFileFromApplicationUriAsync(derivedSource);
191+
}
192+
193+
sampleString = await FileIO.ReadTextAsync(file);
172194

173195
FormatAndRenderSampleFromString(sampleString, presenter, highlightLanguage);
174196
}

WinUIGallery/Directory.Build.targets

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,5 @@
55
<!-- These are set in Directory.Build.targets because we need to import the publish profile first -->
66
<AppxPackageName>WinUIGallery.Desktop</AppxPackageName>
77
</PropertyGroup>
8-
<ItemGroup Condition="'$(WindowsPackageType)' == 'MSIX'">
9-
<AppxManifest Include="Package.$(WindowsPackageType).appxmanifest">
10-
<SubType>Designer</SubType>
11-
</AppxManifest>
12-
</ItemGroup>
138
<Import Project="net6.override.targets" Condition="'$(MSBuildRuntimeType)' == 'Core'" />
149
</Project>
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
//*********************************************************
2+
//
3+
// Copyright (c) Microsoft. All rights reserved.
4+
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
5+
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
6+
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
7+
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
8+
//
9+
//*********************************************************
10+
11+
using System;
12+
using System.Collections.Generic;
13+
using System.Linq;
14+
using System.Runtime.InteropServices;
15+
using System.Text;
16+
using System.Threading.Tasks;
17+
18+
namespace AppUIBasics.Helper
19+
{
20+
internal class NativeHelper
21+
{
22+
public const int ERROR_SUCCESS = 0;
23+
public const int ERROR_INSUFFICIENT_BUFFER = 122;
24+
public const int APPMODEL_ERROR_NO_PACKAGE = 15700;
25+
26+
[DllImport("api-ms-win-appmodel-runtime-l1-1-1", SetLastError = true)]
27+
[return: MarshalAs(UnmanagedType.U4)]
28+
internal static extern uint GetCurrentPackageId(ref int pBufferLength, out byte pBuffer);
29+
30+
public static bool IsAppPackaged
31+
{
32+
get
33+
{
34+
int bufferSize = 0;
35+
byte byteBuffer = 0;
36+
uint lastError = NativeHelper.GetCurrentPackageId(ref bufferSize, out byteBuffer);
37+
bool isPackaged = true;
38+
39+
if (lastError == NativeHelper.APPMODEL_ERROR_NO_PACKAGE)
40+
{
41+
isPackaged = false;
42+
}
43+
return isPackaged;
44+
}
45+
}
46+
}
47+
}

WinUIGallery/Helper/NavigationOrientationHelper.cs

Lines changed: 21 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -9,34 +9,37 @@ public static class NavigationOrientationHelper
99
{
1010

1111
private const string IsLeftModeKey = "NavigationIsOnLeftMode";
12-
13-
#if UNPACKAGED
1412
private static bool _isLeftMode = true;
15-
#endif
1613

1714
public static bool IsLeftMode()
1815
{
19-
#if !UNPACKAGED
20-
var valueFromSettings = ApplicationData.Current.LocalSettings.Values[IsLeftModeKey];
21-
if(valueFromSettings == null)
16+
if (NativeHelper.IsAppPackaged)
2217
{
23-
ApplicationData.Current.LocalSettings.Values[IsLeftModeKey] = true;
24-
valueFromSettings = true;
18+
var valueFromSettings = ApplicationData.Current.LocalSettings.Values[IsLeftModeKey];
19+
if (valueFromSettings == null)
20+
{
21+
ApplicationData.Current.LocalSettings.Values[IsLeftModeKey] = true;
22+
valueFromSettings = true;
23+
}
24+
return (bool)valueFromSettings;
25+
}
26+
else
27+
{
28+
return _isLeftMode;
2529
}
26-
return (bool)valueFromSettings;
27-
#else
28-
return _isLeftMode;
29-
#endif
3030
}
3131

3232
public static void IsLeftModeForElement(bool isLeftMode, UIElement element)
3333
{
3434
UpdateNavigationViewForElement(isLeftMode, element);
35-
#if !UNPACKAGED
36-
ApplicationData.Current.LocalSettings.Values[IsLeftModeKey] = isLeftMode;
37-
#else
38-
_isLeftMode = isLeftMode;
39-
#endif
35+
if (NativeHelper.IsAppPackaged)
36+
{
37+
ApplicationData.Current.LocalSettings.Values[IsLeftModeKey] = isLeftMode;
38+
}
39+
else
40+
{
41+
_isLeftMode = isLeftMode;
42+
}
4043
}
4144

4245
public static void UpdateNavigationViewForElement(bool isLeftMode, UIElement element)
@@ -53,5 +56,6 @@ public static void UpdateNavigationViewForElement(bool isLeftMode, UIElement ele
5356
Grid.SetRow(_navView, 1);
5457
}
5558
}
59+
5660
}
5761
}

WinUIGallery/Helper/ProtocolActivationClipboardHelper.cs

Lines changed: 24 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -12,33 +12,40 @@ namespace AppUIBasics.Helper
1212
public static class ProtocolActivationClipboardHelper
1313
{
1414
private const string ShowCopyLinkTeachingTipKey = "ShowCopyLinkTeachingTip";
15-
16-
#if UNPACKAGED
1715
private static bool _showCopyLinkTeachingTip = true;
18-
#endif
1916

2017
public static bool ShowCopyLinkTeachingTip
2118
{
2219
get
2320
{
24-
#if !UNPACKAGED
25-
object valueFromSettings = ApplicationData.Current.LocalSettings.Values[ShowCopyLinkTeachingTipKey];
26-
if (valueFromSettings == null)
21+
if (NativeHelper.IsAppPackaged)
22+
{
23+
object valueFromSettings = ApplicationData.Current.LocalSettings.Values[ShowCopyLinkTeachingTipKey];
24+
if (valueFromSettings == null)
25+
{
26+
ApplicationData.Current.LocalSettings.Values[ShowCopyLinkTeachingTipKey] = true;
27+
valueFromSettings = true;
28+
}
29+
return (bool)valueFromSettings;
30+
}
31+
else
2732
{
28-
ApplicationData.Current.LocalSettings.Values[ShowCopyLinkTeachingTipKey] = true;
29-
valueFromSettings = true;
33+
return _showCopyLinkTeachingTip;
3034
}
31-
return (bool)valueFromSettings;
32-
#else
33-
return _showCopyLinkTeachingTip;
34-
#endif
3535
}
3636

37-
#if !UNPACKAGED
38-
set => ApplicationData.Current.LocalSettings.Values[ShowCopyLinkTeachingTipKey] = value;
39-
#else
40-
set => _showCopyLinkTeachingTip = value;
41-
#endif
37+
set
38+
{
39+
if (NativeHelper.IsAppPackaged)
40+
{
41+
ApplicationData.Current.LocalSettings.Values[ShowCopyLinkTeachingTipKey] = value;
42+
43+
}
44+
else
45+
{
46+
_showCopyLinkTeachingTip = value;
47+
}
48+
}
4249
}
4350

4451
public static void Copy(ControlInfoDataItem item)

0 commit comments

Comments
 (0)