Skip to content

Commit

Permalink
Create public sample (#4734)
Browse files Browse the repository at this point in the history
## Change
Copy the current dev tool, COM calling application into a new location
and update significantly with the goal of being a public sample of
usage. Cleaned up the code and tried to include more error handling and
commenting.

Major changes to the UX:
- Removed the dev switch as this is intended as a public sample
- Added example search options selection
- Add `Upgrade` button so that function could be called as well
- Add `Uninstall` button for installed packages
- Disconnected installed and active operation lists from catalog
selection and package search

Major change to DevX:
- Move to using the OOP COM nuget package
- This isn't ready for use yet, as the OOP activation dll isn't
available in a public version yet and we are still working on the exact
shape of that update.
  • Loading branch information
JohnMcPMS authored Aug 14, 2024
1 parent 5427597 commit 095b221
Show file tree
Hide file tree
Showing 24 changed files with 1,826 additions and 0 deletions.
43 changes: 43 additions & 0 deletions samples/WinGetUWPCaller/WinGetUWPCaller.sln
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.30704.19
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "WinGetUWPCaller", "WinGetUWPCaller\WinGetUWPCaller.vcxproj", "{37F1FD2A-4D63-45A0-82AA-66EF126CB322}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|ARM64 = Debug|ARM64
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|ARM64 = Release|ARM64
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{37F1FD2A-4D63-45A0-82AA-66EF126CB322}.Debug|ARM64.ActiveCfg = Debug|ARM64
{37F1FD2A-4D63-45A0-82AA-66EF126CB322}.Debug|ARM64.Build.0 = Debug|ARM64
{37F1FD2A-4D63-45A0-82AA-66EF126CB322}.Debug|ARM64.Deploy.0 = Debug|ARM64
{37F1FD2A-4D63-45A0-82AA-66EF126CB322}.Debug|x64.ActiveCfg = Debug|x64
{37F1FD2A-4D63-45A0-82AA-66EF126CB322}.Debug|x64.Build.0 = Debug|x64
{37F1FD2A-4D63-45A0-82AA-66EF126CB322}.Debug|x64.Deploy.0 = Debug|x64
{37F1FD2A-4D63-45A0-82AA-66EF126CB322}.Debug|x86.ActiveCfg = Debug|Win32
{37F1FD2A-4D63-45A0-82AA-66EF126CB322}.Debug|x86.Build.0 = Debug|Win32
{37F1FD2A-4D63-45A0-82AA-66EF126CB322}.Debug|x86.Deploy.0 = Debug|Win32
{37F1FD2A-4D63-45A0-82AA-66EF126CB322}.Release|ARM64.ActiveCfg = Release|ARM64
{37F1FD2A-4D63-45A0-82AA-66EF126CB322}.Release|ARM64.Build.0 = Release|ARM64
{37F1FD2A-4D63-45A0-82AA-66EF126CB322}.Release|ARM64.Deploy.0 = Release|ARM64
{37F1FD2A-4D63-45A0-82AA-66EF126CB322}.Release|x64.ActiveCfg = Release|x64
{37F1FD2A-4D63-45A0-82AA-66EF126CB322}.Release|x64.Build.0 = Release|x64
{37F1FD2A-4D63-45A0-82AA-66EF126CB322}.Release|x64.Deploy.0 = Release|x64
{37F1FD2A-4D63-45A0-82AA-66EF126CB322}.Release|x86.ActiveCfg = Release|Win32
{37F1FD2A-4D63-45A0-82AA-66EF126CB322}.Release|x86.Build.0 = Release|Win32
{37F1FD2A-4D63-45A0-82AA-66EF126CB322}.Release|x86.Deploy.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {D7D1DE2E-A7C1-4FB3-A191-C848562A3EBD}
EndGlobalSection
EndGlobal
87 changes: 87 additions & 0 deletions samples/WinGetUWPCaller/WinGetUWPCaller/ActivePackageView.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
#include "pch.h"
#include "ActivePackageView.h"
#include "ActivePackageView.g.cpp"
#include <winrt/Windows.UI.Core.h>

namespace winrt::WinGetUWPCaller::implementation
{
Microsoft::Management::Deployment::CatalogPackage ActivePackageView::Package()
{
return m_package;
}

void ActivePackageView::Package(Microsoft::Management::Deployment::CatalogPackage const& value)
{
m_package = value;
}

ActivePackageView::AsyncOperation_t ActivePackageView::AsyncOperation()
{
return m_asyncOperation;
}

Windows::Foundation::IAsyncAction UpdateUIProgress(
Microsoft::Management::Deployment::InstallProgress progress,
WinGetUWPCaller::ActivePackageView view)
{
co_await resume_foreground(view.Dispatcher());
view.Progress(progress.DownloadProgress * 100);
}

void ActivePackageView::AsyncOperation(ActivePackageView::AsyncOperation_t const& value)
{
m_asyncOperation = value;
m_asyncOperation.Progress([=](
ActivePackageView::AsyncOperation_t const& /* sender */,
Microsoft::Management::Deployment::InstallProgress const& progress)
{
UpdateUIProgress(progress, *this);
});
}

double ActivePackageView::Progress()
{
return m_progress;
}

void ActivePackageView::Progress(double value)
{
if (m_progress != value)
{
m_progress = value;
m_propertyChanged(*this, Windows::UI::Xaml::Data::PropertyChangedEventArgs{ L"Progress" });
}
}

hstring ActivePackageView::StatusText()
{
return m_text;
}

void ActivePackageView::StatusText(hstring const& value)
{
m_text = value;
}

Windows::UI::Core::CoreDispatcher ActivePackageView::Dispatcher()
{
return m_dispatcher;
}

void ActivePackageView::Dispatcher(Windows::UI::Core::CoreDispatcher const& value)
{
m_dispatcher = value;
}

event_token ActivePackageView::PropertyChanged(Windows::UI::Xaml::Data::PropertyChangedEventHandler const& handler)
{
return m_propertyChanged.add(handler);
}

void ActivePackageView::PropertyChanged(event_token const& token)
{
m_propertyChanged.remove(token);
}
}
42 changes: 42 additions & 0 deletions samples/WinGetUWPCaller/WinGetUWPCaller/ActivePackageView.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
#pragma once
#include "ActivePackageView.g.h"

namespace winrt::WinGetUWPCaller::implementation
{
struct ActivePackageView : ActivePackageViewT<ActivePackageView>
{
using AsyncOperation_t = Windows::Foundation::IAsyncOperationWithProgress<Microsoft::Management::Deployment::InstallResult, Microsoft::Management::Deployment::InstallProgress>;

ActivePackageView() = default;

Microsoft::Management::Deployment::CatalogPackage Package();
void Package(Microsoft::Management::Deployment::CatalogPackage const& value);
AsyncOperation_t AsyncOperation();
void AsyncOperation(AsyncOperation_t const& value);
double Progress();
void Progress(double value);
hstring StatusText();
void StatusText(hstring const& value);
Windows::UI::Core::CoreDispatcher Dispatcher();
void Dispatcher(Windows::UI::Core::CoreDispatcher const& value);
event_token PropertyChanged(Windows::UI::Xaml::Data::PropertyChangedEventHandler const& value);
void PropertyChanged(event_token const& token);

private:
Microsoft::Management::Deployment::CatalogPackage m_package{ nullptr };
AsyncOperation_t m_asyncOperation{ nullptr };
double m_progress = 0;
hstring m_text;
Windows::UI::Core::CoreDispatcher m_dispatcher{ nullptr };
event<Windows::UI::Xaml::Data::PropertyChangedEventHandler> m_propertyChanged;
};
}

namespace winrt::WinGetUWPCaller::factory_implementation
{
struct ActivePackageView : ActivePackageViewT<ActivePackageView, implementation::ActivePackageView>
{
};
}
121 changes: 121 additions & 0 deletions samples/WinGetUWPCaller/WinGetUWPCaller/App.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
#include "pch.h"

#include "App.h"
#include "MainPage.h"

using namespace winrt;
using namespace Windows::ApplicationModel;
using namespace Windows::ApplicationModel::Activation;
using namespace Windows::Foundation;
using namespace Windows::UI::Xaml;
using namespace Windows::UI::Xaml::Controls;
using namespace Windows::UI::Xaml::Navigation;
using namespace WinGetUWPCaller;
using namespace WinGetUWPCaller::implementation;

/// <summary>
/// Initializes the singleton application object. This is the first line of authored code
/// executed, and as such is the logical equivalent of main() or WinMain().
/// </summary>
App::App()
{
InitializeComponent();
Suspending({ this, &App::OnSuspending });

#if defined _DEBUG && !defined DISABLE_XAML_GENERATED_BREAK_ON_UNHANDLED_EXCEPTION
UnhandledException([this](IInspectable const&, UnhandledExceptionEventArgs const& e)
{
if (IsDebuggerPresent())
{
auto errorMessage = e.Message();
__debugbreak();
}
});
#endif
}

/// <summary>
/// Invoked when the application is launched normally by the end user. Other entry points
/// will be used such as when the application is launched to open a specific file.
/// </summary>
/// <param name="e">Details about the launch request and process.</param>
void App::OnLaunched(LaunchActivatedEventArgs const& e)
{
Frame rootFrame{ nullptr };
auto content = Window::Current().Content();
if (content)
{
rootFrame = content.try_as<Frame>();
}

// Do not repeat app initialization when the Window already has content,
// just ensure that the window is active
if (rootFrame == nullptr)
{
// Create a Frame to act as the navigation context and associate it with
// a SuspensionManager key
rootFrame = Frame();

rootFrame.NavigationFailed({ this, &App::OnNavigationFailed });

if (e.PreviousExecutionState() == ApplicationExecutionState::Terminated)
{
// Restore the saved session state only when appropriate, scheduling the
// final launch steps after the restore is complete
}

if (e.PrelaunchActivated() == false)
{
if (rootFrame.Content() == nullptr)
{
// When the navigation stack isn't restored navigate to the first page,
// configuring the new page by passing required information as a navigation
// parameter
rootFrame.Navigate(xaml_typename<WinGetUWPCaller::MainPage>(), box_value(e.Arguments()));
}
// Place the frame in the current Window
Window::Current().Content(rootFrame);
// Ensure the current window is active
Window::Current().Activate();
}
}
else
{
if (e.PrelaunchActivated() == false)
{
if (rootFrame.Content() == nullptr)
{
// When the navigation stack isn't restored navigate to the first page,
// configuring the new page by passing required information as a navigation
// parameter
rootFrame.Navigate(xaml_typename<WinGetUWPCaller::MainPage>(), box_value(e.Arguments()));
}
// Ensure the current window is active
Window::Current().Activate();
}
}
}

/// <summary>
/// Invoked when application execution is being suspended. Application state is saved
/// without knowing whether the application will be terminated or resumed with the contents
/// of memory still intact.
/// </summary>
/// <param name="sender">The source of the suspend request.</param>
/// <param name="e">Details about the suspend request.</param>
void App::OnSuspending([[maybe_unused]] IInspectable const& sender, [[maybe_unused]] SuspendingEventArgs const& e)
{
// Save application state and stop any background activity
}

/// <summary>
/// Invoked when Navigation to a certain page fails
/// </summary>
/// <param name="sender">The Frame which failed navigation</param>
/// <param name="e">Details about the navigation failure</param>
void App::OnNavigationFailed(IInspectable const&, NavigationFailedEventArgs const& e)
{
throw hresult_error(E_FAIL, hstring(L"Failed to load Page ") + e.SourcePageType().Name);
}
16 changes: 16 additions & 0 deletions samples/WinGetUWPCaller/WinGetUWPCaller/App.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
#pragma once
#include "App.xaml.g.h"

namespace winrt::WinGetUWPCaller::implementation
{
struct App : AppT<App>
{
App();

void OnLaunched(Windows::ApplicationModel::Activation::LaunchActivatedEventArgs const&);
void OnSuspending(IInspectable const&, Windows::ApplicationModel::SuspendingEventArgs const&);
void OnNavigationFailed(IInspectable const&, Windows::UI::Xaml::Navigation::NavigationFailedEventArgs const&);
};
}
3 changes: 3 additions & 0 deletions samples/WinGetUWPCaller/WinGetUWPCaller/App.idl
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
namespace WinGetUWPCaller
{
}
9 changes: 9 additions & 0 deletions samples/WinGetUWPCaller/WinGetUWPCaller/App.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<!-- Copyright (c) Microsoft Corporation.
Licensed under the MIT License. -->
<Application
x:Class="WinGetUWPCaller.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:WinGetUWPCaller">

</Application>
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit 095b221

Please sign in to comment.