From a243907470537581acdc01071e3cacd0f71b5364 Mon Sep 17 00:00:00 2001 From: Dinah Gao <116714259+DinahK-2SO@users.noreply.github.com> Date: Tue, 10 Dec 2024 11:01:23 +0800 Subject: [PATCH 01/39] Microsoft.Windows.Storage.Pickers.FileOpenPicker.PickSingleFileAsync (#4945) Creating new API Microsoft.Windows.Storage.Pickers.FileOpenPicker.PickSingleFileAsync --- WindowsAppRuntime.sln | 19 ++++++ build/CopyFilesToStagingDir.ps1 | 4 ++ build/NuSpecs/AppxManifest.xml | 3 + .../WindowsAppSDK-Nuget-Native.WinRt.props | 6 ++ .../WindowsAppSDK-Nuget-Native.targets | 8 +++ dev/Interop/StoragePicker/FileOpenPicker.cpp | 58 +++++++++++++++++++ dev/Interop/StoragePicker/FileOpenPicker.h | 19 ++++++ dev/Interop/StoragePicker/FileOpenPicker.idl | 13 +++++ .../StoragePicker/StoragePicker.vcxitems | 25 ++++++++ ....Windows.Storage.Pickers.Projection.csproj | 58 +++++++++++++++++++ .../WindowsAppRuntime_DLL.vcxproj | 1 + 11 files changed, 214 insertions(+) create mode 100644 dev/Interop/StoragePicker/FileOpenPicker.cpp create mode 100644 dev/Interop/StoragePicker/FileOpenPicker.h create mode 100644 dev/Interop/StoragePicker/FileOpenPicker.idl create mode 100644 dev/Interop/StoragePicker/StoragePicker.vcxitems create mode 100644 dev/Projections/CS/Microsoft.Windows.Storage.Pickers.Projection/Microsoft.Windows.Storage.Pickers.Projection.csproj diff --git a/WindowsAppRuntime.sln b/WindowsAppRuntime.sln index 266ae49a34..2e644489bd 100644 --- a/WindowsAppRuntime.sln +++ b/WindowsAppRuntime.sln @@ -566,6 +566,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "IXP", "IXP", "{7B323048-439 EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IXP.TransportPackage.PackageReference", "eng\PackageReference\IXP\IXP.TransportPackage.PackageReference.csproj", "{A949149D-29CA-4AA7-B1ED-0E571B4AD9BB}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.Windows.Storage.Pickers.Projection", "dev\Projections\CS\Microsoft.Windows.Storage.Pickers.Projection\Microsoft.Windows.Storage.Pickers.Projection.csproj", "{8E01AA4F-A16A-4E3F-A59F-6D49422B4410}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -2002,6 +2004,22 @@ Global {A949149D-29CA-4AA7-B1ED-0E571B4AD9BB}.Release|x64.Build.0 = Release|x64 {A949149D-29CA-4AA7-B1ED-0E571B4AD9BB}.Release|x86.ActiveCfg = Release|x86 {A949149D-29CA-4AA7-B1ED-0E571B4AD9BB}.Release|x86.Build.0 = Release|x86 + {8E01AA4F-A16A-4E3F-A59F-6D49422B4410}.Debug|Any CPU.ActiveCfg = Debug|x64 + {8E01AA4F-A16A-4E3F-A59F-6D49422B4410}.Debug|Any CPU.Build.0 = Debug|x64 + {8E01AA4F-A16A-4E3F-A59F-6D49422B4410}.Debug|ARM64.ActiveCfg = Debug|arm64 + {8E01AA4F-A16A-4E3F-A59F-6D49422B4410}.Debug|ARM64.Build.0 = Debug|arm64 + {8E01AA4F-A16A-4E3F-A59F-6D49422B4410}.Debug|x64.ActiveCfg = Debug|x64 + {8E01AA4F-A16A-4E3F-A59F-6D49422B4410}.Debug|x64.Build.0 = Debug|x64 + {8E01AA4F-A16A-4E3F-A59F-6D49422B4410}.Debug|x86.ActiveCfg = Debug|x86 + {8E01AA4F-A16A-4E3F-A59F-6D49422B4410}.Debug|x86.Build.0 = Debug|x86 + {8E01AA4F-A16A-4E3F-A59F-6D49422B4410}.Release|Any CPU.ActiveCfg = Release|x64 + {8E01AA4F-A16A-4E3F-A59F-6D49422B4410}.Release|Any CPU.Build.0 = Release|x64 + {8E01AA4F-A16A-4E3F-A59F-6D49422B4410}.Release|ARM64.ActiveCfg = Release|arm64 + {8E01AA4F-A16A-4E3F-A59F-6D49422B4410}.Release|ARM64.Build.0 = Release|arm64 + {8E01AA4F-A16A-4E3F-A59F-6D49422B4410}.Release|x64.ActiveCfg = Release|x64 + {8E01AA4F-A16A-4E3F-A59F-6D49422B4410}.Release|x64.Build.0 = Release|x64 + {8E01AA4F-A16A-4E3F-A59F-6D49422B4410}.Release|x86.ActiveCfg = Release|x86 + {8E01AA4F-A16A-4E3F-A59F-6D49422B4410}.Release|x86.Build.0 = Release|x86 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -2181,6 +2199,7 @@ Global {D5958784-4518-44F1-A518-80514B380ED5} = {E24C263A-DE3E-4844-BA50-842DA5AD7A49} {7B323048-439F-47E9-A3D4-7342C5ADE2A5} = {5C88AE1D-AC20-4A41-9299-1EEA15B80724} {A949149D-29CA-4AA7-B1ED-0E571B4AD9BB} = {7B323048-439F-47E9-A3D4-7342C5ADE2A5} + {8E01AA4F-A16A-4E3F-A59F-6D49422B4410} = {716C26A0-E6B0-4981-8412-D14A4D410531} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {4B3D7591-CFEC-4762-9A07-ABE99938FB77} diff --git a/build/CopyFilesToStagingDir.ps1 b/build/CopyFilesToStagingDir.ps1 index 3c261aaac2..656d6e5e88 100644 --- a/build/CopyFilesToStagingDir.ps1 +++ b/build/CopyFilesToStagingDir.ps1 @@ -55,6 +55,7 @@ PublishFile $FullBuildOutput\WindowsAppRuntime_DLL\StrippedWinMD\Microsoft.Windo PublishFile $FullBuildOutput\WindowsAppRuntime_DLL\StrippedWinMD\Microsoft.Windows.AppNotifications.winmd $FullPublishDir\Microsoft.WindowsAppRuntime\ PublishFile $FullBuildOutput\WindowsAppRuntime_DLL\StrippedWinMD\Microsoft.Windows.Management.Deployment.winmd $FullPublishDir\Microsoft.WindowsAppRuntime\ PublishFile $FullBuildOutput\WindowsAppRuntime_DLL\StrippedWinMD\Microsoft.Windows.Media.Capture.winmd $FullPublishDir\Microsoft.WindowsAppRuntime\ +PublishFile $FullBuildOutput\WindowsAppRuntime_DLL\StrippedWinMD\Microsoft.Windows.Storage.Pickers.winmd $FullPublishDir\Microsoft.WindowsAppRuntime\ PublishFile $FullBuildOutput\WindowsAppRuntime_DLL\StrippedWinMD\Microsoft.Windows.PushNotifications.winmd $FullPublishDir\Microsoft.WindowsAppRuntime\ PublishFile $FullBuildOutput\WindowsAppRuntime_DLL\StrippedWinMD\Microsoft.Windows.Security.AccessControl.winmd $FullPublishDir\Microsoft.WindowsAppRuntime\ PublishFile $FullBuildOutput\WindowsAppRuntime_DLL\StrippedWinMD\Microsoft.Security.Authentication.OAuth.winmd $FullPublishDir\Microsoft.WindowsAppRuntime\ @@ -126,6 +127,8 @@ PublishFile $FullBuildOutput\Microsoft.Windows.Management.Deployment.Projection\ PublishFile $FullBuildOutput\Microsoft.Windows.Management.Deployment.Projection\Microsoft.Windows.Management.Deployment.Projection.pdb $NugetDir\lib\net6.0-windows10.0.17763.0 PublishFile $FullBuildOutput\Microsoft.Windows.Media.Capture.Projection\Microsoft.Windows.Media.Capture.Projection.dll $NugetDir\lib\net6.0-windows10.0.17763.0 PublishFile $FullBuildOutput\Microsoft.Windows.Media.Capture.Projection\Microsoft.Windows.Media.Capture.Projection.pdb $NugetDir\lib\net6.0-windows10.0.17763.0 +PublishFile $FullBuildOutput\Microsoft.Windows.Storage.Pickers.Projection\Microsoft.Windows.Storage.Pickers.Projection.dll $NugetDir\lib\net6.0-windows10.0.17763.0 +PublishFile $FullBuildOutput\Microsoft.Windows.Storage.Pickers.Projection\Microsoft.Windows.Storage.Pickers.Projection.pdb $NugetDir\lib\net6.0-windows10.0.17763.0 PublishFile $FullBuildOutput\Microsoft.Windows.PushNotifications.Projection\Microsoft.Windows.PushNotifications.Projection.dll $NugetDir\lib\net6.0-windows10.0.17763.0 PublishFile $FullBuildOutput\Microsoft.Windows.PushNotifications.Projection\Microsoft.Windows.PushNotifications.Projection.pdb $NugetDir\lib\net6.0-windows10.0.17763.0 PublishFile $FullBuildOutput\Microsoft.Windows.Security.AccessControl.Projection\Microsoft.Windows.Security.AccessControl.Projection.dll $NugetDir\lib\net6.0-windows10.0.17763.0 @@ -202,6 +205,7 @@ PublishFile $FullBuildOutput\WindowsAppRuntime_DLL\StrippedWinMD\Microsoft.Windo PublishFile $FullBuildOutput\WindowsAppRuntime_DLL\StrippedWinMD\Microsoft.Windows.AppNotifications.winmd $NugetDir\lib\uap10.0 PublishFile $FullBuildOutput\WindowsAppRuntime_DLL\StrippedWinMD\Microsoft.Windows.Management.Deployment.winmd $NugetDir\lib\uap10.0 PublishFile $FullBuildOutput\WindowsAppRuntime_DLL\StrippedWinMD\Microsoft.Windows.Media.Capture.winmd $NugetDir\lib\uap10.0 +PublishFile $FullBuildOutput\WindowsAppRuntime_DLL\StrippedWinMD\Microsoft.Windows.Storage.Pickers.winmd $NugetDir\lib\uap10.0 PublishFile $FullBuildOutput\WindowsAppRuntime_DLL\StrippedWinMD\Microsoft.Windows.PushNotifications.winmd $NugetDir\lib\uap10.0 PublishFile $FullBuildOutput\WindowsAppRuntime_DLL\StrippedWinMD\Microsoft.Windows.Security.AccessControl.winmd $NugetDir\lib\uap10.0 PublishFile $FullBuildOutput\WindowsAppRuntime_DLL\StrippedWinMD\Microsoft.Security.Authentication.OAuth.winmd $NugetDir\lib\uap10.0 diff --git a/build/NuSpecs/AppxManifest.xml b/build/NuSpecs/AppxManifest.xml index e079468216..2ee96bb190 100644 --- a/build/NuSpecs/AppxManifest.xml +++ b/build/NuSpecs/AppxManifest.xml @@ -111,6 +111,9 @@ + + + diff --git a/build/NuSpecs/WindowsAppSDK-Nuget-Native.WinRt.props b/build/NuSpecs/WindowsAppSDK-Nuget-Native.WinRt.props index 88fede76fd..02b59d588d 100644 --- a/build/NuSpecs/WindowsAppSDK-Nuget-Native.WinRt.props +++ b/build/NuSpecs/WindowsAppSDK-Nuget-Native.WinRt.props @@ -75,6 +75,12 @@ $(MSBuildThisFileDirectory)..\..\runtimes\win10-$(_WindowsAppSDKFoundationPlatform)\native\Microsoft.WindowsAppRuntime.dll true + + $(MSBuildThisFileDirectory)..\..\lib\uap10.0\Microsoft.Windows.Storage.Pickers.winmd + $(MSBuildThisFileDirectory)..\..\runtimes\win10-$(_WindowsAppSDKFoundationPlatform)\native\Microsoft.WindowsAppRuntime.dll + true + diff --git a/build/NuSpecs/WindowsAppSDK-Nuget-Native.targets b/build/NuSpecs/WindowsAppSDK-Nuget-Native.targets index c18bdb650a..7057bff1ae 100644 --- a/build/NuSpecs/WindowsAppSDK-Nuget-Native.targets +++ b/build/NuSpecs/WindowsAppSDK-Nuget-Native.targets @@ -135,6 +135,14 @@ + + + false + Microsoft.WindowsAppRuntime.dll + + + diff --git a/dev/Interop/StoragePicker/FileOpenPicker.cpp b/dev/Interop/StoragePicker/FileOpenPicker.cpp new file mode 100644 index 0000000000..08b869f9e8 --- /dev/null +++ b/dev/Interop/StoragePicker/FileOpenPicker.cpp @@ -0,0 +1,58 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See LICENSE in the project root for license information. +#include "pch.h" +#include "FileOpenPicker.h" +#include "Microsoft.Windows.Storage.Pickers.FileOpenPicker.g.cpp" +#include +#include +#include +#include +#include + +namespace winrt::Microsoft::Windows::Storage::Pickers::implementation +{ + winrt::Windows::Foundation::IAsyncOperation FileOpenPicker::PickSingleFileAsync() + { + winrt::apartment_context ui_thread; + + co_await winrt::resume_background(); + + // Handle cancellation. + auto cancellationToken = co_await winrt::get_cancellation_token(); + if (cancellationToken()) + { + co_return nullptr; + } + + // TODO: should we initialize COM? + //wil::com_initialize_ex initializeCom{ COINIT_APARTMENTTHREADED }; + + wil::com_ptr fileOpenDialog; + THROW_IF_FAILED(CoCreateInstance(CLSID_FileOpenDialog, nullptr, CLSCTX_ALL, IID_PPV_ARGS(&fileOpenDialog))); + + HRESULT hr = fileOpenDialog->Show(nullptr); + if (FAILED(hr) || cancellationToken()) + { + co_return nullptr; + } + + wil::com_ptr shellItem; + THROW_IF_FAILED(fileOpenDialog->GetResult(shellItem.put())); + + wil::unique_cotaskmem_string filePath; + THROW_IF_FAILED(shellItem->GetDisplayName(SIGDN_FILESYSPATH, &filePath)); + + // Convert the file path to a StorageFile. + auto const& file = co_await winrt::Windows::Storage::StorageFile::GetFileFromPathAsync(filePath.get()); + if (cancellationToken()) { + co_return nullptr; + } + + co_await ui_thread; + if (cancellationToken()) { + co_return nullptr; + } + + co_return file; + } +} diff --git a/dev/Interop/StoragePicker/FileOpenPicker.h b/dev/Interop/StoragePicker/FileOpenPicker.h new file mode 100644 index 0000000000..1a9665cb71 --- /dev/null +++ b/dev/Interop/StoragePicker/FileOpenPicker.h @@ -0,0 +1,19 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See LICENSE in the project root for license information. +#pragma once +#include "Microsoft.Windows.Storage.Pickers.FileOpenPicker.g.h" + +namespace winrt::Microsoft::Windows::Storage::Pickers::implementation +{ + struct FileOpenPicker : FileOpenPickerT + { + FileOpenPicker() = default; + winrt::Windows::Foundation::IAsyncOperation PickSingleFileAsync(); + }; +} +namespace winrt::Microsoft::Windows::Storage::Pickers::factory_implementation +{ + struct FileOpenPicker : FileOpenPickerT + { + }; +} diff --git a/dev/Interop/StoragePicker/FileOpenPicker.idl b/dev/Interop/StoragePicker/FileOpenPicker.idl new file mode 100644 index 0000000000..0af9f685ef --- /dev/null +++ b/dev/Interop/StoragePicker/FileOpenPicker.idl @@ -0,0 +1,13 @@ +namespace Microsoft.Windows.Storage.Pickers +{ + [contractversion(1)] + apicontract FileOpenPickerContract {}; + + [contract(FileOpenPickerContract, 1)] + runtimeclass FileOpenPicker + { + FileOpenPicker(); + + Windows.Foundation.IAsyncOperation PickSingleFileAsync(); + }; +} diff --git a/dev/Interop/StoragePicker/StoragePicker.vcxitems b/dev/Interop/StoragePicker/StoragePicker.vcxitems new file mode 100644 index 0000000000..f49e671656 --- /dev/null +++ b/dev/Interop/StoragePicker/StoragePicker.vcxitems @@ -0,0 +1,25 @@ + + + + $(MSBuildAllProjects);$(MSBuildThisFileFullPath) + true + {a39e7b2f-5f67-47dd-8443-531d095ca7f3} + + + + %(AdditionalIncludeDirectories);$(MSBuildThisFileDirectory) + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dev/Projections/CS/Microsoft.Windows.Storage.Pickers.Projection/Microsoft.Windows.Storage.Pickers.Projection.csproj b/dev/Projections/CS/Microsoft.Windows.Storage.Pickers.Projection/Microsoft.Windows.Storage.Pickers.Projection.csproj new file mode 100644 index 0000000000..a13846ff90 --- /dev/null +++ b/dev/Projections/CS/Microsoft.Windows.Storage.Pickers.Projection/Microsoft.Windows.Storage.Pickers.Projection.csproj @@ -0,0 +1,58 @@ + + + net6.0-windows10.0.17763.0 + 10.0.17763.0 + x64;x86;arm64 + AnyCPU + false + + + + true + true + + + + + 8305 + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + Microsoft.Windows.Storage.Pickers + 10.0.17763.0 + false + + + + + pdbonly + true + + + + + + + + + + + + + $(OutDir)..\WindowsAppRuntime_DLL\StrippedWinMD\Microsoft.Windows.Storage.Pickers.winmd + true + + + diff --git a/dev/WindowsAppRuntime_DLL/WindowsAppRuntime_DLL.vcxproj b/dev/WindowsAppRuntime_DLL/WindowsAppRuntime_DLL.vcxproj index 62e67cef13..75db43c1f0 100644 --- a/dev/WindowsAppRuntime_DLL/WindowsAppRuntime_DLL.vcxproj +++ b/dev/WindowsAppRuntime_DLL/WindowsAppRuntime_DLL.vcxproj @@ -102,6 +102,7 @@ + From 7a282f2021af4e5bf976c65691ee5770928a3b96 Mon Sep 17 00:00:00 2001 From: Dinah Gao Date: Wed, 11 Dec 2024 15:00:41 +0800 Subject: [PATCH 02/39] add one telemetry --- dev/Interop/StoragePicker/FileOpenPicker.cpp | 5 ++++ dev/Interop/StoragePicker/FileOpenPicker.h | 5 ++++ .../StoragePicker/StoragePickersTelemetry.h | 29 +++++++++++++++++++ 3 files changed, 39 insertions(+) create mode 100644 dev/Interop/StoragePicker/StoragePickersTelemetry.h diff --git a/dev/Interop/StoragePicker/FileOpenPicker.cpp b/dev/Interop/StoragePicker/FileOpenPicker.cpp index 08b869f9e8..9684ff2f98 100644 --- a/dev/Interop/StoragePicker/FileOpenPicker.cpp +++ b/dev/Interop/StoragePicker/FileOpenPicker.cpp @@ -3,6 +3,7 @@ #include "pch.h" #include "FileOpenPicker.h" #include "Microsoft.Windows.Storage.Pickers.FileOpenPicker.g.cpp" +#include "StoragePickersTelemetry.h" #include #include #include @@ -13,6 +14,10 @@ namespace winrt::Microsoft::Windows::Storage::Pickers::implementation { winrt::Windows::Foundation::IAsyncOperation FileOpenPicker::PickSingleFileAsync() { + bool isAppPackaged = m_telemetryHelper.IsPackagedApp(); + PCWSTR appName = m_telemetryHelper.GetAppName().c_str(); + auto logCaptureOperation{ StoragePickersTelemetry::StoragePickersOperation::Start(isAppPackaged, appName) }; + winrt::apartment_context ui_thread; co_await winrt::resume_background(); diff --git a/dev/Interop/StoragePicker/FileOpenPicker.h b/dev/Interop/StoragePicker/FileOpenPicker.h index 1a9665cb71..c97752674f 100644 --- a/dev/Interop/StoragePicker/FileOpenPicker.h +++ b/dev/Interop/StoragePicker/FileOpenPicker.h @@ -2,6 +2,7 @@ // Licensed under the MIT License. See LICENSE in the project root for license information. #pragma once #include "Microsoft.Windows.Storage.Pickers.FileOpenPicker.g.h" +#include "TelemetryHelper.h" namespace winrt::Microsoft::Windows::Storage::Pickers::implementation { @@ -9,8 +10,12 @@ namespace winrt::Microsoft::Windows::Storage::Pickers::implementation { FileOpenPicker() = default; winrt::Windows::Foundation::IAsyncOperation PickSingleFileAsync(); + + private: + TelemetryHelper m_telemetryHelper; }; } + namespace winrt::Microsoft::Windows::Storage::Pickers::factory_implementation { struct FileOpenPicker : FileOpenPickerT diff --git a/dev/Interop/StoragePicker/StoragePickersTelemetry.h b/dev/Interop/StoragePicker/StoragePickersTelemetry.h new file mode 100644 index 0000000000..beff1e2a22 --- /dev/null +++ b/dev/Interop/StoragePicker/StoragePickersTelemetry.h @@ -0,0 +1,29 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT license. + +#pragma once +#include "..\WindowsAppRuntime_Insights\WindowsAppRuntimeInsights.h" +#include + +DECLARE_TRACELOGGING_CLASS(StoragePickersTelemetryProvider, + "Microsoft.WindowsAppSDK.StoragePickersTelemetry", + // {3be0d45f-3a9d-46be-a1cf-b08465473cc4} + (0x3be0d45f, 0x3a9d, 0x46be, 0xa1, 0xcf, 0xb0, 0x84, 0x65, 0x47, 0x3c, 0xc4)); + +class StoragePickersTelemetry : public wil::TraceLoggingProvider +{ + IMPLEMENT_TELEMETRY_CLASS(StoragePickersTelemetry, StoragePickersTelemetryProvider); + +public: + BEGIN_COMPLIANT_MEASURES_ACTIVITY_CLASS(StoragePickersOperation, PDT_ProductAndServicePerformance); + DEFINE_ACTIVITY_START(bool isAppPackaged, PCWSTR appName) noexcept try + { + TraceLoggingClassWriteStart( + StoragePickersOperation, + _GENERIC_PARTB_FIELDS_ENABLED, + TraceLoggingBool(isAppPackaged, "IsAppPackaged"), + TraceLoggingWideString(appName, "AppName")); + } + CATCH_LOG() + END_ACTIVITY_CLASS(); +}; \ No newline at end of file From e6997b5962f46de7bee95646ccd97114f9fbb4df Mon Sep 17 00:00:00 2001 From: Dinah Gao Date: Thu, 12 Dec 2024 14:41:49 +0800 Subject: [PATCH 03/39] Merge codes from branch 'user/xianghong/pickers-prototype' at \prototype-workingdir\Microsoft.Storage.Pickers Squashed commit of the following: commit 4ce840f9aedef32b3312cde280318bd170223c99 Author: Dinah Gao Date: Wed Dec 11 15:00:41 2024 +0800 add one telemetry commit bbf72f8edecc9a4b74bf61bfb5ab5f8c72b0956f Author: Dinah Gao <116714259+DinahK-2SO@users.noreply.github.com> Date: Tue Dec 10 11:01:23 2024 +0800 Microsoft.Windows.Storage.Pickers.FileOpenPicker.PickSingleFileAsync (#4945) Creating new API Microsoft.Windows.Storage.Pickers.FileOpenPicker.PickSingleFileAsync commit ff3f2a8aa226a9d2435c99b113c11fad722f090d Author: Xiang Hong Date: Mon Dec 9 18:14:16 2024 +0800 fix: fix project configuration and add certificate notes to README.md commit e11c8e60e993ea9712970da4cc2ba5ca9c27013b Author: Xiang Hong (from Dev Box) Date: Sun Dec 8 20:54:23 2024 +0800 update readme for folder description commit c6966f34805ce56b85f6d14d35e8fe29304fc4a9 Author: Xiang Hong (from Dev Box) Date: Sun Dec 8 20:08:46 2024 +0800 add a simple READEME commit c17750f2fd2f4282b3b3228a97cb0df8394e6b3b Author: Xiang Hong (from Dev Box) Date: Sun Dec 8 11:27:04 2024 +0800 feature: add basic implementations for SavePickers FileExtension/SuggestedSaveFile/Name functionalities commit 3be9dc1194ab01acb78d020b638d6cc2dd5c87b3 Author: Xiang Hong (from Dev Box) Date: Sun Dec 8 10:35:59 2024 +0800 clean: code clean on naming styles etc commit 9fcc249c6a584c04e29fbc015a140b21b894f4be Author: Xiang Hong (from Dev Box) Date: Sat Dec 7 22:22:21 2024 +0800 refactor: use WinRT MD5 hash string to Guid commit 756bafa151e319ef1a40f2a25411f04b364c96c5 Author: Xiang Hong (from Dev Box) Date: Sat Dec 7 22:02:55 2024 +0800 fix: fix file type filter issues and refactor to use PickParameters commit 8dea72ab4a2e80ee8f8e6ddd01eb3d8c76bbf5d4 Author: Xiang Hong (from Dev Box) Date: Sat Dec 7 19:46:45 2024 +0800 feature: add COM FileSavePicker basic implementation commit 37a5a75bc883f67e662e96b04c74a3ed25ce44f6 Author: Xiang Hong Date: Sat Dec 7 17:13:55 2024 +0800 add save file dialog usage in demo app commit fc9a03af48cf4522a67a2cce717548270cfa8942 Author: Xiang Hong Date: Sat Dec 7 12:06:47 2024 +0800 feature: add folder functionalities to demo test app commit 34556bd7594bf6bd4c2e1493320b10588d049214 Author: Xiang Hong Date: Fri Dec 6 22:51:55 2024 +0800 feature: add COM based picker prototype basic implementation --- .../FileOpenPicker.cpp | 154 ++++++++++++++ .../FileOpenPicker.h | 44 ++++ .../FileSavePicker.cpp | 138 ++++++++++++ .../FileSavePicker.h | 53 +++++ .../FolderPicker.cpp | 98 +++++++++ .../Microsoft.Storage.Pickers/FolderPicker.h | 45 ++++ .../Microsoft.Storage.Pickers.vcxproj | 160 ++++++++++++++ .../Microsoft.Storage.Pickers.vcxproj.filters | 37 ++++ .../Microsoft_Storage_Pickers.def | 3 + .../PickerCommon.cpp | 200 ++++++++++++++++++ .../Microsoft.Storage.Pickers/PickerCommon.h | 27 +++ .../Microsoft.Storage.Pickers/Pickers.idl | 68 ++++++ .../Microsoft.Storage.Pickers/packages.config | 8 + .../Microsoft.Storage.Pickers/pch.cpp | 1 + .../Microsoft.Storage.Pickers/pch.h | 33 +++ .../Microsoft.Storage.Pickers/readme.txt | 27 +++ 16 files changed, 1096 insertions(+) create mode 100644 prototype-workingdir/Microsoft.Storage.Pickers/FileOpenPicker.cpp create mode 100644 prototype-workingdir/Microsoft.Storage.Pickers/FileOpenPicker.h create mode 100644 prototype-workingdir/Microsoft.Storage.Pickers/FileSavePicker.cpp create mode 100644 prototype-workingdir/Microsoft.Storage.Pickers/FileSavePicker.h create mode 100644 prototype-workingdir/Microsoft.Storage.Pickers/FolderPicker.cpp create mode 100644 prototype-workingdir/Microsoft.Storage.Pickers/FolderPicker.h create mode 100644 prototype-workingdir/Microsoft.Storage.Pickers/Microsoft.Storage.Pickers.vcxproj create mode 100644 prototype-workingdir/Microsoft.Storage.Pickers/Microsoft.Storage.Pickers.vcxproj.filters create mode 100644 prototype-workingdir/Microsoft.Storage.Pickers/Microsoft_Storage_Pickers.def create mode 100644 prototype-workingdir/Microsoft.Storage.Pickers/PickerCommon.cpp create mode 100644 prototype-workingdir/Microsoft.Storage.Pickers/PickerCommon.h create mode 100644 prototype-workingdir/Microsoft.Storage.Pickers/Pickers.idl create mode 100644 prototype-workingdir/Microsoft.Storage.Pickers/packages.config create mode 100644 prototype-workingdir/Microsoft.Storage.Pickers/pch.cpp create mode 100644 prototype-workingdir/Microsoft.Storage.Pickers/pch.h create mode 100644 prototype-workingdir/Microsoft.Storage.Pickers/readme.txt diff --git a/prototype-workingdir/Microsoft.Storage.Pickers/FileOpenPicker.cpp b/prototype-workingdir/Microsoft.Storage.Pickers/FileOpenPicker.cpp new file mode 100644 index 0000000000..d3d42329d3 --- /dev/null +++ b/prototype-workingdir/Microsoft.Storage.Pickers/FileOpenPicker.cpp @@ -0,0 +1,154 @@ +#include "pch.h" +#include "FileOpenPicker.h" +#include "FileOpenPicker.g.cpp" +#include +#include +#include +#include +#include "PickerCommon.h" + +namespace winrt::Microsoft::Storage::Pickers::implementation +{ + FileOpenPicker::FileOpenPicker(winrt::Microsoft::UI::WindowId const& windowId) + : m_windowId(windowId) + { + } + + winrt::Microsoft::Storage::Pickers::PickerViewMode FileOpenPicker::ViewMode() + { + return m_viewMode; + } + void FileOpenPicker::ViewMode(winrt::Microsoft::Storage::Pickers::PickerViewMode const& value) + { + m_viewMode = value; + } + hstring FileOpenPicker::SettingsIdentifier() + { + return m_settingsIdentifier; + } + void FileOpenPicker::SettingsIdentifier(hstring const& value) + { + m_settingsIdentifier = value; + } + winrt::Microsoft::Storage::Pickers::PickerLocationId FileOpenPicker::SuggestedStartLocation() + { + return m_suggestedStartLocation; + } + void FileOpenPicker::SuggestedStartLocation(winrt::Microsoft::Storage::Pickers::PickerLocationId const& value) + { + m_suggestedStartLocation = value; + } + winrt::hstring FileOpenPicker::CommitButtonText() + { + return m_commitButtonText; + } + void FileOpenPicker::CommitButtonText(winrt::hstring const& value) + { + m_commitButtonText = value; + } + winrt::Windows::Foundation::Collections::IVector FileOpenPicker::FileTypeFilter() + { + return m_fileTypeFilter; + } + + void FileOpenPicker::CaptureParameters(PickerCommon::PickerParameters& parameters) + { + parameters.HWnd = winrt::Microsoft::UI::GetWindowFromWindowId(m_windowId); + parameters.CommitButtonText = m_commitButtonText; + parameters.SettingsIdentifierId = m_settingsIdentifier; + parameters.PickerLocationId = m_suggestedStartLocation; + parameters.FileTypeFilterPara = PickerCommon::CaptureFilterSpec(parameters.FileTypeFilterData, m_fileTypeFilter.GetView()); + } + + winrt::Windows::Foundation::IAsyncOperation FileOpenPicker::PickSingleFileAsync() + { + PickerCommon::PickerParameters parameters{}; + + CaptureParameters(parameters); + + co_await winrt::resume_background(); + + auto cancellationToken = co_await winrt::get_cancellation_token(); + if (cancellationToken()) + { + co_return nullptr; + } + + // TODO: should we initialize COM? + // wil::com_initialize_ex initializeCom{ COINIT_APARTMENTTHREADED }; + + auto dialog = create_instance(CLSID_FileOpenDialog, CONTEXT_ALL); + + parameters.ConfigureDialog(dialog); + + { + auto hr = dialog->Show(parameters.HWnd); + if (FAILED(hr) || cancellationToken()) + { + co_return nullptr; + } + } + + winrt::com_ptr shellItem{}; + check_hresult(dialog->GetResult(shellItem.put())); + auto file = co_await PickerCommon::CreateStorageFileFromShellItem(shellItem); + + if (cancellationToken()) + { + co_return nullptr; + } + co_return file; + } + + winrt::Windows::Foundation::IAsyncOperation> FileOpenPicker::PickMultipleFilesAsync() + { + PickerCommon::PickerParameters parameters{}; + + CaptureParameters(parameters); + + co_await winrt::resume_background(); + + winrt::Windows::Foundation::Collections::IVector results{ winrt::single_threaded_vector() }; + + auto cancellationToken = co_await winrt::get_cancellation_token(); + if (cancellationToken()) + { + co_return results.GetView(); + } + + auto dialog = create_instance(CLSID_FileOpenDialog, CONTEXT_ALL); + + parameters.ConfigureDialog(dialog); + + check_hresult(dialog->SetOptions(FOS_ALLOWMULTISELECT)); + + { + auto hr = dialog->Show(parameters.HWnd); + if (FAILED(hr) || cancellationToken()) + { + co_return results.GetView(); + } + } + + winrt::com_ptr shellItems{}; + check_hresult(dialog->GetResults(shellItems.put())); + + DWORD itemCount = 0; + check_hresult(shellItems->GetCount(&itemCount)); + + winrt::com_ptr shellItem{}; + for (DWORD i = 0; i < itemCount; i++) + { + check_hresult(shellItems->GetItemAt(i, shellItem.put())); + auto file = co_await PickerCommon::CreateStorageFileFromShellItem(shellItem); + results.Append(file); + } + + if (cancellationToken()) + { + results.Clear(); + co_return results.GetView(); + } + co_return results.GetView(); + } +} diff --git a/prototype-workingdir/Microsoft.Storage.Pickers/FileOpenPicker.h b/prototype-workingdir/Microsoft.Storage.Pickers/FileOpenPicker.h new file mode 100644 index 0000000000..fb68a34d2b --- /dev/null +++ b/prototype-workingdir/Microsoft.Storage.Pickers/FileOpenPicker.h @@ -0,0 +1,44 @@ +#pragma once +#include "FileOpenPicker.g.h" +#include "PickerCommon.h" + +namespace winrt::Microsoft::Storage::Pickers::implementation +{ + struct FileOpenPicker : FileOpenPickerT + { + FileOpenPicker(winrt::Microsoft::UI::WindowId const& windowId); + + winrt::Microsoft::Storage::Pickers::PickerViewMode ViewMode(); + void ViewMode(winrt::Microsoft::Storage::Pickers::PickerViewMode const& value); + + hstring SettingsIdentifier(); + void SettingsIdentifier(hstring const& value); + + winrt::Microsoft::Storage::Pickers::PickerLocationId SuggestedStartLocation(); + void SuggestedStartLocation(winrt::Microsoft::Storage::Pickers::PickerLocationId const& value); + + winrt::hstring CommitButtonText(); + void CommitButtonText(winrt::hstring const& value); + + winrt::Windows::Foundation::Collections::IVector FileTypeFilter(); + + winrt::Windows::Foundation::IAsyncOperation PickSingleFileAsync(); + winrt::Windows::Foundation::IAsyncOperation> PickMultipleFilesAsync(); + + private: + winrt::Microsoft::UI::WindowId m_windowId{}; + PickerViewMode m_viewMode{ PickerViewMode::List }; + winrt::hstring m_settingsIdentifier{}; + PickerLocationId m_suggestedStartLocation{ PickerLocationId::Unspecified }; + winrt::hstring m_commitButtonText{}; + winrt::Windows::Foundation::Collections::IVector m_fileTypeFilter{ winrt::single_threaded_vector() }; + + void CaptureParameters(PickerCommon::PickerParameters& parameters); + }; +} +namespace winrt::Microsoft::Storage::Pickers::factory_implementation +{ + struct FileOpenPicker : FileOpenPickerT + { + }; +} diff --git a/prototype-workingdir/Microsoft.Storage.Pickers/FileSavePicker.cpp b/prototype-workingdir/Microsoft.Storage.Pickers/FileSavePicker.cpp new file mode 100644 index 0000000000..052135bf98 --- /dev/null +++ b/prototype-workingdir/Microsoft.Storage.Pickers/FileSavePicker.cpp @@ -0,0 +1,138 @@ +#include "pch.h" +#include "FileSavePicker.h" +#include "FileSavePicker.g.cpp" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "PickerCommon.h" + +namespace winrt::Microsoft::Storage::Pickers::implementation +{ + + FileSavePicker::FileSavePicker(winrt::Microsoft::UI::WindowId const& windowId) + : m_windowId(windowId) + { + } + hstring FileSavePicker::SettingsIdentifier() + { + return m_settingsIdentifier; + } + void FileSavePicker::SettingsIdentifier(hstring const& value) + { + m_settingsIdentifier = value; + } + winrt::Microsoft::Storage::Pickers::PickerLocationId FileSavePicker::SuggestedStartLocation() + { + return m_suggestedStartLocation; + } + void FileSavePicker::SuggestedStartLocation(winrt::Microsoft::Storage::Pickers::PickerLocationId const& value) + { + m_suggestedStartLocation = value; + } + hstring FileSavePicker::CommitButtonText() + { + return m_commitButtonText; + } + void FileSavePicker::CommitButtonText(hstring const& value) + { + m_commitButtonText = value; + } + winrt::Windows::Foundation::Collections::IMap> FileSavePicker::FileTypeChoices() + { + return m_fileTypeChoices; + } + hstring FileSavePicker::DefaultFileExtension() + { + return m_defaultFileExtension; + } + void FileSavePicker::DefaultFileExtension(hstring const& value) + { + m_defaultFileExtension = value; + } + winrt::Windows::Storage::StorageFile FileSavePicker::SuggestedSaveFile() + { + return m_suggestedSaveFile; + } + void FileSavePicker::SuggestedSaveFile(winrt::Windows::Storage::StorageFile const& value) + { + m_suggestedSaveFile = value; + } + hstring FileSavePicker::SuggestedFileName() + { + return m_suggestedFileName; + } + void FileSavePicker::SuggestedFileName(hstring const& value) + { + m_suggestedFileName = value; + } + + + void FileSavePicker::CaptureParameters(PickerCommon::PickerParameters& parameters) + { + parameters.HWnd = winrt::Microsoft::UI::GetWindowFromWindowId(m_windowId); + parameters.CommitButtonText = m_commitButtonText; + parameters.SettingsIdentifierId = m_settingsIdentifier; + parameters.PickerLocationId = m_suggestedStartLocation; + parameters.FileTypeFilterPara = PickerCommon::CaptureFilterSpec(parameters.FileTypeFilterData, m_fileTypeChoices.GetView()); + + } + + winrt::Windows::Foundation::IAsyncOperation FileSavePicker::PickSaveFileAsync() + { + PickerCommon::PickerParameters parameters{}; + CaptureParameters(parameters); + auto defaultFileExtension = m_defaultFileExtension; + auto suggestedSaveFile = m_suggestedSaveFile; + auto suggestedFileName = m_suggestedFileName; + + co_await winrt::resume_background(); + auto cancellationToken = co_await winrt::get_cancellation_token(); + if (cancellationToken()) + { + co_return nullptr; + } + + auto dialog = create_instance(CLSID_FileSaveDialog, CONTEXT_ALL); + parameters.ConfigureDialog(dialog); + + if (!PickerCommon::IsHStringNullOrEmpty(defaultFileExtension)) + { + check_hresult(dialog->SetDefaultExtension(defaultFileExtension.c_str())); + } + if (!PickerCommon::IsHStringNullOrEmpty(suggestedFileName)) + { + check_hresult(dialog->SetFileName(suggestedFileName.c_str())); + } + if (suggestedSaveFile != nullptr) + { + winrt::com_ptr shellItem; + check_hresult(SHCreateItemFromParsingName(suggestedSaveFile.Path().c_str(), nullptr, IID_PPV_ARGS(shellItem.put()))); + check_hresult(dialog->SetSaveAsItem(shellItem.get())); + } + + { + auto hr = dialog->Show(parameters.HWnd); + if (FAILED(hr)) + { + co_return nullptr; + } + } + + winrt::com_ptr shellItem{}; + check_hresult(dialog->GetResult(shellItem.put())); + auto file = co_await PickerCommon::CreateStorageFileFromShellItem(shellItem); + + if (cancellationToken()) + { + co_return nullptr; + } + co_return file; + } +} diff --git a/prototype-workingdir/Microsoft.Storage.Pickers/FileSavePicker.h b/prototype-workingdir/Microsoft.Storage.Pickers/FileSavePicker.h new file mode 100644 index 0000000000..2144f51292 --- /dev/null +++ b/prototype-workingdir/Microsoft.Storage.Pickers/FileSavePicker.h @@ -0,0 +1,53 @@ +#pragma once +#include "FileSavePicker.g.h" +#include "PickerCommon.h" + +namespace winrt::Microsoft::Storage::Pickers::implementation +{ + struct FileSavePickerParameters; + + struct FileSavePicker : FileSavePickerT + { + FileSavePicker(winrt::Microsoft::UI::WindowId const& windowId); + + hstring SettingsIdentifier(); + void SettingsIdentifier(hstring const& value); + + winrt::Microsoft::Storage::Pickers::PickerLocationId SuggestedStartLocation(); + void SuggestedStartLocation(winrt::Microsoft::Storage::Pickers::PickerLocationId const& value); + + hstring CommitButtonText(); + void CommitButtonText(hstring const& value); + + winrt::Windows::Foundation::Collections::IMap> FileTypeChoices(); + + hstring DefaultFileExtension(); + void DefaultFileExtension(hstring const& value); + + winrt::Windows::Storage::StorageFile SuggestedSaveFile(); + void SuggestedSaveFile(winrt::Windows::Storage::StorageFile const& value); + + hstring SuggestedFileName(); + void SuggestedFileName(hstring const& value); + + winrt::Windows::Foundation::IAsyncOperation PickSaveFileAsync(); + + private: + winrt::Microsoft::UI::WindowId m_windowId{}; + hstring m_settingsIdentifier{}; + PickerLocationId m_suggestedStartLocation{ PickerLocationId::Unspecified }; + hstring m_commitButtonText{}; + winrt::Windows::Foundation::Collections::IMap> m_fileTypeChoices{ winrt::single_threaded_map>() }; + hstring m_defaultFileExtension{}; + winrt::Windows::Storage::StorageFile m_suggestedSaveFile{ nullptr }; + hstring m_suggestedFileName{}; + + void CaptureParameters(PickerCommon::PickerParameters& parameters); + }; +} +namespace winrt::Microsoft::Storage::Pickers::factory_implementation +{ + struct FileSavePicker : FileSavePickerT + { + }; +} diff --git a/prototype-workingdir/Microsoft.Storage.Pickers/FolderPicker.cpp b/prototype-workingdir/Microsoft.Storage.Pickers/FolderPicker.cpp new file mode 100644 index 0000000000..6e7c62d0be --- /dev/null +++ b/prototype-workingdir/Microsoft.Storage.Pickers/FolderPicker.cpp @@ -0,0 +1,98 @@ +#include "pch.h" +#include "FolderPicker.h" +#include "FolderPicker.g.cpp" +#include +#include +#include +#include "PickerCommon.h" + +namespace winrt::Microsoft::Storage::Pickers::implementation +{ + FolderPicker::FolderPicker(winrt::Microsoft::UI::WindowId const& windowId) + : m_windowId(windowId) + { + } + winrt::Microsoft::Storage::Pickers::PickerViewMode FolderPicker::ViewMode() + { + return m_viewMode; + } + void FolderPicker::ViewMode(winrt::Microsoft::Storage::Pickers::PickerViewMode const& value) + { + m_viewMode = value; + } + hstring FolderPicker::SettingsIdentifier() + { + return m_settingsIdentifier; + } + void FolderPicker::SettingsIdentifier(hstring const& value) + { + m_settingsIdentifier = value; + } + winrt::Microsoft::Storage::Pickers::PickerLocationId FolderPicker::SuggestedStartLocation() + { + return m_suggestedStartLocation; + } + void FolderPicker::SuggestedStartLocation(winrt::Microsoft::Storage::Pickers::PickerLocationId const& value) + { + m_suggestedStartLocation = value; + } + hstring FolderPicker::CommitButtonText() + { + return m_commitButtonText; + } + void FolderPicker::CommitButtonText(hstring const& value) + { + m_commitButtonText = value; + } + winrt::Windows::Foundation::Collections::IVector FolderPicker::FileTypeFilter() + { + return m_fileTypeFilter; + } + + void FolderPicker::CaptureParameters(PickerCommon::PickerParameters& parameters) + { + parameters.HWnd = winrt::Microsoft::UI::GetWindowFromWindowId(m_windowId); + parameters.CommitButtonText = m_commitButtonText; + parameters.SettingsIdentifierId = m_settingsIdentifier; + parameters.PickerLocationId = m_suggestedStartLocation; + parameters.FileTypeFilterPara = PickerCommon::CaptureFilterSpec(parameters.FileTypeFilterData, m_fileTypeFilter.GetView()); + } + + + winrt::Windows::Foundation::IAsyncOperation FolderPicker::PickSingleFolderAsync() + { + PickerCommon::PickerParameters parameters{}; + CaptureParameters(parameters); + + co_await winrt::resume_background(); + + auto cancellationToken = co_await winrt::get_cancellation_token(); + if (cancellationToken()) + { + co_return nullptr; + } + + auto dialog = create_instance(CLSID_FileOpenDialog, CONTEXT_ALL); + + parameters.ConfigureDialog(dialog); + dialog->SetOptions(FOS_PICKFOLDERS); + + { + auto hr = dialog->Show(parameters.HWnd); + if (FAILED(hr) || cancellationToken()) + { + co_return nullptr; + } + } + + winrt::com_ptr shellItem{}; + check_hresult(dialog->GetResult(shellItem.put())); + auto folder = co_await PickerCommon::CreateStorageFolderFromShellItem(shellItem); + + if (cancellationToken()) + { + co_return nullptr; + } + co_return folder; + } +} diff --git a/prototype-workingdir/Microsoft.Storage.Pickers/FolderPicker.h b/prototype-workingdir/Microsoft.Storage.Pickers/FolderPicker.h new file mode 100644 index 0000000000..56af65cb19 --- /dev/null +++ b/prototype-workingdir/Microsoft.Storage.Pickers/FolderPicker.h @@ -0,0 +1,45 @@ +#pragma once +#include "FolderPicker.g.h" +#include "PickerCommon.h" + +namespace winrt::Microsoft::Storage::Pickers::implementation +{ + struct FolderPicker : FolderPickerT + { + FolderPicker(winrt::Microsoft::UI::WindowId const& windowId); + + winrt::Microsoft::Storage::Pickers::PickerViewMode ViewMode(); + void ViewMode(winrt::Microsoft::Storage::Pickers::PickerViewMode const& value); + + hstring SettingsIdentifier(); + void SettingsIdentifier(hstring const& value); + + winrt::Microsoft::Storage::Pickers::PickerLocationId SuggestedStartLocation(); + void SuggestedStartLocation(winrt::Microsoft::Storage::Pickers::PickerLocationId const& value); + + hstring CommitButtonText(); + void CommitButtonText(hstring const& value); + + winrt::Windows::Foundation::Collections::IVector FileTypeFilter(); + + winrt::Windows::Foundation::IAsyncOperation PickSingleFolderAsync(); + + private: + winrt::Microsoft::UI::WindowId m_windowId{}; + + PickerViewMode m_viewMode{ PickerViewMode::List }; + hstring m_settingsIdentifier{}; + PickerLocationId m_suggestedStartLocation{ PickerLocationId::Unspecified }; + hstring m_commitButtonText{}; + + winrt::Windows::Foundation::Collections::IVector m_fileTypeFilter{ winrt::single_threaded_vector() }; + + void CaptureParameters(PickerCommon::PickerParameters& parameters); + }; +} +namespace winrt::Microsoft::Storage::Pickers::factory_implementation +{ + struct FolderPicker : FolderPickerT + { + }; +} diff --git a/prototype-workingdir/Microsoft.Storage.Pickers/Microsoft.Storage.Pickers.vcxproj b/prototype-workingdir/Microsoft.Storage.Pickers/Microsoft.Storage.Pickers.vcxproj new file mode 100644 index 0000000000..b1b1eaf438 --- /dev/null +++ b/prototype-workingdir/Microsoft.Storage.Pickers/Microsoft.Storage.Pickers.vcxproj @@ -0,0 +1,160 @@ + + + + + + + true + true + true + {349e64cf-cb0c-4202-b1b5-7f543cc6e886} + Microsoft.Storage.Pickers + Microsoft.Storage.Pickers + en-US + 16.0 + false + Windows Store + 10.0 + 10.0.22621.0 + 10.0.22000.0 + true + true + + + + + Debug + Win32 + + + Debug + x64 + + + Debug + ARM64 + + + Release + Win32 + + + Release + x64 + + + Release + ARM64 + + + + DynamicLibrary + v143 + Unicode + false + true + + + true + true + + + false + true + false + + + + + + + + + + + + + + Use + pch.h + $(IntDir)pch.pch + Level4 + %(AdditionalOptions) /bigobj + _WINRT_DLL;%(PreprocessorDefinitions) + $(WindowsSDK_WindowsMetadata);$(AdditionalUsingDirectories) + + + Console + true + Microsoft_Storage_Pickers.def + + + + + _DEBUG;%(PreprocessorDefinitions) + + + $(CoreLibraryDependencies);%(AdditionalDependencies);shell32.lib + + + + + NDEBUG;%(PreprocessorDefinitions) + + + true + true + $(CoreLibraryDependencies);%(AdditionalDependencies);shell32.lib + + + + + + + + + + + + + + + Create + + + + + + + + + + + false + + + + + + + + + + + + + + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + + + + + + + + \ No newline at end of file diff --git a/prototype-workingdir/Microsoft.Storage.Pickers/Microsoft.Storage.Pickers.vcxproj.filters b/prototype-workingdir/Microsoft.Storage.Pickers/Microsoft.Storage.Pickers.vcxproj.filters new file mode 100644 index 0000000000..af63f3cf8e --- /dev/null +++ b/prototype-workingdir/Microsoft.Storage.Pickers/Microsoft.Storage.Pickers.vcxproj.filters @@ -0,0 +1,37 @@ + + + + + accd3aa8-1ba0-4223-9bbe-0c431709210b + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tga;tiff;tif;png;wav;mfcribbon-ms + + + {926ab91d-31b4-48c3-b9a4-e681349f27f0} + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/prototype-workingdir/Microsoft.Storage.Pickers/Microsoft_Storage_Pickers.def b/prototype-workingdir/Microsoft.Storage.Pickers/Microsoft_Storage_Pickers.def new file mode 100644 index 0000000000..24e7c1235c --- /dev/null +++ b/prototype-workingdir/Microsoft.Storage.Pickers/Microsoft_Storage_Pickers.def @@ -0,0 +1,3 @@ +EXPORTS +DllCanUnloadNow = WINRT_CanUnloadNow PRIVATE +DllGetActivationFactory = WINRT_GetActivationFactory PRIVATE diff --git a/prototype-workingdir/Microsoft.Storage.Pickers/PickerCommon.cpp b/prototype-workingdir/Microsoft.Storage.Pickers/PickerCommon.cpp new file mode 100644 index 0000000000..63e29b7ebf --- /dev/null +++ b/prototype-workingdir/Microsoft.Storage.Pickers/PickerCommon.cpp @@ -0,0 +1,200 @@ +#include "pch.h" +#include "PickerCommon.h" +#include +#include "ShObjIdl.h" +#include + +namespace { + + GUID HashHStringToGuid(winrt::hstring const& input) + { + auto algorithmProvider = winrt::Windows::Security::Cryptography::Core::HashAlgorithmProvider::OpenAlgorithm(winrt::Windows::Security::Cryptography::Core::HashAlgorithmNames::Md5()); + + auto buffer = winrt::Windows::Security::Cryptography::CryptographicBuffer::ConvertStringToBinary(input, winrt::Windows::Security::Cryptography::BinaryStringEncoding::Utf16LE); + + auto hash = algorithmProvider.HashData(buffer); + + if (hash.Length() != 16) + { + throw winrt::hresult_error(E_FAIL, L"Invalid hash length"); + } + + winrt::com_array resultBuffer{}; + winrt::Windows::Security::Cryptography::CryptographicBuffer::CopyToByteArray(hash, resultBuffer); + GUID guid = *(reinterpret_cast(resultBuffer.data())); + + // TODO: verify bit pattern code from copilot is correct to fit spec + // Adjust the GUID to conform to version 3 UUID (MD5-based) + guid.Data3 = (guid.Data3 & 0x0FFF) | 0x3000; // Set the version to 3 + guid.Data4[0] = (guid.Data4[0] & 0x3F) | 0x80; // Set variant to RFC 4122 + + return guid; + } + + // TODO: use better winrt implementations? + // Challenge: currently winrt based Storage.KnownFolder APIs does not provide all location id we need + winrt::com_ptr GetKnownFolderFromId(winrt::Microsoft::Storage::Pickers::PickerLocationId pickerLocationId) + { + KNOWNFOLDERID knownFolderId; + switch (pickerLocationId) + { + case winrt::Microsoft::Storage::Pickers::PickerLocationId::DocumentsLibrary: + knownFolderId = FOLDERID_Documents; + break; + case winrt::Microsoft::Storage::Pickers::PickerLocationId::ComputerFolder: + knownFolderId = FOLDERID_ComputerFolder; + break; + case winrt::Microsoft::Storage::Pickers::PickerLocationId::Desktop: + knownFolderId = FOLDERID_Desktop; + break; + case winrt::Microsoft::Storage::Pickers::PickerLocationId::Downloads: + knownFolderId = FOLDERID_Downloads; + break; + case winrt::Microsoft::Storage::Pickers::PickerLocationId::HomeGroup: + knownFolderId = FOLDERID_HomeGroup; + break; + case winrt::Microsoft::Storage::Pickers::PickerLocationId::MusicLibrary: + knownFolderId = FOLDERID_MusicLibrary; + break; + case winrt::Microsoft::Storage::Pickers::PickerLocationId::PicturesLibrary: + knownFolderId = FOLDERID_PicturesLibrary; + break; + case winrt::Microsoft::Storage::Pickers::PickerLocationId::VideosLibrary: + knownFolderId = FOLDERID_VideosLibrary; + break; + case winrt::Microsoft::Storage::Pickers::PickerLocationId::Objects3D: + knownFolderId = FOLDERID_Objects3D; + break; + default: + return nullptr; + } + + auto knownFolderManager = winrt::create_instance(CLSID_KnownFolderManager); + winrt::com_ptr knownFolder{}; + winrt::check_hresult(knownFolderManager->GetFolder(knownFolderId, knownFolder.put())); + winrt::com_ptr defaultFolder{}; + winrt::check_hresult(knownFolder->GetShellItem(0, IID_PPV_ARGS(defaultFolder.put()))); + return defaultFolder; + } + + + winrt::hstring FormatExtensionWithWildcard(winrt::hstring extension) + { + if (!extension.empty() && extension[0] == L'*') + { + return extension; + } + else + { + return L"*" + extension; + } + } + + winrt::hstring JoinExtensions(winrt::Windows::Foundation::Collections::IVectorView extensions) + { + winrt::hstring result; + bool first = true; + for (const auto& ext : extensions) + { + if (first) + { + result = FormatExtensionWithWildcard(ext); + first = false; + } + else + { + result = result + L";" + FormatExtensionWithWildcard(ext); + } + } + return result; + } + +} + + +namespace PickerCommon { + + using namespace winrt; + + bool IsHStringNullOrEmpty(winrt::hstring value) + { + // TODO: proper handling of null string reference? + return value.empty(); + } + + + // TODO: better way to convert ShellItem a StorageFile without relying on path?. + winrt::Windows::Foundation::IAsyncOperation CreateStorageFileFromShellItem(winrt::com_ptr shellItem) + { + wil::unique_cotaskmem_string filePath; + check_hresult(shellItem->GetDisplayName(SIGDN_FILESYSPATH, &filePath)); + co_return co_await winrt::Windows::Storage::StorageFile::GetFileFromPathAsync(filePath.get()); + } + + winrt::Windows::Foundation::IAsyncOperation CreateStorageFolderFromShellItem(winrt::com_ptr shellItem) + { + wil::unique_cotaskmem_string filePath; + check_hresult(shellItem->GetDisplayName(SIGDN_FILESYSPATH, &filePath)); + co_return co_await winrt::Windows::Storage::StorageFolder::GetFolderFromPathAsync(filePath.get()); + } + + std::vector CaptureFilterSpec(std::vector& buffer, winrt::Windows::Foundation::Collections::IVectorView filters) + { + std::vector result(filters.Size()); + buffer.clear(); + buffer.reserve(filters.Size() * (size_t)2); + for (auto filter : filters) + { + auto ext = FormatExtensionWithWildcard(filter); + buffer.push_back(filter); + buffer.push_back(ext); + } + for (size_t i = 0; i < filters.Size(); i++) + { + result.at(i) = { buffer.at(i * 2).c_str(), buffer.at(i * 2 + 1).c_str() }; + } + return result; + } + + std::vector CaptureFilterSpec(std::vector& buffer, winrt::Windows::Foundation::Collections::IMapView> filters) + { + std::vector result(filters.Size()); + buffer.clear(); + buffer.reserve(filters.Size() * (size_t)2); + + for (const auto& filter : filters) + { + buffer.push_back(filter.Key()); + auto extensionList = JoinExtensions(filter.Value().GetView()); + buffer.push_back(extensionList); + } + for (size_t i = 0; i < filters.Size(); i++) + { + result.at(i) = { buffer.at(i * 2).c_str(), buffer.at(i * 2 + 1).c_str() }; + } + return result; + } + + void PickerParameters::ConfigureDialog(winrt::com_ptr dialog) + { + if (!IsHStringNullOrEmpty(CommitButtonText)) + { + check_hresult(dialog->SetOkButtonLabel(CommitButtonText.c_str())); + } + + if (!IsHStringNullOrEmpty(SettingsIdentifierId)) + { + auto guid = HashHStringToGuid(SettingsIdentifierId); + check_hresult(dialog->SetClientGuid(guid)); + } + + auto defaultFolder = GetKnownFolderFromId(PickerLocationId); + if (defaultFolder != nullptr) + { + check_hresult(dialog->SetFolder(defaultFolder.get())); + check_hresult(dialog->SetDefaultFolder(defaultFolder.get())); + } + + check_hresult(dialog->SetFileTypes(FileTypeFilterPara.size(), FileTypeFilterPara.data())); + } +} diff --git a/prototype-workingdir/Microsoft.Storage.Pickers/PickerCommon.h b/prototype-workingdir/Microsoft.Storage.Pickers/PickerCommon.h new file mode 100644 index 0000000000..de7db7ac54 --- /dev/null +++ b/prototype-workingdir/Microsoft.Storage.Pickers/PickerCommon.h @@ -0,0 +1,27 @@ +// TODO: use better namespace, maybe anonymous namespace? +#pragma once +#include "pch.h" +#include "ShObjIdl.h" +#include "winrt/Microsoft.Storage.Pickers.h" + +namespace PickerCommon { + winrt::Windows::Foundation::IAsyncOperation CreateStorageFileFromShellItem(winrt::com_ptr shellItem); + winrt::Windows::Foundation::IAsyncOperation CreateStorageFolderFromShellItem(winrt::com_ptr shellItem); + + std::vector CaptureFilterSpec(std::vector& buffer, winrt::Windows::Foundation::Collections::IVectorView filters); + std::vector CaptureFilterSpec(std::vector& buffer, winrt::Windows::Foundation::Collections::IMapView> filters); + + // TODO: remove this if we know proper and null safe empty test for string + bool IsHStringNullOrEmpty(winrt::hstring value); + + struct PickerParameters { + HWND HWnd; + winrt::hstring CommitButtonText; + winrt::hstring SettingsIdentifierId; + winrt::Microsoft::Storage::Pickers::PickerLocationId PickerLocationId; + std::vector FileTypeFilterData{}; + std::vector FileTypeFilterPara{}; + + void ConfigureDialog(winrt::com_ptr dialog); + }; +} diff --git a/prototype-workingdir/Microsoft.Storage.Pickers/Pickers.idl b/prototype-workingdir/Microsoft.Storage.Pickers/Pickers.idl new file mode 100644 index 0000000000..31c4c6c7ea --- /dev/null +++ b/prototype-workingdir/Microsoft.Storage.Pickers/Pickers.idl @@ -0,0 +1,68 @@ +namespace Microsoft.Storage.Pickers +{ + enum PickerViewMode + { + List, + Thumbnail, + }; + + enum PickerLocationId + { + DocumentsLibrary, + ComputerFolder, + Desktop, + Downloads, + HomeGroup, + MusicLibrary, + PicturesLibrary, + VideosLibrary, + Objects3D, + Unspecified, + }; + + + [default_interface] + runtimeclass FileOpenPicker + { + FileOpenPicker(Microsoft.UI.WindowId windowId); + + Microsoft.Storage.Pickers.PickerViewMode ViewMode; + String SettingsIdentifier; + Microsoft.Storage.Pickers.PickerLocationId SuggestedStartLocation; + String CommitButtonText; + Windows.Foundation.Collections.IVector FileTypeFilter{ get; }; + + [remote_sync] Windows.Foundation.IAsyncOperation PickSingleFileAsync(); + [remote_sync] Windows.Foundation.IAsyncOperation > PickMultipleFilesAsync(); + } + + [default_interface] + runtimeclass FileSavePicker + { + FileSavePicker(Microsoft.UI.WindowId windowId); + + String SettingsIdentifier; + Microsoft.Storage.Pickers.PickerLocationId SuggestedStartLocation; + String CommitButtonText; + Windows.Foundation.Collections.IMap > FileTypeChoices{ get; }; + String DefaultFileExtension; + Windows.Storage.StorageFile SuggestedSaveFile; + String SuggestedFileName; + + [remote_sync] Windows.Foundation.IAsyncOperation PickSaveFileAsync(); + } + + [default_interface] + runtimeclass FolderPicker + { + FolderPicker(Microsoft.UI.WindowId windowId); + + Microsoft.Storage.Pickers.PickerViewMode ViewMode; + String SettingsIdentifier; + Microsoft.Storage.Pickers.PickerLocationId SuggestedStartLocation; + String CommitButtonText; + Windows.Foundation.Collections.IVector FileTypeFilter{ get; }; + + [remote_sync] Windows.Foundation.IAsyncOperation PickSingleFolderAsync(); + } +} diff --git a/prototype-workingdir/Microsoft.Storage.Pickers/packages.config b/prototype-workingdir/Microsoft.Storage.Pickers/packages.config new file mode 100644 index 0000000000..6e553cc88c --- /dev/null +++ b/prototype-workingdir/Microsoft.Storage.Pickers/packages.config @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/prototype-workingdir/Microsoft.Storage.Pickers/pch.cpp b/prototype-workingdir/Microsoft.Storage.Pickers/pch.cpp new file mode 100644 index 0000000000..1d9f38c57d --- /dev/null +++ b/prototype-workingdir/Microsoft.Storage.Pickers/pch.cpp @@ -0,0 +1 @@ +#include "pch.h" diff --git a/prototype-workingdir/Microsoft.Storage.Pickers/pch.h b/prototype-workingdir/Microsoft.Storage.Pickers/pch.h new file mode 100644 index 0000000000..21563b73b3 --- /dev/null +++ b/prototype-workingdir/Microsoft.Storage.Pickers/pch.h @@ -0,0 +1,33 @@ +#pragma once +#include +#include +#include +#include + +// Undefine GetCurrentTime macro to prevent +// conflict with Storyboard::GetCurrentTime +#undef GetCurrentTime + + +#include "winrt/Microsoft.Storage.Pickers.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include diff --git a/prototype-workingdir/Microsoft.Storage.Pickers/readme.txt b/prototype-workingdir/Microsoft.Storage.Pickers/readme.txt new file mode 100644 index 0000000000..6b46510cd0 --- /dev/null +++ b/prototype-workingdir/Microsoft.Storage.Pickers/readme.txt @@ -0,0 +1,27 @@ +======================================================================== + Microsoft.Storage.Pickers Project Overview +======================================================================== + +This project demonstrates how to get started authoring Windows Runtime +classes directly with standard C++, using the Windows App SDK and +C++/WinRT packages to generate implementation headers from interface +(IDL) files. The generated Windows Runtime component binary and WinMD +files should then be bundled with the app consuming them. + +Steps: +1. Create an interface (IDL) file to define your Windows Runtime class, + its default interface, and any other interfaces it implements. +2. Build the project once to generate module.g.cpp, module.h.cpp, and + implementation templates under the "Generated Files" folder, as + well as skeleton class definitions under "Generated Files\sources". +3. Use the skeleton class definitions for reference to implement your + Windows Runtime classes. + +======================================================================== +Learn more about Windows App SDK here: +https://docs.microsoft.com/windows/apps/windows-app-sdk/ +Learn more about WinUI3 here: +https://docs.microsoft.com/windows/apps/winui/winui3/ +Learn more about C++/WinRT here: +http://aka.ms/cppwinrt/ +======================================================================== From e34f27243249ff72a7e43e43c457faf012a93078 Mon Sep 17 00:00:00 2001 From: Dinah Gao Date: Thu, 12 Dec 2024 21:14:02 +0800 Subject: [PATCH 04/39] add the pickers --- dev/Interop/StoragePicker/FileOpenPicker.cpp | 63 ------------------- dev/Interop/StoragePicker/FileOpenPicker.h | 24 ------- dev/Interop/StoragePicker/FileOpenPicker.idl | 13 ---- .../StoragePickers}/FileOpenPicker.cpp | 15 +++-- .../Interop/StoragePickers}/FileOpenPicker.h | 12 ++-- .../StoragePickers}/FileSavePicker.cpp | 6 +- .../Interop/StoragePickers}/FileSavePicker.h | 8 +-- .../Interop/StoragePickers}/FolderPicker.cpp | 10 +-- .../Interop/StoragePickers}/FolderPicker.h | 12 ++-- .../Microsoft.Windows.Storage.Pickers.idl | 12 ++-- .../Interop/StoragePickers}/PickerCommon.cpp | 20 +++--- .../Interop/StoragePickers}/PickerCommon.h | 4 +- .../StoragePickers.vcxitems} | 20 +++++- .../StoragePickersTelemetry.h | 0 .../Interop/StoragePickers}/readme.txt | 2 +- .../WindowsAppRuntime_DLL.vcxproj | 22 ++++--- dev/WindowsAppRuntime_DLL/packages.config | 4 +- dev/WindowsAppRuntime_DLL/pch.h | 27 ++++++++ eng/Version.Dependencies.props | 2 + eng/Version.Dependencies.xml | 2 + 20 files changed, 120 insertions(+), 158 deletions(-) delete mode 100644 dev/Interop/StoragePicker/FileOpenPicker.cpp delete mode 100644 dev/Interop/StoragePicker/FileOpenPicker.h delete mode 100644 dev/Interop/StoragePicker/FileOpenPicker.idl rename {prototype-workingdir/Microsoft.Storage.Pickers => dev/Interop/StoragePickers}/FileOpenPicker.cpp (86%) rename {prototype-workingdir/Microsoft.Storage.Pickers => dev/Interop/StoragePickers}/FileOpenPicker.h (72%) rename {prototype-workingdir/Microsoft.Storage.Pickers => dev/Interop/StoragePickers}/FileSavePicker.cpp (94%) rename {prototype-workingdir/Microsoft.Storage.Pickers => dev/Interop/StoragePickers}/FileSavePicker.h (83%) rename {prototype-workingdir/Microsoft.Storage.Pickers => dev/Interop/StoragePickers}/FolderPicker.cpp (86%) rename {prototype-workingdir/Microsoft.Storage.Pickers => dev/Interop/StoragePickers}/FolderPicker.h (68%) rename prototype-workingdir/Microsoft.Storage.Pickers/Pickers.idl => dev/Interop/StoragePickers/Microsoft.Windows.Storage.Pickers.idl (79%) rename {prototype-workingdir/Microsoft.Storage.Pickers => dev/Interop/StoragePickers}/PickerCommon.cpp (88%) rename {prototype-workingdir/Microsoft.Storage.Pickers => dev/Interop/StoragePickers}/PickerCommon.h (90%) rename dev/Interop/{StoragePicker/StoragePicker.vcxitems => StoragePickers/StoragePickers.vcxitems} (58%) rename dev/Interop/{StoragePicker => StoragePickers}/StoragePickersTelemetry.h (100%) rename {prototype-workingdir/Microsoft.Storage.Pickers => dev/Interop/StoragePickers}/readme.txt (96%) diff --git a/dev/Interop/StoragePicker/FileOpenPicker.cpp b/dev/Interop/StoragePicker/FileOpenPicker.cpp deleted file mode 100644 index 9684ff2f98..0000000000 --- a/dev/Interop/StoragePicker/FileOpenPicker.cpp +++ /dev/null @@ -1,63 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. See LICENSE in the project root for license information. -#include "pch.h" -#include "FileOpenPicker.h" -#include "Microsoft.Windows.Storage.Pickers.FileOpenPicker.g.cpp" -#include "StoragePickersTelemetry.h" -#include -#include -#include -#include -#include - -namespace winrt::Microsoft::Windows::Storage::Pickers::implementation -{ - winrt::Windows::Foundation::IAsyncOperation FileOpenPicker::PickSingleFileAsync() - { - bool isAppPackaged = m_telemetryHelper.IsPackagedApp(); - PCWSTR appName = m_telemetryHelper.GetAppName().c_str(); - auto logCaptureOperation{ StoragePickersTelemetry::StoragePickersOperation::Start(isAppPackaged, appName) }; - - winrt::apartment_context ui_thread; - - co_await winrt::resume_background(); - - // Handle cancellation. - auto cancellationToken = co_await winrt::get_cancellation_token(); - if (cancellationToken()) - { - co_return nullptr; - } - - // TODO: should we initialize COM? - //wil::com_initialize_ex initializeCom{ COINIT_APARTMENTTHREADED }; - - wil::com_ptr fileOpenDialog; - THROW_IF_FAILED(CoCreateInstance(CLSID_FileOpenDialog, nullptr, CLSCTX_ALL, IID_PPV_ARGS(&fileOpenDialog))); - - HRESULT hr = fileOpenDialog->Show(nullptr); - if (FAILED(hr) || cancellationToken()) - { - co_return nullptr; - } - - wil::com_ptr shellItem; - THROW_IF_FAILED(fileOpenDialog->GetResult(shellItem.put())); - - wil::unique_cotaskmem_string filePath; - THROW_IF_FAILED(shellItem->GetDisplayName(SIGDN_FILESYSPATH, &filePath)); - - // Convert the file path to a StorageFile. - auto const& file = co_await winrt::Windows::Storage::StorageFile::GetFileFromPathAsync(filePath.get()); - if (cancellationToken()) { - co_return nullptr; - } - - co_await ui_thread; - if (cancellationToken()) { - co_return nullptr; - } - - co_return file; - } -} diff --git a/dev/Interop/StoragePicker/FileOpenPicker.h b/dev/Interop/StoragePicker/FileOpenPicker.h deleted file mode 100644 index c97752674f..0000000000 --- a/dev/Interop/StoragePicker/FileOpenPicker.h +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. See LICENSE in the project root for license information. -#pragma once -#include "Microsoft.Windows.Storage.Pickers.FileOpenPicker.g.h" -#include "TelemetryHelper.h" - -namespace winrt::Microsoft::Windows::Storage::Pickers::implementation -{ - struct FileOpenPicker : FileOpenPickerT - { - FileOpenPicker() = default; - winrt::Windows::Foundation::IAsyncOperation PickSingleFileAsync(); - - private: - TelemetryHelper m_telemetryHelper; - }; -} - -namespace winrt::Microsoft::Windows::Storage::Pickers::factory_implementation -{ - struct FileOpenPicker : FileOpenPickerT - { - }; -} diff --git a/dev/Interop/StoragePicker/FileOpenPicker.idl b/dev/Interop/StoragePicker/FileOpenPicker.idl deleted file mode 100644 index 0af9f685ef..0000000000 --- a/dev/Interop/StoragePicker/FileOpenPicker.idl +++ /dev/null @@ -1,13 +0,0 @@ -namespace Microsoft.Windows.Storage.Pickers -{ - [contractversion(1)] - apicontract FileOpenPickerContract {}; - - [contract(FileOpenPickerContract, 1)] - runtimeclass FileOpenPicker - { - FileOpenPicker(); - - Windows.Foundation.IAsyncOperation PickSingleFileAsync(); - }; -} diff --git a/prototype-workingdir/Microsoft.Storage.Pickers/FileOpenPicker.cpp b/dev/Interop/StoragePickers/FileOpenPicker.cpp similarity index 86% rename from prototype-workingdir/Microsoft.Storage.Pickers/FileOpenPicker.cpp rename to dev/Interop/StoragePickers/FileOpenPicker.cpp index d3d42329d3..27ebb3cfe9 100644 --- a/prototype-workingdir/Microsoft.Storage.Pickers/FileOpenPicker.cpp +++ b/dev/Interop/StoragePickers/FileOpenPicker.cpp @@ -1,24 +1,25 @@ #include "pch.h" #include "FileOpenPicker.h" #include "FileOpenPicker.g.cpp" +#include "StoragePickersTelemetry.h" #include #include #include #include #include "PickerCommon.h" -namespace winrt::Microsoft::Storage::Pickers::implementation +namespace winrt::Microsoft::Windows::Storage::Pickers::implementation { FileOpenPicker::FileOpenPicker(winrt::Microsoft::UI::WindowId const& windowId) : m_windowId(windowId) { } - winrt::Microsoft::Storage::Pickers::PickerViewMode FileOpenPicker::ViewMode() + winrt::Microsoft::Windows::Storage::Pickers::PickerViewMode FileOpenPicker::ViewMode() { return m_viewMode; } - void FileOpenPicker::ViewMode(winrt::Microsoft::Storage::Pickers::PickerViewMode const& value) + void FileOpenPicker::ViewMode(winrt::Microsoft::Windows::Storage::Pickers::PickerViewMode const& value) { m_viewMode = value; } @@ -30,11 +31,11 @@ namespace winrt::Microsoft::Storage::Pickers::implementation { m_settingsIdentifier = value; } - winrt::Microsoft::Storage::Pickers::PickerLocationId FileOpenPicker::SuggestedStartLocation() + winrt::Microsoft::Windows::Storage::Pickers::PickerLocationId FileOpenPicker::SuggestedStartLocation() { return m_suggestedStartLocation; } - void FileOpenPicker::SuggestedStartLocation(winrt::Microsoft::Storage::Pickers::PickerLocationId const& value) + void FileOpenPicker::SuggestedStartLocation(winrt::Microsoft::Windows::Storage::Pickers::PickerLocationId const& value) { m_suggestedStartLocation = value; } @@ -62,6 +63,10 @@ namespace winrt::Microsoft::Storage::Pickers::implementation winrt::Windows::Foundation::IAsyncOperation FileOpenPicker::PickSingleFileAsync() { + bool isAppPackaged = m_telemetryHelper.IsPackagedApp(); + PCWSTR appName = m_telemetryHelper.GetAppName().c_str(); + auto logCaptureOperation{ StoragePickersTelemetry::StoragePickersOperation::Start(isAppPackaged, appName) }; + PickerCommon::PickerParameters parameters{}; CaptureParameters(parameters); diff --git a/prototype-workingdir/Microsoft.Storage.Pickers/FileOpenPicker.h b/dev/Interop/StoragePickers/FileOpenPicker.h similarity index 72% rename from prototype-workingdir/Microsoft.Storage.Pickers/FileOpenPicker.h rename to dev/Interop/StoragePickers/FileOpenPicker.h index fb68a34d2b..edfa016bc6 100644 --- a/prototype-workingdir/Microsoft.Storage.Pickers/FileOpenPicker.h +++ b/dev/Interop/StoragePickers/FileOpenPicker.h @@ -2,20 +2,20 @@ #include "FileOpenPicker.g.h" #include "PickerCommon.h" -namespace winrt::Microsoft::Storage::Pickers::implementation +namespace winrt::Microsoft::Windows::Storage::Pickers::implementation { struct FileOpenPicker : FileOpenPickerT { FileOpenPicker(winrt::Microsoft::UI::WindowId const& windowId); - winrt::Microsoft::Storage::Pickers::PickerViewMode ViewMode(); - void ViewMode(winrt::Microsoft::Storage::Pickers::PickerViewMode const& value); + winrt::Microsoft::Windows::Storage::Pickers::PickerViewMode ViewMode(); + void ViewMode(winrt::Microsoft::Windows::Storage::Pickers::PickerViewMode const& value); hstring SettingsIdentifier(); void SettingsIdentifier(hstring const& value); - winrt::Microsoft::Storage::Pickers::PickerLocationId SuggestedStartLocation(); - void SuggestedStartLocation(winrt::Microsoft::Storage::Pickers::PickerLocationId const& value); + winrt::Microsoft::Windows::Storage::Pickers::PickerLocationId SuggestedStartLocation(); + void SuggestedStartLocation(winrt::Microsoft::Windows::Storage::Pickers::PickerLocationId const& value); winrt::hstring CommitButtonText(); void CommitButtonText(winrt::hstring const& value); @@ -36,7 +36,7 @@ namespace winrt::Microsoft::Storage::Pickers::implementation void CaptureParameters(PickerCommon::PickerParameters& parameters); }; } -namespace winrt::Microsoft::Storage::Pickers::factory_implementation +namespace winrt::Microsoft::Windows::Storage::Pickers::factory_implementation { struct FileOpenPicker : FileOpenPickerT { diff --git a/prototype-workingdir/Microsoft.Storage.Pickers/FileSavePicker.cpp b/dev/Interop/StoragePickers/FileSavePicker.cpp similarity index 94% rename from prototype-workingdir/Microsoft.Storage.Pickers/FileSavePicker.cpp rename to dev/Interop/StoragePickers/FileSavePicker.cpp index 052135bf98..ca3fc03ae8 100644 --- a/prototype-workingdir/Microsoft.Storage.Pickers/FileSavePicker.cpp +++ b/dev/Interop/StoragePickers/FileSavePicker.cpp @@ -13,7 +13,7 @@ #include #include "PickerCommon.h" -namespace winrt::Microsoft::Storage::Pickers::implementation +namespace winrt::Microsoft::Windows::Storage::Pickers::implementation { FileSavePicker::FileSavePicker(winrt::Microsoft::UI::WindowId const& windowId) @@ -28,11 +28,11 @@ namespace winrt::Microsoft::Storage::Pickers::implementation { m_settingsIdentifier = value; } - winrt::Microsoft::Storage::Pickers::PickerLocationId FileSavePicker::SuggestedStartLocation() + winrt::Microsoft::Windows::Storage::Pickers::PickerLocationId FileSavePicker::SuggestedStartLocation() { return m_suggestedStartLocation; } - void FileSavePicker::SuggestedStartLocation(winrt::Microsoft::Storage::Pickers::PickerLocationId const& value) + void FileSavePicker::SuggestedStartLocation(winrt::Microsoft::Windows::Storage::Pickers::PickerLocationId const& value) { m_suggestedStartLocation = value; } diff --git a/prototype-workingdir/Microsoft.Storage.Pickers/FileSavePicker.h b/dev/Interop/StoragePickers/FileSavePicker.h similarity index 83% rename from prototype-workingdir/Microsoft.Storage.Pickers/FileSavePicker.h rename to dev/Interop/StoragePickers/FileSavePicker.h index 2144f51292..3aae7b5034 100644 --- a/prototype-workingdir/Microsoft.Storage.Pickers/FileSavePicker.h +++ b/dev/Interop/StoragePickers/FileSavePicker.h @@ -2,7 +2,7 @@ #include "FileSavePicker.g.h" #include "PickerCommon.h" -namespace winrt::Microsoft::Storage::Pickers::implementation +namespace winrt::Microsoft::Windows::Storage::Pickers::implementation { struct FileSavePickerParameters; @@ -13,8 +13,8 @@ namespace winrt::Microsoft::Storage::Pickers::implementation hstring SettingsIdentifier(); void SettingsIdentifier(hstring const& value); - winrt::Microsoft::Storage::Pickers::PickerLocationId SuggestedStartLocation(); - void SuggestedStartLocation(winrt::Microsoft::Storage::Pickers::PickerLocationId const& value); + winrt::Microsoft::Windows::Storage::Pickers::PickerLocationId SuggestedStartLocation(); + void SuggestedStartLocation(winrt::Microsoft::Windows::Storage::Pickers::PickerLocationId const& value); hstring CommitButtonText(); void CommitButtonText(hstring const& value); @@ -45,7 +45,7 @@ namespace winrt::Microsoft::Storage::Pickers::implementation void CaptureParameters(PickerCommon::PickerParameters& parameters); }; } -namespace winrt::Microsoft::Storage::Pickers::factory_implementation +namespace winrt::Microsoft::Windows::Storage::Pickers::factory_implementation { struct FileSavePicker : FileSavePickerT { diff --git a/prototype-workingdir/Microsoft.Storage.Pickers/FolderPicker.cpp b/dev/Interop/StoragePickers/FolderPicker.cpp similarity index 86% rename from prototype-workingdir/Microsoft.Storage.Pickers/FolderPicker.cpp rename to dev/Interop/StoragePickers/FolderPicker.cpp index 6e7c62d0be..46dc44d610 100644 --- a/prototype-workingdir/Microsoft.Storage.Pickers/FolderPicker.cpp +++ b/dev/Interop/StoragePickers/FolderPicker.cpp @@ -6,17 +6,17 @@ #include #include "PickerCommon.h" -namespace winrt::Microsoft::Storage::Pickers::implementation +namespace winrt::Microsoft::Windows::Storage::Pickers::implementation { FolderPicker::FolderPicker(winrt::Microsoft::UI::WindowId const& windowId) : m_windowId(windowId) { } - winrt::Microsoft::Storage::Pickers::PickerViewMode FolderPicker::ViewMode() + winrt::Microsoft::Windows::Storage::Pickers::PickerViewMode FolderPicker::ViewMode() { return m_viewMode; } - void FolderPicker::ViewMode(winrt::Microsoft::Storage::Pickers::PickerViewMode const& value) + void FolderPicker::ViewMode(winrt::Microsoft::Windows::Storage::Pickers::PickerViewMode const& value) { m_viewMode = value; } @@ -28,11 +28,11 @@ namespace winrt::Microsoft::Storage::Pickers::implementation { m_settingsIdentifier = value; } - winrt::Microsoft::Storage::Pickers::PickerLocationId FolderPicker::SuggestedStartLocation() + winrt::Microsoft::Windows::Storage::Pickers::PickerLocationId FolderPicker::SuggestedStartLocation() { return m_suggestedStartLocation; } - void FolderPicker::SuggestedStartLocation(winrt::Microsoft::Storage::Pickers::PickerLocationId const& value) + void FolderPicker::SuggestedStartLocation(winrt::Microsoft::Windows::Storage::Pickers::PickerLocationId const& value) { m_suggestedStartLocation = value; } diff --git a/prototype-workingdir/Microsoft.Storage.Pickers/FolderPicker.h b/dev/Interop/StoragePickers/FolderPicker.h similarity index 68% rename from prototype-workingdir/Microsoft.Storage.Pickers/FolderPicker.h rename to dev/Interop/StoragePickers/FolderPicker.h index 56af65cb19..9d3d984abb 100644 --- a/prototype-workingdir/Microsoft.Storage.Pickers/FolderPicker.h +++ b/dev/Interop/StoragePickers/FolderPicker.h @@ -2,20 +2,20 @@ #include "FolderPicker.g.h" #include "PickerCommon.h" -namespace winrt::Microsoft::Storage::Pickers::implementation +namespace winrt::Microsoft::Windows::Storage::Pickers::implementation { struct FolderPicker : FolderPickerT { FolderPicker(winrt::Microsoft::UI::WindowId const& windowId); - winrt::Microsoft::Storage::Pickers::PickerViewMode ViewMode(); - void ViewMode(winrt::Microsoft::Storage::Pickers::PickerViewMode const& value); + winrt::Microsoft::Windows::Storage::Pickers::PickerViewMode ViewMode(); + void ViewMode(winrt::Microsoft::Windows::Storage::Pickers::PickerViewMode const& value); hstring SettingsIdentifier(); void SettingsIdentifier(hstring const& value); - winrt::Microsoft::Storage::Pickers::PickerLocationId SuggestedStartLocation(); - void SuggestedStartLocation(winrt::Microsoft::Storage::Pickers::PickerLocationId const& value); + winrt::Microsoft::Windows::Storage::Pickers::PickerLocationId SuggestedStartLocation(); + void SuggestedStartLocation(winrt::Microsoft::Windows::Storage::Pickers::PickerLocationId const& value); hstring CommitButtonText(); void CommitButtonText(hstring const& value); @@ -37,7 +37,7 @@ namespace winrt::Microsoft::Storage::Pickers::implementation void CaptureParameters(PickerCommon::PickerParameters& parameters); }; } -namespace winrt::Microsoft::Storage::Pickers::factory_implementation +namespace winrt::Microsoft::Windows::Storage::Pickers::factory_implementation { struct FolderPicker : FolderPickerT { diff --git a/prototype-workingdir/Microsoft.Storage.Pickers/Pickers.idl b/dev/Interop/StoragePickers/Microsoft.Windows.Storage.Pickers.idl similarity index 79% rename from prototype-workingdir/Microsoft.Storage.Pickers/Pickers.idl rename to dev/Interop/StoragePickers/Microsoft.Windows.Storage.Pickers.idl index 31c4c6c7ea..3a8f24cc03 100644 --- a/prototype-workingdir/Microsoft.Storage.Pickers/Pickers.idl +++ b/dev/Interop/StoragePickers/Microsoft.Windows.Storage.Pickers.idl @@ -1,4 +1,4 @@ -namespace Microsoft.Storage.Pickers +namespace Microsoft.Windows.Storage.Pickers { enum PickerViewMode { @@ -26,9 +26,9 @@ namespace Microsoft.Storage.Pickers { FileOpenPicker(Microsoft.UI.WindowId windowId); - Microsoft.Storage.Pickers.PickerViewMode ViewMode; + Microsoft.Windows.Storage.Pickers.PickerViewMode ViewMode; String SettingsIdentifier; - Microsoft.Storage.Pickers.PickerLocationId SuggestedStartLocation; + Microsoft.Windows.Storage.Pickers.PickerLocationId SuggestedStartLocation; String CommitButtonText; Windows.Foundation.Collections.IVector FileTypeFilter{ get; }; @@ -42,7 +42,7 @@ namespace Microsoft.Storage.Pickers FileSavePicker(Microsoft.UI.WindowId windowId); String SettingsIdentifier; - Microsoft.Storage.Pickers.PickerLocationId SuggestedStartLocation; + Microsoft.Windows.Storage.Pickers.PickerLocationId SuggestedStartLocation; String CommitButtonText; Windows.Foundation.Collections.IMap > FileTypeChoices{ get; }; String DefaultFileExtension; @@ -57,9 +57,9 @@ namespace Microsoft.Storage.Pickers { FolderPicker(Microsoft.UI.WindowId windowId); - Microsoft.Storage.Pickers.PickerViewMode ViewMode; + Microsoft.Windows.Storage.Pickers.PickerViewMode ViewMode; String SettingsIdentifier; - Microsoft.Storage.Pickers.PickerLocationId SuggestedStartLocation; + Microsoft.Windows.Storage.Pickers.PickerLocationId SuggestedStartLocation; String CommitButtonText; Windows.Foundation.Collections.IVector FileTypeFilter{ get; }; diff --git a/prototype-workingdir/Microsoft.Storage.Pickers/PickerCommon.cpp b/dev/Interop/StoragePickers/PickerCommon.cpp similarity index 88% rename from prototype-workingdir/Microsoft.Storage.Pickers/PickerCommon.cpp rename to dev/Interop/StoragePickers/PickerCommon.cpp index 63e29b7ebf..bbf2fd33f9 100644 --- a/prototype-workingdir/Microsoft.Storage.Pickers/PickerCommon.cpp +++ b/dev/Interop/StoragePickers/PickerCommon.cpp @@ -33,36 +33,36 @@ namespace { // TODO: use better winrt implementations? // Challenge: currently winrt based Storage.KnownFolder APIs does not provide all location id we need - winrt::com_ptr GetKnownFolderFromId(winrt::Microsoft::Storage::Pickers::PickerLocationId pickerLocationId) + winrt::com_ptr GetKnownFolderFromId(winrt::Microsoft::Windows::Storage::Pickers::PickerLocationId pickerLocationId) { KNOWNFOLDERID knownFolderId; switch (pickerLocationId) { - case winrt::Microsoft::Storage::Pickers::PickerLocationId::DocumentsLibrary: + case winrt::Microsoft::Windows::Storage::Pickers::PickerLocationId::DocumentsLibrary: knownFolderId = FOLDERID_Documents; break; - case winrt::Microsoft::Storage::Pickers::PickerLocationId::ComputerFolder: + case winrt::Microsoft::Windows::Storage::Pickers::PickerLocationId::ComputerFolder: knownFolderId = FOLDERID_ComputerFolder; break; - case winrt::Microsoft::Storage::Pickers::PickerLocationId::Desktop: + case winrt::Microsoft::Windows::Storage::Pickers::PickerLocationId::Desktop: knownFolderId = FOLDERID_Desktop; break; - case winrt::Microsoft::Storage::Pickers::PickerLocationId::Downloads: + case winrt::Microsoft::Windows::Storage::Pickers::PickerLocationId::Downloads: knownFolderId = FOLDERID_Downloads; break; - case winrt::Microsoft::Storage::Pickers::PickerLocationId::HomeGroup: + case winrt::Microsoft::Windows::Storage::Pickers::PickerLocationId::HomeGroup: knownFolderId = FOLDERID_HomeGroup; break; - case winrt::Microsoft::Storage::Pickers::PickerLocationId::MusicLibrary: + case winrt::Microsoft::Windows::Storage::Pickers::PickerLocationId::MusicLibrary: knownFolderId = FOLDERID_MusicLibrary; break; - case winrt::Microsoft::Storage::Pickers::PickerLocationId::PicturesLibrary: + case winrt::Microsoft::Windows::Storage::Pickers::PickerLocationId::PicturesLibrary: knownFolderId = FOLDERID_PicturesLibrary; break; - case winrt::Microsoft::Storage::Pickers::PickerLocationId::VideosLibrary: + case winrt::Microsoft::Windows::Storage::Pickers::PickerLocationId::VideosLibrary: knownFolderId = FOLDERID_VideosLibrary; break; - case winrt::Microsoft::Storage::Pickers::PickerLocationId::Objects3D: + case winrt::Microsoft::Windows::Storage::Pickers::PickerLocationId::Objects3D: knownFolderId = FOLDERID_Objects3D; break; default: diff --git a/prototype-workingdir/Microsoft.Storage.Pickers/PickerCommon.h b/dev/Interop/StoragePickers/PickerCommon.h similarity index 90% rename from prototype-workingdir/Microsoft.Storage.Pickers/PickerCommon.h rename to dev/Interop/StoragePickers/PickerCommon.h index de7db7ac54..6cd2b106b4 100644 --- a/prototype-workingdir/Microsoft.Storage.Pickers/PickerCommon.h +++ b/dev/Interop/StoragePickers/PickerCommon.h @@ -2,7 +2,7 @@ #pragma once #include "pch.h" #include "ShObjIdl.h" -#include "winrt/Microsoft.Storage.Pickers.h" +#include "winrt/Microsoft.Windows.Storage.Pickers.h" namespace PickerCommon { winrt::Windows::Foundation::IAsyncOperation CreateStorageFileFromShellItem(winrt::com_ptr shellItem); @@ -18,7 +18,7 @@ namespace PickerCommon { HWND HWnd; winrt::hstring CommitButtonText; winrt::hstring SettingsIdentifierId; - winrt::Microsoft::Storage::Pickers::PickerLocationId PickerLocationId; + winrt::Microsoft::Windows::Storage::Pickers::PickerLocationId PickerLocationId; std::vector FileTypeFilterData{}; std::vector FileTypeFilterPara{}; diff --git a/dev/Interop/StoragePicker/StoragePicker.vcxitems b/dev/Interop/StoragePickers/StoragePickers.vcxitems similarity index 58% rename from dev/Interop/StoragePicker/StoragePicker.vcxitems rename to dev/Interop/StoragePickers/StoragePickers.vcxitems index f49e671656..07dc6f4e8a 100644 --- a/dev/Interop/StoragePicker/StoragePicker.vcxitems +++ b/dev/Interop/StoragePickers/StoragePickers.vcxitems @@ -13,6 +13,12 @@ + + + + + + @@ -20,6 +26,18 @@ - + + + + + + + + + + + + + \ No newline at end of file diff --git a/dev/Interop/StoragePicker/StoragePickersTelemetry.h b/dev/Interop/StoragePickers/StoragePickersTelemetry.h similarity index 100% rename from dev/Interop/StoragePicker/StoragePickersTelemetry.h rename to dev/Interop/StoragePickers/StoragePickersTelemetry.h diff --git a/prototype-workingdir/Microsoft.Storage.Pickers/readme.txt b/dev/Interop/StoragePickers/readme.txt similarity index 96% rename from prototype-workingdir/Microsoft.Storage.Pickers/readme.txt rename to dev/Interop/StoragePickers/readme.txt index 6b46510cd0..66c1579928 100644 --- a/prototype-workingdir/Microsoft.Storage.Pickers/readme.txt +++ b/dev/Interop/StoragePickers/readme.txt @@ -1,5 +1,5 @@ ======================================================================== - Microsoft.Storage.Pickers Project Overview + Microsoft.Windows.Storage.Pickers Project Overview ======================================================================== This project demonstrates how to get started authoring Windows Runtime diff --git a/dev/WindowsAppRuntime_DLL/WindowsAppRuntime_DLL.vcxproj b/dev/WindowsAppRuntime_DLL/WindowsAppRuntime_DLL.vcxproj index 75db43c1f0..78d95ecadc 100644 --- a/dev/WindowsAppRuntime_DLL/WindowsAppRuntime_DLL.vcxproj +++ b/dev/WindowsAppRuntime_DLL/WindowsAppRuntime_DLL.vcxproj @@ -1,10 +1,11 @@ - + + Debug @@ -102,7 +103,7 @@ - + @@ -169,7 +170,7 @@ Windows false - onecore.lib;onecoreuap.lib;%(AdditionalDependencies) + onecore.lib;onecoreuap.lib;shell32.lib;%(AdditionalDependencies) WindowsAppRuntime.def Microsoft.Internal.FrameworkUdk.dll;%(DelayLoadDLLs) @@ -187,7 +188,7 @@ Windows false - onecore.lib;onecoreuap.lib;%(AdditionalDependencies) + onecore.lib;onecoreuap.lib;shell32.lib;%(AdditionalDependencies) WindowsAppRuntime.def Microsoft.Internal.FrameworkUdk.dll;%(DelayLoadDLLs) @@ -205,7 +206,7 @@ Windows false - onecore.lib;onecoreuap.lib;%(AdditionalDependencies) + onecore.lib;onecoreuap.lib;shell32.lib;%(AdditionalDependencies) WindowsAppRuntime.def Microsoft.Internal.FrameworkUdk.dll;%(DelayLoadDLLs) @@ -223,7 +224,7 @@ Windows false - onecore.lib;onecoreuap.lib;%(AdditionalDependencies) + onecore.lib;onecoreuap.lib;shell32.lib;%(AdditionalDependencies) WindowsAppRuntime.def Microsoft.Internal.FrameworkUdk.dll;%(DelayLoadDLLs) @@ -241,7 +242,7 @@ Windows false - onecore.lib;onecoreuap.lib;%(AdditionalDependencies) + onecore.lib;onecoreuap.lib;shell32.lib;%(AdditionalDependencies) WindowsAppRuntime.def Microsoft.Internal.FrameworkUdk.dll;%(DelayLoadDLLs) @@ -298,6 +299,8 @@ + + @@ -321,10 +324,13 @@ + + + - + \ No newline at end of file diff --git a/dev/WindowsAppRuntime_DLL/packages.config b/dev/WindowsAppRuntime_DLL/packages.config index 89ff0a09ad..f0fde149d4 100644 --- a/dev/WindowsAppRuntime_DLL/packages.config +++ b/dev/WindowsAppRuntime_DLL/packages.config @@ -3,8 +3,10 @@ + + - + \ No newline at end of file diff --git a/dev/WindowsAppRuntime_DLL/pch.h b/dev/WindowsAppRuntime_DLL/pch.h index 8dcd8e87ea..4074a04733 100644 --- a/dev/WindowsAppRuntime_DLL/pch.h +++ b/dev/WindowsAppRuntime_DLL/pch.h @@ -14,6 +14,9 @@ #include #include +#include +#include + #include #include #include @@ -62,4 +65,28 @@ #include #include +#include +#include +#include +#include +#include +#include +#include + + +#include +#include +#include +#include +#include +#include +#include +#include +#include + + #define MIDL_NS_PREFIX + +// Undefine GetCurrentTime macro to prevent +// conflict with Storyboard::GetCurrentTime +#undef GetCurrentTime diff --git a/eng/Version.Dependencies.props b/eng/Version.Dependencies.props index b5789e71cf..9a575e12ea 100644 --- a/eng/Version.Dependencies.props +++ b/eng/Version.Dependencies.props @@ -23,6 +23,8 @@ $([System.Text.RegularExpressions.Regex]::Match($(VersionDependenciesXml), 'Name="Microsoft.Taef"\s+Version="(.*?)"').Groups[1].Value) $([System.Text.RegularExpressions.Regex]::Match($(VersionDependenciesXml), 'Name="Microsoft.Telemetry.Inbox.Native"\s+Version="(.*?)"').Groups[1].Value) $([System.Text.RegularExpressions.Regex]::Match($(VersionDependenciesXml), 'Name="Microsoft.WindowsAppSDK.Protobuf"\s+Version="(.*?)"').Groups[1].Value) + $([System.Text.RegularExpressions.Regex]::Match($(VersionDependenciesXml), 'Name="Microsoft.UI.Xaml"\s+Version="(.*?)"').Groups[1].Value) + $([System.Text.RegularExpressions.Regex]::Match($(VersionDependenciesXml), 'Name="Microsoft.Web.WebView2"\s+Version="(.*?)"').Groups[1].Value) $([System.Text.RegularExpressions.Regex]::Match($(VersionDependenciesXml), 'Name="Microsoft.Windows.CppWinRT"\s+Version="(.*?)"').Groups[1].Value) $([System.Text.RegularExpressions.Regex]::Match($(VersionDependenciesXml), 'Name="Microsoft.Windows.ImplementationLibrary"\s+Version="(.*?)"').Groups[1].Value) diff --git a/eng/Version.Dependencies.xml b/eng/Version.Dependencies.xml index 2b871b0695..32daae382a 100644 --- a/eng/Version.Dependencies.xml +++ b/eng/Version.Dependencies.xml @@ -32,6 +32,8 @@ + + From 9356b17dbb0c4e7ebd1cab0a9c79907e7f4bade8 Mon Sep 17 00:00:00 2001 From: Dinah Gao Date: Fri, 13 Dec 2024 12:06:37 +0800 Subject: [PATCH 05/39] Fix build errors msbuild dev\WindowsAppRuntime_DLL\WindowsAppRuntime_DLL.vcxproj --- dev/Interop/StoragePickers/FileOpenPicker.cpp | 2 +- dev/Interop/StoragePickers/FileOpenPicker.h | 4 +- dev/Interop/StoragePickers/FileSavePicker.cpp | 3 +- dev/Interop/StoragePickers/FileSavePicker.h | 2 +- dev/Interop/StoragePickers/FolderPicker.cpp | 2 +- dev/Interop/StoragePickers/FolderPicker.h | 2 +- dev/WindowsAppRuntime_DLL/pch.h | 18 +- .../Microsoft.Storage.Pickers.vcxproj | 160 ------------------ .../Microsoft.Storage.Pickers.vcxproj.filters | 37 ---- .../Microsoft_Storage_Pickers.def | 3 - .../Microsoft.Storage.Pickers/packages.config | 8 - .../Microsoft.Storage.Pickers/pch.cpp | 1 - .../Microsoft.Storage.Pickers/pch.h | 33 ---- 13 files changed, 9 insertions(+), 266 deletions(-) delete mode 100644 prototype-workingdir/Microsoft.Storage.Pickers/Microsoft.Storage.Pickers.vcxproj delete mode 100644 prototype-workingdir/Microsoft.Storage.Pickers/Microsoft.Storage.Pickers.vcxproj.filters delete mode 100644 prototype-workingdir/Microsoft.Storage.Pickers/Microsoft_Storage_Pickers.def delete mode 100644 prototype-workingdir/Microsoft.Storage.Pickers/packages.config delete mode 100644 prototype-workingdir/Microsoft.Storage.Pickers/pch.cpp delete mode 100644 prototype-workingdir/Microsoft.Storage.Pickers/pch.h diff --git a/dev/Interop/StoragePickers/FileOpenPicker.cpp b/dev/Interop/StoragePickers/FileOpenPicker.cpp index 27ebb3cfe9..f3f1f139e2 100644 --- a/dev/Interop/StoragePickers/FileOpenPicker.cpp +++ b/dev/Interop/StoragePickers/FileOpenPicker.cpp @@ -1,6 +1,6 @@ #include "pch.h" #include "FileOpenPicker.h" -#include "FileOpenPicker.g.cpp" +#include "Microsoft.Windows.Storage.Pickers.FileOpenPicker.g.cpp" #include "StoragePickersTelemetry.h" #include #include diff --git a/dev/Interop/StoragePickers/FileOpenPicker.h b/dev/Interop/StoragePickers/FileOpenPicker.h index edfa016bc6..d03368f0b9 100644 --- a/dev/Interop/StoragePickers/FileOpenPicker.h +++ b/dev/Interop/StoragePickers/FileOpenPicker.h @@ -1,6 +1,7 @@ #pragma once -#include "FileOpenPicker.g.h" +#include "Microsoft.Windows.Storage.Pickers.FileOpenPicker.g.h" #include "PickerCommon.h" +#include "TelemetryHelper.h" namespace winrt::Microsoft::Windows::Storage::Pickers::implementation { @@ -32,6 +33,7 @@ namespace winrt::Microsoft::Windows::Storage::Pickers::implementation PickerLocationId m_suggestedStartLocation{ PickerLocationId::Unspecified }; winrt::hstring m_commitButtonText{}; winrt::Windows::Foundation::Collections::IVector m_fileTypeFilter{ winrt::single_threaded_vector() }; + TelemetryHelper m_telemetryHelper; void CaptureParameters(PickerCommon::PickerParameters& parameters); }; diff --git a/dev/Interop/StoragePickers/FileSavePicker.cpp b/dev/Interop/StoragePickers/FileSavePicker.cpp index ca3fc03ae8..cc72c2266f 100644 --- a/dev/Interop/StoragePickers/FileSavePicker.cpp +++ b/dev/Interop/StoragePickers/FileSavePicker.cpp @@ -1,6 +1,6 @@ #include "pch.h" #include "FileSavePicker.h" -#include "FileSavePicker.g.cpp" +#include "Microsoft.Windows.Storage.Pickers.FileSavePicker.g.cpp" #include #include #include @@ -8,7 +8,6 @@ #include #include #include -#include #include #include #include "PickerCommon.h" diff --git a/dev/Interop/StoragePickers/FileSavePicker.h b/dev/Interop/StoragePickers/FileSavePicker.h index 3aae7b5034..5ea9999305 100644 --- a/dev/Interop/StoragePickers/FileSavePicker.h +++ b/dev/Interop/StoragePickers/FileSavePicker.h @@ -1,5 +1,5 @@ #pragma once -#include "FileSavePicker.g.h" +#include "Microsoft.Windows.Storage.Pickers.FileSavePicker.g.h" #include "PickerCommon.h" namespace winrt::Microsoft::Windows::Storage::Pickers::implementation diff --git a/dev/Interop/StoragePickers/FolderPicker.cpp b/dev/Interop/StoragePickers/FolderPicker.cpp index 46dc44d610..6e98421a17 100644 --- a/dev/Interop/StoragePickers/FolderPicker.cpp +++ b/dev/Interop/StoragePickers/FolderPicker.cpp @@ -1,6 +1,6 @@ #include "pch.h" #include "FolderPicker.h" -#include "FolderPicker.g.cpp" +#include "Microsoft.Windows.Storage.Pickers.FolderPicker.g.cpp" #include #include #include diff --git a/dev/Interop/StoragePickers/FolderPicker.h b/dev/Interop/StoragePickers/FolderPicker.h index 9d3d984abb..96e4a3bc0b 100644 --- a/dev/Interop/StoragePickers/FolderPicker.h +++ b/dev/Interop/StoragePickers/FolderPicker.h @@ -1,5 +1,5 @@ #pragma once -#include "FolderPicker.g.h" +#include "Microsoft.Windows.Storage.Pickers.FolderPicker.g.h" #include "PickerCommon.h" namespace winrt::Microsoft::Windows::Storage::Pickers::implementation diff --git a/dev/WindowsAppRuntime_DLL/pch.h b/dev/WindowsAppRuntime_DLL/pch.h index 4074a04733..40782aea6a 100644 --- a/dev/WindowsAppRuntime_DLL/pch.h +++ b/dev/WindowsAppRuntime_DLL/pch.h @@ -14,8 +14,6 @@ #include #include -#include -#include #include #include @@ -67,24 +65,10 @@ #include #include -#include -#include -#include -#include +// #include // Don't remove for now. #include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - #define MIDL_NS_PREFIX // Undefine GetCurrentTime macro to prevent diff --git a/prototype-workingdir/Microsoft.Storage.Pickers/Microsoft.Storage.Pickers.vcxproj b/prototype-workingdir/Microsoft.Storage.Pickers/Microsoft.Storage.Pickers.vcxproj deleted file mode 100644 index b1b1eaf438..0000000000 --- a/prototype-workingdir/Microsoft.Storage.Pickers/Microsoft.Storage.Pickers.vcxproj +++ /dev/null @@ -1,160 +0,0 @@ - - - - - - - true - true - true - {349e64cf-cb0c-4202-b1b5-7f543cc6e886} - Microsoft.Storage.Pickers - Microsoft.Storage.Pickers - en-US - 16.0 - false - Windows Store - 10.0 - 10.0.22621.0 - 10.0.22000.0 - true - true - - - - - Debug - Win32 - - - Debug - x64 - - - Debug - ARM64 - - - Release - Win32 - - - Release - x64 - - - Release - ARM64 - - - - DynamicLibrary - v143 - Unicode - false - true - - - true - true - - - false - true - false - - - - - - - - - - - - - - Use - pch.h - $(IntDir)pch.pch - Level4 - %(AdditionalOptions) /bigobj - _WINRT_DLL;%(PreprocessorDefinitions) - $(WindowsSDK_WindowsMetadata);$(AdditionalUsingDirectories) - - - Console - true - Microsoft_Storage_Pickers.def - - - - - _DEBUG;%(PreprocessorDefinitions) - - - $(CoreLibraryDependencies);%(AdditionalDependencies);shell32.lib - - - - - NDEBUG;%(PreprocessorDefinitions) - - - true - true - $(CoreLibraryDependencies);%(AdditionalDependencies);shell32.lib - - - - - - - - - - - - - - - Create - - - - - - - - - - - false - - - - - - - - - - - - - - - - This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - - - - - - - - - - - \ No newline at end of file diff --git a/prototype-workingdir/Microsoft.Storage.Pickers/Microsoft.Storage.Pickers.vcxproj.filters b/prototype-workingdir/Microsoft.Storage.Pickers/Microsoft.Storage.Pickers.vcxproj.filters deleted file mode 100644 index af63f3cf8e..0000000000 --- a/prototype-workingdir/Microsoft.Storage.Pickers/Microsoft.Storage.Pickers.vcxproj.filters +++ /dev/null @@ -1,37 +0,0 @@ - - - - - accd3aa8-1ba0-4223-9bbe-0c431709210b - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tga;tiff;tif;png;wav;mfcribbon-ms - - - {926ab91d-31b4-48c3-b9a4-e681349f27f0} - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/prototype-workingdir/Microsoft.Storage.Pickers/Microsoft_Storage_Pickers.def b/prototype-workingdir/Microsoft.Storage.Pickers/Microsoft_Storage_Pickers.def deleted file mode 100644 index 24e7c1235c..0000000000 --- a/prototype-workingdir/Microsoft.Storage.Pickers/Microsoft_Storage_Pickers.def +++ /dev/null @@ -1,3 +0,0 @@ -EXPORTS -DllCanUnloadNow = WINRT_CanUnloadNow PRIVATE -DllGetActivationFactory = WINRT_GetActivationFactory PRIVATE diff --git a/prototype-workingdir/Microsoft.Storage.Pickers/packages.config b/prototype-workingdir/Microsoft.Storage.Pickers/packages.config deleted file mode 100644 index 6e553cc88c..0000000000 --- a/prototype-workingdir/Microsoft.Storage.Pickers/packages.config +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/prototype-workingdir/Microsoft.Storage.Pickers/pch.cpp b/prototype-workingdir/Microsoft.Storage.Pickers/pch.cpp deleted file mode 100644 index 1d9f38c57d..0000000000 --- a/prototype-workingdir/Microsoft.Storage.Pickers/pch.cpp +++ /dev/null @@ -1 +0,0 @@ -#include "pch.h" diff --git a/prototype-workingdir/Microsoft.Storage.Pickers/pch.h b/prototype-workingdir/Microsoft.Storage.Pickers/pch.h deleted file mode 100644 index 21563b73b3..0000000000 --- a/prototype-workingdir/Microsoft.Storage.Pickers/pch.h +++ /dev/null @@ -1,33 +0,0 @@ -#pragma once -#include -#include -#include -#include - -// Undefine GetCurrentTime macro to prevent -// conflict with Storyboard::GetCurrentTime -#undef GetCurrentTime - - -#include "winrt/Microsoft.Storage.Pickers.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include From 3af3177c8ad22d764014eec497816603c4060fcc Mon Sep 17 00:00:00 2001 From: Dinah Gao Date: Fri, 13 Dec 2024 14:12:32 +0800 Subject: [PATCH 06/39] Cleanup ; add into projections --- build/NuSpecs/AppxManifest.xml | 2 ++ dev/WindowsAppRuntime_DLL/WindowsAppRuntime_DLL.vcxproj | 8 +------- dev/WindowsAppRuntime_DLL/pch.h | 1 - eng/Version.Dependencies.props | 2 -- eng/Version.Dependencies.xml | 2 -- 5 files changed, 3 insertions(+), 12 deletions(-) diff --git a/build/NuSpecs/AppxManifest.xml b/build/NuSpecs/AppxManifest.xml index 2ee96bb190..c8c3879302 100644 --- a/build/NuSpecs/AppxManifest.xml +++ b/build/NuSpecs/AppxManifest.xml @@ -114,6 +114,8 @@ + + diff --git a/dev/WindowsAppRuntime_DLL/WindowsAppRuntime_DLL.vcxproj b/dev/WindowsAppRuntime_DLL/WindowsAppRuntime_DLL.vcxproj index 78d95ecadc..6be69839db 100644 --- a/dev/WindowsAppRuntime_DLL/WindowsAppRuntime_DLL.vcxproj +++ b/dev/WindowsAppRuntime_DLL/WindowsAppRuntime_DLL.vcxproj @@ -1,11 +1,10 @@ - + - Debug @@ -299,8 +298,6 @@ - - @@ -324,9 +321,6 @@ - - - diff --git a/dev/WindowsAppRuntime_DLL/pch.h b/dev/WindowsAppRuntime_DLL/pch.h index 40782aea6a..62a7cec1fc 100644 --- a/dev/WindowsAppRuntime_DLL/pch.h +++ b/dev/WindowsAppRuntime_DLL/pch.h @@ -14,7 +14,6 @@ #include #include - #include #include #include diff --git a/eng/Version.Dependencies.props b/eng/Version.Dependencies.props index 9a575e12ea..b5789e71cf 100644 --- a/eng/Version.Dependencies.props +++ b/eng/Version.Dependencies.props @@ -23,8 +23,6 @@ $([System.Text.RegularExpressions.Regex]::Match($(VersionDependenciesXml), 'Name="Microsoft.Taef"\s+Version="(.*?)"').Groups[1].Value) $([System.Text.RegularExpressions.Regex]::Match($(VersionDependenciesXml), 'Name="Microsoft.Telemetry.Inbox.Native"\s+Version="(.*?)"').Groups[1].Value) $([System.Text.RegularExpressions.Regex]::Match($(VersionDependenciesXml), 'Name="Microsoft.WindowsAppSDK.Protobuf"\s+Version="(.*?)"').Groups[1].Value) - $([System.Text.RegularExpressions.Regex]::Match($(VersionDependenciesXml), 'Name="Microsoft.UI.Xaml"\s+Version="(.*?)"').Groups[1].Value) - $([System.Text.RegularExpressions.Regex]::Match($(VersionDependenciesXml), 'Name="Microsoft.Web.WebView2"\s+Version="(.*?)"').Groups[1].Value) $([System.Text.RegularExpressions.Regex]::Match($(VersionDependenciesXml), 'Name="Microsoft.Windows.CppWinRT"\s+Version="(.*?)"').Groups[1].Value) $([System.Text.RegularExpressions.Regex]::Match($(VersionDependenciesXml), 'Name="Microsoft.Windows.ImplementationLibrary"\s+Version="(.*?)"').Groups[1].Value) diff --git a/eng/Version.Dependencies.xml b/eng/Version.Dependencies.xml index 32daae382a..2b871b0695 100644 --- a/eng/Version.Dependencies.xml +++ b/eng/Version.Dependencies.xml @@ -32,8 +32,6 @@ - - From 3ae4f6d0886984dd5f663583c5bff1084188e782 Mon Sep 17 00:00:00 2001 From: Dinah Gao Date: Fri, 13 Dec 2024 14:20:27 +0800 Subject: [PATCH 07/39] fix build errors; clean up msbuild dev\Projections\CS\Microsoft.Windows.Storage.Pickers.Projection\Microsoft.Windows.Storage.Pickers.Projection.csproj --- .../Microsoft.Windows.Storage.Pickers.Projection.csproj | 1 + dev/WindowsAppRuntime_DLL/packages.config | 2 -- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/dev/Projections/CS/Microsoft.Windows.Storage.Pickers.Projection/Microsoft.Windows.Storage.Pickers.Projection.csproj b/dev/Projections/CS/Microsoft.Windows.Storage.Pickers.Projection/Microsoft.Windows.Storage.Pickers.Projection.csproj index a13846ff90..46e216e9bc 100644 --- a/dev/Projections/CS/Microsoft.Windows.Storage.Pickers.Projection/Microsoft.Windows.Storage.Pickers.Projection.csproj +++ b/dev/Projections/CS/Microsoft.Windows.Storage.Pickers.Projection/Microsoft.Windows.Storage.Pickers.Projection.csproj @@ -18,6 +18,7 @@ + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/dev/WindowsAppRuntime_DLL/packages.config b/dev/WindowsAppRuntime_DLL/packages.config index f0fde149d4..430adc85fd 100644 --- a/dev/WindowsAppRuntime_DLL/packages.config +++ b/dev/WindowsAppRuntime_DLL/packages.config @@ -3,8 +3,6 @@ - - From 1b84f8cbe1ffc7bde9d9f7b9ac1d5a3bfacfd389 Mon Sep 17 00:00:00 2001 From: Dinah Gao Date: Tue, 17 Dec 2024 15:01:18 +0800 Subject: [PATCH 08/39] graceful solution --- WindowsAppRuntime.sln | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/WindowsAppRuntime.sln b/WindowsAppRuntime.sln index 2e644489bd..1e4e50bda4 100644 --- a/WindowsAppRuntime.sln +++ b/WindowsAppRuntime.sln @@ -568,6 +568,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IXP.TransportPackage.Packag EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.Windows.Storage.Pickers.Projection", "dev\Projections\CS\Microsoft.Windows.Storage.Pickers.Projection\Microsoft.Windows.Storage.Pickers.Projection.csproj", "{8E01AA4F-A16A-4E3F-A59F-6D49422B4410}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "StoragePickers", "dev\Interop\StoragePickers\StoragePickers.vcxitems", "{A39E7B2F-5F67-47DD-8443-531D095CA7F3}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -2200,6 +2202,7 @@ Global {7B323048-439F-47E9-A3D4-7342C5ADE2A5} = {5C88AE1D-AC20-4A41-9299-1EEA15B80724} {A949149D-29CA-4AA7-B1ED-0E571B4AD9BB} = {7B323048-439F-47E9-A3D4-7342C5ADE2A5} {8E01AA4F-A16A-4E3F-A59F-6D49422B4410} = {716C26A0-E6B0-4981-8412-D14A4D410531} + {A39E7B2F-5F67-47DD-8443-531D095CA7F3} = {3B706C5C-55E0-4B76-BF59-89E20FE46795} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {4B3D7591-CFEC-4762-9A07-ABE99938FB77} @@ -2222,6 +2225,7 @@ Global dev\PackageManager\API\PackageManager.vcxitems*{8a9a0c85-65a8-4bca-a49e-45fc4fdbc7d2}*SharedItemsImports = 9 test\inc\inc.vcxitems*{8e52d7ea-a200-4a6b-ba74-8efb49468caf}*SharedItemsImports = 4 dev\Interop\CameraCaptureUI\CameraCaptureUI\CameraCaptureUI.vcxitems*{95409d1e-843f-4316-8d8e-471b3e203f94}*SharedItemsImports = 9 + dev\Interop\StoragePickers\StoragePickers.vcxitems*{a39e7b2f-5f67-47dd-8443-531d095ca7f3}*SharedItemsImports = 9 dev\AppNotifications\AppNotifications.vcxitems*{b4824897-88e0-4927-8fb9-e60106f01ed9}*SharedItemsImports = 9 test\inc\inc.vcxitems*{b567fe2e-3a03-48d0-b2b5-760cdec35891}*SharedItemsImports = 9 dev\ApplicationData\ApplicationData.vcxitems*{b73ad907-6164-4294-88fb-f3c9c10da1f1}*SharedItemsImports = 4 From 9ad9cc8492c946c1769898acffc08245ead59d29 Mon Sep 17 00:00:00 2001 From: "Xiang Hong (from Dev Box)" Date: Wed, 18 Dec 2024 14:06:58 +0800 Subject: [PATCH 09/39] add ad hoc working in progress fix --- .gitignore | 3 +++ WindowsAppRuntime.sln | 5 +++++ tools/adhoc-install-packages.ps1 | 36 ++++++++++++++++++++++++++++++++ tools/postbuild.cmd | 13 ++++++++++++ 4 files changed, 57 insertions(+) create mode 100644 tools/adhoc-install-packages.ps1 create mode 100644 tools/postbuild.cmd diff --git a/.gitignore b/.gitignore index 863bfdce8f..5df5f6736d 100644 --- a/.gitignore +++ b/.gitignore @@ -395,3 +395,6 @@ build/override/ # WindowsAppSDK specific files Microsoft.WinUI.AppX.targets !dev/vsix/**/*.pubxml + +# TAEF related +redist/ diff --git a/WindowsAppRuntime.sln b/WindowsAppRuntime.sln index 5df671addf..99ffd2aba9 100644 --- a/WindowsAppRuntime.sln +++ b/WindowsAppRuntime.sln @@ -567,6 +567,7 @@ EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IXP.TransportPackage.PackageReference", "eng\PackageReference\IXP\IXP.TransportPackage.PackageReference.csproj", "{A949149D-29CA-4AA7-B1ED-0E571B4AD9BB}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.Windows.Storage.Pickers.Projection", "dev\Projections\CS\Microsoft.Windows.Storage.Pickers.Projection\Microsoft.Windows.Storage.Pickers.Projection.csproj", "{8E01AA4F-A16A-4E3F-A59F-6D49422B4410}" +EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Notifications", "Notifications", "{43FE6980-3E16-4EF9-A3DE-29B402FB4FAB}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "BaseNotifications", "BaseNotifications", "{586EA218-74C8-420B-B47E-0B307AA4B82D}" @@ -579,6 +580,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "BaseNotifications", "dev\No EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.Windows.BadgeNotifications.Projection", "dev\Projections\CS\Microsoft.Windows.BadgeNotifications.Projection\Microsoft.Windows.BadgeNotifications.Projection.csproj", "{A243A58D-ABD7-4520-8C71-F492247B7B92}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "StoragePickers", "dev\Interop\StoragePickers\StoragePickers.vcxitems", "{A39E7B2F-5F67-47DD-8443-531D095CA7F3}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -2233,6 +2236,7 @@ Global {85D111C7-B720-4E19-A56D-03C87B953983} = {50205ED9-0E08-4878-B124-9AC0EBA138D6} {2BD7A1BB-D3D8-484F-9180-409D781DCCF9} = {586EA218-74C8-420B-B47E-0B307AA4B82D} {A243A58D-ABD7-4520-8C71-F492247B7B92} = {716C26A0-E6B0-4981-8412-D14A4D410531} + {A39E7B2F-5F67-47DD-8443-531D095CA7F3} = {3B706C5C-55E0-4B76-BF59-89E20FE46795} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {4B3D7591-CFEC-4762-9A07-ABE99938FB77} @@ -2257,6 +2261,7 @@ Global dev\PackageManager\API\PackageManager.vcxitems*{8a9a0c85-65a8-4bca-a49e-45fc4fdbc7d2}*SharedItemsImports = 9 test\inc\inc.vcxitems*{8e52d7ea-a200-4a6b-ba74-8efb49468caf}*SharedItemsImports = 4 dev\Interop\CameraCaptureUI\CameraCaptureUI\CameraCaptureUI.vcxitems*{95409d1e-843f-4316-8d8e-471b3e203f94}*SharedItemsImports = 9 + dev\Interop\StoragePickers\StoragePickers.vcxitems*{a39e7b2f-5f67-47dd-8443-531d095ca7f3}*SharedItemsImports = 9 dev\AppNotifications\AppNotifications.vcxitems*{b4824897-88e0-4927-8fb9-e60106f01ed9}*SharedItemsImports = 9 test\inc\inc.vcxitems*{b567fe2e-3a03-48d0-b2b5-760cdec35891}*SharedItemsImports = 9 dev\ApplicationData\ApplicationData.vcxitems*{b73ad907-6164-4294-88fb-f3c9c10da1f1}*SharedItemsImports = 4 diff --git a/tools/adhoc-install-packages.ps1 b/tools/adhoc-install-packages.ps1 new file mode 100644 index 0000000000..3533c3bf6a --- /dev/null +++ b/tools/adhoc-install-packages.ps1 @@ -0,0 +1,36 @@ +cd Packages # for instance, C:\ado\WindowsAppSDK\Packages + +# Define the source and destination paths for all versions +$sourcePaths = @( + "Microsoft.FrameworkUdk.1.8.0-CI-26107.1720.241003-1631.3", + "Microsoft.FrameworkUdk.1.8.0-CI-26107.1728.241202-0947.0", + "Microsoft.FrameworkUdk.1.8.0-CI-26107.1730.241212-1315.0", + "Microsoft.ProjectReunion.InteractiveExperiences.TransportPackage.1.8.0-CI-26107.1720.241003-1631.3", + "Microsoft.ProjectReunion.InteractiveExperiences.TransportPackage.1.8.0-CI-26107.1728.241202-0947.0", + "Microsoft.ProjectReunion.InteractiveExperiences.TransportPackage.1.8.0-CI-26107.1730.241212-1315.0" +) + +# Loop through each source path and copy the content to the corresponding destination path + +foreach ($sourcePath in $sourcePaths) { + # Extract the root directory and version from the source path + $rootDir = $sourcePath -replace "\.\d.*", "" + $version = $sourcePath -replace "$rootDir\.", "" + $destinationPath = "$rootDir/$version" + + # Create the root directory if it doesn't exist + if (-Not (Test-Path -Path $rootDir)) { + New-Item -ItemType Directory -Path $rootDir + } + + # Create the versioned directory inside the destination directory if it doesn't exist + if (-Not (Test-Path -Path $destinationPath)) { + New-Item -ItemType Directory -Path $destinationPath + } + + # Copy the content from the source directory to the destination directory + Copy-Item -Path "$sourcePath\*" -Destination $destinationPath -Recurse -Force + + Write-Output "Content copied from $sourcePath to $destinationPath successfully." + +} \ No newline at end of file diff --git a/tools/postbuild.cmd b/tools/postbuild.cmd new file mode 100644 index 0000000000..f0d07fbad9 --- /dev/null +++ b/tools/postbuild.cmd @@ -0,0 +1,13 @@ +@echo off + +REM Step 1: Rename the .nupkg file to .zip +ren "C:\Users\xianghong\Documents\WindowsAppSDK\BuildOutput\Microsoft.WindowsAppSDK.Foundation.TransportPackage.1.1.1.1.nupkg" "Microsoft.WindowsAppSDK.Foundation.TransportPackage.1.1.1.1.zip" + +REM Step 2: Clear content in the target directory +rd /s /q "C:\Users\xianghong\Documents\WindowsAppSDKAggregator\build\packages\Microsoft.WindowsAppSDK.Foundation.TransportPackage.1.1.1.1" +md "C:\Users\xianghong\Documents\WindowsAppSDKAggregator\build\packages\Microsoft.WindowsAppSDK.Foundation.TransportPackage.1.1.1.1" + +REM Step 3: Extract contents of the .zip file into the target directory +powershell -command "Expand-Archive -Path 'C:\Users\xianghong\Documents\WindowsAppSDK\BuildOutput\Microsoft.WindowsAppSDK.Foundation.TransportPackage.1.1.1.1.zip' -DestinationPath 'C:\ado\WindowsAppSDKAggregator\build\packages\Microsoft.WindowsAppSDK.Foundation.TransportPackage.1.1.1.1' -Force" + +echo Done From 965abecb53a409b40c3eeb1d4a7b4732a48cdb09 Mon Sep 17 00:00:00 2001 From: "Xiang Hong (from Dev Box)" Date: Fri, 20 Dec 2024 11:29:55 +0800 Subject: [PATCH 10/39] adding basic tests --- .../CameraCaptureUITests.vcxproj | 7 ++ .../CameraCaptureUITests.vcxproj.filters | 4 + test/CameraCaptureUITests/PickersAPITests.cpp | 100 ++++++++++++++++++ .../appxmanifest.xml | 8 ++ 4 files changed, 119 insertions(+) create mode 100644 test/CameraCaptureUITests/PickersAPITests.cpp diff --git a/test/CameraCaptureUITests/CameraCaptureUITests.vcxproj b/test/CameraCaptureUITests/CameraCaptureUITests.vcxproj index 1c4a3d46dc..0ea4c6a937 100644 --- a/test/CameraCaptureUITests/CameraCaptureUITests.vcxproj +++ b/test/CameraCaptureUITests/CameraCaptureUITests.vcxproj @@ -212,6 +212,7 @@ + Create Create @@ -233,6 +234,12 @@ true + + + $(OutDir)\..\WindowsAppRuntime_DLL\Microsoft.Windows.Storage.Pickers.winmd + true + + {f76b776e-86f5-48c5-8fc7-d2795ecc9746} diff --git a/test/CameraCaptureUITests/CameraCaptureUITests.vcxproj.filters b/test/CameraCaptureUITests/CameraCaptureUITests.vcxproj.filters index 2fe119871b..18f283828d 100644 --- a/test/CameraCaptureUITests/CameraCaptureUITests.vcxproj.filters +++ b/test/CameraCaptureUITests/CameraCaptureUITests.vcxproj.filters @@ -23,6 +23,10 @@ Source Files + + Source Files + + Source Files diff --git a/test/CameraCaptureUITests/PickersAPITests.cpp b/test/CameraCaptureUITests/PickersAPITests.cpp new file mode 100644 index 0000000000..6f469223f8 --- /dev/null +++ b/test/CameraCaptureUITests/PickersAPITests.cpp @@ -0,0 +1,100 @@ +#include "pch.h" +#include "winrt\Microsoft.Windows.Storage.Pickers.h" +#include "winrt\Microsoft.Windows.Media.Capture.h" +#include +#include +#include +#include +#include +#include + + +using namespace std::chrono_literals; +using namespace WEX::Common; +using namespace WEX::Logging; +using namespace WEX::TestExecution; +using namespace winrt::Windows::Storage; + +namespace TB = ::Test::Bootstrap; +namespace TP = ::Test::Packages; + +namespace CameraCaptureUITests +{ + // Timeout in milliseconds + class PickersAPITests + { + public: + BEGIN_TEST_CLASS(PickersAPITests) + TEST_CLASS_PROPERTY(L"ThreadingModel", L"MTA") + TEST_CLASS_PROPERTY(L"RunFixtureAs:Class", L"RestrictedUser") + //TEST_CLASS_PROPERTY(L"RunAs", L"Restricted") + TEST_CLASS_PROPERTY(L"RunAs", L"UAP") + TEST_CLASS_PROPERTY(L"UAP:AppxManifest", L"CameraCaptureUI-AppxManifest.xml") + END_TEST_CLASS() + + TEST_CLASS_SETUP(ClassInit) + { + ::Test::Bootstrap::SetupPackages(); + return true; + } + + TEST_CLASS_CLEANUP(ClassUninit) + { + ::Test::Bootstrap::CleanupPackages(); + return true; + } + + TEST_METHOD_SETUP(MethodInit) + { + VERIFY_IS_TRUE(TP::IsPackageRegistered_WindowsAppRuntimeFramework()); + return true; + } + + TEST_METHOD_CLEANUP(MethodUninit) + { + VERIFY_IS_TRUE(TP::IsPackageRegistered_WindowsAppRuntimeFramework()); + return true; + } + + TEST_METHOD(FileSavePicker_ShouldCreateNewFile) + { + try + { + auto parentWindow = ::GetForegroundWindow(); + winrt::Microsoft::UI::WindowId windowId{ reinterpret_cast(parentWindow) }; + //{ + // winrt::Microsoft::Windows::Media::Capture::CameraCaptureUI cameraUI(windowId); + //} + winrt::Microsoft::Windows::Storage::Pickers::FileSavePicker savePicker(windowId); + //savePicker.SuggestedStartLocation(winrt::Microsoft::Windows::Storage::Pickers::PickerLocationId::DocumentsLibrary); + savePicker.FileTypeChoices().Insert(L"Plain Text", winrt::single_threaded_vector({ L".txt" })); + savePicker.SuggestedFileName(L"test.txt"); + // Act + auto fileOperation = savePicker.PickSaveFileAsync(); + auto file = fileOperation.get(); + + // Assert + if (file != nullptr) + { + Log::Comment(L"File save was successful."); + VERIFY_IS_TRUE(file.Name().c_str() != nullptr); + } + else + { + Log::Error(L"Photo capture failed or was canceled."); + VERIFY_FAIL(L"File save returned null."); + } + } + catch (const winrt::hresult_error& ex) + { + Log::Error((std::wstring(L"Exception thrown: ") + ex.message().c_str()).c_str()); + VERIFY_FAIL(L"Exception occurred during photo capture."); + } + catch (const std::exception& ex) + { + Log::Error((std::wstring(L"Standard exception thrown: ") + winrt::to_hstring(ex.what()).c_str()).c_str()); + VERIFY_FAIL(L"Standard exception occurred during photo capture."); + } + } + }; +} diff --git a/test/DynamicDependency/data/Microsoft.WindowsAppRuntime.Framework/appxmanifest.xml b/test/DynamicDependency/data/Microsoft.WindowsAppRuntime.Framework/appxmanifest.xml index a4f395306f..d48537271f 100644 --- a/test/DynamicDependency/data/Microsoft.WindowsAppRuntime.Framework/appxmanifest.xml +++ b/test/DynamicDependency/data/Microsoft.WindowsAppRuntime.Framework/appxmanifest.xml @@ -113,6 +113,14 @@ + + + Microsoft.WindowsAppRuntime.dll + + + + + Microsoft.WindowsAppRuntime.dll From bc22a5c859e8d1063fcae056f97db982bb931f69 Mon Sep 17 00:00:00 2001 From: Dinah Gao Date: Fri, 20 Dec 2024 17:42:39 +0800 Subject: [PATCH 11/39] allow optional filters; add test configs --- dev/Interop/StoragePickers/PickerCommon.cpp | 10 ++++++++++ .../appxmanifest.xml | 8 ++++++++ 2 files changed, 18 insertions(+) diff --git a/dev/Interop/StoragePickers/PickerCommon.cpp b/dev/Interop/StoragePickers/PickerCommon.cpp index bbf2fd33f9..a9b17d610b 100644 --- a/dev/Interop/StoragePickers/PickerCommon.cpp +++ b/dev/Interop/StoragePickers/PickerCommon.cpp @@ -153,6 +153,11 @@ namespace PickerCommon { { result.at(i) = { buffer.at(i * 2).c_str(), buffer.at(i * 2 + 1).c_str() }; } + + if (result.size() == 0) + { + result.push_back({ L"All Files", L"*.*" }); + } return result; } @@ -172,6 +177,11 @@ namespace PickerCommon { { result.at(i) = { buffer.at(i * 2).c_str(), buffer.at(i * 2 + 1).c_str() }; } + + if (result.size() == 0) + { + result.push_back({ L"All Files", L"*.*" }); + } return result; } diff --git a/test/DynamicDependency/data/Microsoft.WindowsAppRuntime.Framework/appxmanifest.xml b/test/DynamicDependency/data/Microsoft.WindowsAppRuntime.Framework/appxmanifest.xml index a4f395306f..d48537271f 100644 --- a/test/DynamicDependency/data/Microsoft.WindowsAppRuntime.Framework/appxmanifest.xml +++ b/test/DynamicDependency/data/Microsoft.WindowsAppRuntime.Framework/appxmanifest.xml @@ -113,6 +113,14 @@ + + + Microsoft.WindowsAppRuntime.dll + + + + + Microsoft.WindowsAppRuntime.dll From 30bc81ae55f4d42c67b4622311109d5da16d7603 Mon Sep 17 00:00:00 2001 From: Dinah Gao Date: Mon, 23 Dec 2024 12:34:03 +0800 Subject: [PATCH 12/39] use relative path for postbuild script --- tools/postbuild.cmd | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/tools/postbuild.cmd b/tools/postbuild.cmd index f0d07fbad9..2f70b3ad8d 100644 --- a/tools/postbuild.cmd +++ b/tools/postbuild.cmd @@ -1,13 +1,15 @@ +REM execute this script from the root directory of WindowAppSDK repository + @echo off REM Step 1: Rename the .nupkg file to .zip -ren "C:\Users\xianghong\Documents\WindowsAppSDK\BuildOutput\Microsoft.WindowsAppSDK.Foundation.TransportPackage.1.1.1.1.nupkg" "Microsoft.WindowsAppSDK.Foundation.TransportPackage.1.1.1.1.zip" +ren "BuildOutput\Microsoft.WindowsAppSDK.Foundation.TransportPackage.1.1.1.1.nupkg" "Microsoft.WindowsAppSDK.Foundation.TransportPackage.1.1.1.1.zip" REM Step 2: Clear content in the target directory -rd /s /q "C:\Users\xianghong\Documents\WindowsAppSDKAggregator\build\packages\Microsoft.WindowsAppSDK.Foundation.TransportPackage.1.1.1.1" -md "C:\Users\xianghong\Documents\WindowsAppSDKAggregator\build\packages\Microsoft.WindowsAppSDK.Foundation.TransportPackage.1.1.1.1" +rd /s /q "..\WindowsAppSDKAggregator\build\packages\Microsoft.WindowsAppSDK.Foundation.TransportPackage.1.1.1.1" +md "..\WindowsAppSDKAggregator\build\packages\Microsoft.WindowsAppSDK.Foundation.TransportPackage.1.1.1.1" REM Step 3: Extract contents of the .zip file into the target directory -powershell -command "Expand-Archive -Path 'C:\Users\xianghong\Documents\WindowsAppSDK\BuildOutput\Microsoft.WindowsAppSDK.Foundation.TransportPackage.1.1.1.1.zip' -DestinationPath 'C:\ado\WindowsAppSDKAggregator\build\packages\Microsoft.WindowsAppSDK.Foundation.TransportPackage.1.1.1.1' -Force" +powershell -command "Expand-Archive -Path 'BuildOutput\Microsoft.WindowsAppSDK.Foundation.TransportPackage.1.1.1.1.zip' -DestinationPath '..\WindowsAppSDKAggregator\build\packages\Microsoft.WindowsAppSDK.Foundation.TransportPackage.1.1.1.1' -Force" -echo Done +echo Done \ No newline at end of file From 963de7fd14431f3fe92822d9b93e603cb427e823 Mon Sep 17 00:00:00 2001 From: Dinah Gao Date: Mon, 23 Dec 2024 15:57:31 +0800 Subject: [PATCH 13/39] update script - add cleanup --- tools/postbuild.cmd | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/tools/postbuild.cmd b/tools/postbuild.cmd index 2f70b3ad8d..944df5c64a 100644 --- a/tools/postbuild.cmd +++ b/tools/postbuild.cmd @@ -2,8 +2,13 @@ REM execute this script from the root directory of WindowAppSDK repository @echo off -REM Step 1: Rename the .nupkg file to .zip -ren "BuildOutput\Microsoft.WindowsAppSDK.Foundation.TransportPackage.1.1.1.1.nupkg" "Microsoft.WindowsAppSDK.Foundation.TransportPackage.1.1.1.1.zip" +REM if exist, delete "BuildOutput\Microsoft.WindowsAppSDK.Foundation.TransportPackage.1.1.1.1.zip" +if exist "BuildOutput\Microsoft.WindowsAppSDK.Foundation.TransportPackage.1.1.1.1.zip" ( + del "BuildOutput\Microsoft.WindowsAppSDK.Foundation.TransportPackage.1.1.1.1.zip" +) + +REM Step 1: duplicate a .zip file from .nupkg +copy "BuildOutput\Microsoft.WindowsAppSDK.Foundation.TransportPackage.1.1.1.1.nupkg" "BuildOutput\Microsoft.WindowsAppSDK.Foundation.TransportPackage.1.1.1.1.zip" REM Step 2: Clear content in the target directory rd /s /q "..\WindowsAppSDKAggregator\build\packages\Microsoft.WindowsAppSDK.Foundation.TransportPackage.1.1.1.1" From b42b78105e48930aee199300ebe27f8a24e00076 Mon Sep 17 00:00:00 2001 From: Xiang Hong Date: Fri, 10 Jan 2025 15:41:05 +0800 Subject: [PATCH 14/39] work in progress --- WindowsAppRuntime.sln | 109 +++++++++--------- .../CompatibilityTests/CompatibilityTests.cpp | 45 ++++++++ .../CompatibilityTests.vcxproj | 6 + 3 files changed, 108 insertions(+), 52 deletions(-) diff --git a/WindowsAppRuntime.sln b/WindowsAppRuntime.sln index 968f8f6267..ef056539ec 100644 --- a/WindowsAppRuntime.sln +++ b/WindowsAppRuntime.sln @@ -582,6 +582,7 @@ EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "BaseNotifications", "dev\Notifications\BaseNotifications\BaseNotifications.vcxitems", "{2BD7A1BB-D3D8-484F-9180-409D781DCCF9}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.Windows.BadgeNotifications.Projection", "dev\Projections\CS\Microsoft.Windows.BadgeNotifications.Projection\Microsoft.Windows.BadgeNotifications.Projection.csproj", "{A243A58D-ABD7-4520-8C71-F492247B7B92}" +EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CompatibilityOptions", "dev\CompatibilityOptions\CompatibilityOptions.vcxitems", "{1F7B9E9F-9987-490B-9E6E-093C7F63FEC4}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "CompatibilityOptions", "CompatibilityOptions", "{35972D8A-F47E-4875-A341-E8C25DB7A098}" @@ -602,10 +603,13 @@ EndProject Project("{C7167F0D-BC9F-4E6E-AFE1-012C56B48DB5}") = "OAuthTestAppPackage", "test\TestApps\OAuthTestAppPackage\OAuthTestAppPackage.wapproj", "{455C01F8-0A3E-42C4-9F22-13992EB909EC}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "OAuth2ManagerTests", "test\OAuth2ManagerTests\OAuth2ManagerTests.vcxproj", "{0FF6A68F-6C7F-4E66-8CB8-C0B9501060CA}" +EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.Windows.Storage.Pickers.Projection", "dev\Projections\CS\Microsoft.Windows.Storage.Pickers.Projection\Microsoft.Windows.Storage.Pickers.Projection.csproj", "{8E01AA4F-A16A-4E3F-A59F-6D49422B4410}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "StoragePickers", "dev\Interop\StoragePickers\StoragePickers.vcxitems", "{A39E7B2F-5F67-47DD-8443-531D095CA7F3}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StoragePickersTests", "StoragePickersTests", "{179D0CF8-4A10-4973-A245-64A380E9FFBD}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -2074,6 +2078,54 @@ Global {A243A58D-ABD7-4520-8C71-F492247B7B92}.Release|x64.Build.0 = Release|Any CPU {A243A58D-ABD7-4520-8C71-F492247B7B92}.Release|x86.ActiveCfg = Release|Any CPU {A243A58D-ABD7-4520-8C71-F492247B7B92}.Release|x86.Build.0 = Release|Any CPU + {040BB64B-012E-4E4F-BB02-E85EF46D3475}.Debug|Any CPU.ActiveCfg = Debug|x64 + {040BB64B-012E-4E4F-BB02-E85EF46D3475}.Debug|Any CPU.Build.0 = Debug|x64 + {040BB64B-012E-4E4F-BB02-E85EF46D3475}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {040BB64B-012E-4E4F-BB02-E85EF46D3475}.Debug|ARM64.Build.0 = Debug|ARM64 + {040BB64B-012E-4E4F-BB02-E85EF46D3475}.Debug|x64.ActiveCfg = Debug|x64 + {040BB64B-012E-4E4F-BB02-E85EF46D3475}.Debug|x64.Build.0 = Debug|x64 + {040BB64B-012E-4E4F-BB02-E85EF46D3475}.Debug|x86.ActiveCfg = Debug|Win32 + {040BB64B-012E-4E4F-BB02-E85EF46D3475}.Debug|x86.Build.0 = Debug|Win32 + {040BB64B-012E-4E4F-BB02-E85EF46D3475}.Release|Any CPU.ActiveCfg = Release|x64 + {040BB64B-012E-4E4F-BB02-E85EF46D3475}.Release|Any CPU.Build.0 = Release|x64 + {040BB64B-012E-4E4F-BB02-E85EF46D3475}.Release|ARM64.ActiveCfg = Release|ARM64 + {040BB64B-012E-4E4F-BB02-E85EF46D3475}.Release|ARM64.Build.0 = Release|ARM64 + {040BB64B-012E-4E4F-BB02-E85EF46D3475}.Release|x64.ActiveCfg = Release|x64 + {040BB64B-012E-4E4F-BB02-E85EF46D3475}.Release|x64.Build.0 = Release|x64 + {040BB64B-012E-4E4F-BB02-E85EF46D3475}.Release|x86.ActiveCfg = Release|Win32 + {040BB64B-012E-4E4F-BB02-E85EF46D3475}.Release|x86.Build.0 = Release|Win32 + {7FAFCBD2-BDD5-433C-B3D4-700B5C5A67AA}.Debug|Any CPU.ActiveCfg = Debug|x64 + {7FAFCBD2-BDD5-433C-B3D4-700B5C5A67AA}.Debug|Any CPU.Build.0 = Debug|x64 + {7FAFCBD2-BDD5-433C-B3D4-700B5C5A67AA}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {7FAFCBD2-BDD5-433C-B3D4-700B5C5A67AA}.Debug|ARM64.Build.0 = Debug|ARM64 + {7FAFCBD2-BDD5-433C-B3D4-700B5C5A67AA}.Debug|x64.ActiveCfg = Debug|x64 + {7FAFCBD2-BDD5-433C-B3D4-700B5C5A67AA}.Debug|x64.Build.0 = Debug|x64 + {7FAFCBD2-BDD5-433C-B3D4-700B5C5A67AA}.Debug|x86.ActiveCfg = Debug|Win32 + {7FAFCBD2-BDD5-433C-B3D4-700B5C5A67AA}.Debug|x86.Build.0 = Debug|Win32 + {7FAFCBD2-BDD5-433C-B3D4-700B5C5A67AA}.Release|Any CPU.ActiveCfg = Release|x64 + {7FAFCBD2-BDD5-433C-B3D4-700B5C5A67AA}.Release|Any CPU.Build.0 = Release|x64 + {7FAFCBD2-BDD5-433C-B3D4-700B5C5A67AA}.Release|ARM64.ActiveCfg = Release|ARM64 + {7FAFCBD2-BDD5-433C-B3D4-700B5C5A67AA}.Release|ARM64.Build.0 = Release|ARM64 + {7FAFCBD2-BDD5-433C-B3D4-700B5C5A67AA}.Release|x64.ActiveCfg = Release|x64 + {7FAFCBD2-BDD5-433C-B3D4-700B5C5A67AA}.Release|x64.Build.0 = Release|x64 + {7FAFCBD2-BDD5-433C-B3D4-700B5C5A67AA}.Release|x86.ActiveCfg = Release|Win32 + {7FAFCBD2-BDD5-433C-B3D4-700B5C5A67AA}.Release|x86.Build.0 = Release|Win32 + {42B6776C-2CCA-4C0B-8555-7121AA9AEDA9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {42B6776C-2CCA-4C0B-8555-7121AA9AEDA9}.Debug|Any CPU.Build.0 = Debug|Any CPU + {42B6776C-2CCA-4C0B-8555-7121AA9AEDA9}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {42B6776C-2CCA-4C0B-8555-7121AA9AEDA9}.Debug|ARM64.Build.0 = Debug|ARM64 + {42B6776C-2CCA-4C0B-8555-7121AA9AEDA9}.Debug|x64.ActiveCfg = Debug|x64 + {42B6776C-2CCA-4C0B-8555-7121AA9AEDA9}.Debug|x64.Build.0 = Debug|x64 + {42B6776C-2CCA-4C0B-8555-7121AA9AEDA9}.Debug|x86.ActiveCfg = Debug|x86 + {42B6776C-2CCA-4C0B-8555-7121AA9AEDA9}.Debug|x86.Build.0 = Debug|x86 + {42B6776C-2CCA-4C0B-8555-7121AA9AEDA9}.Release|Any CPU.ActiveCfg = Release|Any CPU + {42B6776C-2CCA-4C0B-8555-7121AA9AEDA9}.Release|Any CPU.Build.0 = Release|Any CPU + {42B6776C-2CCA-4C0B-8555-7121AA9AEDA9}.Release|ARM64.ActiveCfg = Release|ARM64 + {42B6776C-2CCA-4C0B-8555-7121AA9AEDA9}.Release|ARM64.Build.0 = Release|ARM64 + {42B6776C-2CCA-4C0B-8555-7121AA9AEDA9}.Release|x64.ActiveCfg = Release|x64 + {42B6776C-2CCA-4C0B-8555-7121AA9AEDA9}.Release|x64.Build.0 = Release|x64 + {42B6776C-2CCA-4C0B-8555-7121AA9AEDA9}.Release|x86.ActiveCfg = Release|x86 + {42B6776C-2CCA-4C0B-8555-7121AA9AEDA9}.Release|x86.Build.0 = Release|x86 {4CAA3052-7FAE-4C5B-A1CB-02D7F910C991}.Debug|Any CPU.ActiveCfg = Debug|x64 {4CAA3052-7FAE-4C5B-A1CB-02D7F910C991}.Debug|Any CPU.Build.0 = Debug|x64 {4CAA3052-7FAE-4C5B-A1CB-02D7F910C991}.Debug|ARM64.ActiveCfg = Debug|x64 @@ -2130,54 +2182,6 @@ Global {0FF6A68F-6C7F-4E66-8CB8-C0B9501060CA}.Release|x64.Build.0 = Release|x64 {0FF6A68F-6C7F-4E66-8CB8-C0B9501060CA}.Release|x86.ActiveCfg = Release|Win32 {0FF6A68F-6C7F-4E66-8CB8-C0B9501060CA}.Release|x86.Build.0 = Release|Win32 - {040BB64B-012E-4E4F-BB02-E85EF46D3475}.Debug|Any CPU.ActiveCfg = Debug|x64 - {040BB64B-012E-4E4F-BB02-E85EF46D3475}.Debug|Any CPU.Build.0 = Debug|x64 - {040BB64B-012E-4E4F-BB02-E85EF46D3475}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {040BB64B-012E-4E4F-BB02-E85EF46D3475}.Debug|ARM64.Build.0 = Debug|ARM64 - {040BB64B-012E-4E4F-BB02-E85EF46D3475}.Debug|x64.ActiveCfg = Debug|x64 - {040BB64B-012E-4E4F-BB02-E85EF46D3475}.Debug|x64.Build.0 = Debug|x64 - {040BB64B-012E-4E4F-BB02-E85EF46D3475}.Debug|x86.ActiveCfg = Debug|Win32 - {040BB64B-012E-4E4F-BB02-E85EF46D3475}.Debug|x86.Build.0 = Debug|Win32 - {040BB64B-012E-4E4F-BB02-E85EF46D3475}.Release|Any CPU.ActiveCfg = Release|x64 - {040BB64B-012E-4E4F-BB02-E85EF46D3475}.Release|Any CPU.Build.0 = Release|x64 - {040BB64B-012E-4E4F-BB02-E85EF46D3475}.Release|ARM64.ActiveCfg = Release|ARM64 - {040BB64B-012E-4E4F-BB02-E85EF46D3475}.Release|ARM64.Build.0 = Release|ARM64 - {040BB64B-012E-4E4F-BB02-E85EF46D3475}.Release|x64.ActiveCfg = Release|x64 - {040BB64B-012E-4E4F-BB02-E85EF46D3475}.Release|x64.Build.0 = Release|x64 - {040BB64B-012E-4E4F-BB02-E85EF46D3475}.Release|x86.ActiveCfg = Release|Win32 - {040BB64B-012E-4E4F-BB02-E85EF46D3475}.Release|x86.Build.0 = Release|Win32 - {7FAFCBD2-BDD5-433C-B3D4-700B5C5A67AA}.Debug|Any CPU.ActiveCfg = Debug|x64 - {7FAFCBD2-BDD5-433C-B3D4-700B5C5A67AA}.Debug|Any CPU.Build.0 = Debug|x64 - {7FAFCBD2-BDD5-433C-B3D4-700B5C5A67AA}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {7FAFCBD2-BDD5-433C-B3D4-700B5C5A67AA}.Debug|ARM64.Build.0 = Debug|ARM64 - {7FAFCBD2-BDD5-433C-B3D4-700B5C5A67AA}.Debug|x64.ActiveCfg = Debug|x64 - {7FAFCBD2-BDD5-433C-B3D4-700B5C5A67AA}.Debug|x64.Build.0 = Debug|x64 - {7FAFCBD2-BDD5-433C-B3D4-700B5C5A67AA}.Debug|x86.ActiveCfg = Debug|Win32 - {7FAFCBD2-BDD5-433C-B3D4-700B5C5A67AA}.Debug|x86.Build.0 = Debug|Win32 - {7FAFCBD2-BDD5-433C-B3D4-700B5C5A67AA}.Release|Any CPU.ActiveCfg = Release|x64 - {7FAFCBD2-BDD5-433C-B3D4-700B5C5A67AA}.Release|Any CPU.Build.0 = Release|x64 - {7FAFCBD2-BDD5-433C-B3D4-700B5C5A67AA}.Release|ARM64.ActiveCfg = Release|ARM64 - {7FAFCBD2-BDD5-433C-B3D4-700B5C5A67AA}.Release|ARM64.Build.0 = Release|ARM64 - {7FAFCBD2-BDD5-433C-B3D4-700B5C5A67AA}.Release|x64.ActiveCfg = Release|x64 - {7FAFCBD2-BDD5-433C-B3D4-700B5C5A67AA}.Release|x64.Build.0 = Release|x64 - {7FAFCBD2-BDD5-433C-B3D4-700B5C5A67AA}.Release|x86.ActiveCfg = Release|Win32 - {7FAFCBD2-BDD5-433C-B3D4-700B5C5A67AA}.Release|x86.Build.0 = Release|Win32 - {42B6776C-2CCA-4C0B-8555-7121AA9AEDA9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {42B6776C-2CCA-4C0B-8555-7121AA9AEDA9}.Debug|Any CPU.Build.0 = Debug|Any CPU - {42B6776C-2CCA-4C0B-8555-7121AA9AEDA9}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {42B6776C-2CCA-4C0B-8555-7121AA9AEDA9}.Debug|ARM64.Build.0 = Debug|ARM64 - {42B6776C-2CCA-4C0B-8555-7121AA9AEDA9}.Debug|x64.ActiveCfg = Debug|x64 - {42B6776C-2CCA-4C0B-8555-7121AA9AEDA9}.Debug|x64.Build.0 = Debug|x64 - {42B6776C-2CCA-4C0B-8555-7121AA9AEDA9}.Debug|x86.ActiveCfg = Debug|x86 - {42B6776C-2CCA-4C0B-8555-7121AA9AEDA9}.Debug|x86.Build.0 = Debug|x86 - {42B6776C-2CCA-4C0B-8555-7121AA9AEDA9}.Release|Any CPU.ActiveCfg = Release|Any CPU - {42B6776C-2CCA-4C0B-8555-7121AA9AEDA9}.Release|Any CPU.Build.0 = Release|Any CPU - {42B6776C-2CCA-4C0B-8555-7121AA9AEDA9}.Release|ARM64.ActiveCfg = Release|ARM64 - {42B6776C-2CCA-4C0B-8555-7121AA9AEDA9}.Release|ARM64.Build.0 = Release|ARM64 - {42B6776C-2CCA-4C0B-8555-7121AA9AEDA9}.Release|x64.ActiveCfg = Release|x64 - {42B6776C-2CCA-4C0B-8555-7121AA9AEDA9}.Release|x64.Build.0 = Release|x64 - {42B6776C-2CCA-4C0B-8555-7121AA9AEDA9}.Release|x86.ActiveCfg = Release|x86 - {42B6776C-2CCA-4C0B-8555-7121AA9AEDA9}.Release|x86.Build.0 = Release|x86 {8E01AA4F-A16A-4E3F-A59F-6D49422B4410}.Debug|Any CPU.ActiveCfg = Debug|x64 {8E01AA4F-A16A-4E3F-A59F-6D49422B4410}.Debug|Any CPU.Build.0 = Debug|x64 {8E01AA4F-A16A-4E3F-A59F-6D49422B4410}.Debug|ARM64.ActiveCfg = Debug|arm64 @@ -2380,17 +2384,18 @@ Global {85D111C7-B720-4E19-A56D-03C87B953983} = {50205ED9-0E08-4878-B124-9AC0EBA138D6} {2BD7A1BB-D3D8-484F-9180-409D781DCCF9} = {586EA218-74C8-420B-B47E-0B307AA4B82D} {A243A58D-ABD7-4520-8C71-F492247B7B92} = {716C26A0-E6B0-4981-8412-D14A4D410531} - {4CAA3052-7FAE-4C5B-A1CB-02D7F910C991} = {AC5FFC80-92FE-4933-BED2-EC5519AC4440} - {455C01F8-0A3E-42C4-9F22-13992EB909EC} = {AC5FFC80-92FE-4933-BED2-EC5519AC4440} - {0FF6A68F-6C7F-4E66-8CB8-C0B9501060CA} = {8630F7AA-2969-4DC9-8700-9B468C1DC21D} {1F7B9E9F-9987-490B-9E6E-093C7F63FEC4} = {35972D8A-F47E-4875-A341-E8C25DB7A098} {35972D8A-F47E-4875-A341-E8C25DB7A098} = {448ED2E5-0B37-4D97-9E6B-8C10A507976A} {040BB64B-012E-4E4F-BB02-E85EF46D3475} = {423E7BAC-0125-46F4-944D-E8F138B3C654} {423E7BAC-0125-46F4-944D-E8F138B3C654} = {8630F7AA-2969-4DC9-8700-9B468C1DC21D} {7FAFCBD2-BDD5-433C-B3D4-700B5C5A67AA} = {423E7BAC-0125-46F4-944D-E8F138B3C654} {42B6776C-2CCA-4C0B-8555-7121AA9AEDA9} = {423E7BAC-0125-46F4-944D-E8F138B3C654} + {4CAA3052-7FAE-4C5B-A1CB-02D7F910C991} = {AC5FFC80-92FE-4933-BED2-EC5519AC4440} + {455C01F8-0A3E-42C4-9F22-13992EB909EC} = {AC5FFC80-92FE-4933-BED2-EC5519AC4440} + {0FF6A68F-6C7F-4E66-8CB8-C0B9501060CA} = {8630F7AA-2969-4DC9-8700-9B468C1DC21D} {8E01AA4F-A16A-4E3F-A59F-6D49422B4410} = {716C26A0-E6B0-4981-8412-D14A4D410531} {A39E7B2F-5F67-47DD-8443-531D095CA7F3} = {3B706C5C-55E0-4B76-BF59-89E20FE46795} + {179D0CF8-4A10-4973-A245-64A380E9FFBD} = {8630F7AA-2969-4DC9-8700-9B468C1DC21D} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {4B3D7591-CFEC-4762-9A07-ABE99938FB77} @@ -2399,8 +2404,8 @@ Global test\inc\inc.vcxitems*{08bc78e0-63c6-49a7-81b3-6afc3deac4de}*SharedItemsImports = 4 test\inc\inc.vcxitems*{0ff6a68f-6c7f-4e66-8cb8-c0b9501060ca}*SharedItemsImports = 4 dev\PushNotifications\PushNotifications.vcxitems*{103c0c23-7ba8-4d44-a63c-83488e2e3a81}*SharedItemsImports = 9 - dev\Notifications\BaseNotifications\BaseNotifications.vcxitems*{2bd7a1bb-d3d8-484f-9180-409d781dccf9}*SharedItemsImports = 9 dev\CompatibilityOptions\CompatibilityOptions.vcxitems*{1f7b9e9f-9987-490b-9e6e-093c7f63fec4}*SharedItemsImports = 9 + dev\Notifications\BaseNotifications\BaseNotifications.vcxitems*{2bd7a1bb-d3d8-484f-9180-409d781dccf9}*SharedItemsImports = 9 dev\EnvironmentManager\API\Microsoft.Process.Environment.vcxitems*{2f3fad1b-d3df-4866-a3a3-c2c777d55638}*SharedItemsImports = 9 dev\OAuth\OAuth.vcxitems*{3e7fd510-8b66-40e7-a80b-780cb8972f83}*SharedItemsImports = 9 test\inc\inc.vcxitems*{412d023e-8635-4ad2-a0ea-e19e08d36915}*SharedItemsImports = 4 diff --git a/test/Compatibility/CompatibilityTests/CompatibilityTests.cpp b/test/Compatibility/CompatibilityTests/CompatibilityTests.cpp index 8bbe369856..56564617ae 100644 --- a/test/Compatibility/CompatibilityTests/CompatibilityTests.cpp +++ b/test/Compatibility/CompatibilityTests/CompatibilityTests.cpp @@ -6,10 +6,15 @@ #include #include +#include "winrt\Microsoft.Windows.Storage.Pickers.h" namespace TB = ::Test::Bootstrap; namespace TP = ::Test::Packages; +using namespace WEX::Common; +using namespace WEX::Logging; +using namespace WEX::TestExecution; + namespace WAR = winrt::Microsoft::Windows::ApplicationModel::WindowsAppRuntime; namespace Test::CompatibilityTests @@ -28,6 +33,46 @@ namespace Test::CompatibilityTests ::Test::Bootstrap::SetupPackages(); return true; } + TEST_METHOD(FileSavePicker_ShouldCreateNewFile) + { + try + { + auto parentWindow = ::GetForegroundWindow(); + winrt::Microsoft::UI::WindowId windowId{ reinterpret_cast(parentWindow) }; + //{ + // winrt::Microsoft::Windows::Media::Capture::CameraCaptureUI cameraUI(windowId); + //} + winrt::Microsoft::Windows::Storage::Pickers::FileSavePicker savePicker(windowId); + //savePicker.SuggestedStartLocation(winrt::Microsoft::Windows::Storage::Pickers::PickerLocationId::DocumentsLibrary); + savePicker.FileTypeChoices().Insert(L"Plain Text", winrt::single_threaded_vector({ L".txt" })); + savePicker.SuggestedFileName(L"test.txt"); + // Act + auto fileOperation = savePicker.PickSaveFileAsync(); + auto file = fileOperation.get(); + + // Assert + if (file != nullptr) + { + Log::Comment(L"File save was successful."); + VERIFY_IS_TRUE(file.Name().c_str() != nullptr); + } + else + { + Log::Error(L"Photo capture failed or was canceled."); + VERIFY_FAIL(L"File save returned null."); + } + } + catch (const winrt::hresult_error& ex) + { + Log::Error((std::wstring(L"Exception thrown: ") + ex.message().c_str()).c_str()); + VERIFY_FAIL(L"Exception occurred during photo capture."); + } + catch (const std::exception& ex) + { + Log::Error((std::wstring(L"Standard exception thrown: ") + winrt::to_hstring(ex.what()).c_str()).c_str()); + VERIFY_FAIL(L"Standard exception occurred during photo capture."); + } + } TEST_CLASS_CLEANUP(ClassCleanup) { diff --git a/test/Compatibility/CompatibilityTests/CompatibilityTests.vcxproj b/test/Compatibility/CompatibilityTests/CompatibilityTests.vcxproj index ee37756ff4..e2b4443bb0 100644 --- a/test/Compatibility/CompatibilityTests/CompatibilityTests.vcxproj +++ b/test/Compatibility/CompatibilityTests/CompatibilityTests.vcxproj @@ -122,6 +122,12 @@ true + + + $(OutDir)\..\WindowsAppRuntime_DLL\Microsoft.Windows.Storage.Pickers.winmd + true + + {f76b776e-86f5-48c5-8fc7-d2795ecc9746} From 8680c9e112ca65d6b235c2a95f60debfbd7af7c8 Mon Sep 17 00:00:00 2001 From: Dinah Gao Date: Tue, 14 Jan 2025 13:52:09 +0800 Subject: [PATCH 15/39] Squashed commit of the following: commit 4a6b97a5635209049d87483b621a7f533dd8d325 Author: Dinah Gao Date: Tue Jan 14 13:43:22 2025 +0800 create file for fileSavePicker commit 369651ddd607d62b94ca7a5b13fa90e7715dfdd9 Author: Dinah Gao Date: Mon Jan 13 18:13:47 2025 +0800 save investigation progress commit f025b6416c3c1d864822c29900943cc58505a4d3 Author: Dinah Gao Date: Mon Jan 13 11:54:10 2025 +0800 update doc commit cc4b8cb80c3890c4096ac1fc02d6908ddec580a1 Author: Dinah Gao Date: Mon Jan 13 11:47:36 2025 +0800 atls.lib commit dc26511b03932d7c8bd7c1b51bdf943571cd610d Author: Dinah Gao Date: Fri Jan 10 17:56:21 2025 +0800 COM APIs commit d0f487c864551dbe9e2cf8e76e4bb523691f7e67 Author: Dinah Gao Date: Fri Jan 10 15:05:10 2025 +0800 fix file save picker not creating new file --- dev/Interop/StoragePickers/FileSavePicker.cpp | 7 ++++++- dev/Interop/StoragePickers/PickerCommon.cpp | 17 ++++++++++++++--- dev/Interop/StoragePickers/PickerCommon.h | 2 +- tools/postbuild.cmd | 2 ++ 4 files changed, 23 insertions(+), 5 deletions(-) diff --git a/dev/Interop/StoragePickers/FileSavePicker.cpp b/dev/Interop/StoragePickers/FileSavePicker.cpp index cc72c2266f..34b17b279f 100644 --- a/dev/Interop/StoragePickers/FileSavePicker.cpp +++ b/dev/Interop/StoragePickers/FileSavePicker.cpp @@ -105,10 +105,12 @@ namespace winrt::Microsoft::Windows::Storage::Pickers::implementation { check_hresult(dialog->SetDefaultExtension(defaultFileExtension.c_str())); } + if (!PickerCommon::IsHStringNullOrEmpty(suggestedFileName)) { check_hresult(dialog->SetFileName(suggestedFileName.c_str())); } + if (suggestedSaveFile != nullptr) { winrt::com_ptr shellItem; @@ -126,7 +128,10 @@ namespace winrt::Microsoft::Windows::Storage::Pickers::implementation winrt::com_ptr shellItem{}; check_hresult(dialog->GetResult(shellItem.put())); - auto file = co_await PickerCommon::CreateStorageFileFromShellItem(shellItem); + + // TODO: Manually append the default extension if not present + + auto file = co_await PickerCommon::CreateStorageFileFromShellItem(shellItem, true); if (cancellationToken()) { diff --git a/dev/Interop/StoragePickers/PickerCommon.cpp b/dev/Interop/StoragePickers/PickerCommon.cpp index a9b17d610b..b003bf973d 100644 --- a/dev/Interop/StoragePickers/PickerCommon.cpp +++ b/dev/Interop/StoragePickers/PickerCommon.cpp @@ -122,13 +122,24 @@ namespace PickerCommon { return value.empty(); } - // TODO: better way to convert ShellItem a StorageFile without relying on path?. - winrt::Windows::Foundation::IAsyncOperation CreateStorageFileFromShellItem(winrt::com_ptr shellItem) + winrt::Windows::Foundation::IAsyncOperation CreateStorageFileFromShellItem(winrt::com_ptr shellItem, bool createFile) { wil::unique_cotaskmem_string filePath; check_hresult(shellItem->GetDisplayName(SIGDN_FILESYSPATH, &filePath)); - co_return co_await winrt::Windows::Storage::StorageFile::GetFileFromPathAsync(filePath.get()); + auto pathStr = filePath.get(); + + if (createFile) + { + HANDLE hFile = CreateFile(pathStr, GENERIC_WRITE, 0, nullptr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr); + if (hFile == INVALID_HANDLE_VALUE) + { + co_return nullptr; + } + CloseHandle(hFile); + } + + co_return co_await winrt::Windows::Storage::StorageFile::GetFileFromPathAsync(pathStr); } winrt::Windows::Foundation::IAsyncOperation CreateStorageFolderFromShellItem(winrt::com_ptr shellItem) diff --git a/dev/Interop/StoragePickers/PickerCommon.h b/dev/Interop/StoragePickers/PickerCommon.h index 6cd2b106b4..0b9dc69050 100644 --- a/dev/Interop/StoragePickers/PickerCommon.h +++ b/dev/Interop/StoragePickers/PickerCommon.h @@ -5,7 +5,7 @@ #include "winrt/Microsoft.Windows.Storage.Pickers.h" namespace PickerCommon { - winrt::Windows::Foundation::IAsyncOperation CreateStorageFileFromShellItem(winrt::com_ptr shellItem); + winrt::Windows::Foundation::IAsyncOperation CreateStorageFileFromShellItem(winrt::com_ptr shellItem, bool createFile = false); winrt::Windows::Foundation::IAsyncOperation CreateStorageFolderFromShellItem(winrt::com_ptr shellItem); std::vector CaptureFilterSpec(std::vector& buffer, winrt::Windows::Foundation::Collections::IVectorView filters); diff --git a/tools/postbuild.cmd b/tools/postbuild.cmd index 944df5c64a..d0465d59d2 100644 --- a/tools/postbuild.cmd +++ b/tools/postbuild.cmd @@ -2,6 +2,8 @@ REM execute this script from the root directory of WindowAppSDK repository @echo off +copy "BuildOutput\Microsoft.WindowsAppSDK.Foundation.TransportPackage.1.1.1.1.nupkg" "..\WindowsAppSDKAggregator\localpackages\Microsoft.WindowsAppSDK.Foundation.TransportPackage.1.1.1.1.nupkg" + REM if exist, delete "BuildOutput\Microsoft.WindowsAppSDK.Foundation.TransportPackage.1.1.1.1.zip" if exist "BuildOutput\Microsoft.WindowsAppSDK.Foundation.TransportPackage.1.1.1.1.zip" ( del "BuildOutput\Microsoft.WindowsAppSDK.Foundation.TransportPackage.1.1.1.1.zip" From 77cc4857b16f69c429f5b2ae27bd9f458b5468f2 Mon Sep 17 00:00:00 2001 From: Xiang Hong Date: Wed, 15 Jan 2025 15:31:38 +0800 Subject: [PATCH 16/39] ad hoc working, examing in progress --- .../TerminalVelocityFeatures-StoragePickers.h | 27 ++++++++ ...erminalVelocityFeatures-StoragePickers.xml | 20 ++++++ test/CameraCaptureUITests/PickersAPITests.cpp | 49 +++++++++++++- .../CompatibilityTests/CompatibilityTests.cpp | 64 ++++++++++--------- .../CompatibilityTests.vcxproj | 7 ++ test/Compatibility/CompatibilityTests/pch.h | 1 + 6 files changed, 136 insertions(+), 32 deletions(-) create mode 100644 dev/Common/TerminalVelocityFeatures-StoragePickers.h create mode 100644 dev/Common/TerminalVelocityFeatures-StoragePickers.xml diff --git a/dev/Common/TerminalVelocityFeatures-StoragePickers.h b/dev/Common/TerminalVelocityFeatures-StoragePickers.h new file mode 100644 index 0000000000..2b7b2f1b95 --- /dev/null +++ b/dev/Common/TerminalVelocityFeatures-StoragePickers.h @@ -0,0 +1,27 @@ +// Copyright (c) Microsoft Corporation and Contributors. +// Licensed under the MIT License. + +// THIS FILE IS AUTOMATICALLY GENERATED; DO NOT EDIT IT + +// INPUT FILE: .\dev\Common\TerminalVelocityFeatures-StoragePickers.xml +// OPTIONS: -Channel Experimental -Language C++ -Path .\dev\Common\TerminalVelocityFeatures-StoragePickers.xml + +#if defined(__midlrt) +namespace features +{ + feature_name Feature_StoragePickers = { DisabledByDefault, FALSE }; +} +#endif // defined(__midlrt) + +// Feature constants +#define WINDOWSAPPRUNTIME_FEATURE_STORAGEPICKERS_ENABLED 1 + +#if defined(__cplusplus) + +__pragma(detect_mismatch("ODR_violation_WINDOWSAPPRUNTIME_FEATURE_STORAGEPICKERS_ENABLED_mismatch", "AlwaysEnabled")) +struct Feature_StoragePickers +{ + static constexpr bool IsEnabled() { return WINDOWSAPPRUNTIME_FEATURE_STORAGEPICKERS_ENABLED == 1; } +}; + +#endif // defined(__cplusplus) \ No newline at end of file diff --git a/dev/Common/TerminalVelocityFeatures-StoragePickers.xml b/dev/Common/TerminalVelocityFeatures-StoragePickers.xml new file mode 100644 index 0000000000..123cf78ecb --- /dev/null +++ b/dev/Common/TerminalVelocityFeatures-StoragePickers.xml @@ -0,0 +1,20 @@ + + + + + + + + + + Feature_StoragePickers + StoragePickers for the WindowsAppRuntime + AlwaysEnabled + + Preview + Stable + + + diff --git a/test/CameraCaptureUITests/PickersAPITests.cpp b/test/CameraCaptureUITests/PickersAPITests.cpp index 6f469223f8..1ac27691ed 100644 --- a/test/CameraCaptureUITests/PickersAPITests.cpp +++ b/test/CameraCaptureUITests/PickersAPITests.cpp @@ -7,7 +7,8 @@ #include #include #include - +#include "winrt\Microsoft.Windows.Media.Capture.h" +#include using namespace std::chrono_literals; using namespace WEX::Common; @@ -56,6 +57,52 @@ namespace CameraCaptureUITests return true; } + // The unit tests will be updated,first test might is there for testing purpose locally. + // Focusing solely on functional tests for now. + TEST_METHOD(CapturePhoto_ShouldReturnFile_Desktop) + { + if (!::Microsoft::Windows::Media::Capture::Feature_CameraCaptureUI::IsEnabled()) + { + Log::Result(TestResults::Skipped, L"CameraCaptureUI API Features are not enabled."); + return; + } + try + { + auto parentWindow = ::GetForegroundWindow(); + winrt::Microsoft::UI::WindowId windowId{ reinterpret_cast(parentWindow) }; + winrt::Microsoft::Windows::Media::Capture::CameraCaptureUI cameraUI(windowId); + return; + // Configure Photo Settings + cameraUI.PhotoSettings().Format(winrt::Microsoft::Windows::Media::Capture::CameraCaptureUIPhotoFormat::Png); + cameraUI.PhotoSettings().AllowCropping(false); + // Act + auto photoOperation = cameraUI.CaptureFileAsync(winrt::Microsoft::Windows::Media::Capture::CameraCaptureUIMode::Photo); + auto photo = photoOperation.get(); + + // Assert + if (photo != nullptr) + { + Log::Comment(L"Photo capture was successful."); + VERIFY_IS_TRUE(photo.Name().c_str() != nullptr); + } + else + { + Log::Error(L"Photo capture failed or was canceled."); + VERIFY_FAIL(L"Photo capture returned null."); + } + } + catch (const winrt::hresult_error& ex) + { + Log::Error((std::wstring(L"Exception thrown: ") + ex.message().c_str()).c_str()); + VERIFY_FAIL(L"Exception occurred during photo capture."); + } + catch (const std::exception& ex) + { + Log::Error((std::wstring(L"Standard exception thrown: ") + winrt::to_hstring(ex.what()).c_str()).c_str()); + VERIFY_FAIL(L"Standard exception occurred during photo capture."); + } + } + TEST_METHOD(FileSavePicker_ShouldCreateNewFile) { try diff --git a/test/Compatibility/CompatibilityTests/CompatibilityTests.cpp b/test/Compatibility/CompatibilityTests/CompatibilityTests.cpp index 56564617ae..96de98ab30 100644 --- a/test/Compatibility/CompatibilityTests/CompatibilityTests.cpp +++ b/test/Compatibility/CompatibilityTests/CompatibilityTests.cpp @@ -6,7 +6,9 @@ #include #include -#include "winrt\Microsoft.Windows.Storage.Pickers.h" +#include +#include +#include namespace TB = ::Test::Bootstrap; namespace TP = ::Test::Packages; @@ -25,23 +27,48 @@ namespace Test::CompatibilityTests BEGIN_TEST_CLASS(CompatibilityTests) TEST_CLASS_PROPERTY(L"ThreadingModel", L"MTA") // MTA is required for ::Test::Bootstrap::SetupPackages() TEST_CLASS_PROPERTY(L"RunFixtureAs:Class", L"RestrictedUser") + //TEST_CLASS_PROPERTY(L"RunFixtureAs:Class", L"UAP") + //TEST_CLASS_PROPERTY(L"RunAs", L"UAP") + TEST_CLASS_PROPERTY(L"IsolationLevel", L"Method") // each test sets its own CompatibilityOptions - END_TEST_CLASS() + END_TEST_CLASS() - TEST_CLASS_SETUP(ClassSetup) + TEST_CLASS_SETUP(ClassSetup) { ::Test::Bootstrap::SetupPackages(); return true; } + + TEST_CLASS_CLEANUP(ClassCleanup) + { + ::Test::Bootstrap::CleanupPackages(); + return true; + } + + TEST_METHOD_SETUP(MethodInit) + { + VERIFY_IS_TRUE(TP::IsPackageRegistered_WindowsAppRuntimeFramework()); + + // The test method setup and execution is on a different thread than the class setup. + // Initialize the framework for the test thread. + ::Test::Bootstrap::SetupBootstrap(); + return true; + } + + TEST_METHOD_CLEANUP(MethodUninit) + { + VERIFY_IS_TRUE(TP::IsPackageRegistered_WindowsAppRuntimeFramework()); + ::Test::Bootstrap::CleanupBootstrap(); + return true; + } + TEST_METHOD(FileSavePicker_ShouldCreateNewFile) { try { auto parentWindow = ::GetForegroundWindow(); winrt::Microsoft::UI::WindowId windowId{ reinterpret_cast(parentWindow) }; - //{ - // winrt::Microsoft::Windows::Media::Capture::CameraCaptureUI cameraUI(windowId); - //} + winrt::Microsoft::Windows::Media::Capture::CameraCaptureUI cameraUI(windowId); winrt::Microsoft::Windows::Storage::Pickers::FileSavePicker savePicker(windowId); //savePicker.SuggestedStartLocation(winrt::Microsoft::Windows::Storage::Pickers::PickerLocationId::DocumentsLibrary); savePicker.FileTypeChoices().Insert(L"Plain Text", winrt::single_threaded_vector({ L".txt" })); @@ -54,12 +81,10 @@ namespace Test::CompatibilityTests if (file != nullptr) { Log::Comment(L"File save was successful."); - VERIFY_IS_TRUE(file.Name().c_str() != nullptr); } else { Log::Error(L"Photo capture failed or was canceled."); - VERIFY_FAIL(L"File save returned null."); } } catch (const winrt::hresult_error& ex) @@ -74,29 +99,6 @@ namespace Test::CompatibilityTests } } - TEST_CLASS_CLEANUP(ClassCleanup) - { - ::Test::Bootstrap::CleanupPackages(); - return true; - } - - TEST_METHOD_SETUP(MethodInit) - { - VERIFY_IS_TRUE(TP::IsPackageRegistered_WindowsAppRuntimeFramework()); - - // The test method setup and execution is on a different thread than the class setup. - // Initialize the framework for the test thread. - ::Test::Bootstrap::SetupBootstrap(); - return true; - } - - TEST_METHOD_CLEANUP(MethodUninit) - { - VERIFY_IS_TRUE(TP::IsPackageRegistered_WindowsAppRuntimeFramework()); - ::Test::Bootstrap::CleanupBootstrap(); - return true; - } - TEST_METHOD(CanSetCompatibilityOptions) { WEX::Logging::Log::Comment(WEX::Common::String(L"Starting CanSetCompatibilityOptions...")); diff --git a/test/Compatibility/CompatibilityTests/CompatibilityTests.vcxproj b/test/Compatibility/CompatibilityTests/CompatibilityTests.vcxproj index e2b4443bb0..41d7247bc3 100644 --- a/test/Compatibility/CompatibilityTests/CompatibilityTests.vcxproj +++ b/test/Compatibility/CompatibilityTests/CompatibilityTests.vcxproj @@ -122,6 +122,12 @@ true + + + $(OutDir)\..\WindowsAppRuntime_DLL\Microsoft.Windows.Media.Capture.winmd + true + + $(OutDir)\..\WindowsAppRuntime_DLL\Microsoft.Windows.Storage.Pickers.winmd @@ -139,6 +145,7 @@ + diff --git a/test/Compatibility/CompatibilityTests/pch.h b/test/Compatibility/CompatibilityTests/pch.h index d9ababf69f..5518c5fd5c 100644 --- a/test/Compatibility/CompatibilityTests/pch.h +++ b/test/Compatibility/CompatibilityTests/pch.h @@ -12,6 +12,7 @@ #include #include +#include "winrt/Microsoft.Windows.Storage.Pickers.h" #include From c4d276803f5487dd1d8cce2e4c13d334455ca4db Mon Sep 17 00:00:00 2001 From: Xiang Hong Date: Thu, 16 Jan 2025 11:13:35 +0800 Subject: [PATCH 17/39] add unit test project for storage pickers APIs --- WindowsAppRuntime.sln | 19 +++ .../CameraCaptureUITests.vcxproj | 7 - .../CameraCaptureUITests.vcxproj.filters | 4 - .../CompatibilityTests/CompatibilityTests.cpp | 51 +----- .../CompatibilityTests.vcxproj | 13 -- test/Compatibility/CompatibilityTests/pch.h | 1 - .../StoragePickers.vcxproj | 152 ++++++++++++++++++ .../StoragePickersTests.cpp | 97 +++++++++++ .../StoragePickersTests.vcxproj.filters | 36 +++++ test/StoragePickersTests/packages.config | 6 + test/StoragePickersTests/pch.cpp | 8 + test/StoragePickersTests/pch.h | 22 +++ 12 files changed, 342 insertions(+), 74 deletions(-) create mode 100644 test/StoragePickersTests/StoragePickers.vcxproj create mode 100644 test/StoragePickersTests/StoragePickersTests.cpp create mode 100644 test/StoragePickersTests/StoragePickersTests.vcxproj.filters create mode 100644 test/StoragePickersTests/packages.config create mode 100644 test/StoragePickersTests/pch.cpp create mode 100644 test/StoragePickersTests/pch.h diff --git a/WindowsAppRuntime.sln b/WindowsAppRuntime.sln index ef056539ec..dc573116f1 100644 --- a/WindowsAppRuntime.sln +++ b/WindowsAppRuntime.sln @@ -610,6 +610,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "StoragePickers", "dev\Inter EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StoragePickersTests", "StoragePickersTests", "{179D0CF8-4A10-4973-A245-64A380E9FFBD}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "StoragePickers", "test\StoragePickersTests\StoragePickers.vcxproj", "{85C86306-46D1-4563-8303-0A79DF923586}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -2198,6 +2200,22 @@ Global {8E01AA4F-A16A-4E3F-A59F-6D49422B4410}.Release|x64.Build.0 = Release|x64 {8E01AA4F-A16A-4E3F-A59F-6D49422B4410}.Release|x86.ActiveCfg = Release|x86 {8E01AA4F-A16A-4E3F-A59F-6D49422B4410}.Release|x86.Build.0 = Release|x86 + {85C86306-46D1-4563-8303-0A79DF923586}.Debug|Any CPU.ActiveCfg = Debug|x64 + {85C86306-46D1-4563-8303-0A79DF923586}.Debug|Any CPU.Build.0 = Debug|x64 + {85C86306-46D1-4563-8303-0A79DF923586}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {85C86306-46D1-4563-8303-0A79DF923586}.Debug|ARM64.Build.0 = Debug|ARM64 + {85C86306-46D1-4563-8303-0A79DF923586}.Debug|x64.ActiveCfg = Debug|x64 + {85C86306-46D1-4563-8303-0A79DF923586}.Debug|x64.Build.0 = Debug|x64 + {85C86306-46D1-4563-8303-0A79DF923586}.Debug|x86.ActiveCfg = Debug|Win32 + {85C86306-46D1-4563-8303-0A79DF923586}.Debug|x86.Build.0 = Debug|Win32 + {85C86306-46D1-4563-8303-0A79DF923586}.Release|Any CPU.ActiveCfg = Release|x64 + {85C86306-46D1-4563-8303-0A79DF923586}.Release|Any CPU.Build.0 = Release|x64 + {85C86306-46D1-4563-8303-0A79DF923586}.Release|ARM64.ActiveCfg = Release|ARM64 + {85C86306-46D1-4563-8303-0A79DF923586}.Release|ARM64.Build.0 = Release|ARM64 + {85C86306-46D1-4563-8303-0A79DF923586}.Release|x64.ActiveCfg = Release|x64 + {85C86306-46D1-4563-8303-0A79DF923586}.Release|x64.Build.0 = Release|x64 + {85C86306-46D1-4563-8303-0A79DF923586}.Release|x86.ActiveCfg = Release|Win32 + {85C86306-46D1-4563-8303-0A79DF923586}.Release|x86.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -2396,6 +2414,7 @@ Global {8E01AA4F-A16A-4E3F-A59F-6D49422B4410} = {716C26A0-E6B0-4981-8412-D14A4D410531} {A39E7B2F-5F67-47DD-8443-531D095CA7F3} = {3B706C5C-55E0-4B76-BF59-89E20FE46795} {179D0CF8-4A10-4973-A245-64A380E9FFBD} = {8630F7AA-2969-4DC9-8700-9B468C1DC21D} + {85C86306-46D1-4563-8303-0A79DF923586} = {8630F7AA-2969-4DC9-8700-9B468C1DC21D} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {4B3D7591-CFEC-4762-9A07-ABE99938FB77} diff --git a/test/CameraCaptureUITests/CameraCaptureUITests.vcxproj b/test/CameraCaptureUITests/CameraCaptureUITests.vcxproj index 0ea4c6a937..1c4a3d46dc 100644 --- a/test/CameraCaptureUITests/CameraCaptureUITests.vcxproj +++ b/test/CameraCaptureUITests/CameraCaptureUITests.vcxproj @@ -212,7 +212,6 @@ - Create Create @@ -234,12 +233,6 @@ true - - - $(OutDir)\..\WindowsAppRuntime_DLL\Microsoft.Windows.Storage.Pickers.winmd - true - - {f76b776e-86f5-48c5-8fc7-d2795ecc9746} diff --git a/test/CameraCaptureUITests/CameraCaptureUITests.vcxproj.filters b/test/CameraCaptureUITests/CameraCaptureUITests.vcxproj.filters index 18f283828d..2fe119871b 100644 --- a/test/CameraCaptureUITests/CameraCaptureUITests.vcxproj.filters +++ b/test/CameraCaptureUITests/CameraCaptureUITests.vcxproj.filters @@ -23,10 +23,6 @@ Source Files - - Source Files - - Source Files diff --git a/test/Compatibility/CompatibilityTests/CompatibilityTests.cpp b/test/Compatibility/CompatibilityTests/CompatibilityTests.cpp index 96de98ab30..8bbe369856 100644 --- a/test/Compatibility/CompatibilityTests/CompatibilityTests.cpp +++ b/test/Compatibility/CompatibilityTests/CompatibilityTests.cpp @@ -6,17 +6,10 @@ #include #include -#include -#include -#include namespace TB = ::Test::Bootstrap; namespace TP = ::Test::Packages; -using namespace WEX::Common; -using namespace WEX::Logging; -using namespace WEX::TestExecution; - namespace WAR = winrt::Microsoft::Windows::ApplicationModel::WindowsAppRuntime; namespace Test::CompatibilityTests @@ -27,13 +20,10 @@ namespace Test::CompatibilityTests BEGIN_TEST_CLASS(CompatibilityTests) TEST_CLASS_PROPERTY(L"ThreadingModel", L"MTA") // MTA is required for ::Test::Bootstrap::SetupPackages() TEST_CLASS_PROPERTY(L"RunFixtureAs:Class", L"RestrictedUser") - //TEST_CLASS_PROPERTY(L"RunFixtureAs:Class", L"UAP") - //TEST_CLASS_PROPERTY(L"RunAs", L"UAP") - TEST_CLASS_PROPERTY(L"IsolationLevel", L"Method") // each test sets its own CompatibilityOptions - END_TEST_CLASS() + END_TEST_CLASS() - TEST_CLASS_SETUP(ClassSetup) + TEST_CLASS_SETUP(ClassSetup) { ::Test::Bootstrap::SetupPackages(); return true; @@ -62,43 +52,6 @@ namespace Test::CompatibilityTests return true; } - TEST_METHOD(FileSavePicker_ShouldCreateNewFile) - { - try - { - auto parentWindow = ::GetForegroundWindow(); - winrt::Microsoft::UI::WindowId windowId{ reinterpret_cast(parentWindow) }; - winrt::Microsoft::Windows::Media::Capture::CameraCaptureUI cameraUI(windowId); - winrt::Microsoft::Windows::Storage::Pickers::FileSavePicker savePicker(windowId); - //savePicker.SuggestedStartLocation(winrt::Microsoft::Windows::Storage::Pickers::PickerLocationId::DocumentsLibrary); - savePicker.FileTypeChoices().Insert(L"Plain Text", winrt::single_threaded_vector({ L".txt" })); - savePicker.SuggestedFileName(L"test.txt"); - // Act - auto fileOperation = savePicker.PickSaveFileAsync(); - auto file = fileOperation.get(); - - // Assert - if (file != nullptr) - { - Log::Comment(L"File save was successful."); - } - else - { - Log::Error(L"Photo capture failed or was canceled."); - } - } - catch (const winrt::hresult_error& ex) - { - Log::Error((std::wstring(L"Exception thrown: ") + ex.message().c_str()).c_str()); - VERIFY_FAIL(L"Exception occurred during photo capture."); - } - catch (const std::exception& ex) - { - Log::Error((std::wstring(L"Standard exception thrown: ") + winrt::to_hstring(ex.what()).c_str()).c_str()); - VERIFY_FAIL(L"Standard exception occurred during photo capture."); - } - } - TEST_METHOD(CanSetCompatibilityOptions) { WEX::Logging::Log::Comment(WEX::Common::String(L"Starting CanSetCompatibilityOptions...")); diff --git a/test/Compatibility/CompatibilityTests/CompatibilityTests.vcxproj b/test/Compatibility/CompatibilityTests/CompatibilityTests.vcxproj index 41d7247bc3..ee37756ff4 100644 --- a/test/Compatibility/CompatibilityTests/CompatibilityTests.vcxproj +++ b/test/Compatibility/CompatibilityTests/CompatibilityTests.vcxproj @@ -122,18 +122,6 @@ true - - - $(OutDir)\..\WindowsAppRuntime_DLL\Microsoft.Windows.Media.Capture.winmd - true - - - - - $(OutDir)\..\WindowsAppRuntime_DLL\Microsoft.Windows.Storage.Pickers.winmd - true - - {f76b776e-86f5-48c5-8fc7-d2795ecc9746} @@ -145,7 +133,6 @@ - diff --git a/test/Compatibility/CompatibilityTests/pch.h b/test/Compatibility/CompatibilityTests/pch.h index 5518c5fd5c..d9ababf69f 100644 --- a/test/Compatibility/CompatibilityTests/pch.h +++ b/test/Compatibility/CompatibilityTests/pch.h @@ -12,7 +12,6 @@ #include #include -#include "winrt/Microsoft.Windows.Storage.Pickers.h" #include diff --git a/test/StoragePickersTests/StoragePickers.vcxproj b/test/StoragePickersTests/StoragePickers.vcxproj new file mode 100644 index 0000000000..0fba931b4b --- /dev/null +++ b/test/StoragePickersTests/StoragePickers.vcxproj @@ -0,0 +1,152 @@ + + + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + Debug + ARM64 + + + Release + ARM64 + + + + 17.0 + Win32Proj + {85C86306-46D1-4563-8303-0A79DF923586} + StoragePickersTests + 10.0 + + + DynamicLibrary + v143 + Unicode + + + false + + + true + + + + + + + + + + + + + + + + + + + + + + + + + + + Use + true + pch.h + $(RepoRoot)\test\inc;$(VCInstallDir)UnitTest\include;%(AdditionalIncludeDirectories);$(OutDir)\..\WindowsAppRuntime_DLL;$(OutDir)\..\WindowsAppRuntime_BootstrapDLL;$(RepoRoot)\dev\common + $(RepoRoot);%(AdditionalIncludeDirectories) + + + Windows + onecore.lib;onecoreuap.lib;Microsoft.WindowsAppRuntime.lib;wex.common.lib;wex.logger.lib;te.common.lib;%(AdditionalDependencies) + $(VCInstallDir)UnitTest\lib;%(AdditionalLibraryDirectories);$(OutDir)\..\WindowsAppRuntime_DLL + + + + + NDEBUG;%(PreprocessorDefinitions) + + + + + + + _DEBUG;%(PreprocessorDefinitions) + + + + + + + WIN32;%(PreprocessorDefinitions) + + + + + Create + + + $(RepoRoot)\build\VersionInfo;%(AdditionalIncludeDirectories) + + + + + + + + + + + $(OutDir)\..\WindowsAppRuntime_DLL\Microsoft.Windows.Storage.Pickers.winmd + true + + + + + {f76b776e-86f5-48c5-8fc7-d2795ecc9746} + + + + + + + + + + + + + + + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + + + + + diff --git a/test/StoragePickersTests/StoragePickersTests.cpp b/test/StoragePickersTests/StoragePickersTests.cpp new file mode 100644 index 0000000000..03065237a5 --- /dev/null +++ b/test/StoragePickersTests/StoragePickersTests.cpp @@ -0,0 +1,97 @@ +// Copyright (c) Microsoft Corporation and Contributors. +// Licensed under the MIT License. + +#include "pch.h" +#include "AssemblyInfo.h" + +#include +#include +#include + +namespace TB = ::Test::Bootstrap; +namespace TP = ::Test::Packages; + +using namespace WEX::Common; +using namespace WEX::Logging; +using namespace WEX::TestExecution; + +namespace Test::StoragePickersTests +{ + class StoragePickersTests + { + public: + BEGIN_TEST_CLASS(StoragePickersTests) + TEST_CLASS_PROPERTY(L"ThreadingModel", L"MTA") // MTA is required for ::Test::Bootstrap::SetupPackages() + TEST_CLASS_PROPERTY(L"RunFixtureAs:Class", L"RestrictedUser") + //TEST_CLASS_PROPERTY(L"RunFixtureAs:Class", L"UAP") + //TEST_CLASS_PROPERTY(L"RunAs", L"UAP") + + TEST_CLASS_PROPERTY(L"IsolationLevel", L"Method") // each test sets its own CompatibilityOptions + END_TEST_CLASS() + + TEST_CLASS_SETUP(ClassSetup) + { + ::Test::Bootstrap::SetupPackages(); + return true; + } + + TEST_CLASS_CLEANUP(ClassCleanup) + { + ::Test::Bootstrap::CleanupPackages(); + return true; + } + + TEST_METHOD_SETUP(MethodInit) + { + VERIFY_IS_TRUE(TP::IsPackageRegistered_WindowsAppRuntimeFramework()); + + // The test method setup and execution is on a different thread than the class setup. + // Initialize the framework for the test thread. + ::Test::Bootstrap::SetupBootstrap(); + return true; + } + + TEST_METHOD_CLEANUP(MethodUninit) + { + VERIFY_IS_TRUE(TP::IsPackageRegistered_WindowsAppRuntimeFramework()); + ::Test::Bootstrap::CleanupBootstrap(); + return true; + } + + TEST_METHOD(FileSavePicker_ShouldCreateNewFile) + { + try + { + auto parentWindow = ::GetForegroundWindow(); + winrt::Microsoft::UI::WindowId windowId{ reinterpret_cast(parentWindow) }; + winrt::Microsoft::Windows::Storage::Pickers::FileSavePicker savePicker(windowId); + //savePicker.SuggestedStartLocation(winrt::Microsoft::Windows::Storage::Pickers::PickerLocationId::DocumentsLibrary); + savePicker.FileTypeChoices().Insert(L"Plain Text", winrt::single_threaded_vector({ L".txt" })); + savePicker.SuggestedFileName(L"test.txt"); + // Act + auto fileOperation = savePicker.PickSaveFileAsync(); + auto file = fileOperation.get(); + + // Assert + if (file != nullptr) + { + Log::Comment(L"File save was successful."); + } + else + { + Log::Error(L"Photo capture failed or was canceled."); + } + } + catch (const winrt::hresult_error& ex) + { + Log::Error((std::wstring(L"Exception thrown: ") + ex.message().c_str()).c_str()); + VERIFY_FAIL(L"Exception occurred during photo capture."); + } + catch (const std::exception& ex) + { + Log::Error((std::wstring(L"Standard exception thrown: ") + winrt::to_hstring(ex.what()).c_str()).c_str()); + VERIFY_FAIL(L"Standard exception occurred during photo capture."); + } + } + }; +} diff --git a/test/StoragePickersTests/StoragePickersTests.vcxproj.filters b/test/StoragePickersTests/StoragePickersTests.vcxproj.filters new file mode 100644 index 0000000000..404acd038b --- /dev/null +++ b/test/StoragePickersTests/StoragePickersTests.vcxproj.filters @@ -0,0 +1,36 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + + + + + + + Source Files + + + Source Files + + + + + Header Files + + + \ No newline at end of file diff --git a/test/StoragePickersTests/packages.config b/test/StoragePickersTests/packages.config new file mode 100644 index 0000000000..63e5716140 --- /dev/null +++ b/test/StoragePickersTests/packages.config @@ -0,0 +1,6 @@ + + + + + + diff --git a/test/StoragePickersTests/pch.cpp b/test/StoragePickersTests/pch.cpp new file mode 100644 index 0000000000..a77728ba07 --- /dev/null +++ b/test/StoragePickersTests/pch.cpp @@ -0,0 +1,8 @@ +// Copyright (c) Microsoft Corporation and Contributors. +// Licensed under the MIT License. + +// pch.cpp: source file corresponding to the pre-compiled header + +#include "pch.h" + +// When you are using pre-compiled headers, this source file is necessary for compilation to succeed. diff --git a/test/StoragePickersTests/pch.h b/test/StoragePickersTests/pch.h new file mode 100644 index 0000000000..0c38a1ba77 --- /dev/null +++ b/test/StoragePickersTests/pch.h @@ -0,0 +1,22 @@ +// Copyright (c) Microsoft Corporation and Contributors. +// Licensed under the MIT License. + +#ifndef PCH_H +#define PCH_H + +#include + +#include + +#include +#include + +#include "winrt/Microsoft.Windows.Storage.Pickers.h" + +#include + +#include +#include +#include + +#endif //PCH_H From a1e2c91f0138a1fd65b106dd0dedc1a95fb3350e Mon Sep 17 00:00:00 2001 From: Xiang Hong Date: Thu, 16 Jan 2025 14:46:03 +0800 Subject: [PATCH 18/39] fix project name --- WindowsAppRuntime.sln | 5 +---- .../{StoragePickers.vcxproj => StoragePickersTests.vcxproj} | 3 ++- 2 files changed, 3 insertions(+), 5 deletions(-) rename test/StoragePickersTests/{StoragePickers.vcxproj => StoragePickersTests.vcxproj} (99%) diff --git a/WindowsAppRuntime.sln b/WindowsAppRuntime.sln index dc573116f1..cd77601b04 100644 --- a/WindowsAppRuntime.sln +++ b/WindowsAppRuntime.sln @@ -608,9 +608,7 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.Windows.Storage.P EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "StoragePickers", "dev\Interop\StoragePickers\StoragePickers.vcxitems", "{A39E7B2F-5F67-47DD-8443-531D095CA7F3}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StoragePickersTests", "StoragePickersTests", "{179D0CF8-4A10-4973-A245-64A380E9FFBD}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "StoragePickers", "test\StoragePickersTests\StoragePickers.vcxproj", "{85C86306-46D1-4563-8303-0A79DF923586}" +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "StoragePickersTests", "test\StoragePickersTests\StoragePickersTests.vcxproj", "{85C86306-46D1-4563-8303-0A79DF923586}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -2413,7 +2411,6 @@ Global {0FF6A68F-6C7F-4E66-8CB8-C0B9501060CA} = {8630F7AA-2969-4DC9-8700-9B468C1DC21D} {8E01AA4F-A16A-4E3F-A59F-6D49422B4410} = {716C26A0-E6B0-4981-8412-D14A4D410531} {A39E7B2F-5F67-47DD-8443-531D095CA7F3} = {3B706C5C-55E0-4B76-BF59-89E20FE46795} - {179D0CF8-4A10-4973-A245-64A380E9FFBD} = {8630F7AA-2969-4DC9-8700-9B468C1DC21D} {85C86306-46D1-4563-8303-0A79DF923586} = {8630F7AA-2969-4DC9-8700-9B468C1DC21D} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution diff --git a/test/StoragePickersTests/StoragePickers.vcxproj b/test/StoragePickersTests/StoragePickersTests.vcxproj similarity index 99% rename from test/StoragePickersTests/StoragePickers.vcxproj rename to test/StoragePickersTests/StoragePickersTests.vcxproj index 0fba931b4b..ebe73a74e7 100644 --- a/test/StoragePickersTests/StoragePickers.vcxproj +++ b/test/StoragePickersTests/StoragePickersTests.vcxproj @@ -34,6 +34,7 @@ {85C86306-46D1-4563-8303-0A79DF923586} StoragePickersTests 10.0 + StoragePickersTests DynamicLibrary @@ -149,4 +150,4 @@ - + \ No newline at end of file From f8e8e543d6988eb6bc84f5b63c6c542cae25ed35 Mon Sep 17 00:00:00 2001 From: Dinah Gao Date: Thu, 6 Feb 2025 13:14:46 +0800 Subject: [PATCH 19/39] remove [default_interface] in idl files --- .../Microsoft.Windows.Storage.Pickers.idl | 104 +++++++++--------- 1 file changed, 50 insertions(+), 54 deletions(-) diff --git a/dev/Interop/StoragePickers/Microsoft.Windows.Storage.Pickers.idl b/dev/Interop/StoragePickers/Microsoft.Windows.Storage.Pickers.idl index 3a8f24cc03..0e177ab57e 100644 --- a/dev/Interop/StoragePickers/Microsoft.Windows.Storage.Pickers.idl +++ b/dev/Interop/StoragePickers/Microsoft.Windows.Storage.Pickers.idl @@ -1,68 +1,64 @@ namespace Microsoft.Windows.Storage.Pickers { - enum PickerViewMode - { - List, - Thumbnail, - }; + enum PickerViewMode + { + List, + Thumbnail, + }; - enum PickerLocationId - { - DocumentsLibrary, - ComputerFolder, - Desktop, - Downloads, - HomeGroup, - MusicLibrary, - PicturesLibrary, - VideosLibrary, - Objects3D, - Unspecified, - }; + enum PickerLocationId + { + DocumentsLibrary, + ComputerFolder, + Desktop, + Downloads, + HomeGroup, + MusicLibrary, + PicturesLibrary, + VideosLibrary, + Objects3D, + Unspecified, + }; + runtimeclass FileOpenPicker + { + FileOpenPicker(Microsoft.UI.WindowId windowId); - [default_interface] - runtimeclass FileOpenPicker - { - FileOpenPicker(Microsoft.UI.WindowId windowId); + Microsoft.Windows.Storage.Pickers.PickerViewMode ViewMode; + String SettingsIdentifier; + Microsoft.Windows.Storage.Pickers.PickerLocationId SuggestedStartLocation; + String CommitButtonText; + Windows.Foundation.Collections.IVector FileTypeFilter{ get; }; - Microsoft.Windows.Storage.Pickers.PickerViewMode ViewMode; - String SettingsIdentifier; - Microsoft.Windows.Storage.Pickers.PickerLocationId SuggestedStartLocation; - String CommitButtonText; - Windows.Foundation.Collections.IVector FileTypeFilter{ get; }; + [remote_sync] Windows.Foundation.IAsyncOperation PickSingleFileAsync(); + [remote_sync] Windows.Foundation.IAsyncOperation > PickMultipleFilesAsync(); + } - [remote_sync] Windows.Foundation.IAsyncOperation PickSingleFileAsync(); - [remote_sync] Windows.Foundation.IAsyncOperation > PickMultipleFilesAsync(); - } - - [default_interface] runtimeclass FileSavePicker - { - FileSavePicker(Microsoft.UI.WindowId windowId); + { + FileSavePicker(Microsoft.UI.WindowId windowId); - String SettingsIdentifier; - Microsoft.Windows.Storage.Pickers.PickerLocationId SuggestedStartLocation; - String CommitButtonText; - Windows.Foundation.Collections.IMap > FileTypeChoices{ get; }; - String DefaultFileExtension; - Windows.Storage.StorageFile SuggestedSaveFile; - String SuggestedFileName; + String SettingsIdentifier; + Microsoft.Windows.Storage.Pickers.PickerLocationId SuggestedStartLocation; + String CommitButtonText; + Windows.Foundation.Collections.IMap > FileTypeChoices{ get; }; + String DefaultFileExtension; + Windows.Storage.StorageFile SuggestedSaveFile; + String SuggestedFileName; - [remote_sync] Windows.Foundation.IAsyncOperation PickSaveFileAsync(); - } + [remote_sync] Windows.Foundation.IAsyncOperation PickSaveFileAsync(); + } - [default_interface] - runtimeclass FolderPicker - { - FolderPicker(Microsoft.UI.WindowId windowId); + runtimeclass FolderPicker + { + FolderPicker(Microsoft.UI.WindowId windowId); - Microsoft.Windows.Storage.Pickers.PickerViewMode ViewMode; - String SettingsIdentifier; - Microsoft.Windows.Storage.Pickers.PickerLocationId SuggestedStartLocation; - String CommitButtonText; - Windows.Foundation.Collections.IVector FileTypeFilter{ get; }; + Microsoft.Windows.Storage.Pickers.PickerViewMode ViewMode; + String SettingsIdentifier; + Microsoft.Windows.Storage.Pickers.PickerLocationId SuggestedStartLocation; + String CommitButtonText; + Windows.Foundation.Collections.IVector FileTypeFilter{ get; }; - [remote_sync] Windows.Foundation.IAsyncOperation PickSingleFolderAsync(); - } + [remote_sync] Windows.Foundation.IAsyncOperation PickSingleFolderAsync(); + } } From 522a85a367905a7775d8c8e30c80e88c4afcdc03 Mon Sep 17 00:00:00 2001 From: Dinah Gao Date: Fri, 14 Feb 2025 16:40:33 +0800 Subject: [PATCH 20/39] filesavepicker-autoapply-filetypechoices when extension's missing --- dev/Interop/StoragePickers/FileSavePicker.cpp | 31 +++++++++++++++++-- dev/Interop/StoragePickers/PickerCommon.cpp | 12 +------ dev/Interop/StoragePickers/PickerCommon.h | 2 +- 3 files changed, 31 insertions(+), 14 deletions(-) diff --git a/dev/Interop/StoragePickers/FileSavePicker.cpp b/dev/Interop/StoragePickers/FileSavePicker.cpp index 34b17b279f..5788c2b903 100644 --- a/dev/Interop/StoragePickers/FileSavePicker.cpp +++ b/dev/Interop/StoragePickers/FileSavePicker.cpp @@ -90,6 +90,7 @@ namespace winrt::Microsoft::Windows::Storage::Pickers::implementation auto defaultFileExtension = m_defaultFileExtension; auto suggestedSaveFile = m_suggestedSaveFile; auto suggestedFileName = m_suggestedFileName; + auto fileTypeChoices = m_fileTypeChoices; co_await winrt::resume_background(); auto cancellationToken = co_await winrt::get_cancellation_token(); @@ -129,14 +130,40 @@ namespace winrt::Microsoft::Windows::Storage::Pickers::implementation winrt::com_ptr shellItem{}; check_hresult(dialog->GetResult(shellItem.put())); - // TODO: Manually append the default extension if not present + // Get the file path from the dialog + wil::unique_cotaskmem_string filePath; + check_hresult(shellItem->GetDisplayName(SIGDN_FILESYSPATH, &filePath)); + winrt::hstring pathStr(filePath.get()); - auto file = co_await PickerCommon::CreateStorageFileFromShellItem(shellItem, true); + wil::unique_cotaskmem_string fileName; + check_hresult(shellItem->GetDisplayName(SIGDN_NORMALDISPLAY, &fileName)); + std::wstring fileNameStr(fileName.get()); + + // Check if the file name has an extension + if (fileNameStr.find_last_of(L".") == std::wstring::npos) + { + // If the user defined file name doesn't have an extension, + // automatically use the first extension from the first category in fileTypeChoices. + auto firstCategory = fileTypeChoices.First().Current(); + auto firstExtension = firstCategory.Value().GetAt(0); + pathStr = pathStr + firstExtension; + } + + // Create a file. If the file already exists, will prompt to let user select cancele or override. + HANDLE hFile = CreateFile(pathStr.c_str(), GENERIC_WRITE, 0, nullptr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr); + if (hFile == INVALID_HANDLE_VALUE) + { + co_return nullptr; + } + CloseHandle(hFile); + + auto file = co_await winrt::Windows::Storage::StorageFile::GetFileFromPathAsync(pathStr); if (cancellationToken()) { co_return nullptr; } + co_return file; } } diff --git a/dev/Interop/StoragePickers/PickerCommon.cpp b/dev/Interop/StoragePickers/PickerCommon.cpp index b003bf973d..0a0e3a8ca8 100644 --- a/dev/Interop/StoragePickers/PickerCommon.cpp +++ b/dev/Interop/StoragePickers/PickerCommon.cpp @@ -123,22 +123,12 @@ namespace PickerCommon { } // TODO: better way to convert ShellItem a StorageFile without relying on path?. - winrt::Windows::Foundation::IAsyncOperation CreateStorageFileFromShellItem(winrt::com_ptr shellItem, bool createFile) + winrt::Windows::Foundation::IAsyncOperation CreateStorageFileFromShellItem(winrt::com_ptr shellItem) { wil::unique_cotaskmem_string filePath; check_hresult(shellItem->GetDisplayName(SIGDN_FILESYSPATH, &filePath)); auto pathStr = filePath.get(); - if (createFile) - { - HANDLE hFile = CreateFile(pathStr, GENERIC_WRITE, 0, nullptr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr); - if (hFile == INVALID_HANDLE_VALUE) - { - co_return nullptr; - } - CloseHandle(hFile); - } - co_return co_await winrt::Windows::Storage::StorageFile::GetFileFromPathAsync(pathStr); } diff --git a/dev/Interop/StoragePickers/PickerCommon.h b/dev/Interop/StoragePickers/PickerCommon.h index 0b9dc69050..6cd2b106b4 100644 --- a/dev/Interop/StoragePickers/PickerCommon.h +++ b/dev/Interop/StoragePickers/PickerCommon.h @@ -5,7 +5,7 @@ #include "winrt/Microsoft.Windows.Storage.Pickers.h" namespace PickerCommon { - winrt::Windows::Foundation::IAsyncOperation CreateStorageFileFromShellItem(winrt::com_ptr shellItem, bool createFile = false); + winrt::Windows::Foundation::IAsyncOperation CreateStorageFileFromShellItem(winrt::com_ptr shellItem); winrt::Windows::Foundation::IAsyncOperation CreateStorageFolderFromShellItem(winrt::com_ptr shellItem); std::vector CaptureFilterSpec(std::vector& buffer, winrt::Windows::Foundation::Collections::IVectorView filters); From 7ae526d3dca2ae0e7f40f7fecf2ff0d1cdaedcd5 Mon Sep 17 00:00:00 2001 From: Dinah Gao Date: Mon, 17 Feb 2025 16:05:39 +0800 Subject: [PATCH 21/39] set default folder - consistent to UWP picker behaviour --- dev/Interop/StoragePickers/PickerCommon.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/dev/Interop/StoragePickers/PickerCommon.cpp b/dev/Interop/StoragePickers/PickerCommon.cpp index 0a0e3a8ca8..20f646bf11 100644 --- a/dev/Interop/StoragePickers/PickerCommon.cpp +++ b/dev/Interop/StoragePickers/PickerCommon.cpp @@ -202,7 +202,6 @@ namespace PickerCommon { auto defaultFolder = GetKnownFolderFromId(PickerLocationId); if (defaultFolder != nullptr) { - check_hresult(dialog->SetFolder(defaultFolder.get())); check_hresult(dialog->SetDefaultFolder(defaultFolder.get())); } From 9ecade3322ed3b4c563e7372be4d6fe275884b59 Mon Sep 17 00:00:00 2001 From: Dinah Gao Date: Fri, 28 Feb 2025 14:58:19 +0800 Subject: [PATCH 22/39] fall back to Documents, if the specified location doesn't exists. --- dev/Interop/StoragePickers/PickerCommon.cpp | 23 +++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/dev/Interop/StoragePickers/PickerCommon.cpp b/dev/Interop/StoragePickers/PickerCommon.cpp index 20f646bf11..46f2ff225d 100644 --- a/dev/Interop/StoragePickers/PickerCommon.cpp +++ b/dev/Interop/StoragePickers/PickerCommon.cpp @@ -70,10 +70,29 @@ namespace { } auto knownFolderManager = winrt::create_instance(CLSID_KnownFolderManager); + winrt::com_ptr knownFolder{}; - winrt::check_hresult(knownFolderManager->GetFolder(knownFolderId, knownFolder.put())); + HRESULT hr = knownFolderManager->GetFolder(knownFolderId, knownFolder.put()); + if (!knownFolder) + { + if (pickerLocationId == winrt::Microsoft::Windows::Storage::Pickers::PickerLocationId::DocumentsLibrary) + { + return nullptr; + } + else + { + // if the folder is not found, fallback to the Documents Library. This behavior is consistent with that of Windows.Storage.Pickers + return GetKnownFolderFromId(winrt::Microsoft::Windows::Storage::Pickers::PickerLocationId::DocumentsLibrary); + } + } + winrt::com_ptr defaultFolder{}; - winrt::check_hresult(knownFolder->GetShellItem(0, IID_PPV_ARGS(defaultFolder.put()))); + hr = knownFolder->GetShellItem(0, IID_PPV_ARGS(defaultFolder.put())); + if (FAILED(hr)) + { + return nullptr; + } + return defaultFolder; } From 663e3fad045d3b84123b7a41af77b07dc765147d Mon Sep 17 00:00:00 2001 From: Dinah Gao Date: Fri, 28 Feb 2025 16:14:38 +0800 Subject: [PATCH 23/39] use winrt::hresult --- dev/Interop/StoragePickers/PickerCommon.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev/Interop/StoragePickers/PickerCommon.cpp b/dev/Interop/StoragePickers/PickerCommon.cpp index 46f2ff225d..bb9c62b733 100644 --- a/dev/Interop/StoragePickers/PickerCommon.cpp +++ b/dev/Interop/StoragePickers/PickerCommon.cpp @@ -72,7 +72,7 @@ namespace { auto knownFolderManager = winrt::create_instance(CLSID_KnownFolderManager); winrt::com_ptr knownFolder{}; - HRESULT hr = knownFolderManager->GetFolder(knownFolderId, knownFolder.put()); + winrt::hresult hr = knownFolderManager->GetFolder(knownFolderId, knownFolder.put()); if (!knownFolder) { if (pickerLocationId == winrt::Microsoft::Windows::Storage::Pickers::PickerLocationId::DocumentsLibrary) From da6a44e7f305b52d3a3092bf4e5f0e6a072d7fd1 Mon Sep 17 00:00:00 2001 From: Dinah Gao Date: Tue, 11 Mar 2025 14:47:44 +0800 Subject: [PATCH 24/39] use the telemetry guid generated by TlgGuid tool --- dev/Interop/StoragePickers/StoragePickersTelemetry.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dev/Interop/StoragePickers/StoragePickersTelemetry.h b/dev/Interop/StoragePickers/StoragePickersTelemetry.h index beff1e2a22..01fdfe47bd 100644 --- a/dev/Interop/StoragePickers/StoragePickersTelemetry.h +++ b/dev/Interop/StoragePickers/StoragePickersTelemetry.h @@ -7,8 +7,8 @@ DECLARE_TRACELOGGING_CLASS(StoragePickersTelemetryProvider, "Microsoft.WindowsAppSDK.StoragePickersTelemetry", - // {3be0d45f-3a9d-46be-a1cf-b08465473cc4} - (0x3be0d45f, 0x3a9d, 0x46be, 0xa1, 0xcf, 0xb0, 0x84, 0x65, 0x47, 0x3c, 0xc4)); + // {6ddc5826-bf0a-522e-cc84-0e70eda439ed} + (0x6ddc5826,0xbf0a,0x522e,0xcc,0x84,0x0e,0x70,0xed,0xa4,0x39,0xed)); class StoragePickersTelemetry : public wil::TraceLoggingProvider { From 5f83dd31018a74967857709f2568fb44420d8d8c Mon Sep 17 00:00:00 2001 From: Xiang Hong Date: Thu, 13 Mar 2025 17:03:31 +0800 Subject: [PATCH 25/39] update idl file --- .../Microsoft.Windows.Storage.Pickers.idl | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/dev/Interop/StoragePickers/Microsoft.Windows.Storage.Pickers.idl b/dev/Interop/StoragePickers/Microsoft.Windows.Storage.Pickers.idl index 0e177ab57e..376dbe4c25 100644 --- a/dev/Interop/StoragePickers/Microsoft.Windows.Storage.Pickers.idl +++ b/dev/Interop/StoragePickers/Microsoft.Windows.Storage.Pickers.idl @@ -20,6 +20,10 @@ namespace Microsoft.Windows.Storage.Pickers Unspecified, }; + runtimeclass PickFileResult { + String Path { get;} + } + runtimeclass FileOpenPicker { FileOpenPicker(Microsoft.UI.WindowId windowId); @@ -30,8 +34,8 @@ namespace Microsoft.Windows.Storage.Pickers String CommitButtonText; Windows.Foundation.Collections.IVector FileTypeFilter{ get; }; - [remote_sync] Windows.Foundation.IAsyncOperation PickSingleFileAsync(); - [remote_sync] Windows.Foundation.IAsyncOperation > PickMultipleFilesAsync(); + [remote_sync] Windows.Foundation.IAsyncOperation PickSingleFileAsync(); + [remote_sync] Windows.Foundation.IAsyncOperation> PickMultipleFilesAsync(); } runtimeclass FileSavePicker @@ -46,7 +50,11 @@ namespace Microsoft.Windows.Storage.Pickers Windows.Storage.StorageFile SuggestedSaveFile; String SuggestedFileName; - [remote_sync] Windows.Foundation.IAsyncOperation PickSaveFileAsync(); + [remote_sync] Windows.Foundation.IAsyncOperation PickSaveFileAsync(); + } + + runtimeclass PickFolderResult { + String Path { get;} } runtimeclass FolderPicker @@ -59,6 +67,6 @@ namespace Microsoft.Windows.Storage.Pickers String CommitButtonText; Windows.Foundation.Collections.IVector FileTypeFilter{ get; }; - [remote_sync] Windows.Foundation.IAsyncOperation PickSingleFolderAsync(); + [remote_sync] Windows.Foundation.IAsyncOperation PickSingleFolderAsync(); } } From 841f879c52dee7b268f551e126fc31b286d87862 Mon Sep 17 00:00:00 2001 From: Xiang Hong Date: Fri, 14 Mar 2025 17:57:46 +0800 Subject: [PATCH 26/39] work in progress --- dev/Interop/StoragePickers/FileOpenPicker.cpp | 31 ++++++++++++------- dev/Interop/StoragePickers/FileOpenPicker.h | 6 ++-- dev/Interop/StoragePickers/FileSavePicker.cpp | 12 +++++-- dev/Interop/StoragePickers/FileSavePicker.h | 3 +- dev/Interop/StoragePickers/FolderPicker.cpp | 14 +++++++-- dev/Interop/StoragePickers/FolderPicker.h | 3 +- .../Microsoft.Windows.Storage.Pickers.idl | 12 ++++--- dev/Interop/StoragePickers/PickFileResult.cpp | 16 ++++++++++ dev/Interop/StoragePickers/PickFileResult.h | 18 +++++++++++ .../StoragePickers/PickFolderResult.cpp | 16 ++++++++++ dev/Interop/StoragePickers/PickFolderResult.h | 18 +++++++++++ dev/Interop/StoragePickers/PickerCommon.cpp | 9 ++++++ dev/Interop/StoragePickers/PickerCommon.h | 3 ++ .../StoragePickers/StoragePickers.vcxitems | 5 +++ 14 files changed, 140 insertions(+), 26 deletions(-) create mode 100644 dev/Interop/StoragePickers/PickFileResult.cpp create mode 100644 dev/Interop/StoragePickers/PickFileResult.h create mode 100644 dev/Interop/StoragePickers/PickFolderResult.cpp create mode 100644 dev/Interop/StoragePickers/PickFolderResult.h diff --git a/dev/Interop/StoragePickers/FileOpenPicker.cpp b/dev/Interop/StoragePickers/FileOpenPicker.cpp index f3f1f139e2..cde0f7eb31 100644 --- a/dev/Interop/StoragePickers/FileOpenPicker.cpp +++ b/dev/Interop/StoragePickers/FileOpenPicker.cpp @@ -7,6 +7,7 @@ #include #include #include "PickerCommon.h" +#include "PickFileResult.h" namespace winrt::Microsoft::Windows::Storage::Pickers::implementation { @@ -61,11 +62,15 @@ namespace winrt::Microsoft::Windows::Storage::Pickers::implementation parameters.FileTypeFilterPara = PickerCommon::CaptureFilterSpec(parameters.FileTypeFilterData, m_fileTypeFilter.GetView()); } - winrt::Windows::Foundation::IAsyncOperation FileOpenPicker::PickSingleFileAsync() + winrt::Windows::Foundation::IAsyncOperation FileOpenPicker::PickSingleFileAsync() { + // throw winrt::hresult_not_implemented(); + //} + //winrt::Windows::Foundation::IAsyncOperation FileOpenPicker::PickSingleFileAsyncLegacy() + //{ bool isAppPackaged = m_telemetryHelper.IsPackagedApp(); PCWSTR appName = m_telemetryHelper.GetAppName().c_str(); - auto logCaptureOperation{ StoragePickersTelemetry::StoragePickersOperation::Start(isAppPackaged, appName) }; + auto logCaptureOperation{ StoragePickersTelemetry::StoragePickersOperation::Start(isAppPackaged, appName) }; PickerCommon::PickerParameters parameters{}; @@ -79,9 +84,6 @@ namespace winrt::Microsoft::Windows::Storage::Pickers::implementation co_return nullptr; } - // TODO: should we initialize COM? - // wil::com_initialize_ex initializeCom{ COINIT_APARTMENTTHREADED }; - auto dialog = create_instance(CLSID_FileOpenDialog, CONTEXT_ALL); parameters.ConfigureDialog(dialog); @@ -96,24 +98,29 @@ namespace winrt::Microsoft::Windows::Storage::Pickers::implementation winrt::com_ptr shellItem{}; check_hresult(dialog->GetResult(shellItem.put())); - auto file = co_await PickerCommon::CreateStorageFileFromShellItem(shellItem); + //auto file = co_await PickerCommon::CreateStorageFileFromShellItem(shellItem); + auto path = PickerCommon::GetPathFromShellItem(shellItem); if (cancellationToken()) { co_return nullptr; } - co_return file; + co_return make(path); } - winrt::Windows::Foundation::IAsyncOperation> FileOpenPicker::PickMultipleFilesAsync() + winrt::Windows::Foundation::IAsyncOperation > FileOpenPicker::PickMultipleFilesAsync() { + //throw winrt::hresult_not_implemented(); + //} + //winrt::Windows::Foundation::IAsyncOperation> FileOpenPicker::PickMultipleFilesAsyncLegacy() + //{ PickerCommon::PickerParameters parameters{}; CaptureParameters(parameters); co_await winrt::resume_background(); - winrt::Windows::Foundation::Collections::IVector results{ winrt::single_threaded_vector() }; + winrt::Windows::Foundation::Collections::IVector results{ winrt::single_threaded_vector() }; auto cancellationToken = co_await winrt::get_cancellation_token(); if (cancellationToken()) @@ -145,8 +152,10 @@ namespace winrt::Microsoft::Windows::Storage::Pickers::implementation for (DWORD i = 0; i < itemCount; i++) { check_hresult(shellItems->GetItemAt(i, shellItem.put())); - auto file = co_await PickerCommon::CreateStorageFileFromShellItem(shellItem); - results.Append(file); + //auto file = co_await PickerCommon::CreateStorageFileFromShellItem(shellItem); + //results.Append(file); + auto path = PickerCommon::GetPathFromShellItem(shellItem); + results.Append(make(path)); } if (cancellationToken()) diff --git a/dev/Interop/StoragePickers/FileOpenPicker.h b/dev/Interop/StoragePickers/FileOpenPicker.h index d03368f0b9..bea24b2232 100644 --- a/dev/Interop/StoragePickers/FileOpenPicker.h +++ b/dev/Interop/StoragePickers/FileOpenPicker.h @@ -23,8 +23,10 @@ namespace winrt::Microsoft::Windows::Storage::Pickers::implementation winrt::Windows::Foundation::Collections::IVector FileTypeFilter(); - winrt::Windows::Foundation::IAsyncOperation PickSingleFileAsync(); - winrt::Windows::Foundation::IAsyncOperation> PickMultipleFilesAsync(); + //winrt::Windows::Foundation::IAsyncOperation PickSingleFileAsyncLegacy(); + //winrt::Windows::Foundation::IAsyncOperation> PickMultipleFilesAsyncLegacy(); + winrt::Windows::Foundation::IAsyncOperation PickSingleFileAsync(); + winrt::Windows::Foundation::IAsyncOperation> PickMultipleFilesAsync(); private: winrt::Microsoft::UI::WindowId m_windowId{}; diff --git a/dev/Interop/StoragePickers/FileSavePicker.cpp b/dev/Interop/StoragePickers/FileSavePicker.cpp index 5788c2b903..962b677eec 100644 --- a/dev/Interop/StoragePickers/FileSavePicker.cpp +++ b/dev/Interop/StoragePickers/FileSavePicker.cpp @@ -11,6 +11,7 @@ #include #include #include "PickerCommon.h" +#include "PickFileResult.h" namespace winrt::Microsoft::Windows::Storage::Pickers::implementation { @@ -83,8 +84,12 @@ namespace winrt::Microsoft::Windows::Storage::Pickers::implementation } - winrt::Windows::Foundation::IAsyncOperation FileSavePicker::PickSaveFileAsync() + winrt::Windows::Foundation::IAsyncOperation FileSavePicker::PickSaveFileAsync() { + // throw winrt::hresult_not_implemented(); + //} + //winrt::Windows::Foundation::IAsyncOperation FileSavePicker::PickSaveFileAsyncLegacy() + //{ PickerCommon::PickerParameters parameters{}; CaptureParameters(parameters); auto defaultFileExtension = m_defaultFileExtension; @@ -157,13 +162,14 @@ namespace winrt::Microsoft::Windows::Storage::Pickers::implementation } CloseHandle(hFile); - auto file = co_await winrt::Windows::Storage::StorageFile::GetFileFromPathAsync(pathStr); + //auto file = co_await winrt::Windows::Storage::StorageFile::GetFileFromPathAsync(pathStr); if (cancellationToken()) { co_return nullptr; } - co_return file; + //co_return file; + co_return make(pathStr); } } diff --git a/dev/Interop/StoragePickers/FileSavePicker.h b/dev/Interop/StoragePickers/FileSavePicker.h index 5ea9999305..3d5f9cdc95 100644 --- a/dev/Interop/StoragePickers/FileSavePicker.h +++ b/dev/Interop/StoragePickers/FileSavePicker.h @@ -30,7 +30,8 @@ namespace winrt::Microsoft::Windows::Storage::Pickers::implementation hstring SuggestedFileName(); void SuggestedFileName(hstring const& value); - winrt::Windows::Foundation::IAsyncOperation PickSaveFileAsync(); + //winrt::Windows::Foundation::IAsyncOperation PickSaveFileAsyncLegacy(); + winrt::Windows::Foundation::IAsyncOperation PickSaveFileAsync(); private: winrt::Microsoft::UI::WindowId m_windowId{}; diff --git a/dev/Interop/StoragePickers/FolderPicker.cpp b/dev/Interop/StoragePickers/FolderPicker.cpp index 6e98421a17..88689502ae 100644 --- a/dev/Interop/StoragePickers/FolderPicker.cpp +++ b/dev/Interop/StoragePickers/FolderPicker.cpp @@ -5,6 +5,7 @@ #include #include #include "PickerCommon.h" +#include "PickFolderResult.h" namespace winrt::Microsoft::Windows::Storage::Pickers::implementation { @@ -59,8 +60,13 @@ namespace winrt::Microsoft::Windows::Storage::Pickers::implementation } - winrt::Windows::Foundation::IAsyncOperation FolderPicker::PickSingleFolderAsync() + //winrt::Windows::Foundation::IAsyncOperation FolderPicker::PickSingleFolderAsync() + winrt::Windows::Foundation::IAsyncOperation FolderPicker::PickSingleFolderAsync() { + // throw winrt::hresult_not_implemented(); + //} + //winrt::Windows::Foundation::IAsyncOperation FolderPicker::PickSingleFolderAsyncLegacy() + //{ PickerCommon::PickerParameters parameters{}; CaptureParameters(parameters); @@ -87,12 +93,14 @@ namespace winrt::Microsoft::Windows::Storage::Pickers::implementation winrt::com_ptr shellItem{}; check_hresult(dialog->GetResult(shellItem.put())); - auto folder = co_await PickerCommon::CreateStorageFolderFromShellItem(shellItem); + //auto folder = co_await PickerCommon::CreateStorageFolderFromShellItem(shellItem); + auto path = PickerCommon::GetPathFromShellItem(shellItem); if (cancellationToken()) { co_return nullptr; } - co_return folder; + //co_return folder; + co_return make(path); } } diff --git a/dev/Interop/StoragePickers/FolderPicker.h b/dev/Interop/StoragePickers/FolderPicker.h index 96e4a3bc0b..a23337c322 100644 --- a/dev/Interop/StoragePickers/FolderPicker.h +++ b/dev/Interop/StoragePickers/FolderPicker.h @@ -22,7 +22,8 @@ namespace winrt::Microsoft::Windows::Storage::Pickers::implementation winrt::Windows::Foundation::Collections::IVector FileTypeFilter(); - winrt::Windows::Foundation::IAsyncOperation PickSingleFolderAsync(); + //winrt::Windows::Foundation::IAsyncOperation PickSingleFolderAsyncLegacy(); + winrt::Windows::Foundation::IAsyncOperation PickSingleFolderAsync(); private: winrt::Microsoft::UI::WindowId m_windowId{}; diff --git a/dev/Interop/StoragePickers/Microsoft.Windows.Storage.Pickers.idl b/dev/Interop/StoragePickers/Microsoft.Windows.Storage.Pickers.idl index 376dbe4c25..54c1c2aead 100644 --- a/dev/Interop/StoragePickers/Microsoft.Windows.Storage.Pickers.idl +++ b/dev/Interop/StoragePickers/Microsoft.Windows.Storage.Pickers.idl @@ -20,8 +20,9 @@ namespace Microsoft.Windows.Storage.Pickers Unspecified, }; - runtimeclass PickFileResult { - String Path { get;} + runtimeclass PickFileResult + { + String Path { get; }; } runtimeclass FileOpenPicker @@ -35,7 +36,7 @@ namespace Microsoft.Windows.Storage.Pickers Windows.Foundation.Collections.IVector FileTypeFilter{ get; }; [remote_sync] Windows.Foundation.IAsyncOperation PickSingleFileAsync(); - [remote_sync] Windows.Foundation.IAsyncOperation> PickMultipleFilesAsync(); + [remote_sync] Windows.Foundation.IAsyncOperation > PickMultipleFilesAsync(); } runtimeclass FileSavePicker @@ -53,8 +54,9 @@ namespace Microsoft.Windows.Storage.Pickers [remote_sync] Windows.Foundation.IAsyncOperation PickSaveFileAsync(); } - runtimeclass PickFolderResult { - String Path { get;} + runtimeclass PickFolderResult + { + String Path { get; }; } runtimeclass FolderPicker diff --git a/dev/Interop/StoragePickers/PickFileResult.cpp b/dev/Interop/StoragePickers/PickFileResult.cpp new file mode 100644 index 0000000000..6822c37efc --- /dev/null +++ b/dev/Interop/StoragePickers/PickFileResult.cpp @@ -0,0 +1,16 @@ +#include "pch.h" +#include "PickFileResult.h" +#include "Microsoft.Windows.Storage.Pickers.PickFileResult.g.cpp" + +namespace winrt::Microsoft::Windows::Storage::Pickers::implementation +{ + PickFileResult::PickFileResult(hstring const& path) : + m_path(path) + { + } + + hstring PickFileResult::Path() + { + return m_path; + } +} diff --git a/dev/Interop/StoragePickers/PickFileResult.h b/dev/Interop/StoragePickers/PickFileResult.h new file mode 100644 index 0000000000..c980f50544 --- /dev/null +++ b/dev/Interop/StoragePickers/PickFileResult.h @@ -0,0 +1,18 @@ +#pragma once +#include "Microsoft.Windows.Storage.Pickers.PickFileResult.g.h" +#include "PickerCommon.h" + +namespace winrt::Microsoft::Windows::Storage::Pickers::implementation +{ + struct PickFileResult : PickFileResultT + { + PickFileResult() = default; + + PickFileResult(winrt::hstring const& path); + + hstring Path(); + + private: + hstring m_path{}; + }; +} diff --git a/dev/Interop/StoragePickers/PickFolderResult.cpp b/dev/Interop/StoragePickers/PickFolderResult.cpp new file mode 100644 index 0000000000..83033913b8 --- /dev/null +++ b/dev/Interop/StoragePickers/PickFolderResult.cpp @@ -0,0 +1,16 @@ +#include "pch.h" +#include "PickFolderResult.h" +#include "Microsoft.Windows.Storage.Pickers.PickFolderResult.g.cpp" + +namespace winrt::Microsoft::Windows::Storage::Pickers::implementation +{ + PickFolderResult::PickFolderResult(winrt::hstring const& path) + : m_path(path) + { + } + + hstring PickFolderResult::Path() + { + return m_path; + } +} diff --git a/dev/Interop/StoragePickers/PickFolderResult.h b/dev/Interop/StoragePickers/PickFolderResult.h new file mode 100644 index 0000000000..eee9f0f02b --- /dev/null +++ b/dev/Interop/StoragePickers/PickFolderResult.h @@ -0,0 +1,18 @@ +#pragma once +#include "Microsoft.Windows.Storage.Pickers.PickFolderResult.g.h" +#include "PickerCommon.h" + +namespace winrt::Microsoft::Windows::Storage::Pickers::implementation +{ + struct PickFolderResult : PickFolderResultT + { + PickFolderResult() = default; + + PickFolderResult(winrt::hstring const& path); + + hstring Path(); + + private: + hstring m_path{}; + }; +} diff --git a/dev/Interop/StoragePickers/PickerCommon.cpp b/dev/Interop/StoragePickers/PickerCommon.cpp index bb9c62b733..31df2e4195 100644 --- a/dev/Interop/StoragePickers/PickerCommon.cpp +++ b/dev/Interop/StoragePickers/PickerCommon.cpp @@ -151,6 +151,14 @@ namespace PickerCommon { co_return co_await winrt::Windows::Storage::StorageFile::GetFileFromPathAsync(pathStr); } + winrt::hstring GetPathFromShellItem(winrt::com_ptr shellItem) + { + wil::unique_cotaskmem_string filePath; + check_hresult(shellItem->GetDisplayName(SIGDN_FILESYSPATH, &filePath)); + throw hresult_not_implemented(); + } + + winrt::Windows::Foundation::IAsyncOperation CreateStorageFolderFromShellItem(winrt::com_ptr shellItem) { wil::unique_cotaskmem_string filePath; @@ -158,6 +166,7 @@ namespace PickerCommon { co_return co_await winrt::Windows::Storage::StorageFolder::GetFolderFromPathAsync(filePath.get()); } + std::vector CaptureFilterSpec(std::vector& buffer, winrt::Windows::Foundation::Collections::IVectorView filters) { std::vector result(filters.Size()); diff --git a/dev/Interop/StoragePickers/PickerCommon.h b/dev/Interop/StoragePickers/PickerCommon.h index 6cd2b106b4..96a937b465 100644 --- a/dev/Interop/StoragePickers/PickerCommon.h +++ b/dev/Interop/StoragePickers/PickerCommon.h @@ -2,12 +2,15 @@ #pragma once #include "pch.h" #include "ShObjIdl.h" +#include "winrt/base.h" #include "winrt/Microsoft.Windows.Storage.Pickers.h" namespace PickerCommon { winrt::Windows::Foundation::IAsyncOperation CreateStorageFileFromShellItem(winrt::com_ptr shellItem); winrt::Windows::Foundation::IAsyncOperation CreateStorageFolderFromShellItem(winrt::com_ptr shellItem); + winrt::hstring GetPathFromShellItem(winrt::com_ptr shellItem); + std::vector CaptureFilterSpec(std::vector& buffer, winrt::Windows::Foundation::Collections::IVectorView filters); std::vector CaptureFilterSpec(std::vector& buffer, winrt::Windows::Foundation::Collections::IMapView> filters); diff --git a/dev/Interop/StoragePickers/StoragePickers.vcxitems b/dev/Interop/StoragePickers/StoragePickers.vcxitems index 07dc6f4e8a..c36647c25e 100644 --- a/dev/Interop/StoragePickers/StoragePickers.vcxitems +++ b/dev/Interop/StoragePickers/StoragePickers.vcxitems @@ -15,9 +15,14 @@ + + + + + From e8d6dd01902108edc5247705e5f7ff4a6b82ded3 Mon Sep 17 00:00:00 2001 From: Xiang Hong Date: Mon, 17 Mar 2025 11:51:54 +0800 Subject: [PATCH 27/39] adding resume to ui context --- dev/Interop/StoragePickers/FileOpenPicker.cpp | 7 +++- .../StoragePickersTests.cpp | 37 +++++++++++++++++++ 2 files changed, 43 insertions(+), 1 deletion(-) diff --git a/dev/Interop/StoragePickers/FileOpenPicker.cpp b/dev/Interop/StoragePickers/FileOpenPicker.cpp index cde0f7eb31..4e8e89504d 100644 --- a/dev/Interop/StoragePickers/FileOpenPicker.cpp +++ b/dev/Interop/StoragePickers/FileOpenPicker.cpp @@ -68,6 +68,8 @@ namespace winrt::Microsoft::Windows::Storage::Pickers::implementation //} //winrt::Windows::Foundation::IAsyncOperation FileOpenPicker::PickSingleFileAsyncLegacy() //{ + winrt::apartment_context ui_thread; + bool isAppPackaged = m_telemetryHelper.IsPackagedApp(); PCWSTR appName = m_telemetryHelper.GetAppName().c_str(); auto logCaptureOperation{ StoragePickersTelemetry::StoragePickersOperation::Start(isAppPackaged, appName) }; @@ -101,6 +103,8 @@ namespace winrt::Microsoft::Windows::Storage::Pickers::implementation //auto file = co_await PickerCommon::CreateStorageFileFromShellItem(shellItem); auto path = PickerCommon::GetPathFromShellItem(shellItem); + co_await ui_thread; + if (cancellationToken()) { co_return nullptr; @@ -155,7 +159,8 @@ namespace winrt::Microsoft::Windows::Storage::Pickers::implementation //auto file = co_await PickerCommon::CreateStorageFileFromShellItem(shellItem); //results.Append(file); auto path = PickerCommon::GetPathFromShellItem(shellItem); - results.Append(make(path)); + auto result = make(path); + results.Append(result); } if (cancellationToken()) diff --git a/test/StoragePickersTests/StoragePickersTests.cpp b/test/StoragePickersTests/StoragePickersTests.cpp index 03065237a5..3481e6b327 100644 --- a/test/StoragePickersTests/StoragePickersTests.cpp +++ b/test/StoragePickersTests/StoragePickersTests.cpp @@ -58,6 +58,42 @@ namespace Test::StoragePickersTests return true; } + TEST_METHOD(FileOpenPicker_ShouldPickFile) + { + try + { + auto parentWindow = ::GetForegroundWindow(); + winrt::Microsoft::UI::WindowId windowId{ reinterpret_cast(parentWindow) }; + winrt::Microsoft::Windows::Storage::Pickers::FileOpenPicker picker{ windowId }; + //savePicker.SuggestedStartLocation(winrt::Microsoft::Windows::Storage::Pickers::PickerLocationId::DocumentsLibrary); + picker.FileTypeFilter().Append(L"*"); + // Act + auto fileOperation = picker.PickSingleFileAsync(); + auto file = fileOperation.get(); + auto path = file.Path(); + + // Assert + if (file != nullptr) + { + Log::Comment(L"File open was successful"); + } + else + { + Log::Error(L"File open canceled."); + } + } + catch (const winrt::hresult_error& ex) + { + Log::Error((std::wstring(L"Exception thrown: ") + ex.message().c_str()).c_str()); + VERIFY_FAIL(L"Exception occurred during file open picker."); + } + catch (const std::exception& ex) + { + Log::Error((std::wstring(L"Standard exception thrown: ") + winrt::to_hstring(ex.what()).c_str()).c_str()); + VERIFY_FAIL(L"Standard exception occurred during file open picker."); + } + } + TEST_METHOD(FileSavePicker_ShouldCreateNewFile) { try @@ -71,6 +107,7 @@ namespace Test::StoragePickersTests // Act auto fileOperation = savePicker.PickSaveFileAsync(); auto file = fileOperation.get(); + auto path = file.Path(); // Assert if (file != nullptr) From 826ff76303ecb5098533e196cec510e34095444a Mon Sep 17 00:00:00 2001 From: Xiang Hong Date: Mon, 17 Mar 2025 12:25:07 +0800 Subject: [PATCH 28/39] fix get path --- dev/Interop/StoragePickers/PickerCommon.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dev/Interop/StoragePickers/PickerCommon.cpp b/dev/Interop/StoragePickers/PickerCommon.cpp index 31df2e4195..378396eadb 100644 --- a/dev/Interop/StoragePickers/PickerCommon.cpp +++ b/dev/Interop/StoragePickers/PickerCommon.cpp @@ -155,7 +155,7 @@ namespace PickerCommon { { wil::unique_cotaskmem_string filePath; check_hresult(shellItem->GetDisplayName(SIGDN_FILESYSPATH, &filePath)); - throw hresult_not_implemented(); + return winrt::hstring{ filePath.get() }; } @@ -166,7 +166,7 @@ namespace PickerCommon { co_return co_await winrt::Windows::Storage::StorageFolder::GetFolderFromPathAsync(filePath.get()); } - + std::vector CaptureFilterSpec(std::vector& buffer, winrt::Windows::Foundation::Collections::IVectorView filters) { std::vector result(filters.Size()); From 509fc8b1464ce7e7e62fc7eff9e761582e8c1383 Mon Sep 17 00:00:00 2001 From: Xiang Hong Date: Tue, 18 Mar 2025 12:52:38 +0800 Subject: [PATCH 29/39] code clean, add velocity related code --- ...dowsAppSDK-SetupBuildEnvironment-Steps.yml | 8 ++++ .../TerminalVelocityFeatures-StoragePickers.h | 17 ++++--- dev/Interop/StoragePickers/FileOpenPicker.cpp | 15 +----- dev/Interop/StoragePickers/FileOpenPicker.h | 2 - dev/Interop/StoragePickers/FileSavePicker.cpp | 21 ++------- dev/Interop/StoragePickers/FileSavePicker.h | 1 - dev/Interop/StoragePickers/FolderPicker.cpp | 8 +--- dev/Interop/StoragePickers/FolderPicker.h | 1 - .../Microsoft.Windows.Storage.Pickers.idl | 12 ++++- dev/Interop/StoragePickers/PickerCommon.cpp | 47 ++++--------------- dev/Interop/StoragePickers/PickerCommon.h | 6 +-- .../StoragePickersTests.cpp | 5 +- 12 files changed, 51 insertions(+), 92 deletions(-) diff --git a/build/AzurePipelinesTemplates/WindowsAppSDK-SetupBuildEnvironment-Steps.yml b/build/AzurePipelinesTemplates/WindowsAppSDK-SetupBuildEnvironment-Steps.yml index f085304fc5..817994d4e7 100644 --- a/build/AzurePipelinesTemplates/WindowsAppSDK-SetupBuildEnvironment-Steps.yml +++ b/build/AzurePipelinesTemplates/WindowsAppSDK-SetupBuildEnvironment-Steps.yml @@ -187,6 +187,14 @@ steps: arguments: -Path $(Build.SourcesDirectory)\dev\common\TerminalVelocityFeatures-CameraCaptureUI.xml -Channel $(channel) -Language C++ -Namespace Microsoft.Windows.Media.Capture -Output $(Build.SourcesDirectory)\dev\common\TerminalVelocityFeatures-CameraCaptureUI.h workingDirectory: '$(Build.SourcesDirectory)' +- task: powershell@2 + displayName: 'Create OAuth2Manager TerminalVelocity features' + inputs: + targetType: filePath + filePath: tools\TerminalVelocity\Generate-TerminalVelocityFeatures.ps1 + arguments: -Path $(Build.SourcesDirectory)\dev\common\TerminalVelocityFeatures-StoragePickers.xml -Channel $(channel) -Language C++ -Namespace Microsoft.Windows.Storage.Pickers -Output $(Build.SourcesDirectory)\dev\common\TerminalVelocityFeatures-StoragePickers.h + workingDirectory: '$(Build.SourcesDirectory)' + - task: powershell@2 displayName: 'Create OAuth2Manager TerminalVelocity features' inputs: diff --git a/dev/Common/TerminalVelocityFeatures-StoragePickers.h b/dev/Common/TerminalVelocityFeatures-StoragePickers.h index 2b7b2f1b95..85d77e743d 100644 --- a/dev/Common/TerminalVelocityFeatures-StoragePickers.h +++ b/dev/Common/TerminalVelocityFeatures-StoragePickers.h @@ -3,8 +3,8 @@ // THIS FILE IS AUTOMATICALLY GENERATED; DO NOT EDIT IT -// INPUT FILE: .\dev\Common\TerminalVelocityFeatures-StoragePickers.xml -// OPTIONS: -Channel Experimental -Language C++ -Path .\dev\Common\TerminalVelocityFeatures-StoragePickers.xml +// INPUT FILE: dev\Common\TerminalVelocityFeatures-StoragePickers.xml +// OPTIONS: -Channel Experimental -Language C++ -Namespace Microsoft.Windows.Storage.Pickers -Path dev\Common\TerminalVelocityFeatures-StoragePickers.xml -Output dev\Common\TerminalVelocityFeatures-StoragePickers.h #if defined(__midlrt) namespace features @@ -14,14 +14,19 @@ namespace features #endif // defined(__midlrt) // Feature constants -#define WINDOWSAPPRUNTIME_FEATURE_STORAGEPICKERS_ENABLED 1 +#define WINDOWSAPPRUNTIME_MICROSOFT_WINDOWS_STORAGE_PICKERS_FEATURE_STORAGEPICKERS_ENABLED 1 #if defined(__cplusplus) -__pragma(detect_mismatch("ODR_violation_WINDOWSAPPRUNTIME_FEATURE_STORAGEPICKERS_ENABLED_mismatch", "AlwaysEnabled")) +namespace Microsoft::Windows::Storage::Pickers +{ + +__pragma(detect_mismatch("ODR_violation_WINDOWSAPPRUNTIME_MICROSOFT_WINDOWS_STORAGE_PICKERS_FEATURE_STORAGEPICKERS_ENABLED_mismatch", "AlwaysEnabled")) struct Feature_StoragePickers { - static constexpr bool IsEnabled() { return WINDOWSAPPRUNTIME_FEATURE_STORAGEPICKERS_ENABLED == 1; } + static constexpr bool IsEnabled() { return WINDOWSAPPRUNTIME_MICROSOFT_WINDOWS_STORAGE_PICKERS_FEATURE_STORAGEPICKERS_ENABLED == 1; } }; -#endif // defined(__cplusplus) \ No newline at end of file +} // namespace Microsoft.Windows.Storage.Pickers + +#endif // defined(__cplusplus) diff --git a/dev/Interop/StoragePickers/FileOpenPicker.cpp b/dev/Interop/StoragePickers/FileOpenPicker.cpp index 4e8e89504d..917c396902 100644 --- a/dev/Interop/StoragePickers/FileOpenPicker.cpp +++ b/dev/Interop/StoragePickers/FileOpenPicker.cpp @@ -14,6 +14,7 @@ namespace winrt::Microsoft::Windows::Storage::Pickers::implementation FileOpenPicker::FileOpenPicker(winrt::Microsoft::UI::WindowId const& windowId) : m_windowId(windowId) { + THROW_HR_IF(E_NOTIMPL, !::Microsoft::Windows::Storage::Pickers::Feature_StoragePickers::IsEnabled()); } winrt::Microsoft::Windows::Storage::Pickers::PickerViewMode FileOpenPicker::ViewMode() @@ -64,10 +65,6 @@ namespace winrt::Microsoft::Windows::Storage::Pickers::implementation winrt::Windows::Foundation::IAsyncOperation FileOpenPicker::PickSingleFileAsync() { - // throw winrt::hresult_not_implemented(); - //} - //winrt::Windows::Foundation::IAsyncOperation FileOpenPicker::PickSingleFileAsyncLegacy() - //{ winrt::apartment_context ui_thread; bool isAppPackaged = m_telemetryHelper.IsPackagedApp(); @@ -100,7 +97,6 @@ namespace winrt::Microsoft::Windows::Storage::Pickers::implementation winrt::com_ptr shellItem{}; check_hresult(dialog->GetResult(shellItem.put())); - //auto file = co_await PickerCommon::CreateStorageFileFromShellItem(shellItem); auto path = PickerCommon::GetPathFromShellItem(shellItem); co_await ui_thread; @@ -114,12 +110,8 @@ namespace winrt::Microsoft::Windows::Storage::Pickers::implementation winrt::Windows::Foundation::IAsyncOperation > FileOpenPicker::PickMultipleFilesAsync() { - //throw winrt::hresult_not_implemented(); - //} - //winrt::Windows::Foundation::IAsyncOperation> FileOpenPicker::PickMultipleFilesAsyncLegacy() - //{ + // capture parameters to avoid using get strong referece of picker PickerCommon::PickerParameters parameters{}; - CaptureParameters(parameters); co_await winrt::resume_background(); @@ -156,8 +148,6 @@ namespace winrt::Microsoft::Windows::Storage::Pickers::implementation for (DWORD i = 0; i < itemCount; i++) { check_hresult(shellItems->GetItemAt(i, shellItem.put())); - //auto file = co_await PickerCommon::CreateStorageFileFromShellItem(shellItem); - //results.Append(file); auto path = PickerCommon::GetPathFromShellItem(shellItem); auto result = make(path); results.Append(result); @@ -166,7 +156,6 @@ namespace winrt::Microsoft::Windows::Storage::Pickers::implementation if (cancellationToken()) { results.Clear(); - co_return results.GetView(); } co_return results.GetView(); } diff --git a/dev/Interop/StoragePickers/FileOpenPicker.h b/dev/Interop/StoragePickers/FileOpenPicker.h index bea24b2232..50dce02ba3 100644 --- a/dev/Interop/StoragePickers/FileOpenPicker.h +++ b/dev/Interop/StoragePickers/FileOpenPicker.h @@ -23,8 +23,6 @@ namespace winrt::Microsoft::Windows::Storage::Pickers::implementation winrt::Windows::Foundation::Collections::IVector FileTypeFilter(); - //winrt::Windows::Foundation::IAsyncOperation PickSingleFileAsyncLegacy(); - //winrt::Windows::Foundation::IAsyncOperation> PickMultipleFilesAsyncLegacy(); winrt::Windows::Foundation::IAsyncOperation PickSingleFileAsync(); winrt::Windows::Foundation::IAsyncOperation> PickMultipleFilesAsync(); diff --git a/dev/Interop/StoragePickers/FileSavePicker.cpp b/dev/Interop/StoragePickers/FileSavePicker.cpp index 962b677eec..8301e1aa7f 100644 --- a/dev/Interop/StoragePickers/FileSavePicker.cpp +++ b/dev/Interop/StoragePickers/FileSavePicker.cpp @@ -19,6 +19,7 @@ namespace winrt::Microsoft::Windows::Storage::Pickers::implementation FileSavePicker::FileSavePicker(winrt::Microsoft::UI::WindowId const& windowId) : m_windowId(windowId) { + THROW_HR_IF(E_NOTIMPL, !::Microsoft::Windows::Storage::Pickers::Feature_StoragePickers::IsEnabled()); } hstring FileSavePicker::SettingsIdentifier() { @@ -86,10 +87,6 @@ namespace winrt::Microsoft::Windows::Storage::Pickers::implementation winrt::Windows::Foundation::IAsyncOperation FileSavePicker::PickSaveFileAsync() { - // throw winrt::hresult_not_implemented(); - //} - //winrt::Windows::Foundation::IAsyncOperation FileSavePicker::PickSaveFileAsyncLegacy() - //{ PickerCommon::PickerParameters parameters{}; CaptureParameters(parameters); auto defaultFileExtension = m_defaultFileExtension; @@ -136,12 +133,12 @@ namespace winrt::Microsoft::Windows::Storage::Pickers::implementation check_hresult(dialog->GetResult(shellItem.put())); // Get the file path from the dialog - wil::unique_cotaskmem_string filePath; - check_hresult(shellItem->GetDisplayName(SIGDN_FILESYSPATH, &filePath)); + wil::unique_cotaskmem_string filePath{}; + check_hresult(shellItem->GetDisplayName(SIGDN_FILESYSPATH, filePath.put())); winrt::hstring pathStr(filePath.get()); wil::unique_cotaskmem_string fileName; - check_hresult(shellItem->GetDisplayName(SIGDN_NORMALDISPLAY, &fileName)); + check_hresult(shellItem->GetDisplayName(SIGDN_NORMALDISPLAY, fileName.put())); std::wstring fileNameStr(fileName.get()); // Check if the file name has an extension @@ -155,21 +152,13 @@ namespace winrt::Microsoft::Windows::Storage::Pickers::implementation } // Create a file. If the file already exists, will prompt to let user select cancele or override. - HANDLE hFile = CreateFile(pathStr.c_str(), GENERIC_WRITE, 0, nullptr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr); - if (hFile == INVALID_HANDLE_VALUE) - { - co_return nullptr; - } - CloseHandle(hFile); - - //auto file = co_await winrt::Windows::Storage::StorageFile::GetFileFromPathAsync(pathStr); + auto [handle, _] = wil::try_open_or_truncate_existing_file(pathStr.c_str(), GENERIC_WRITE); if (cancellationToken()) { co_return nullptr; } - //co_return file; co_return make(pathStr); } } diff --git a/dev/Interop/StoragePickers/FileSavePicker.h b/dev/Interop/StoragePickers/FileSavePicker.h index 3d5f9cdc95..2ad466c1e6 100644 --- a/dev/Interop/StoragePickers/FileSavePicker.h +++ b/dev/Interop/StoragePickers/FileSavePicker.h @@ -30,7 +30,6 @@ namespace winrt::Microsoft::Windows::Storage::Pickers::implementation hstring SuggestedFileName(); void SuggestedFileName(hstring const& value); - //winrt::Windows::Foundation::IAsyncOperation PickSaveFileAsyncLegacy(); winrt::Windows::Foundation::IAsyncOperation PickSaveFileAsync(); private: diff --git a/dev/Interop/StoragePickers/FolderPicker.cpp b/dev/Interop/StoragePickers/FolderPicker.cpp index 88689502ae..4f8a04fe53 100644 --- a/dev/Interop/StoragePickers/FolderPicker.cpp +++ b/dev/Interop/StoragePickers/FolderPicker.cpp @@ -12,6 +12,7 @@ namespace winrt::Microsoft::Windows::Storage::Pickers::implementation FolderPicker::FolderPicker(winrt::Microsoft::UI::WindowId const& windowId) : m_windowId(windowId) { + THROW_HR_IF(E_NOTIMPL, !::Microsoft::Windows::Storage::Pickers::Feature_StoragePickers::IsEnabled()); } winrt::Microsoft::Windows::Storage::Pickers::PickerViewMode FolderPicker::ViewMode() { @@ -60,13 +61,8 @@ namespace winrt::Microsoft::Windows::Storage::Pickers::implementation } - //winrt::Windows::Foundation::IAsyncOperation FolderPicker::PickSingleFolderAsync() winrt::Windows::Foundation::IAsyncOperation FolderPicker::PickSingleFolderAsync() { - // throw winrt::hresult_not_implemented(); - //} - //winrt::Windows::Foundation::IAsyncOperation FolderPicker::PickSingleFolderAsyncLegacy() - //{ PickerCommon::PickerParameters parameters{}; CaptureParameters(parameters); @@ -93,14 +89,12 @@ namespace winrt::Microsoft::Windows::Storage::Pickers::implementation winrt::com_ptr shellItem{}; check_hresult(dialog->GetResult(shellItem.put())); - //auto folder = co_await PickerCommon::CreateStorageFolderFromShellItem(shellItem); auto path = PickerCommon::GetPathFromShellItem(shellItem); if (cancellationToken()) { co_return nullptr; } - //co_return folder; co_return make(path); } } diff --git a/dev/Interop/StoragePickers/FolderPicker.h b/dev/Interop/StoragePickers/FolderPicker.h index a23337c322..5f79ca7c29 100644 --- a/dev/Interop/StoragePickers/FolderPicker.h +++ b/dev/Interop/StoragePickers/FolderPicker.h @@ -22,7 +22,6 @@ namespace winrt::Microsoft::Windows::Storage::Pickers::implementation winrt::Windows::Foundation::Collections::IVector FileTypeFilter(); - //winrt::Windows::Foundation::IAsyncOperation PickSingleFolderAsyncLegacy(); winrt::Windows::Foundation::IAsyncOperation PickSingleFolderAsync(); private: diff --git a/dev/Interop/StoragePickers/Microsoft.Windows.Storage.Pickers.idl b/dev/Interop/StoragePickers/Microsoft.Windows.Storage.Pickers.idl index 54c1c2aead..880ca55eb2 100644 --- a/dev/Interop/StoragePickers/Microsoft.Windows.Storage.Pickers.idl +++ b/dev/Interop/StoragePickers/Microsoft.Windows.Storage.Pickers.idl @@ -1,11 +1,14 @@ +#include namespace Microsoft.Windows.Storage.Pickers { + [feature(Feature_StoragePickers)] enum PickerViewMode { List, Thumbnail, }; + [feature(Feature_StoragePickers)] enum PickerLocationId { DocumentsLibrary, @@ -20,11 +23,13 @@ namespace Microsoft.Windows.Storage.Pickers Unspecified, }; - runtimeclass PickFileResult + [feature(Feature_StoragePickers)] + runtimeclass PickFileResult { String Path { get; }; } + [feature(Feature_StoragePickers)] runtimeclass FileOpenPicker { FileOpenPicker(Microsoft.UI.WindowId windowId); @@ -35,10 +40,11 @@ namespace Microsoft.Windows.Storage.Pickers String CommitButtonText; Windows.Foundation.Collections.IVector FileTypeFilter{ get; }; - [remote_sync] Windows.Foundation.IAsyncOperation PickSingleFileAsync(); + Windows.Foundation.IAsyncOperation PickSingleFileAsync(); [remote_sync] Windows.Foundation.IAsyncOperation > PickMultipleFilesAsync(); } + [feature(Feature_StoragePickers)] runtimeclass FileSavePicker { FileSavePicker(Microsoft.UI.WindowId windowId); @@ -54,11 +60,13 @@ namespace Microsoft.Windows.Storage.Pickers [remote_sync] Windows.Foundation.IAsyncOperation PickSaveFileAsync(); } + [feature(Feature_StoragePickers)] runtimeclass PickFolderResult { String Path { get; }; } + [feature(Feature_StoragePickers)] runtimeclass FolderPicker { FolderPicker(Microsoft.UI.WindowId windowId); diff --git a/dev/Interop/StoragePickers/PickerCommon.cpp b/dev/Interop/StoragePickers/PickerCommon.cpp index 378396eadb..b613b21b7c 100644 --- a/dev/Interop/StoragePickers/PickerCommon.cpp +++ b/dev/Interop/StoragePickers/PickerCommon.cpp @@ -8,22 +8,22 @@ namespace { GUID HashHStringToGuid(winrt::hstring const& input) { - auto algorithmProvider = winrt::Windows::Security::Cryptography::Core::HashAlgorithmProvider::OpenAlgorithm(winrt::Windows::Security::Cryptography::Core::HashAlgorithmNames::Md5()); + auto algorithm = winrt::Windows::Security::Cryptography::Core::HashAlgorithmProvider::OpenAlgorithm(winrt::Windows::Security::Cryptography::Core::HashAlgorithmNames::Md5()); auto buffer = winrt::Windows::Security::Cryptography::CryptographicBuffer::ConvertStringToBinary(input, winrt::Windows::Security::Cryptography::BinaryStringEncoding::Utf16LE); - auto hash = algorithmProvider.HashData(buffer); + auto hash = algorithm.HashData(buffer); - if (hash.Length() != 16) + if (hash.Length() != sizeof(GUID)) { throw winrt::hresult_error(E_FAIL, L"Invalid hash length"); } - winrt::com_array resultBuffer{}; + winrt::com_array resultBuffer{ sizeof(GUID) }; winrt::Windows::Security::Cryptography::CryptographicBuffer::CopyToByteArray(hash, resultBuffer); GUID guid = *(reinterpret_cast(resultBuffer.data())); - // TODO: verify bit pattern code from copilot is correct to fit spec + // TODO: verify bit pattern code is correct to fit spec // Adjust the GUID to conform to version 3 UUID (MD5-based) guid.Data3 = (guid.Data3 & 0x0FFF) | 0x3000; // Set the version to 3 guid.Data4[0] = (guid.Data4[0] & 0x3F) | 0x80; // Set variant to RFC 4122 @@ -31,8 +31,6 @@ namespace { return guid; } - // TODO: use better winrt implementations? - // Challenge: currently winrt based Storage.KnownFolder APIs does not provide all location id we need winrt::com_ptr GetKnownFolderFromId(winrt::Microsoft::Windows::Storage::Pickers::PickerLocationId pickerLocationId) { KNOWNFOLDERID knownFolderId; @@ -75,15 +73,11 @@ namespace { winrt::hresult hr = knownFolderManager->GetFolder(knownFolderId, knownFolder.put()); if (!knownFolder) { - if (pickerLocationId == winrt::Microsoft::Windows::Storage::Pickers::PickerLocationId::DocumentsLibrary) - { - return nullptr; - } - else - { - // if the folder is not found, fallback to the Documents Library. This behavior is consistent with that of Windows.Storage.Pickers - return GetKnownFolderFromId(winrt::Microsoft::Windows::Storage::Pickers::PickerLocationId::DocumentsLibrary); - } + knownFolderManager->GetFolder(FOLDERID_Documents, knownFolder.put()); + } + if (!knownFolder) + { + return nullptr; } winrt::com_ptr defaultFolder{}; @@ -127,7 +121,6 @@ namespace { } return result; } - } @@ -137,20 +130,9 @@ namespace PickerCommon { bool IsHStringNullOrEmpty(winrt::hstring value) { - // TODO: proper handling of null string reference? return value.empty(); } - // TODO: better way to convert ShellItem a StorageFile without relying on path?. - winrt::Windows::Foundation::IAsyncOperation CreateStorageFileFromShellItem(winrt::com_ptr shellItem) - { - wil::unique_cotaskmem_string filePath; - check_hresult(shellItem->GetDisplayName(SIGDN_FILESYSPATH, &filePath)); - auto pathStr = filePath.get(); - - co_return co_await winrt::Windows::Storage::StorageFile::GetFileFromPathAsync(pathStr); - } - winrt::hstring GetPathFromShellItem(winrt::com_ptr shellItem) { wil::unique_cotaskmem_string filePath; @@ -158,15 +140,6 @@ namespace PickerCommon { return winrt::hstring{ filePath.get() }; } - - winrt::Windows::Foundation::IAsyncOperation CreateStorageFolderFromShellItem(winrt::com_ptr shellItem) - { - wil::unique_cotaskmem_string filePath; - check_hresult(shellItem->GetDisplayName(SIGDN_FILESYSPATH, &filePath)); - co_return co_await winrt::Windows::Storage::StorageFolder::GetFolderFromPathAsync(filePath.get()); - } - - std::vector CaptureFilterSpec(std::vector& buffer, winrt::Windows::Foundation::Collections::IVectorView filters) { std::vector result(filters.Size()); diff --git a/dev/Interop/StoragePickers/PickerCommon.h b/dev/Interop/StoragePickers/PickerCommon.h index 96a937b465..0ea79f0d36 100644 --- a/dev/Interop/StoragePickers/PickerCommon.h +++ b/dev/Interop/StoragePickers/PickerCommon.h @@ -2,19 +2,17 @@ #pragma once #include "pch.h" #include "ShObjIdl.h" +#include "wil/cppwinrt.h" #include "winrt/base.h" #include "winrt/Microsoft.Windows.Storage.Pickers.h" +#include "TerminalVelocityFeatures-StoragePickers.h" namespace PickerCommon { - winrt::Windows::Foundation::IAsyncOperation CreateStorageFileFromShellItem(winrt::com_ptr shellItem); - winrt::Windows::Foundation::IAsyncOperation CreateStorageFolderFromShellItem(winrt::com_ptr shellItem); - winrt::hstring GetPathFromShellItem(winrt::com_ptr shellItem); std::vector CaptureFilterSpec(std::vector& buffer, winrt::Windows::Foundation::Collections::IVectorView filters); std::vector CaptureFilterSpec(std::vector& buffer, winrt::Windows::Foundation::Collections::IMapView> filters); - // TODO: remove this if we know proper and null safe empty test for string bool IsHStringNullOrEmpty(winrt::hstring value); struct PickerParameters { diff --git a/test/StoragePickersTests/StoragePickersTests.cpp b/test/StoragePickersTests/StoragePickersTests.cpp index 3481e6b327..0d60aae6f3 100644 --- a/test/StoragePickersTests/StoragePickersTests.cpp +++ b/test/StoragePickersTests/StoragePickersTests.cpp @@ -68,10 +68,9 @@ namespace Test::StoragePickersTests //savePicker.SuggestedStartLocation(winrt::Microsoft::Windows::Storage::Pickers::PickerLocationId::DocumentsLibrary); picker.FileTypeFilter().Append(L"*"); // Act - auto fileOperation = picker.PickSingleFileAsync(); - auto file = fileOperation.get(); + auto operation = picker.PickSingleFileAsync(); + auto file = operation.get(); auto path = file.Path(); - // Assert if (file != nullptr) { From 18573ede448a995ff00129f1e36b247d023962fe Mon Sep 17 00:00:00 2001 From: Xiang Hong Date: Tue, 18 Mar 2025 14:55:30 +0800 Subject: [PATCH 30/39] code clean for merge --- WindowsAppRuntime.sln | 40 ++++- dev/Interop/StoragePickers/FileOpenPicker.cpp | 4 - .../Microsoft.Windows.Storage.Pickers.idl | 2 +- dev/Interop/StoragePickers/PickerCommon.h | 3 + .../WindowsAppRuntime_DLL.vcxproj | 2 +- dev/WindowsAppRuntime_DLL/pch.h | 10 -- test/CameraCaptureUITests/PickersAPITests.cpp | 147 ------------------ tools/adhoc-install-packages.ps1 | 36 ----- tools/postbuild.cmd | 22 --- 9 files changed, 41 insertions(+), 225 deletions(-) delete mode 100644 test/CameraCaptureUITests/PickersAPITests.cpp delete mode 100644 tools/adhoc-install-packages.ps1 delete mode 100644 tools/postbuild.cmd diff --git a/WindowsAppRuntime.sln b/WindowsAppRuntime.sln index 9f25a1b943..43b01a625c 100644 --- a/WindowsAppRuntime.sln +++ b/WindowsAppRuntime.sln @@ -77,7 +77,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DynamicDependency.DataStore EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DynamicDependency.DataStore.ProxyStub", "dev\DynamicDependencyDataStore\DynamicDependency.DataStore.ProxyStub\DynamicDependency.DataStore.ProxyStub.vcxproj", "{1A41BB90-CC34-4EDD-9A27-50714CDBC169}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DynamicDependency.DataStore.Msix", "test\DynamicDependency\data\DynamicDependency.DataStore.Msix\DynamicDependencies.DataStore.Msix.vcxproj", "{B71E818A-882E-456A-87E5-4DE4A6602B99}" +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DynamicDependencies.DataStore.Msix", "test\DynamicDependency\data\DynamicDependency.DataStore.Msix\DynamicDependencies.DataStore.Msix.vcxproj", "{B71E818A-882E-456A-87E5-4DE4A6602B99}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "DynamicDependencyLifetimeManager", "DynamicDependencyLifetimeManager", "{D043D403-31F1-43F1-B2D4-FA8F7090006D}" EndProject @@ -2354,6 +2354,38 @@ Global {7C8BEED1-7B27-41C5-A22F-9D6B4468F52A}.Release|x64.Build.0 = Release|x64 {7C8BEED1-7B27-41C5-A22F-9D6B4468F52A}.Release|x86.ActiveCfg = Release|Win32 {7C8BEED1-7B27-41C5-A22F-9D6B4468F52A}.Release|x86.Build.0 = Release|Win32 + {8E01AA4F-A16A-4E3F-A59F-6D49422B4410}.Debug|Any CPU.ActiveCfg = Debug|x64 + {8E01AA4F-A16A-4E3F-A59F-6D49422B4410}.Debug|Any CPU.Build.0 = Debug|x64 + {8E01AA4F-A16A-4E3F-A59F-6D49422B4410}.Debug|ARM64.ActiveCfg = Debug|arm64 + {8E01AA4F-A16A-4E3F-A59F-6D49422B4410}.Debug|ARM64.Build.0 = Debug|arm64 + {8E01AA4F-A16A-4E3F-A59F-6D49422B4410}.Debug|x64.ActiveCfg = Debug|x64 + {8E01AA4F-A16A-4E3F-A59F-6D49422B4410}.Debug|x64.Build.0 = Debug|x64 + {8E01AA4F-A16A-4E3F-A59F-6D49422B4410}.Debug|x86.ActiveCfg = Debug|x86 + {8E01AA4F-A16A-4E3F-A59F-6D49422B4410}.Debug|x86.Build.0 = Debug|x86 + {8E01AA4F-A16A-4E3F-A59F-6D49422B4410}.Release|Any CPU.ActiveCfg = Release|x64 + {8E01AA4F-A16A-4E3F-A59F-6D49422B4410}.Release|Any CPU.Build.0 = Release|x64 + {8E01AA4F-A16A-4E3F-A59F-6D49422B4410}.Release|ARM64.ActiveCfg = Release|arm64 + {8E01AA4F-A16A-4E3F-A59F-6D49422B4410}.Release|ARM64.Build.0 = Release|arm64 + {8E01AA4F-A16A-4E3F-A59F-6D49422B4410}.Release|x64.ActiveCfg = Release|x64 + {8E01AA4F-A16A-4E3F-A59F-6D49422B4410}.Release|x64.Build.0 = Release|x64 + {8E01AA4F-A16A-4E3F-A59F-6D49422B4410}.Release|x86.ActiveCfg = Release|x86 + {8E01AA4F-A16A-4E3F-A59F-6D49422B4410}.Release|x86.Build.0 = Release|x86 + {85C86306-46D1-4563-8303-0A79DF923586}.Debug|Any CPU.ActiveCfg = Debug|x64 + {85C86306-46D1-4563-8303-0A79DF923586}.Debug|Any CPU.Build.0 = Debug|x64 + {85C86306-46D1-4563-8303-0A79DF923586}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {85C86306-46D1-4563-8303-0A79DF923586}.Debug|ARM64.Build.0 = Debug|ARM64 + {85C86306-46D1-4563-8303-0A79DF923586}.Debug|x64.ActiveCfg = Debug|x64 + {85C86306-46D1-4563-8303-0A79DF923586}.Debug|x64.Build.0 = Debug|x64 + {85C86306-46D1-4563-8303-0A79DF923586}.Debug|x86.ActiveCfg = Debug|Win32 + {85C86306-46D1-4563-8303-0A79DF923586}.Debug|x86.Build.0 = Debug|Win32 + {85C86306-46D1-4563-8303-0A79DF923586}.Release|Any CPU.ActiveCfg = Release|x64 + {85C86306-46D1-4563-8303-0A79DF923586}.Release|Any CPU.Build.0 = Release|x64 + {85C86306-46D1-4563-8303-0A79DF923586}.Release|ARM64.ActiveCfg = Release|ARM64 + {85C86306-46D1-4563-8303-0A79DF923586}.Release|ARM64.Build.0 = Release|ARM64 + {85C86306-46D1-4563-8303-0A79DF923586}.Release|x64.ActiveCfg = Release|x64 + {85C86306-46D1-4563-8303-0A79DF923586}.Release|x64.Build.0 = Release|x64 + {85C86306-46D1-4563-8303-0A79DF923586}.Release|x86.ActiveCfg = Release|Win32 + {85C86306-46D1-4563-8303-0A79DF923586}.Release|x86.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -2549,9 +2581,6 @@ Global {4CAA3052-7FAE-4C5B-A1CB-02D7F910C991} = {AC5FFC80-92FE-4933-BED2-EC5519AC4440} {455C01F8-0A3E-42C4-9F22-13992EB909EC} = {AC5FFC80-92FE-4933-BED2-EC5519AC4440} {0FF6A68F-6C7F-4E66-8CB8-C0B9501060CA} = {8630F7AA-2969-4DC9-8700-9B468C1DC21D} - {8E01AA4F-A16A-4E3F-A59F-6D49422B4410} = {716C26A0-E6B0-4981-8412-D14A4D410531} - {A39E7B2F-5F67-47DD-8443-531D095CA7F3} = {3B706C5C-55E0-4B76-BF59-89E20FE46795} - {85C86306-46D1-4563-8303-0A79DF923586} = {8630F7AA-2969-4DC9-8700-9B468C1DC21D} {E0B0DD9F-5F0B-48A6-9D5D-132ABE480747} = {17B1F036-8FC3-49E6-9464-0C1F96CEAEB9} {152921FE-A7C0-47AF-A58D-984E6B4899AA} = {E0B0DD9F-5F0B-48A6-9D5D-132ABE480747} {EE9B5D98-8CB3-4225-BD0C-36A5BB825841} = {152921FE-A7C0-47AF-A58D-984E6B4899AA} @@ -2562,6 +2591,9 @@ Global {9369C7DD-430B-4B52-822A-231AA2791D23} = {63196919-AEA8-4EA8-BFB4-08CE824249A3} {9D26A965-065A-4897-B476-4F15B0F5A19F} = {63196919-AEA8-4EA8-BFB4-08CE824249A3} {7C8BEED1-7B27-41C5-A22F-9D6B4468F52A} = {1FDC307C-2DB7-4B40-8F18-F1057E9E0969} + {8E01AA4F-A16A-4E3F-A59F-6D49422B4410} = {716C26A0-E6B0-4981-8412-D14A4D410531} + {A39E7B2F-5F67-47DD-8443-531D095CA7F3} = {3B706C5C-55E0-4B76-BF59-89E20FE46795} + {85C86306-46D1-4563-8303-0A79DF923586} = {8630F7AA-2969-4DC9-8700-9B468C1DC21D} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {4B3D7591-CFEC-4762-9A07-ABE99938FB77} diff --git a/dev/Interop/StoragePickers/FileOpenPicker.cpp b/dev/Interop/StoragePickers/FileOpenPicker.cpp index 917c396902..8d001a5024 100644 --- a/dev/Interop/StoragePickers/FileOpenPicker.cpp +++ b/dev/Interop/StoragePickers/FileOpenPicker.cpp @@ -65,8 +65,6 @@ namespace winrt::Microsoft::Windows::Storage::Pickers::implementation winrt::Windows::Foundation::IAsyncOperation FileOpenPicker::PickSingleFileAsync() { - winrt::apartment_context ui_thread; - bool isAppPackaged = m_telemetryHelper.IsPackagedApp(); PCWSTR appName = m_telemetryHelper.GetAppName().c_str(); auto logCaptureOperation{ StoragePickersTelemetry::StoragePickersOperation::Start(isAppPackaged, appName) }; @@ -99,8 +97,6 @@ namespace winrt::Microsoft::Windows::Storage::Pickers::implementation check_hresult(dialog->GetResult(shellItem.put())); auto path = PickerCommon::GetPathFromShellItem(shellItem); - co_await ui_thread; - if (cancellationToken()) { co_return nullptr; diff --git a/dev/Interop/StoragePickers/Microsoft.Windows.Storage.Pickers.idl b/dev/Interop/StoragePickers/Microsoft.Windows.Storage.Pickers.idl index 880ca55eb2..a48fe2b5ca 100644 --- a/dev/Interop/StoragePickers/Microsoft.Windows.Storage.Pickers.idl +++ b/dev/Interop/StoragePickers/Microsoft.Windows.Storage.Pickers.idl @@ -40,7 +40,7 @@ namespace Microsoft.Windows.Storage.Pickers String CommitButtonText; Windows.Foundation.Collections.IVector FileTypeFilter{ get; }; - Windows.Foundation.IAsyncOperation PickSingleFileAsync(); + [remote_sync] Windows.Foundation.IAsyncOperation PickSingleFileAsync(); [remote_sync] Windows.Foundation.IAsyncOperation > PickMultipleFilesAsync(); } diff --git a/dev/Interop/StoragePickers/PickerCommon.h b/dev/Interop/StoragePickers/PickerCommon.h index 0ea79f0d36..72b807ba7c 100644 --- a/dev/Interop/StoragePickers/PickerCommon.h +++ b/dev/Interop/StoragePickers/PickerCommon.h @@ -6,6 +6,9 @@ #include "winrt/base.h" #include "winrt/Microsoft.Windows.Storage.Pickers.h" #include "TerminalVelocityFeatures-StoragePickers.h" +#include +#include +#include namespace PickerCommon { winrt::hstring GetPathFromShellItem(winrt::com_ptr shellItem); diff --git a/dev/WindowsAppRuntime_DLL/WindowsAppRuntime_DLL.vcxproj b/dev/WindowsAppRuntime_DLL/WindowsAppRuntime_DLL.vcxproj index d2ead9c500..7d273a7e30 100644 --- a/dev/WindowsAppRuntime_DLL/WindowsAppRuntime_DLL.vcxproj +++ b/dev/WindowsAppRuntime_DLL/WindowsAppRuntime_DLL.vcxproj @@ -104,8 +104,8 @@ - + diff --git a/dev/WindowsAppRuntime_DLL/pch.h b/dev/WindowsAppRuntime_DLL/pch.h index 62a7cec1fc..8dcd8e87ea 100644 --- a/dev/WindowsAppRuntime_DLL/pch.h +++ b/dev/WindowsAppRuntime_DLL/pch.h @@ -62,14 +62,4 @@ #include #include -#include -#include -// #include // Don't remove for now. -#include - - #define MIDL_NS_PREFIX - -// Undefine GetCurrentTime macro to prevent -// conflict with Storyboard::GetCurrentTime -#undef GetCurrentTime diff --git a/test/CameraCaptureUITests/PickersAPITests.cpp b/test/CameraCaptureUITests/PickersAPITests.cpp deleted file mode 100644 index 1ac27691ed..0000000000 --- a/test/CameraCaptureUITests/PickersAPITests.cpp +++ /dev/null @@ -1,147 +0,0 @@ -#include "pch.h" -#include "winrt\Microsoft.Windows.Storage.Pickers.h" -#include "winrt\Microsoft.Windows.Media.Capture.h" -#include -#include -#include -#include -#include -#include -#include "winrt\Microsoft.Windows.Media.Capture.h" -#include - -using namespace std::chrono_literals; -using namespace WEX::Common; -using namespace WEX::Logging; -using namespace WEX::TestExecution; -using namespace winrt::Windows::Storage; - -namespace TB = ::Test::Bootstrap; -namespace TP = ::Test::Packages; - -namespace CameraCaptureUITests -{ - // Timeout in milliseconds - class PickersAPITests - { - public: - BEGIN_TEST_CLASS(PickersAPITests) - TEST_CLASS_PROPERTY(L"ThreadingModel", L"MTA") - TEST_CLASS_PROPERTY(L"RunFixtureAs:Class", L"RestrictedUser") - //TEST_CLASS_PROPERTY(L"RunAs", L"Restricted") - TEST_CLASS_PROPERTY(L"RunAs", L"UAP") - TEST_CLASS_PROPERTY(L"UAP:AppxManifest", L"CameraCaptureUI-AppxManifest.xml") - END_TEST_CLASS() - - TEST_CLASS_SETUP(ClassInit) - { - ::Test::Bootstrap::SetupPackages(); - return true; - } - - TEST_CLASS_CLEANUP(ClassUninit) - { - ::Test::Bootstrap::CleanupPackages(); - return true; - } - - TEST_METHOD_SETUP(MethodInit) - { - VERIFY_IS_TRUE(TP::IsPackageRegistered_WindowsAppRuntimeFramework()); - return true; - } - - TEST_METHOD_CLEANUP(MethodUninit) - { - VERIFY_IS_TRUE(TP::IsPackageRegistered_WindowsAppRuntimeFramework()); - return true; - } - - // The unit tests will be updated,first test might is there for testing purpose locally. - // Focusing solely on functional tests for now. - TEST_METHOD(CapturePhoto_ShouldReturnFile_Desktop) - { - if (!::Microsoft::Windows::Media::Capture::Feature_CameraCaptureUI::IsEnabled()) - { - Log::Result(TestResults::Skipped, L"CameraCaptureUI API Features are not enabled."); - return; - } - try - { - auto parentWindow = ::GetForegroundWindow(); - winrt::Microsoft::UI::WindowId windowId{ reinterpret_cast(parentWindow) }; - winrt::Microsoft::Windows::Media::Capture::CameraCaptureUI cameraUI(windowId); - return; - // Configure Photo Settings - cameraUI.PhotoSettings().Format(winrt::Microsoft::Windows::Media::Capture::CameraCaptureUIPhotoFormat::Png); - cameraUI.PhotoSettings().AllowCropping(false); - // Act - auto photoOperation = cameraUI.CaptureFileAsync(winrt::Microsoft::Windows::Media::Capture::CameraCaptureUIMode::Photo); - auto photo = photoOperation.get(); - - // Assert - if (photo != nullptr) - { - Log::Comment(L"Photo capture was successful."); - VERIFY_IS_TRUE(photo.Name().c_str() != nullptr); - } - else - { - Log::Error(L"Photo capture failed or was canceled."); - VERIFY_FAIL(L"Photo capture returned null."); - } - } - catch (const winrt::hresult_error& ex) - { - Log::Error((std::wstring(L"Exception thrown: ") + ex.message().c_str()).c_str()); - VERIFY_FAIL(L"Exception occurred during photo capture."); - } - catch (const std::exception& ex) - { - Log::Error((std::wstring(L"Standard exception thrown: ") + winrt::to_hstring(ex.what()).c_str()).c_str()); - VERIFY_FAIL(L"Standard exception occurred during photo capture."); - } - } - - TEST_METHOD(FileSavePicker_ShouldCreateNewFile) - { - try - { - auto parentWindow = ::GetForegroundWindow(); - winrt::Microsoft::UI::WindowId windowId{ reinterpret_cast(parentWindow) }; - //{ - // winrt::Microsoft::Windows::Media::Capture::CameraCaptureUI cameraUI(windowId); - //} - winrt::Microsoft::Windows::Storage::Pickers::FileSavePicker savePicker(windowId); - //savePicker.SuggestedStartLocation(winrt::Microsoft::Windows::Storage::Pickers::PickerLocationId::DocumentsLibrary); - savePicker.FileTypeChoices().Insert(L"Plain Text", winrt::single_threaded_vector({ L".txt" })); - savePicker.SuggestedFileName(L"test.txt"); - // Act - auto fileOperation = savePicker.PickSaveFileAsync(); - auto file = fileOperation.get(); - - // Assert - if (file != nullptr) - { - Log::Comment(L"File save was successful."); - VERIFY_IS_TRUE(file.Name().c_str() != nullptr); - } - else - { - Log::Error(L"Photo capture failed or was canceled."); - VERIFY_FAIL(L"File save returned null."); - } - } - catch (const winrt::hresult_error& ex) - { - Log::Error((std::wstring(L"Exception thrown: ") + ex.message().c_str()).c_str()); - VERIFY_FAIL(L"Exception occurred during photo capture."); - } - catch (const std::exception& ex) - { - Log::Error((std::wstring(L"Standard exception thrown: ") + winrt::to_hstring(ex.what()).c_str()).c_str()); - VERIFY_FAIL(L"Standard exception occurred during photo capture."); - } - } - }; -} diff --git a/tools/adhoc-install-packages.ps1 b/tools/adhoc-install-packages.ps1 deleted file mode 100644 index 3533c3bf6a..0000000000 --- a/tools/adhoc-install-packages.ps1 +++ /dev/null @@ -1,36 +0,0 @@ -cd Packages # for instance, C:\ado\WindowsAppSDK\Packages - -# Define the source and destination paths for all versions -$sourcePaths = @( - "Microsoft.FrameworkUdk.1.8.0-CI-26107.1720.241003-1631.3", - "Microsoft.FrameworkUdk.1.8.0-CI-26107.1728.241202-0947.0", - "Microsoft.FrameworkUdk.1.8.0-CI-26107.1730.241212-1315.0", - "Microsoft.ProjectReunion.InteractiveExperiences.TransportPackage.1.8.0-CI-26107.1720.241003-1631.3", - "Microsoft.ProjectReunion.InteractiveExperiences.TransportPackage.1.8.0-CI-26107.1728.241202-0947.0", - "Microsoft.ProjectReunion.InteractiveExperiences.TransportPackage.1.8.0-CI-26107.1730.241212-1315.0" -) - -# Loop through each source path and copy the content to the corresponding destination path - -foreach ($sourcePath in $sourcePaths) { - # Extract the root directory and version from the source path - $rootDir = $sourcePath -replace "\.\d.*", "" - $version = $sourcePath -replace "$rootDir\.", "" - $destinationPath = "$rootDir/$version" - - # Create the root directory if it doesn't exist - if (-Not (Test-Path -Path $rootDir)) { - New-Item -ItemType Directory -Path $rootDir - } - - # Create the versioned directory inside the destination directory if it doesn't exist - if (-Not (Test-Path -Path $destinationPath)) { - New-Item -ItemType Directory -Path $destinationPath - } - - # Copy the content from the source directory to the destination directory - Copy-Item -Path "$sourcePath\*" -Destination $destinationPath -Recurse -Force - - Write-Output "Content copied from $sourcePath to $destinationPath successfully." - -} \ No newline at end of file diff --git a/tools/postbuild.cmd b/tools/postbuild.cmd deleted file mode 100644 index d0465d59d2..0000000000 --- a/tools/postbuild.cmd +++ /dev/null @@ -1,22 +0,0 @@ -REM execute this script from the root directory of WindowAppSDK repository - -@echo off - -copy "BuildOutput\Microsoft.WindowsAppSDK.Foundation.TransportPackage.1.1.1.1.nupkg" "..\WindowsAppSDKAggregator\localpackages\Microsoft.WindowsAppSDK.Foundation.TransportPackage.1.1.1.1.nupkg" - -REM if exist, delete "BuildOutput\Microsoft.WindowsAppSDK.Foundation.TransportPackage.1.1.1.1.zip" -if exist "BuildOutput\Microsoft.WindowsAppSDK.Foundation.TransportPackage.1.1.1.1.zip" ( - del "BuildOutput\Microsoft.WindowsAppSDK.Foundation.TransportPackage.1.1.1.1.zip" -) - -REM Step 1: duplicate a .zip file from .nupkg -copy "BuildOutput\Microsoft.WindowsAppSDK.Foundation.TransportPackage.1.1.1.1.nupkg" "BuildOutput\Microsoft.WindowsAppSDK.Foundation.TransportPackage.1.1.1.1.zip" - -REM Step 2: Clear content in the target directory -rd /s /q "..\WindowsAppSDKAggregator\build\packages\Microsoft.WindowsAppSDK.Foundation.TransportPackage.1.1.1.1" -md "..\WindowsAppSDKAggregator\build\packages\Microsoft.WindowsAppSDK.Foundation.TransportPackage.1.1.1.1" - -REM Step 3: Extract contents of the .zip file into the target directory -powershell -command "Expand-Archive -Path 'BuildOutput\Microsoft.WindowsAppSDK.Foundation.TransportPackage.1.1.1.1.zip' -DestinationPath '..\WindowsAppSDKAggregator\build\packages\Microsoft.WindowsAppSDK.Foundation.TransportPackage.1.1.1.1' -Force" - -echo Done \ No newline at end of file From 52768036ee2a5c92e2fa2e6e9ca8cd56ef1f92fa Mon Sep 17 00:00:00 2001 From: Xiang Hong Date: Tue, 18 Mar 2025 15:55:01 +0800 Subject: [PATCH 31/39] update taef version --- test/StoragePickersTests/packages.config | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/StoragePickersTests/packages.config b/test/StoragePickersTests/packages.config index 63e5716140..1a51bd1772 100644 --- a/test/StoragePickersTests/packages.config +++ b/test/StoragePickersTests/packages.config @@ -1,6 +1,6 @@  - + From 147cb88f31471a503b3cd957ac522cec3152e747 Mon Sep 17 00:00:00 2001 From: Xiang Hong Date: Tue, 18 Mar 2025 16:14:14 +0800 Subject: [PATCH 32/39] fixing com_array initialization --- dev/Interop/StoragePickers/PickerCommon.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/dev/Interop/StoragePickers/PickerCommon.cpp b/dev/Interop/StoragePickers/PickerCommon.cpp index b613b21b7c..59ccf703d0 100644 --- a/dev/Interop/StoragePickers/PickerCommon.cpp +++ b/dev/Interop/StoragePickers/PickerCommon.cpp @@ -19,7 +19,7 @@ namespace { throw winrt::hresult_error(E_FAIL, L"Invalid hash length"); } - winrt::com_array resultBuffer{ sizeof(GUID) }; + winrt::com_array resultBuffer(sizeof(GUID)); winrt::Windows::Security::Cryptography::CryptographicBuffer::CopyToByteArray(hash, resultBuffer); GUID guid = *(reinterpret_cast(resultBuffer.data())); @@ -136,7 +136,7 @@ namespace PickerCommon { winrt::hstring GetPathFromShellItem(winrt::com_ptr shellItem) { wil::unique_cotaskmem_string filePath; - check_hresult(shellItem->GetDisplayName(SIGDN_FILESYSPATH, &filePath)); + check_hresult(shellItem->GetDisplayName(SIGDN_FILESYSPATH, filePath.put())); return winrt::hstring{ filePath.get() }; } @@ -167,7 +167,7 @@ namespace PickerCommon { { std::vector result(filters.Size()); buffer.clear(); - buffer.reserve(filters.Size() * (size_t)2); + buffer.reserve(filters.Size() * 2ull); for (const auto& filter : filters) { @@ -180,7 +180,7 @@ namespace PickerCommon { result.at(i) = { buffer.at(i * 2).c_str(), buffer.at(i * 2 + 1).c_str() }; } - if (result.size() == 0) + if (result.empty()) { result.push_back({ L"All Files", L"*.*" }); } @@ -206,6 +206,6 @@ namespace PickerCommon { check_hresult(dialog->SetDefaultFolder(defaultFolder.get())); } - check_hresult(dialog->SetFileTypes(FileTypeFilterPara.size(), FileTypeFilterPara.data())); + check_hresult(dialog->SetFileTypes((UINT)FileTypeFilterPara.size(), FileTypeFilterPara.data())); } } From 02f902404ed23b35d56cfaad5949b07106c592ad Mon Sep 17 00:00:00 2001 From: Xiang Hong Date: Tue, 18 Mar 2025 17:15:52 +0800 Subject: [PATCH 33/39] remove unexpected change --- WindowsAppRuntime.sln | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/WindowsAppRuntime.sln b/WindowsAppRuntime.sln index 43b01a625c..e79cd9d891 100644 --- a/WindowsAppRuntime.sln +++ b/WindowsAppRuntime.sln @@ -77,7 +77,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DynamicDependency.DataStore EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DynamicDependency.DataStore.ProxyStub", "dev\DynamicDependencyDataStore\DynamicDependency.DataStore.ProxyStub\DynamicDependency.DataStore.ProxyStub.vcxproj", "{1A41BB90-CC34-4EDD-9A27-50714CDBC169}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DynamicDependencies.DataStore.Msix", "test\DynamicDependency\data\DynamicDependency.DataStore.Msix\DynamicDependencies.DataStore.Msix.vcxproj", "{B71E818A-882E-456A-87E5-4DE4A6602B99}" +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DynamicDependency.DataStore.Msix", "test\DynamicDependency\data\DynamicDependency.DataStore.Msix\DynamicDependencies.DataStore.Msix.vcxproj", "{B71E818A-882E-456A-87E5-4DE4A6602B99}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "DynamicDependencyLifetimeManager", "DynamicDependencyLifetimeManager", "{D043D403-31F1-43F1-B2D4-FA8F7090006D}" EndProject From 16fe020bfe7fdfefebfee7b2ad9a14ed309f5e5e Mon Sep 17 00:00:00 2001 From: Xiang Hong Date: Tue, 18 Mar 2025 18:04:21 +0800 Subject: [PATCH 34/39] update copyright headers --- dev/Interop/StoragePickers/FileOpenPicker.cpp | 3 +++ dev/Interop/StoragePickers/FileOpenPicker.h | 3 +++ dev/Interop/StoragePickers/FileSavePicker.cpp | 3 +++ dev/Interop/StoragePickers/FileSavePicker.h | 3 +++ dev/Interop/StoragePickers/FolderPicker.cpp | 3 +++ dev/Interop/StoragePickers/FolderPicker.h | 3 +++ .../StoragePickers/Microsoft.Windows.Storage.Pickers.idl | 3 +++ dev/Interop/StoragePickers/PickFileResult.cpp | 3 +++ dev/Interop/StoragePickers/PickFileResult.h | 3 +++ dev/Interop/StoragePickers/PickFolderResult.cpp | 3 +++ dev/Interop/StoragePickers/PickFolderResult.h | 3 +++ dev/Interop/StoragePickers/PickerCommon.cpp | 3 +++ dev/Interop/StoragePickers/PickerCommon.h | 4 +++- 13 files changed, 39 insertions(+), 1 deletion(-) diff --git a/dev/Interop/StoragePickers/FileOpenPicker.cpp b/dev/Interop/StoragePickers/FileOpenPicker.cpp index 8d001a5024..d986dfd5b9 100644 --- a/dev/Interop/StoragePickers/FileOpenPicker.cpp +++ b/dev/Interop/StoragePickers/FileOpenPicker.cpp @@ -1,3 +1,6 @@ +// Copyright (c) Microsoft Corporation and Contributors. +// Licensed under the MIT License. + #include "pch.h" #include "FileOpenPicker.h" #include "Microsoft.Windows.Storage.Pickers.FileOpenPicker.g.cpp" diff --git a/dev/Interop/StoragePickers/FileOpenPicker.h b/dev/Interop/StoragePickers/FileOpenPicker.h index 50dce02ba3..36b6028de6 100644 --- a/dev/Interop/StoragePickers/FileOpenPicker.h +++ b/dev/Interop/StoragePickers/FileOpenPicker.h @@ -1,3 +1,6 @@ +// Copyright (c) Microsoft Corporation and Contributors. +// Licensed under the MIT License. + #pragma once #include "Microsoft.Windows.Storage.Pickers.FileOpenPicker.g.h" #include "PickerCommon.h" diff --git a/dev/Interop/StoragePickers/FileSavePicker.cpp b/dev/Interop/StoragePickers/FileSavePicker.cpp index 8301e1aa7f..d1e317f52a 100644 --- a/dev/Interop/StoragePickers/FileSavePicker.cpp +++ b/dev/Interop/StoragePickers/FileSavePicker.cpp @@ -1,3 +1,6 @@ +// Copyright (c) Microsoft Corporation and Contributors. +// Licensed under the MIT License. + #include "pch.h" #include "FileSavePicker.h" #include "Microsoft.Windows.Storage.Pickers.FileSavePicker.g.cpp" diff --git a/dev/Interop/StoragePickers/FileSavePicker.h b/dev/Interop/StoragePickers/FileSavePicker.h index 2ad466c1e6..9cf419c7b6 100644 --- a/dev/Interop/StoragePickers/FileSavePicker.h +++ b/dev/Interop/StoragePickers/FileSavePicker.h @@ -1,3 +1,6 @@ +// Copyright (c) Microsoft Corporation and Contributors. +// Licensed under the MIT License. + #pragma once #include "Microsoft.Windows.Storage.Pickers.FileSavePicker.g.h" #include "PickerCommon.h" diff --git a/dev/Interop/StoragePickers/FolderPicker.cpp b/dev/Interop/StoragePickers/FolderPicker.cpp index 4f8a04fe53..432d0b38bb 100644 --- a/dev/Interop/StoragePickers/FolderPicker.cpp +++ b/dev/Interop/StoragePickers/FolderPicker.cpp @@ -1,3 +1,6 @@ +// Copyright (c) Microsoft Corporation and Contributors. +// Licensed under the MIT License. + #include "pch.h" #include "FolderPicker.h" #include "Microsoft.Windows.Storage.Pickers.FolderPicker.g.cpp" diff --git a/dev/Interop/StoragePickers/FolderPicker.h b/dev/Interop/StoragePickers/FolderPicker.h index 5f79ca7c29..00026ff7f1 100644 --- a/dev/Interop/StoragePickers/FolderPicker.h +++ b/dev/Interop/StoragePickers/FolderPicker.h @@ -1,3 +1,6 @@ +// Copyright (c) Microsoft Corporation and Contributors. +// Licensed under the MIT License. + #pragma once #include "Microsoft.Windows.Storage.Pickers.FolderPicker.g.h" #include "PickerCommon.h" diff --git a/dev/Interop/StoragePickers/Microsoft.Windows.Storage.Pickers.idl b/dev/Interop/StoragePickers/Microsoft.Windows.Storage.Pickers.idl index a48fe2b5ca..55a64b4fe8 100644 --- a/dev/Interop/StoragePickers/Microsoft.Windows.Storage.Pickers.idl +++ b/dev/Interop/StoragePickers/Microsoft.Windows.Storage.Pickers.idl @@ -1,3 +1,6 @@ +// Copyright (c) Microsoft Corporation and Contributors. +// Licensed under the MIT License. + #include namespace Microsoft.Windows.Storage.Pickers { diff --git a/dev/Interop/StoragePickers/PickFileResult.cpp b/dev/Interop/StoragePickers/PickFileResult.cpp index 6822c37efc..c2029e3757 100644 --- a/dev/Interop/StoragePickers/PickFileResult.cpp +++ b/dev/Interop/StoragePickers/PickFileResult.cpp @@ -1,3 +1,6 @@ +// Copyright (c) Microsoft Corporation and Contributors. +// Licensed under the MIT License. + #include "pch.h" #include "PickFileResult.h" #include "Microsoft.Windows.Storage.Pickers.PickFileResult.g.cpp" diff --git a/dev/Interop/StoragePickers/PickFileResult.h b/dev/Interop/StoragePickers/PickFileResult.h index c980f50544..36e6dee336 100644 --- a/dev/Interop/StoragePickers/PickFileResult.h +++ b/dev/Interop/StoragePickers/PickFileResult.h @@ -1,3 +1,6 @@ +// Copyright (c) Microsoft Corporation and Contributors. +// Licensed under the MIT License. + #pragma once #include "Microsoft.Windows.Storage.Pickers.PickFileResult.g.h" #include "PickerCommon.h" diff --git a/dev/Interop/StoragePickers/PickFolderResult.cpp b/dev/Interop/StoragePickers/PickFolderResult.cpp index 83033913b8..2e61733811 100644 --- a/dev/Interop/StoragePickers/PickFolderResult.cpp +++ b/dev/Interop/StoragePickers/PickFolderResult.cpp @@ -1,3 +1,6 @@ +// Copyright (c) Microsoft Corporation and Contributors. +// Licensed under the MIT License. + #include "pch.h" #include "PickFolderResult.h" #include "Microsoft.Windows.Storage.Pickers.PickFolderResult.g.cpp" diff --git a/dev/Interop/StoragePickers/PickFolderResult.h b/dev/Interop/StoragePickers/PickFolderResult.h index eee9f0f02b..3fa4c827ed 100644 --- a/dev/Interop/StoragePickers/PickFolderResult.h +++ b/dev/Interop/StoragePickers/PickFolderResult.h @@ -1,3 +1,6 @@ +// Copyright (c) Microsoft Corporation and Contributors. +// Licensed under the MIT License. + #pragma once #include "Microsoft.Windows.Storage.Pickers.PickFolderResult.g.h" #include "PickerCommon.h" diff --git a/dev/Interop/StoragePickers/PickerCommon.cpp b/dev/Interop/StoragePickers/PickerCommon.cpp index 59ccf703d0..fc555a230a 100644 --- a/dev/Interop/StoragePickers/PickerCommon.cpp +++ b/dev/Interop/StoragePickers/PickerCommon.cpp @@ -1,3 +1,6 @@ +// Copyright (c) Microsoft Corporation and Contributors. +// Licensed under the MIT License. + #include "pch.h" #include "PickerCommon.h" #include diff --git a/dev/Interop/StoragePickers/PickerCommon.h b/dev/Interop/StoragePickers/PickerCommon.h index 72b807ba7c..515d520fe1 100644 --- a/dev/Interop/StoragePickers/PickerCommon.h +++ b/dev/Interop/StoragePickers/PickerCommon.h @@ -1,4 +1,6 @@ -// TODO: use better namespace, maybe anonymous namespace? +// Copyright (c) Microsoft Corporation and Contributors. +// Licensed under the MIT License. + #pragma once #include "pch.h" #include "ShObjIdl.h" From 0d01aa8bb0bc7db980b7c1a2d6fe3320d8007b06 Mon Sep 17 00:00:00 2001 From: Xiang Hong Date: Tue, 18 Mar 2025 18:41:06 +0800 Subject: [PATCH 35/39] code clean and minor test text fixes --- dev/Interop/StoragePickers/PickerCommon.cpp | 1 - dev/Interop/StoragePickers/readme.txt | 27 ------------------- .../StoragePickersTests.cpp | 7 +++-- 3 files changed, 3 insertions(+), 32 deletions(-) delete mode 100644 dev/Interop/StoragePickers/readme.txt diff --git a/dev/Interop/StoragePickers/PickerCommon.cpp b/dev/Interop/StoragePickers/PickerCommon.cpp index fc555a230a..46922d3768 100644 --- a/dev/Interop/StoragePickers/PickerCommon.cpp +++ b/dev/Interop/StoragePickers/PickerCommon.cpp @@ -26,7 +26,6 @@ namespace { winrt::Windows::Security::Cryptography::CryptographicBuffer::CopyToByteArray(hash, resultBuffer); GUID guid = *(reinterpret_cast(resultBuffer.data())); - // TODO: verify bit pattern code is correct to fit spec // Adjust the GUID to conform to version 3 UUID (MD5-based) guid.Data3 = (guid.Data3 & 0x0FFF) | 0x3000; // Set the version to 3 guid.Data4[0] = (guid.Data4[0] & 0x3F) | 0x80; // Set variant to RFC 4122 diff --git a/dev/Interop/StoragePickers/readme.txt b/dev/Interop/StoragePickers/readme.txt deleted file mode 100644 index 66c1579928..0000000000 --- a/dev/Interop/StoragePickers/readme.txt +++ /dev/null @@ -1,27 +0,0 @@ -======================================================================== - Microsoft.Windows.Storage.Pickers Project Overview -======================================================================== - -This project demonstrates how to get started authoring Windows Runtime -classes directly with standard C++, using the Windows App SDK and -C++/WinRT packages to generate implementation headers from interface -(IDL) files. The generated Windows Runtime component binary and WinMD -files should then be bundled with the app consuming them. - -Steps: -1. Create an interface (IDL) file to define your Windows Runtime class, - its default interface, and any other interfaces it implements. -2. Build the project once to generate module.g.cpp, module.h.cpp, and - implementation templates under the "Generated Files" folder, as - well as skeleton class definitions under "Generated Files\sources". -3. Use the skeleton class definitions for reference to implement your - Windows Runtime classes. - -======================================================================== -Learn more about Windows App SDK here: -https://docs.microsoft.com/windows/apps/windows-app-sdk/ -Learn more about WinUI3 here: -https://docs.microsoft.com/windows/apps/winui/winui3/ -Learn more about C++/WinRT here: -http://aka.ms/cppwinrt/ -======================================================================== diff --git a/test/StoragePickersTests/StoragePickersTests.cpp b/test/StoragePickersTests/StoragePickersTests.cpp index 0d60aae6f3..64af50f82b 100644 --- a/test/StoragePickersTests/StoragePickersTests.cpp +++ b/test/StoragePickersTests/StoragePickersTests.cpp @@ -65,7 +65,6 @@ namespace Test::StoragePickersTests auto parentWindow = ::GetForegroundWindow(); winrt::Microsoft::UI::WindowId windowId{ reinterpret_cast(parentWindow) }; winrt::Microsoft::Windows::Storage::Pickers::FileOpenPicker picker{ windowId }; - //savePicker.SuggestedStartLocation(winrt::Microsoft::Windows::Storage::Pickers::PickerLocationId::DocumentsLibrary); picker.FileTypeFilter().Append(L"*"); // Act auto operation = picker.PickSingleFileAsync(); @@ -115,18 +114,18 @@ namespace Test::StoragePickersTests } else { - Log::Error(L"Photo capture failed or was canceled."); + Log::Error(L"File save failed or was canceled."); } } catch (const winrt::hresult_error& ex) { Log::Error((std::wstring(L"Exception thrown: ") + ex.message().c_str()).c_str()); - VERIFY_FAIL(L"Exception occurred during photo capture."); + VERIFY_FAIL(L"Exception occurred during file save picker."); } catch (const std::exception& ex) { Log::Error((std::wstring(L"Standard exception thrown: ") + winrt::to_hstring(ex.what()).c_str()).c_str()); - VERIFY_FAIL(L"Standard exception occurred during photo capture."); + VERIFY_FAIL(L"Standard exception occurred during file save picker."); } } }; From 7765fa6a31bf02c3dcf8755d053408d0f3fe8b65 Mon Sep 17 00:00:00 2001 From: Xiang Hong Date: Mon, 24 Mar 2025 11:32:29 +0800 Subject: [PATCH 36/39] comment out tests require manual interactive, adding more basic property based tests --- .../StoragePickersTests.cpp | 79 +++++++++++++++++++ 1 file changed, 79 insertions(+) diff --git a/test/StoragePickersTests/StoragePickersTests.cpp b/test/StoragePickersTests/StoragePickersTests.cpp index 64af50f82b..36ee8290a0 100644 --- a/test/StoragePickersTests/StoragePickersTests.cpp +++ b/test/StoragePickersTests/StoragePickersTests.cpp @@ -57,6 +57,11 @@ namespace Test::StoragePickersTests ::Test::Bootstrap::CleanupBootstrap(); return true; } + // The unit tests will be updated,first test might is there for testing purpose locally. + // Focusing solely on functional tests for now. + + // Commenting out this test as it is an E2E scenario test that requires UI automation for pipeline execution. + /* TEST_METHOD(FileOpenPicker_ShouldPickFile) { @@ -128,5 +133,79 @@ namespace Test::StoragePickersTests VERIFY_FAIL(L"Standard exception occurred during file save picker."); } } + + */ + + + TEST_METHOD(VerifyFileOpenPickerOptionsAreReadCorrectly) + { + auto parentWindow = ::GetForegroundWindow(); + winrt::Microsoft::UI::WindowId windowId{ reinterpret_cast(parentWindow) }; + winrt::Microsoft::Windows::Storage::Pickers::FileOpenPicker picker(windowId); + + picker.ViewMode(winrt::Microsoft::Windows::Storage::Pickers::PickerViewMode::List); + VERIFY_ARE_EQUAL(picker.ViewMode(), winrt::Microsoft::Windows::Storage::Pickers::PickerViewMode::List); + + picker.ViewMode(winrt::Microsoft::Windows::Storage::Pickers::PickerViewMode::Thumbnail); + VERIFY_ARE_EQUAL(picker.ViewMode(), winrt::Microsoft::Windows::Storage::Pickers::PickerViewMode::Thumbnail); + + picker.SettingsIdentifier(L"id"); + VERIFY_ARE_EQUAL(picker.SettingsIdentifier(), L"id"); + + picker.SuggestedStartLocation(winrt::Microsoft::Windows::Storage::Pickers::PickerLocationId::DocumentsLibrary); + VERIFY_ARE_EQUAL(picker.SuggestedStartLocation(), winrt::Microsoft::Windows::Storage::Pickers::PickerLocationId::DocumentsLibrary); + + picker.CommitButtonText(L"commit"); + VERIFY_ARE_EQUAL(picker.CommitButtonText(), L"commit"); + + picker.FileTypeFilter().Append(L"*"); + VERIFY_ARE_EQUAL(picker.FileTypeFilter().GetAt(0), L"*"); + } + + TEST_METHOD(VerifyFileSavePickerOptionsAreReadCorrectly) + { + auto parentWindow = ::GetForegroundWindow(); + winrt::Microsoft::UI::WindowId windowId{ reinterpret_cast(parentWindow) }; + winrt::Microsoft::Windows::Storage::Pickers::FileSavePicker picker(windowId); + + picker.SettingsIdentifier(L"id"); + VERIFY_ARE_EQUAL(picker.SettingsIdentifier(), L"id"); + + picker.SuggestedStartLocation(winrt::Microsoft::Windows::Storage::Pickers::PickerLocationId::DocumentsLibrary); + VERIFY_ARE_EQUAL(picker.SuggestedStartLocation(), winrt::Microsoft::Windows::Storage::Pickers::PickerLocationId::DocumentsLibrary); + + picker.CommitButtonText(L"commit"); + VERIFY_ARE_EQUAL(picker.CommitButtonText(), L"commit"); + + auto filters = winrt::single_threaded_vector(); + filters.Append(L"*"); + picker.FileTypeChoices().Insert(L"All Files", filters ); + VERIFY_ARE_EQUAL(picker.FileTypeChoices().Lookup(L"All Files").GetAt(0), L"*"); + } + + TEST_METHOD(VerifyFolderPickerOptionsAreReadCorrectly) + { + auto parentWindow = ::GetForegroundWindow(); + winrt::Microsoft::UI::WindowId windowId{ reinterpret_cast(parentWindow) }; + winrt::Microsoft::Windows::Storage::Pickers::FolderPicker picker(windowId); + + picker.ViewMode(winrt::Microsoft::Windows::Storage::Pickers::PickerViewMode::List); + VERIFY_ARE_EQUAL(picker.ViewMode(), winrt::Microsoft::Windows::Storage::Pickers::PickerViewMode::List); + + picker.ViewMode(winrt::Microsoft::Windows::Storage::Pickers::PickerViewMode::Thumbnail); + VERIFY_ARE_EQUAL(picker.ViewMode(), winrt::Microsoft::Windows::Storage::Pickers::PickerViewMode::Thumbnail); + + picker.SettingsIdentifier(L"id"); + VERIFY_ARE_EQUAL(picker.SettingsIdentifier(), L"id"); + + picker.SuggestedStartLocation(winrt::Microsoft::Windows::Storage::Pickers::PickerLocationId::DocumentsLibrary); + VERIFY_ARE_EQUAL(picker.SuggestedStartLocation(), winrt::Microsoft::Windows::Storage::Pickers::PickerLocationId::DocumentsLibrary); + + picker.CommitButtonText(L"commit"); + VERIFY_ARE_EQUAL(picker.CommitButtonText(), L"commit"); + + picker.FileTypeFilter().Append(L"*"); + VERIFY_ARE_EQUAL(picker.FileTypeFilter().GetAt(0), L"*"); + } }; } From a8db2c8542fbad968976d6df80e19f112ba601e2 Mon Sep 17 00:00:00 2001 From: Dinah Gao Date: Mon, 24 Mar 2025 18:35:46 +0800 Subject: [PATCH 37/39] add telemetry --- dev/Common/StoragePickersTelemetryHelper.h | 92 ++++++++++++++ dev/Interop/StoragePickers/FileOpenPicker.cpp | 33 +++++- dev/Interop/StoragePickers/FileOpenPicker.h | 4 +- dev/Interop/StoragePickers/FileSavePicker.cpp | 11 +- dev/Interop/StoragePickers/FileSavePicker.h | 2 + dev/Interop/StoragePickers/FolderPicker.cpp | 12 +- dev/Interop/StoragePickers/FolderPicker.h | 4 +- .../StoragePickers/StoragePickersTelemetry.h | 112 ++++++++++++++++-- 8 files changed, 252 insertions(+), 18 deletions(-) create mode 100644 dev/Common/StoragePickersTelemetryHelper.h diff --git a/dev/Common/StoragePickersTelemetryHelper.h b/dev/Common/StoragePickersTelemetryHelper.h new file mode 100644 index 0000000000..fae7f391d6 --- /dev/null +++ b/dev/Common/StoragePickersTelemetryHelper.h @@ -0,0 +1,92 @@ +// Copyright (c) Microsoft Corporation and Contributors. +// Licensed under the MIT License. +#pragma once + +#include "TelemetryHelper.h" +#include // For IsUserAnAdmin +#include // For process APIs +#include + +class StoragePickersTelemetryHelper : public TelemetryHelper +{ +public: + StoragePickersTelemetryHelper() : TelemetryHelper() + { + m_asAdmin = IsAsAdmin(); + m_inContainer = IsInContainer(); + } + + inline bool IsRunningAsAdmin() const + { + return m_asAdmin; + } + + inline bool IsRunningInContainer() const + { + return m_inContainer; + } + +private: + bool m_asAdmin; + bool m_inContainer; + + BOOL IsAsAdmin() + { + BOOL fIsRunAsAdmin = FALSE; + DWORD dwError = ERROR_SUCCESS; + PSID pAdministratorsGroup = NULL; + + // Allocate and initialize a SID of the administrators group. + SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY; + if (!AllocateAndInitializeSid(&NtAuthority, 2, + SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, + 0, 0, 0, 0, 0, 0, + &pAdministratorsGroup)) + { + dwError = GetLastError(); + } + else + { + // Determine whether the SID of administrators group is enabled in + // the primary access token of the process. + if (!CheckTokenMembership(NULL, pAdministratorsGroup, &fIsRunAsAdmin)) + { + dwError = GetLastError(); + } + + FreeSid(pAdministratorsGroup); + } + + return fIsRunAsAdmin; + } + + BOOL IsInContainer() + { + BOOL fIsInSandbox = FALSE; + DWORD dwError = ERROR_SUCCESS; + + // Get the process token + HANDLE hToken = NULL; + if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken)) + { + dwError = GetLastError(); + return FALSE; + } + + // Check if the process is running in an AppContainer + DWORD dwIsAppContainer = 0; + DWORD dwSize = sizeof(dwIsAppContainer); + BOOL ans = GetTokenInformation(hToken, TokenIsAppContainer, &dwIsAppContainer, dwSize, &dwSize); + if (!ans) + { + dwError = GetLastError(); + CloseHandle(hToken); + return FALSE; + } + + fIsInSandbox = (dwIsAppContainer != 0); + + CloseHandle(hToken); + return fIsInSandbox; + } +}; diff --git a/dev/Interop/StoragePickers/FileOpenPicker.cpp b/dev/Interop/StoragePickers/FileOpenPicker.cpp index d986dfd5b9..1654489fc5 100644 --- a/dev/Interop/StoragePickers/FileOpenPicker.cpp +++ b/dev/Interop/StoragePickers/FileOpenPicker.cpp @@ -68,9 +68,7 @@ namespace winrt::Microsoft::Windows::Storage::Pickers::implementation winrt::Windows::Foundation::IAsyncOperation FileOpenPicker::PickSingleFileAsync() { - bool isAppPackaged = m_telemetryHelper.IsPackagedApp(); - PCWSTR appName = m_telemetryHelper.GetAppName().c_str(); - auto logCaptureOperation{ StoragePickersTelemetry::StoragePickersOperation::Start(isAppPackaged, appName) }; + auto logTelemetry{ StoragePickersTelemetry::FileOpenPickerPickSingleFile::Start(m_telemetryHelper) }; PickerCommon::PickerParameters parameters{}; @@ -81,6 +79,7 @@ namespace winrt::Microsoft::Windows::Storage::Pickers::implementation auto cancellationToken = co_await winrt::get_cancellation_token(); if (cancellationToken()) { + logTelemetry.Stop(m_telemetryHelper, false); co_return nullptr; } @@ -92,6 +91,7 @@ namespace winrt::Microsoft::Windows::Storage::Pickers::implementation auto hr = dialog->Show(parameters.HWnd); if (FAILED(hr) || cancellationToken()) { + logTelemetry.Stop(m_telemetryHelper, false); co_return nullptr; } } @@ -102,13 +102,20 @@ namespace winrt::Microsoft::Windows::Storage::Pickers::implementation if (cancellationToken()) { + logTelemetry.Stop(m_telemetryHelper, false); co_return nullptr; } - co_return make(path); + + auto result = make(path); + + logTelemetry.Stop(m_telemetryHelper, true); + co_return result; } winrt::Windows::Foundation::IAsyncOperation > FileOpenPicker::PickMultipleFilesAsync() { + auto logTelemetry{ StoragePickersTelemetry::FileOpenPickerPickMultipleFile::Start(m_telemetryHelper) }; + // capture parameters to avoid using get strong referece of picker PickerCommon::PickerParameters parameters{}; CaptureParameters(parameters); @@ -120,6 +127,7 @@ namespace winrt::Microsoft::Windows::Storage::Pickers::implementation auto cancellationToken = co_await winrt::get_cancellation_token(); if (cancellationToken()) { + logTelemetry.Stop(m_telemetryHelper, true, false); co_return results.GetView(); } @@ -133,6 +141,7 @@ namespace winrt::Microsoft::Windows::Storage::Pickers::implementation auto hr = dialog->Show(parameters.HWnd); if (FAILED(hr) || cancellationToken()) { + logTelemetry.Stop(m_telemetryHelper, true, false); co_return results.GetView(); } } @@ -148,14 +157,26 @@ namespace winrt::Microsoft::Windows::Storage::Pickers::implementation { check_hresult(shellItems->GetItemAt(i, shellItem.put())); auto path = PickerCommon::GetPathFromShellItem(shellItem); - auto result = make(path); + auto result{ make(path) }; results.Append(result); } + bool isCancelled = false; if (cancellationToken()) { results.Clear(); + isCancelled = true; + } + auto resultView = results.GetView(); + + if (results.Size() > 0) + { + logTelemetry.Stop(m_telemetryHelper, isCancelled, true); + } + else + { + logTelemetry.Stop(m_telemetryHelper, isCancelled, false); } - co_return results.GetView(); + co_return resultView; } } diff --git a/dev/Interop/StoragePickers/FileOpenPicker.h b/dev/Interop/StoragePickers/FileOpenPicker.h index 36b6028de6..208025488d 100644 --- a/dev/Interop/StoragePickers/FileOpenPicker.h +++ b/dev/Interop/StoragePickers/FileOpenPicker.h @@ -4,7 +4,7 @@ #pragma once #include "Microsoft.Windows.Storage.Pickers.FileOpenPicker.g.h" #include "PickerCommon.h" -#include "TelemetryHelper.h" +#include "StoragePickersTelemetryHelper.h" namespace winrt::Microsoft::Windows::Storage::Pickers::implementation { @@ -36,7 +36,7 @@ namespace winrt::Microsoft::Windows::Storage::Pickers::implementation PickerLocationId m_suggestedStartLocation{ PickerLocationId::Unspecified }; winrt::hstring m_commitButtonText{}; winrt::Windows::Foundation::Collections::IVector m_fileTypeFilter{ winrt::single_threaded_vector() }; - TelemetryHelper m_telemetryHelper; + StoragePickersTelemetryHelper m_telemetryHelper{}; void CaptureParameters(PickerCommon::PickerParameters& parameters); }; diff --git a/dev/Interop/StoragePickers/FileSavePicker.cpp b/dev/Interop/StoragePickers/FileSavePicker.cpp index d1e317f52a..65a643f8e6 100644 --- a/dev/Interop/StoragePickers/FileSavePicker.cpp +++ b/dev/Interop/StoragePickers/FileSavePicker.cpp @@ -4,6 +4,7 @@ #include "pch.h" #include "FileSavePicker.h" #include "Microsoft.Windows.Storage.Pickers.FileSavePicker.g.cpp" +#include "StoragePickersTelemetry.h" #include #include #include @@ -90,6 +91,8 @@ namespace winrt::Microsoft::Windows::Storage::Pickers::implementation winrt::Windows::Foundation::IAsyncOperation FileSavePicker::PickSaveFileAsync() { + auto logTelemetry{ StoragePickersTelemetry::FileSavePickerPickSingleFile::Start(m_telemetryHelper) }; + PickerCommon::PickerParameters parameters{}; CaptureParameters(parameters); auto defaultFileExtension = m_defaultFileExtension; @@ -101,6 +104,7 @@ namespace winrt::Microsoft::Windows::Storage::Pickers::implementation auto cancellationToken = co_await winrt::get_cancellation_token(); if (cancellationToken()) { + logTelemetry.Stop(m_telemetryHelper, false); co_return nullptr; } @@ -128,6 +132,7 @@ namespace winrt::Microsoft::Windows::Storage::Pickers::implementation auto hr = dialog->Show(parameters.HWnd); if (FAILED(hr)) { + logTelemetry.Stop(m_telemetryHelper, false); co_return nullptr; } } @@ -159,9 +164,13 @@ namespace winrt::Microsoft::Windows::Storage::Pickers::implementation if (cancellationToken()) { + logTelemetry.Stop(m_telemetryHelper, false); co_return nullptr; } - co_return make(pathStr); + auto result = make(pathStr); + + logTelemetry.Stop(m_telemetryHelper, true); + co_return result; } } diff --git a/dev/Interop/StoragePickers/FileSavePicker.h b/dev/Interop/StoragePickers/FileSavePicker.h index 9cf419c7b6..92825d661f 100644 --- a/dev/Interop/StoragePickers/FileSavePicker.h +++ b/dev/Interop/StoragePickers/FileSavePicker.h @@ -4,6 +4,7 @@ #pragma once #include "Microsoft.Windows.Storage.Pickers.FileSavePicker.g.h" #include "PickerCommon.h" +#include "StoragePickersTelemetryHelper.h" namespace winrt::Microsoft::Windows::Storage::Pickers::implementation { @@ -44,6 +45,7 @@ namespace winrt::Microsoft::Windows::Storage::Pickers::implementation hstring m_defaultFileExtension{}; winrt::Windows::Storage::StorageFile m_suggestedSaveFile{ nullptr }; hstring m_suggestedFileName{}; + StoragePickersTelemetryHelper m_telemetryHelper{}; void CaptureParameters(PickerCommon::PickerParameters& parameters); }; diff --git a/dev/Interop/StoragePickers/FolderPicker.cpp b/dev/Interop/StoragePickers/FolderPicker.cpp index 432d0b38bb..fd748269ab 100644 --- a/dev/Interop/StoragePickers/FolderPicker.cpp +++ b/dev/Interop/StoragePickers/FolderPicker.cpp @@ -4,6 +4,7 @@ #include "pch.h" #include "FolderPicker.h" #include "Microsoft.Windows.Storage.Pickers.FolderPicker.g.cpp" +#include "StoragePickersTelemetry.h" #include #include #include @@ -66,6 +67,8 @@ namespace winrt::Microsoft::Windows::Storage::Pickers::implementation winrt::Windows::Foundation::IAsyncOperation FolderPicker::PickSingleFolderAsync() { + auto logTelemetry{ StoragePickersTelemetry::FolderPickerPickSingleFolder::Start(m_telemetryHelper) }; + PickerCommon::PickerParameters parameters{}; CaptureParameters(parameters); @@ -74,6 +77,7 @@ namespace winrt::Microsoft::Windows::Storage::Pickers::implementation auto cancellationToken = co_await winrt::get_cancellation_token(); if (cancellationToken()) { + logTelemetry.Stop(m_telemetryHelper, false); co_return nullptr; } @@ -86,6 +90,7 @@ namespace winrt::Microsoft::Windows::Storage::Pickers::implementation auto hr = dialog->Show(parameters.HWnd); if (FAILED(hr) || cancellationToken()) { + logTelemetry.Stop(m_telemetryHelper, false); co_return nullptr; } } @@ -96,8 +101,13 @@ namespace winrt::Microsoft::Windows::Storage::Pickers::implementation if (cancellationToken()) { + logTelemetry.Stop(m_telemetryHelper, false); co_return nullptr; } - co_return make(path); + + auto result = make(path); + + logTelemetry.Stop(m_telemetryHelper, true); + co_return result; } } diff --git a/dev/Interop/StoragePickers/FolderPicker.h b/dev/Interop/StoragePickers/FolderPicker.h index 00026ff7f1..6bd8f2e718 100644 --- a/dev/Interop/StoragePickers/FolderPicker.h +++ b/dev/Interop/StoragePickers/FolderPicker.h @@ -4,6 +4,7 @@ #pragma once #include "Microsoft.Windows.Storage.Pickers.FolderPicker.g.h" #include "PickerCommon.h" +#include "StoragePickersTelemetryHelper.h" namespace winrt::Microsoft::Windows::Storage::Pickers::implementation { @@ -34,8 +35,9 @@ namespace winrt::Microsoft::Windows::Storage::Pickers::implementation hstring m_settingsIdentifier{}; PickerLocationId m_suggestedStartLocation{ PickerLocationId::Unspecified }; hstring m_commitButtonText{}; + StoragePickersTelemetryHelper m_telemetryHelper{}; - winrt::Windows::Foundation::Collections::IVector m_fileTypeFilter{ winrt::single_threaded_vector() }; + winrt::Windows::Foundation::Collections::IVector m_fileTypeFilter{ winrt::single_threaded_vector() }; void CaptureParameters(PickerCommon::PickerParameters& parameters); }; diff --git a/dev/Interop/StoragePickers/StoragePickersTelemetry.h b/dev/Interop/StoragePickers/StoragePickersTelemetry.h index 01fdfe47bd..2811d82a1b 100644 --- a/dev/Interop/StoragePickers/StoragePickersTelemetry.h +++ b/dev/Interop/StoragePickers/StoragePickersTelemetry.h @@ -3,7 +3,7 @@ #pragma once #include "..\WindowsAppRuntime_Insights\WindowsAppRuntimeInsights.h" -#include +#include DECLARE_TRACELOGGING_CLASS(StoragePickersTelemetryProvider, "Microsoft.WindowsAppSDK.StoragePickersTelemetry", @@ -15,15 +15,113 @@ class StoragePickersTelemetry : public wil::TraceLoggingProvider IMPLEMENT_TELEMETRY_CLASS(StoragePickersTelemetry, StoragePickersTelemetryProvider); public: - BEGIN_COMPLIANT_MEASURES_ACTIVITY_CLASS(StoragePickersOperation, PDT_ProductAndServicePerformance); - DEFINE_ACTIVITY_START(bool isAppPackaged, PCWSTR appName) noexcept try + BEGIN_COMPLIANT_MEASURES_ACTIVITY_CLASS(FileOpenPickerPickSingleFile, PDT_ProductAndServicePerformance); + DEFINE_ACTIVITY_START(StoragePickersTelemetryHelper& telemetryHelper) noexcept try { TraceLoggingClassWriteStart( - StoragePickersOperation, + FileOpenPickerPickSingleFile, _GENERIC_PARTB_FIELDS_ENABLED, - TraceLoggingBool(isAppPackaged, "IsAppPackaged"), - TraceLoggingWideString(appName, "AppName")); + TraceLoggingBool(telemetryHelper.IsPackagedApp(), "IsAppPackaged"), + TraceLoggingBool(telemetryHelper.IsRunningAsAdmin(), "IsRunningAsAdmin"), + TraceLoggingBool(telemetryHelper.IsRunningInContainer(), "IsRunningInContainer"), + TraceLoggingWideString(telemetryHelper.GetAppName().c_str(), "AppName") + ); + } + CATCH_LOG() + + DEFINE_ACTIVITY_STOP(StoragePickersTelemetryHelper& telemetryHelper, bool const resultNotNull) noexcept try + { + TraceLoggingClassWriteStop( + FileOpenPickerPickSingleFile, + _GENERIC_PARTB_FIELDS_ENABLED, + TraceLoggingBool(resultNotNull, "resultNotNull"), + TraceLoggingBool(telemetryHelper.IsPackagedApp(), "IsAppPackaged"), + TraceLoggingBool(telemetryHelper.IsRunningAsAdmin(), "IsRunningAsAdmin"), + TraceLoggingBool(telemetryHelper.IsRunningInContainer(), "IsRunningInContainer"), + TraceLoggingWideString(telemetryHelper.GetAppName().c_str(), "AppName")); + } + CATCH_LOG() + END_ACTIVITY_CLASS(); + + BEGIN_COMPLIANT_MEASURES_ACTIVITY_CLASS(FileOpenPickerPickMultipleFile, PDT_ProductAndServicePerformance); + DEFINE_ACTIVITY_START(StoragePickersTelemetryHelper& telemetryHelper) noexcept try + { + TraceLoggingClassWriteStart( + FileOpenPickerPickMultipleFile, + _GENERIC_PARTB_FIELDS_ENABLED, + TraceLoggingBool(telemetryHelper.IsPackagedApp(), "IsAppPackaged"), + TraceLoggingBool(telemetryHelper.IsRunningAsAdmin(), "IsRunningAsAdmin"), + TraceLoggingBool(telemetryHelper.IsRunningInContainer(), "IsRunningInContainer"), + TraceLoggingWideString(telemetryHelper.GetAppName().c_str(), "AppName")); + } + CATCH_LOG() + + DEFINE_ACTIVITY_STOP(StoragePickersTelemetryHelper& telemetryHelper, bool const resultCancelled, bool const resultNotEmpty) noexcept try + { + TraceLoggingClassWriteStop( + FileOpenPickerPickMultipleFile, + _GENERIC_PARTB_FIELDS_ENABLED, + TraceLoggingBool(resultCancelled, "resultCancelled"), + TraceLoggingBool(resultNotEmpty, "resultNotEmpty"), + TraceLoggingBool(telemetryHelper.IsPackagedApp(), "IsAppPackaged"), + TraceLoggingBool(telemetryHelper.IsRunningAsAdmin(), "IsRunningAsAdmin"), + TraceLoggingBool(telemetryHelper.IsRunningInContainer(), "IsRunningInContainer"), + TraceLoggingWideString(telemetryHelper.GetAppName().c_str(), "AppName")); + } + CATCH_LOG() + END_ACTIVITY_CLASS(); + + BEGIN_COMPLIANT_MEASURES_ACTIVITY_CLASS(FileSavePickerPickSingleFile, PDT_ProductAndServicePerformance); + DEFINE_ACTIVITY_START(StoragePickersTelemetryHelper& telemetryHelper) noexcept try + { + TraceLoggingClassWriteStart( + FileSavePickerPickSingleFile, + _GENERIC_PARTB_FIELDS_ENABLED, + TraceLoggingBool(telemetryHelper.IsPackagedApp(), "IsAppPackaged"), + TraceLoggingBool(telemetryHelper.IsRunningAsAdmin(), "IsRunningAsAdmin"), + TraceLoggingBool(telemetryHelper.IsRunningInContainer(), "IsRunningInContainer"), + TraceLoggingWideString(telemetryHelper.GetAppName().c_str(), "AppName")); + } + CATCH_LOG() + + DEFINE_ACTIVITY_STOP(StoragePickersTelemetryHelper& telemetryHelper, bool const resultNotNull) noexcept try + { + TraceLoggingClassWriteStop( + FileSavePickerPickSingleFile, + _GENERIC_PARTB_FIELDS_ENABLED, + TraceLoggingBool(resultNotNull, "resultNotNull"), + TraceLoggingBool(telemetryHelper.IsPackagedApp(), "IsAppPackaged"), + TraceLoggingBool(telemetryHelper.IsRunningAsAdmin(), "IsRunningAsAdmin"), + TraceLoggingBool(telemetryHelper.IsRunningInContainer(), "IsRunningInContainer"), + TraceLoggingWideString(telemetryHelper.GetAppName().c_str(), "AppName")); + } + CATCH_LOG() + END_ACTIVITY_CLASS(); + + BEGIN_COMPLIANT_MEASURES_ACTIVITY_CLASS(FolderPickerPickSingleFolder, PDT_ProductAndServicePerformance); + DEFINE_ACTIVITY_START(StoragePickersTelemetryHelper& telemetryHelper) noexcept try + { + TraceLoggingClassWriteStart( + FolderPickerPickSingleFolder, + _GENERIC_PARTB_FIELDS_ENABLED, + TraceLoggingBool(telemetryHelper.IsPackagedApp(), "IsAppPackaged"), + TraceLoggingBool(telemetryHelper.IsRunningAsAdmin(), "IsRunningAsAdmin"), + TraceLoggingBool(telemetryHelper.IsRunningInContainer(), "IsRunningInContainer"), + TraceLoggingWideString(telemetryHelper.GetAppName().c_str(), "AppName")); + } + CATCH_LOG() + + DEFINE_ACTIVITY_STOP(StoragePickersTelemetryHelper& telemetryHelper, bool const resultNotNull) noexcept try + { + TraceLoggingClassWriteStop( + FolderPickerPickSingleFolder, + _GENERIC_PARTB_FIELDS_ENABLED, + TraceLoggingBool(resultNotNull, "resultNotNull"), + TraceLoggingBool(telemetryHelper.IsPackagedApp(), "IsAppPackaged"), + TraceLoggingBool(telemetryHelper.IsRunningAsAdmin(), "IsRunningAsAdmin"), + TraceLoggingBool(telemetryHelper.IsRunningInContainer(), "IsRunningInContainer"), + TraceLoggingWideString(telemetryHelper.GetAppName().c_str(), "AppName")); } CATCH_LOG() END_ACTIVITY_CLASS(); -}; \ No newline at end of file +}; From 1845a65c5c70f68bb3224de6e5a85b5c4621cde0 Mon Sep 17 00:00:00 2001 From: Xiang Hong Date: Tue, 25 Mar 2025 15:57:33 +0800 Subject: [PATCH 38/39] fixes accroding to PR comments --- .gitignore | 3 --- dev/Interop/StoragePickers/FileOpenPicker.cpp | 12 +++++++++-- dev/Interop/StoragePickers/FileSavePicker.cpp | 21 ++++++++++++++----- dev/Interop/StoragePickers/FolderPicker.cpp | 6 +++++- dev/Interop/StoragePickers/PickerCommon.cpp | 20 ++++++++++++++++-- dev/Interop/StoragePickers/PickerCommon.h | 2 +- .../WindowsAppRuntime_DLL.vcxproj | 14 ++++++------- .../StoragePickersTests.cpp | 13 +++++------- 8 files changed, 62 insertions(+), 29 deletions(-) diff --git a/.gitignore b/.gitignore index 5df5f6736d..863bfdce8f 100644 --- a/.gitignore +++ b/.gitignore @@ -395,6 +395,3 @@ build/override/ # WindowsAppSDK specific files Microsoft.WinUI.AppX.targets !dev/vsix/**/*.pubxml - -# TAEF related -redist/ diff --git a/dev/Interop/StoragePickers/FileOpenPicker.cpp b/dev/Interop/StoragePickers/FileOpenPicker.cpp index 1654489fc5..7f6181c946 100644 --- a/dev/Interop/StoragePickers/FileOpenPicker.cpp +++ b/dev/Interop/StoragePickers/FileOpenPicker.cpp @@ -68,15 +68,19 @@ namespace winrt::Microsoft::Windows::Storage::Pickers::implementation winrt::Windows::Foundation::IAsyncOperation FileOpenPicker::PickSingleFileAsync() { + // TODO: remove get strong reference when telementry is safe stop + auto lifetime { get_strong() }; + auto logTelemetry{ StoragePickersTelemetry::FileOpenPickerPickSingleFile::Start(m_telemetryHelper) }; PickerCommon::PickerParameters parameters{}; CaptureParameters(parameters); + auto cancellationToken = co_await winrt::get_cancellation_token(); + cancellationToken.enable_propagation(true); co_await winrt::resume_background(); - auto cancellationToken = co_await winrt::get_cancellation_token(); if (cancellationToken()) { logTelemetry.Stop(m_telemetryHelper, false); @@ -114,17 +118,21 @@ namespace winrt::Microsoft::Windows::Storage::Pickers::implementation winrt::Windows::Foundation::IAsyncOperation > FileOpenPicker::PickMultipleFilesAsync() { + // TODO: remove get strong reference when telementry is safe stop + auto lifetime { get_strong() }; + auto logTelemetry{ StoragePickersTelemetry::FileOpenPickerPickMultipleFile::Start(m_telemetryHelper) }; // capture parameters to avoid using get strong referece of picker PickerCommon::PickerParameters parameters{}; CaptureParameters(parameters); + auto cancellationToken = co_await winrt::get_cancellation_token(); + cancellationToken.enable_propagation(true); co_await winrt::resume_background(); winrt::Windows::Foundation::Collections::IVector results{ winrt::single_threaded_vector() }; - auto cancellationToken = co_await winrt::get_cancellation_token(); if (cancellationToken()) { logTelemetry.Stop(m_telemetryHelper, true, false); diff --git a/dev/Interop/StoragePickers/FileSavePicker.cpp b/dev/Interop/StoragePickers/FileSavePicker.cpp index 65a643f8e6..339cfaea9a 100644 --- a/dev/Interop/StoragePickers/FileSavePicker.cpp +++ b/dev/Interop/StoragePickers/FileSavePicker.cpp @@ -91,6 +91,9 @@ namespace winrt::Microsoft::Windows::Storage::Pickers::implementation winrt::Windows::Foundation::IAsyncOperation FileSavePicker::PickSaveFileAsync() { + // TODO: remove get strong reference when telementry is safe stop + auto lifetime{ get_strong() }; + auto logTelemetry{ StoragePickersTelemetry::FileSavePickerPickSingleFile::Start(m_telemetryHelper) }; PickerCommon::PickerParameters parameters{}; @@ -100,8 +103,10 @@ namespace winrt::Microsoft::Windows::Storage::Pickers::implementation auto suggestedFileName = m_suggestedFileName; auto fileTypeChoices = m_fileTypeChoices; - co_await winrt::resume_background(); auto cancellationToken = co_await winrt::get_cancellation_token(); + cancellationToken.enable_propagation(true); + co_await winrt::resume_background(); + if (cancellationToken()) { logTelemetry.Stop(m_telemetryHelper, false); @@ -150,16 +155,22 @@ namespace winrt::Microsoft::Windows::Storage::Pickers::implementation std::wstring fileNameStr(fileName.get()); // Check if the file name has an extension - if (fileNameStr.find_last_of(L".") == std::wstring::npos) + if ((fileNameStr.find_last_of(L".") == std::wstring::npos) && (fileTypeChoices.Size() > 0)) { // If the user defined file name doesn't have an extension, // automatically use the first extension from the first category in fileTypeChoices. auto firstCategory = fileTypeChoices.First().Current(); - auto firstExtension = firstCategory.Value().GetAt(0); - pathStr = pathStr + firstExtension; + auto value = firstCategory.Value(); + if (value.Size() > 0) + { + auto firstExtension = value.GetAt(0); + pathStr = pathStr + firstExtension; + } } - // Create a file. If the file already exists, will prompt to let user select cancele or override. + // Create a file. If the file already exists, + // since common item dialog prompts to let user select cancel or override, thus we can safely truncate here. + // Due to our design spec to align with UWP pickers, we need ensure existance of picked file. auto [handle, _] = wil::try_open_or_truncate_existing_file(pathStr.c_str(), GENERIC_WRITE); if (cancellationToken()) diff --git a/dev/Interop/StoragePickers/FolderPicker.cpp b/dev/Interop/StoragePickers/FolderPicker.cpp index fd748269ab..42b8aaa5f4 100644 --- a/dev/Interop/StoragePickers/FolderPicker.cpp +++ b/dev/Interop/StoragePickers/FolderPicker.cpp @@ -67,14 +67,18 @@ namespace winrt::Microsoft::Windows::Storage::Pickers::implementation winrt::Windows::Foundation::IAsyncOperation FolderPicker::PickSingleFolderAsync() { + // TODO: remove get strong reference when telementry is safe stop + auto lifetime{ get_strong() }; + auto logTelemetry{ StoragePickersTelemetry::FolderPickerPickSingleFolder::Start(m_telemetryHelper) }; PickerCommon::PickerParameters parameters{}; CaptureParameters(parameters); + auto cancellationToken = co_await winrt::get_cancellation_token(); + cancellationToken.enable_propagation(true); co_await winrt::resume_background(); - auto cancellationToken = co_await winrt::get_cancellation_token(); if (cancellationToken()) { logTelemetry.Stop(m_telemetryHelper, false); diff --git a/dev/Interop/StoragePickers/PickerCommon.cpp b/dev/Interop/StoragePickers/PickerCommon.cpp index 46922d3768..13e456e3cf 100644 --- a/dev/Interop/StoragePickers/PickerCommon.cpp +++ b/dev/Interop/StoragePickers/PickerCommon.cpp @@ -142,12 +142,20 @@ namespace PickerCommon { return winrt::hstring{ filePath.get() }; } + /// + /// Capture and processing pickers filter inputs and convert them into Common Item Dialog's accepting type + /// + /// temp buffer to hold dynamically transformed strings + /// winrt style filters + /// result Coomon Item Dialog style filters, note only raw pointers here, + /// they are valid up to lifetime of buffer + /// std::vector CaptureFilterSpec(std::vector& buffer, winrt::Windows::Foundation::Collections::IVectorView filters) { std::vector result(filters.Size()); buffer.clear(); buffer.reserve(filters.Size() * (size_t)2); - for (auto filter : filters) + for (const auto& filter : filters) { auto ext = FormatExtensionWithWildcard(filter); buffer.push_back(filter); @@ -165,11 +173,19 @@ namespace PickerCommon { return result; } + /// + /// Capture and processing pickers filter inputs and convert them into Common Item Dialog's accepting type + /// + /// temp buffer to hold dynamically transformed strings + /// winrt style filters + /// result Coomon Item Dialog style filters, note only raw pointers here, + /// they are valid up to lifetime of buffer + /// std::vector CaptureFilterSpec(std::vector& buffer, winrt::Windows::Foundation::Collections::IMapView> filters) { std::vector result(filters.Size()); buffer.clear(); - buffer.reserve(filters.Size() * 2ull); + buffer.reserve(filters.Size() * (size_t)2); for (const auto& filter : filters) { diff --git a/dev/Interop/StoragePickers/PickerCommon.h b/dev/Interop/StoragePickers/PickerCommon.h index 515d520fe1..ad2e314b51 100644 --- a/dev/Interop/StoragePickers/PickerCommon.h +++ b/dev/Interop/StoragePickers/PickerCommon.h @@ -21,7 +21,7 @@ namespace PickerCommon { bool IsHStringNullOrEmpty(winrt::hstring value); struct PickerParameters { - HWND HWnd; + HWND HWnd{}; winrt::hstring CommitButtonText; winrt::hstring SettingsIdentifierId; winrt::Microsoft::Windows::Storage::Pickers::PickerLocationId PickerLocationId; diff --git a/dev/WindowsAppRuntime_DLL/WindowsAppRuntime_DLL.vcxproj b/dev/WindowsAppRuntime_DLL/WindowsAppRuntime_DLL.vcxproj index 7d273a7e30..c5ac889f59 100644 --- a/dev/WindowsAppRuntime_DLL/WindowsAppRuntime_DLL.vcxproj +++ b/dev/WindowsAppRuntime_DLL/WindowsAppRuntime_DLL.vcxproj @@ -154,9 +154,9 @@ Windows false - onecore.lib;onecoreuap.lib;%(AdditionalDependencies) + onecore.lib;onecoreuap.lib;shell32.lib;%(AdditionalDependencies) WindowsAppRuntime.def - Microsoft.Internal.FrameworkUdk.dll;%(DelayLoadDLLs) + Microsoft.Internal.FrameworkUdk.dll;shell32.dll;%(DelayLoadDLLs) $(RepoRoot)\dev\common @@ -174,7 +174,7 @@ false onecore.lib;onecoreuap.lib;shell32.lib;%(AdditionalDependencies) WindowsAppRuntime.def - Microsoft.Internal.FrameworkUdk.dll;%(DelayLoadDLLs) + Microsoft.Internal.FrameworkUdk.dll;shell32.dll;%(DelayLoadDLLs) $(RepoRoot)\dev\common @@ -192,7 +192,7 @@ false onecore.lib;onecoreuap.lib;shell32.lib;%(AdditionalDependencies) WindowsAppRuntime.def - Microsoft.Internal.FrameworkUdk.dll;%(DelayLoadDLLs) + Microsoft.Internal.FrameworkUdk.dll;shell32.dll;%(DelayLoadDLLs) $(RepoRoot)\dev\common @@ -210,7 +210,7 @@ false onecore.lib;onecoreuap.lib;shell32.lib;%(AdditionalDependencies) WindowsAppRuntime.def - Microsoft.Internal.FrameworkUdk.dll;%(DelayLoadDLLs) + Microsoft.Internal.FrameworkUdk.dll;shell32.dll;%(DelayLoadDLLs) $(RepoRoot)\dev\common @@ -228,7 +228,7 @@ false onecore.lib;onecoreuap.lib;shell32.lib;%(AdditionalDependencies) WindowsAppRuntime.def - Microsoft.Internal.FrameworkUdk.dll;%(DelayLoadDLLs) + Microsoft.Internal.FrameworkUdk.dll;shell32.dll;%(DelayLoadDLLs) $(RepoRoot)\dev\common @@ -246,7 +246,7 @@ false onecore.lib;onecoreuap.lib;shell32.lib;%(AdditionalDependencies) WindowsAppRuntime.def - Microsoft.Internal.FrameworkUdk.dll;%(DelayLoadDLLs) + Microsoft.Internal.FrameworkUdk.dll;shell32.dll;%(DelayLoadDLLs) $(RepoRoot)\dev\common diff --git a/test/StoragePickersTests/StoragePickersTests.cpp b/test/StoragePickersTests/StoragePickersTests.cpp index 36ee8290a0..95369d5151 100644 --- a/test/StoragePickersTests/StoragePickersTests.cpp +++ b/test/StoragePickersTests/StoragePickersTests.cpp @@ -26,7 +26,6 @@ namespace Test::StoragePickersTests //TEST_CLASS_PROPERTY(L"RunFixtureAs:Class", L"UAP") //TEST_CLASS_PROPERTY(L"RunAs", L"UAP") - TEST_CLASS_PROPERTY(L"IsolationLevel", L"Method") // each test sets its own CompatibilityOptions END_TEST_CLASS() TEST_CLASS_SETUP(ClassSetup) @@ -57,7 +56,7 @@ namespace Test::StoragePickersTests ::Test::Bootstrap::CleanupBootstrap(); return true; } - // The unit tests will be updated,first test might is there for testing purpose locally. + // The unit tests will be updated,first test might is there for testing purpose locally. // Focusing solely on functional tests for now. // Commenting out this test as it is an E2E scenario test that requires UI automation for pipeline execution. @@ -139,8 +138,7 @@ namespace Test::StoragePickersTests TEST_METHOD(VerifyFileOpenPickerOptionsAreReadCorrectly) { - auto parentWindow = ::GetForegroundWindow(); - winrt::Microsoft::UI::WindowId windowId{ reinterpret_cast(parentWindow) }; + winrt::Microsoft::UI::WindowId windowId{}; winrt::Microsoft::Windows::Storage::Pickers::FileOpenPicker picker(windowId); picker.ViewMode(winrt::Microsoft::Windows::Storage::Pickers::PickerViewMode::List); @@ -164,8 +162,7 @@ namespace Test::StoragePickersTests TEST_METHOD(VerifyFileSavePickerOptionsAreReadCorrectly) { - auto parentWindow = ::GetForegroundWindow(); - winrt::Microsoft::UI::WindowId windowId{ reinterpret_cast(parentWindow) }; + winrt::Microsoft::UI::WindowId windowId{}; winrt::Microsoft::Windows::Storage::Pickers::FileSavePicker picker(windowId); picker.SettingsIdentifier(L"id"); @@ -179,14 +176,14 @@ namespace Test::StoragePickersTests auto filters = winrt::single_threaded_vector(); filters.Append(L"*"); - picker.FileTypeChoices().Insert(L"All Files", filters ); + picker.FileTypeChoices().Insert(L"All Files", filters); VERIFY_ARE_EQUAL(picker.FileTypeChoices().Lookup(L"All Files").GetAt(0), L"*"); } TEST_METHOD(VerifyFolderPickerOptionsAreReadCorrectly) { auto parentWindow = ::GetForegroundWindow(); - winrt::Microsoft::UI::WindowId windowId{ reinterpret_cast(parentWindow) }; + winrt::Microsoft::UI::WindowId windowId{}; winrt::Microsoft::Windows::Storage::Pickers::FolderPicker picker(windowId); picker.ViewMode(winrt::Microsoft::Windows::Storage::Pickers::PickerViewMode::List); From 360e3fed5e524b79506d3c762a9d1497a7e4020c Mon Sep 17 00:00:00 2001 From: Dinah Gao Date: Wed, 26 Mar 2025 00:43:19 +0800 Subject: [PATCH 39/39] Move storagepickerstelemetryhelper to the pickers folder --- dev/Interop/StoragePickers/StoragePickers.vcxitems | 1 + .../StoragePickers}/StoragePickersTelemetryHelper.h | 0 2 files changed, 1 insertion(+) rename dev/{Common => Interop/StoragePickers}/StoragePickersTelemetryHelper.h (100%) diff --git a/dev/Interop/StoragePickers/StoragePickers.vcxitems b/dev/Interop/StoragePickers/StoragePickers.vcxitems index c36647c25e..f733b72cb1 100644 --- a/dev/Interop/StoragePickers/StoragePickers.vcxitems +++ b/dev/Interop/StoragePickers/StoragePickers.vcxitems @@ -23,6 +23,7 @@ + diff --git a/dev/Common/StoragePickersTelemetryHelper.h b/dev/Interop/StoragePickers/StoragePickersTelemetryHelper.h similarity index 100% rename from dev/Common/StoragePickersTelemetryHelper.h rename to dev/Interop/StoragePickers/StoragePickersTelemetryHelper.h