diff --git a/Samples/BackgroundTask/cs-winui/BackgroundTaskBuilder.sln b/Samples/BackgroundTask/cs-winui/BackgroundTaskBuilder.sln new file mode 100644 index 000000000..f09bf495d --- /dev/null +++ b/Samples/BackgroundTask/cs-winui/BackgroundTaskBuilder.sln @@ -0,0 +1,40 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.12.35514.174 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BackgroundTaskBuilder", "BackgroundTaskBuilder\BackgroundTaskBuilder.csproj", "{18896EE2-23CF-4C44-B5D9-1A9867BB7D69}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|ARM64 = Debug|ARM64 + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|ARM64 = Release|ARM64 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {18896EE2-23CF-4C44-B5D9-1A9867BB7D69}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {18896EE2-23CF-4C44-B5D9-1A9867BB7D69}.Debug|ARM64.Build.0 = Debug|ARM64 + {18896EE2-23CF-4C44-B5D9-1A9867BB7D69}.Debug|ARM64.Deploy.0 = Debug|ARM64 + {18896EE2-23CF-4C44-B5D9-1A9867BB7D69}.Debug|x64.ActiveCfg = Debug|x64 + {18896EE2-23CF-4C44-B5D9-1A9867BB7D69}.Debug|x64.Build.0 = Debug|x64 + {18896EE2-23CF-4C44-B5D9-1A9867BB7D69}.Debug|x64.Deploy.0 = Debug|x64 + {18896EE2-23CF-4C44-B5D9-1A9867BB7D69}.Debug|x86.ActiveCfg = Debug|x86 + {18896EE2-23CF-4C44-B5D9-1A9867BB7D69}.Debug|x86.Build.0 = Debug|x86 + {18896EE2-23CF-4C44-B5D9-1A9867BB7D69}.Debug|x86.Deploy.0 = Debug|x86 + {18896EE2-23CF-4C44-B5D9-1A9867BB7D69}.Release|ARM64.ActiveCfg = Release|ARM64 + {18896EE2-23CF-4C44-B5D9-1A9867BB7D69}.Release|ARM64.Build.0 = Release|ARM64 + {18896EE2-23CF-4C44-B5D9-1A9867BB7D69}.Release|ARM64.Deploy.0 = Release|ARM64 + {18896EE2-23CF-4C44-B5D9-1A9867BB7D69}.Release|x64.ActiveCfg = Release|x64 + {18896EE2-23CF-4C44-B5D9-1A9867BB7D69}.Release|x64.Build.0 = Release|x64 + {18896EE2-23CF-4C44-B5D9-1A9867BB7D69}.Release|x64.Deploy.0 = Release|x64 + {18896EE2-23CF-4C44-B5D9-1A9867BB7D69}.Release|x86.ActiveCfg = Release|x86 + {18896EE2-23CF-4C44-B5D9-1A9867BB7D69}.Release|x86.Build.0 = Release|x86 + {18896EE2-23CF-4C44-B5D9-1A9867BB7D69}.Release|x86.Deploy.0 = Release|x86 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/Samples/BackgroundTask/cs-winui/BackgroundTaskBuilder/App.xaml b/Samples/BackgroundTask/cs-winui/BackgroundTaskBuilder/App.xaml new file mode 100644 index 000000000..6bcb9c52a --- /dev/null +++ b/Samples/BackgroundTask/cs-winui/BackgroundTaskBuilder/App.xaml @@ -0,0 +1,16 @@ + + + + + + + + + + + + diff --git a/Samples/BackgroundTask/cs-winui/BackgroundTaskBuilder/App.xaml.cs b/Samples/BackgroundTask/cs-winui/BackgroundTaskBuilder/App.xaml.cs new file mode 100644 index 000000000..77ac2573f --- /dev/null +++ b/Samples/BackgroundTask/cs-winui/BackgroundTaskBuilder/App.xaml.cs @@ -0,0 +1,44 @@ +using BackgroundTaskBuilder; +using Microsoft.UI.Xaml; +using Microsoft.UI.Xaml.Controls; +using Microsoft.UI.Xaml.Controls.Primitives; +using Microsoft.UI.Xaml.Data; +using Microsoft.UI.Xaml.Input; +using Microsoft.UI.Xaml.Media; +using Microsoft.UI.Xaml.Navigation; +using Microsoft.UI.Xaml.Shapes; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Runtime.InteropServices; +using System.Runtime.InteropServices.WindowsRuntime; +using Windows.ApplicationModel; +using Windows.ApplicationModel.Activation; +using Windows.Foundation; +using Windows.Foundation.Collections; + +// To learn more about WinUI, the WinUI project structure, +// and more about our project templates, see: http://aka.ms/winui-project-info. + +namespace BackgroundTaskBuilder +{ + /// + /// Provides application-specific behavior to supplement the default Application class. + /// + public partial class App : Application + { + public App() + { + this.InitializeComponent(); + } + + protected override void OnLaunched(Microsoft.UI.Xaml.LaunchActivatedEventArgs args) + { + m_window = new MainWindow(); + m_window.Activate(); + } + + private Window? m_window; + } +} \ No newline at end of file diff --git a/Samples/BackgroundTask/cs-winui/BackgroundTaskBuilder/Assets/LockScreenLogo.scale-200.png b/Samples/BackgroundTask/cs-winui/BackgroundTaskBuilder/Assets/LockScreenLogo.scale-200.png new file mode 100644 index 000000000..7440f0d4b Binary files /dev/null and b/Samples/BackgroundTask/cs-winui/BackgroundTaskBuilder/Assets/LockScreenLogo.scale-200.png differ diff --git a/Samples/BackgroundTask/cs-winui/BackgroundTaskBuilder/Assets/SplashScreen.scale-200.png b/Samples/BackgroundTask/cs-winui/BackgroundTaskBuilder/Assets/SplashScreen.scale-200.png new file mode 100644 index 000000000..32f486a86 Binary files /dev/null and b/Samples/BackgroundTask/cs-winui/BackgroundTaskBuilder/Assets/SplashScreen.scale-200.png differ diff --git a/Samples/BackgroundTask/cs-winui/BackgroundTaskBuilder/Assets/Square150x150Logo.scale-200.png b/Samples/BackgroundTask/cs-winui/BackgroundTaskBuilder/Assets/Square150x150Logo.scale-200.png new file mode 100644 index 000000000..53ee3777e Binary files /dev/null and b/Samples/BackgroundTask/cs-winui/BackgroundTaskBuilder/Assets/Square150x150Logo.scale-200.png differ diff --git a/Samples/BackgroundTask/cs-winui/BackgroundTaskBuilder/Assets/Square44x44Logo.scale-200.png b/Samples/BackgroundTask/cs-winui/BackgroundTaskBuilder/Assets/Square44x44Logo.scale-200.png new file mode 100644 index 000000000..f713bba67 Binary files /dev/null and b/Samples/BackgroundTask/cs-winui/BackgroundTaskBuilder/Assets/Square44x44Logo.scale-200.png differ diff --git a/Samples/BackgroundTask/cs-winui/BackgroundTaskBuilder/Assets/Square44x44Logo.targetsize-24_altform-unplated.png b/Samples/BackgroundTask/cs-winui/BackgroundTaskBuilder/Assets/Square44x44Logo.targetsize-24_altform-unplated.png new file mode 100644 index 000000000..dc9f5bea0 Binary files /dev/null and b/Samples/BackgroundTask/cs-winui/BackgroundTaskBuilder/Assets/Square44x44Logo.targetsize-24_altform-unplated.png differ diff --git a/Samples/BackgroundTask/cs-winui/BackgroundTaskBuilder/Assets/StoreLogo.png b/Samples/BackgroundTask/cs-winui/BackgroundTaskBuilder/Assets/StoreLogo.png new file mode 100644 index 000000000..a4586f26b Binary files /dev/null and b/Samples/BackgroundTask/cs-winui/BackgroundTaskBuilder/Assets/StoreLogo.png differ diff --git a/Samples/BackgroundTask/cs-winui/BackgroundTaskBuilder/Assets/Wide310x150Logo.scale-200.png b/Samples/BackgroundTask/cs-winui/BackgroundTaskBuilder/Assets/Wide310x150Logo.scale-200.png new file mode 100644 index 000000000..8b4a5d0dd Binary files /dev/null and b/Samples/BackgroundTask/cs-winui/BackgroundTaskBuilder/Assets/Wide310x150Logo.scale-200.png differ diff --git a/Samples/BackgroundTask/cs-winui/BackgroundTaskBuilder/BackgroundTask.cs b/Samples/BackgroundTask/cs-winui/BackgroundTaskBuilder/BackgroundTask.cs new file mode 100644 index 000000000..19c24dfba --- /dev/null +++ b/Samples/BackgroundTask/cs-winui/BackgroundTaskBuilder/BackgroundTask.cs @@ -0,0 +1,62 @@ + +using System; +using System.IO; // Path +using System.Threading; // EventWaitHandle +using System.Collections.Generic; // Queue +using System.Runtime.InteropServices; // Guid, RegistrationServices +using Windows.ApplicationModel.Background; // IBackgroundTask +using Windows.UI.Notifications; // ToastNotificationManager, ToastTemplateType, ToastNotification + +namespace BackgroundTaskBuilder +{ + // Background task implementation. + // {87654321-1234-1234-1234-1234567890AE} is GUID to register this task with BackgroundTaskBuilder. Generate a random GUID before implementing. + [ComVisible(true)] + [ClassInterface(ClassInterfaceType.None)] + [Guid("87654321-1234-1234-1234-1234567890AE")] + [ComSourceInterfaces(typeof(IBackgroundTask))] + public class BackgroundTask : IBackgroundTask + { + private volatile int cleanupTask; // flag used to indicate to Run method that it should exit + + public BackgroundTask() + { + cleanupTask = 0; + } + + /// + /// This method is the main entry point for the background task. The system will believe this background task + /// is complete when this method returns. + /// + [MTAThread] + public void Run(IBackgroundTaskInstance taskInstance) + { + // Wire the cancellation handler. + taskInstance.Canceled += this.OnCanceled; + + // Set the progress to indicate this task has started + taskInstance.Progress = 10; + + // Create the toast notification content + var toastXml = ToastNotificationManager.GetTemplateContent(ToastTemplateType.ToastText01); + var toastTextElements = toastXml.GetElementsByTagName("text"); + toastTextElements[0].AppendChild(toastXml.CreateTextNode("C# Background task executed")); + + // Create the toast notification + var toast = new ToastNotification(toastXml); + + // Show the toast notification + ToastNotificationManager.CreateToastNotifier().Show(toast); + } + + /// + /// This method is signaled when the system requests the background task be canceled. This method will signal + /// to the Run method to clean up and return. + /// + [MTAThread] + public void OnCanceled(IBackgroundTaskInstance taskInstance, BackgroundTaskCancellationReason cancellationReason) + { + cleanupTask = 1; + } + } +} diff --git a/Samples/BackgroundTask/cs-winui/BackgroundTaskBuilder/BackgroundTaskBuilder.csproj b/Samples/BackgroundTask/cs-winui/BackgroundTaskBuilder/BackgroundTaskBuilder.csproj new file mode 100644 index 000000000..cf2d3cb6a --- /dev/null +++ b/Samples/BackgroundTask/cs-winui/BackgroundTaskBuilder/BackgroundTaskBuilder.csproj @@ -0,0 +1,61 @@ + + + WinExe + net8.0-windows10.0.19041.0 + 10.0.17763.0 + BackgroundTaskBuilder + app.manifest + x86;x64;ARM64 + win-x86;win-x64;win-arm64 + win-$(Platform).pubxml + true + true + enable + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + + + + + False + True + False + True + True + + \ No newline at end of file diff --git a/Samples/BackgroundTask/cs-winui/BackgroundTaskBuilder/ComServer.cs b/Samples/BackgroundTask/cs-winui/BackgroundTaskBuilder/ComServer.cs new file mode 100644 index 000000000..45c3adf80 --- /dev/null +++ b/Samples/BackgroundTask/cs-winui/BackgroundTaskBuilder/ComServer.cs @@ -0,0 +1,71 @@ +using System; +using System.Runtime.InteropServices; +using WinRT; + +namespace BackgroundTaskBuilder +{ + // COM server startup code. + internal class ComServer + { + [DllImport("ole32.dll")] + public static extern int CoRegisterClassObject( + ref Guid classId, + [MarshalAs(UnmanagedType.Interface)] IClassFactory objectAsUnknown, + uint executionContext, + uint flags, + out uint registrationToken); + + public const uint CLSCTX_LOCAL_SERVER = 4; + public const uint REGCLS_MULTIPLEUSE = 1; + + public const uint S_OK = 0x00000000; + public const uint CLASS_E_NOAGGREGATION = 0x80040110; + public const uint E_NOINTERFACE = 0x80004002; + + public const string IID_IUnknown = "00000000-0000-0000-C000-000000000046"; + public const string IID_IClassFactory = "00000001-0000-0000-C000-000000000046"; + + [ComImport] + [ComVisible(false)] + [Guid(IID_IClassFactory)] + [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + public interface IClassFactory + { + [PreserveSig] + uint CreateInstance(IntPtr objectAsUnknown, ref Guid interfaceId, out IntPtr objectPointer); + + [PreserveSig] + uint LockServer(bool Lock); + } + + internal class BackgroundTaskFactory : IClassFactory where TaskType : TaskInterface, new() + { + public BackgroundTaskFactory() + { + } + + public uint CreateInstance(IntPtr objectAsUnknown, ref Guid interfaceId, out IntPtr objectPointer) + { + if (objectAsUnknown != IntPtr.Zero) + { + objectPointer = IntPtr.Zero; + return CLASS_E_NOAGGREGATION; + } + + if ((interfaceId != typeof(TaskType).GUID) && (interfaceId != new Guid(IID_IUnknown))) + { + objectPointer = IntPtr.Zero; + return E_NOINTERFACE; + } + + objectPointer = MarshalInterface.FromManaged(new TaskType()); + return S_OK; + } + + public uint LockServer(bool lockServer) + { + return S_OK; + } + } + } +} diff --git a/Samples/BackgroundTask/cs-winui/BackgroundTaskBuilder/MainWindow.xaml b/Samples/BackgroundTask/cs-winui/BackgroundTaskBuilder/MainWindow.xaml new file mode 100644 index 000000000..ab7247281 --- /dev/null +++ b/Samples/BackgroundTask/cs-winui/BackgroundTaskBuilder/MainWindow.xaml @@ -0,0 +1,15 @@ + + + + + + + diff --git a/Samples/BackgroundTask/cs-winui/BackgroundTaskBuilder/MainWindow.xaml.cs b/Samples/BackgroundTask/cs-winui/BackgroundTaskBuilder/MainWindow.xaml.cs new file mode 100644 index 000000000..60330c227 --- /dev/null +++ b/Samples/BackgroundTask/cs-winui/BackgroundTaskBuilder/MainWindow.xaml.cs @@ -0,0 +1,73 @@ +using Microsoft.UI.Xaml; +using Microsoft.UI.Xaml.Controls; +using Microsoft.UI.Xaml.Controls.Primitives; +using Microsoft.UI.Xaml.Data; +using Microsoft.UI.Xaml.Input; +using Microsoft.UI.Xaml.Media; +using Microsoft.UI.Xaml.Navigation; +using Microsoft.Windows.ApplicationModel.Background; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Runtime.InteropServices; +using System.Runtime.InteropServices.WindowsRuntime; +using Windows.ApplicationModel.Background; +using Windows.Foundation; +using Windows.Foundation.Collections; +using WinRT; +using WinRT.Interop; + +// To learn more about WinUI, the WinUI project structure, +// and more about our project templates, see: http://aka.ms/winui-project-info. + +namespace BackgroundTaskBuilder +{ + /// + /// An empty window that can be used on its own or navigated to within a Frame. + /// + public sealed partial class MainWindow : Window + { + static private uint _RegistrationToken; + public MainWindow() + { + this.InitializeComponent(); + } + private void unregisterTasks() + { + var allRegistrations = BackgroundTaskRegistration.AllTasks; + foreach (var taskPair in allRegistrations) + { + IBackgroundTaskRegistration task = taskPair.Value; + task.Unregister(true); + } + } + + private void myButton_Click(object sender, RoutedEventArgs e) + { + myButton.Content = "Registered Task for TimeZone Change"; + myButton.IsEnabled = false; + unregisterTasks(); + registerTimeZoneChangedTask(); + } + + private void registerTimeZoneChangedTask() + { + var taskBuilder = new Microsoft.Windows.ApplicationModel.Background.BackgroundTaskBuilder + { + Name = "TimeZoneChangedTask" + }; + taskBuilder.SetTaskEntryPointClsid(typeof(BackgroundTask).GUID); + taskBuilder.SetTrigger(new SystemTrigger(SystemTriggerType.TimeZoneChange, false)); + BackgroundTaskRegistration task = taskBuilder.Register(); + + + Guid taskGuid = typeof(BackgroundTask).GUID; + ComServer.CoRegisterClassObject(ref taskGuid, + new ComServer.BackgroundTaskFactory(), + ComServer.CLSCTX_LOCAL_SERVER, + ComServer.REGCLS_MULTIPLEUSE, + out _RegistrationToken); + } + } +} diff --git a/Samples/BackgroundTask/cs-winui/BackgroundTaskBuilder/Package.appxmanifest b/Samples/BackgroundTask/cs-winui/BackgroundTaskBuilder/Package.appxmanifest new file mode 100644 index 000000000..38e756c72 --- /dev/null +++ b/Samples/BackgroundTask/cs-winui/BackgroundTaskBuilder/Package.appxmanifest @@ -0,0 +1,74 @@ + + + + + + + + + + BackgroundTaskBuilder + godlyalias + Assets\StoreLogo.png + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Microsoft.Windows.ApplicationModel.Background.UniversalBGTask.dll + + + + + + + + diff --git a/Samples/BackgroundTask/cs-winui/BackgroundTaskBuilder/Properties/PublishProfiles/win-arm64.pubxml b/Samples/BackgroundTask/cs-winui/BackgroundTaskBuilder/Properties/PublishProfiles/win-arm64.pubxml new file mode 100644 index 000000000..8953cce98 --- /dev/null +++ b/Samples/BackgroundTask/cs-winui/BackgroundTaskBuilder/Properties/PublishProfiles/win-arm64.pubxml @@ -0,0 +1,14 @@ + + + + + FileSystem + ARM64 + win-arm64 + bin\$(Configuration)\$(TargetFramework)\$(RuntimeIdentifier)\publish\ + true + False + + \ No newline at end of file diff --git a/Samples/BackgroundTask/cs-winui/BackgroundTaskBuilder/Properties/PublishProfiles/win-x64.pubxml b/Samples/BackgroundTask/cs-winui/BackgroundTaskBuilder/Properties/PublishProfiles/win-x64.pubxml new file mode 100644 index 000000000..cd995617c --- /dev/null +++ b/Samples/BackgroundTask/cs-winui/BackgroundTaskBuilder/Properties/PublishProfiles/win-x64.pubxml @@ -0,0 +1,14 @@ + + + + + FileSystem + x64 + win-x64 + bin\$(Configuration)\$(TargetFramework)\$(RuntimeIdentifier)\publish\ + true + False + + \ No newline at end of file diff --git a/Samples/BackgroundTask/cs-winui/BackgroundTaskBuilder/Properties/PublishProfiles/win-x86.pubxml b/Samples/BackgroundTask/cs-winui/BackgroundTaskBuilder/Properties/PublishProfiles/win-x86.pubxml new file mode 100644 index 000000000..a70c69425 --- /dev/null +++ b/Samples/BackgroundTask/cs-winui/BackgroundTaskBuilder/Properties/PublishProfiles/win-x86.pubxml @@ -0,0 +1,14 @@ + + + + + FileSystem + x86 + win-x86 + bin\$(Configuration)\$(TargetFramework)\$(RuntimeIdentifier)\publish\ + true + False + + \ No newline at end of file diff --git a/Samples/BackgroundTask/cs-winui/BackgroundTaskBuilder/Properties/launchSettings.json b/Samples/BackgroundTask/cs-winui/BackgroundTaskBuilder/Properties/launchSettings.json new file mode 100644 index 000000000..665ee2690 --- /dev/null +++ b/Samples/BackgroundTask/cs-winui/BackgroundTaskBuilder/Properties/launchSettings.json @@ -0,0 +1,12 @@ +{ + "profiles": { + "BackgroundTaskBuilder (Package)": { + "commandName": "MsixPackage", + "nativeDebugging": true + }, + "BackgroundTaskBuilder (Unpackaged)": { + "commandName": "Project", + "nativeDebugging": true + } + } +} \ No newline at end of file diff --git a/Samples/BackgroundTask/cs-winui/BackgroundTaskBuilder/app.manifest b/Samples/BackgroundTask/cs-winui/BackgroundTaskBuilder/app.manifest new file mode 100644 index 000000000..6d901dd11 --- /dev/null +++ b/Samples/BackgroundTask/cs-winui/BackgroundTaskBuilder/app.manifest @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + PerMonitorV2 + + + \ No newline at end of file