Home
%3CLINGO-SUB%20id%3D%22lingo-sub-562400%22%20slang%3D%22ja-JP%22%3EUsing%20Windows%20runtime%20components%20from%20the%20.NET%20Framework%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-562400%22%20slang%3D%22ja-JP%22%3E%3CP%3EThe%20following%20article%20was%20going%20up%20a%20while%20ago.%3C%2FP%3E%0A%3CP%3E%3CA%20title%3D%22Enhancing%20Non-packaged%20Desktop%20Apps%20using%20Windows%20Runtime%20Components%22%20href%3D%22https%3A%2F%2Fblogs.windows.com%2Fbuildingapps%2F2019%2F04%2F30%2Fenhancing-non-packaged-desktop-apps-using-windows-runtime-components%2F%22%20target%3D%22_self%22%20rel%3D%22nofollow%20noopener%20noreferrer%20noopener%20noreferrer%22%3EEnhancing%20Non-packaged%20Desktop%20Apps%20using%20Windows%20Runtime%20Components%3C%2FA%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3EIt%20makes%20it%20possible%20to%20call%20Windows%20Runtime%20components%2C%20especially%20from%20apps%20that%20are%20not%20packaged%20in%20Msix%20or%20appx.%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%3CSTRONG%3ELet's%20try%20it.%3C%2FSTRONG%3E%3C%2FP%3E%0A%3CP%3EI%20want%20to%20try%20that.%3C%2FP%3E%0A%3CP%3ECreate%20an%20ordinary%20.NET%20Framework%20WPF%20application.Then%20add%20the%20Windows%20Runtime%20Component%20(Universal%20Windows-C%2B%2B%2FCX)%20project.Then%20add%20a%20reference%20to%20the%20Windows%20Runtime%20Component%20project%20from%20the%20WPF%20application.You%20will%20feel%20like%20the%20following.%3C%2FP%3E%0A%3CP%3E%3CSPAN%20class%3D%22lia-inline-image-display-wrapper%20lia-image-align-center%22%20style%3D%22width%3A%20733px%3B%22%3E%3CIMG%20src%3D%22https%3A%2F%2Fgxcuf89792.i.lithium.com%2Ft5%2Fimage%2Fserverpage%2Fimage-id%2F113097i4EEBA4BD15628F34%2Fimage-size%2Flarge%3Fv%3D1.0%26amp%3Bpx%3D999%22%20alt%3D%22Comments%202019-05-13%201225611.jpg%22%20title%3D%22%E3%82%B3%E3%83%A1%E3%83%B3%E3%83%88%202019-05-13%20125611.jpg%22%20%2F%3E%3C%2FSPAN%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3EAdd%20a%20simple%20process%20to%20the%20CLASS1.Added%20the%20process%20of%20receiving%20a%20name%20and%20returning%20a%20simple%20message.%3C%2FP%3E%0A%3CPRE%3E%23pragma%20once%0A%0Anamespace%20WindowsRuntimeComponent1%0A%7B%0A%20%20%20%20public%20ref%20class%20Class1%20sealed%0A%20%20%20%20%7B%0A%20%20%20%20public%3A%0A%20%20%20%20%20%20%20%20Class1()%3B%0A%20%20Platform%3A%3AString%5E%20GenerateMessage(Platform%3A%3AString%5E%20name)%3B%0A%20%20%20%20%7D%3B%0A%7D%0A%3C%2FPRE%3E%0A%3CPRE%3E%23include%20%22pch.h%22%0A%23include%20%22Class1.h%22%0A%0Ausing%20namespace%20WindowsRuntimeComponent1%3B%0Ausing%20namespace%20Platform%3B%0A%0AClass1%3A%3AClass1()%0A%7B%0A%7D%0A%0APlatform%3A%3AString%5E%20Class1%3A%3AGenerateMessage(Platform%3A%3AString%5E%20name)%0A%7B%0A%20return%20%22Hello%22%20%2B%20name%3B%0A%7D%3C%2FPRE%3E%0A%3CP%3EWhen%20you%20build%2C%20WINMD%20or%20DLL%20files%20are%20generated.Because%20I'm%20adding%20a%20project%20reference%2C%20I've%20added%20a%20related%20file%20to%20the%20output%20folder%20in%20my%20WPF%20project.%3C%2FP%3E%0A%3CP%3E%3CSPAN%20class%3D%22lia-inline-image-display-wrapper%20lia-image-align-inline%22%20style%3D%22width%3A%20615px%3B%22%3E%3CIMG%20src%3D%22https%3A%2F%2Fgxcuf89792.i.lithium.com%2Ft5%2Fimage%2Fserverpage%2Fimage-id%2F113114iE6828838716D2AAF%2Fimage-size%2Flarge%3Fv%3D1.0%26amp%3Bpx%3D999%22%20alt%3D%22Comments%202019-05-13%20145811.jpg%22%20title%3D%22%E3%82%B3%E3%83%A1%E3%83%B3%E3%83%88%202019-05-13%20145811.jpg%22%20%2F%3E%3C%2FSPAN%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3EBecause%20you%20also%20need%20a%20DLL%20to%20call%20a%20Windows%20runtime%20component%20from%20the%20.NET%20side%2C%20you%20should%20make%20sure%20that%20you%20copy%20the%20DLL%20by%20adding%20the%20following%20command%20as%20a%20post-build%20event%20for%20the%20WPF%20Project%20Properties%20build%20event%3A%3C%2FP%3E%0A%3CPRE%3Ecopy%20%2FY%20%24(SolutionDir)%5C%24(Configuration)%5CWindowsRuntimeComponent1%5C*.dll%20%24(TargetDir)%3C%2FPRE%3E%0A%3CP%3ENow%20that%20the%20DLL%20is%20copied%20to%20the%20output%20folder%2C%20you%20specify%20the%20Windows%20runtime%20component%20to%20use%20in%20the%20manifest.Add%20app.manifest%20to%20the%20WPF%20project.%3C%2FP%3E%0A%3CP%3E%3CSPAN%20class%3D%22lia-inline-image-display-wrapper%20lia-image-align-inline%22%20style%3D%22width%3A%20999px%3B%22%3E%3CIMG%20src%3D%22https%3A%2F%2Fgxcuf89792.i.lithium.com%2Ft5%2Fimage%2Fserverpage%2Fimage-id%2F113116iA060CAC99DDCAE68%2Fimage-size%2Flarge%3Fv%3D1.0%26amp%3Bpx%3D999%22%20alt%3D%22Comments%202019-05-13%20144906.jpg%22%20title%3D%22%E3%82%B3%E3%83%A1%E3%83%B3%E3%83%88%202019-05-13%20144906.jpg%22%20%2F%3E%3C%2FSPAN%3E%3C%2FP%3E%0A%3CP%3EAdd%20the%20following%20tag%20as%20a%20child%20of%20the%20manifest%20assembly%20tag%3AIf%20you%20have%20more%20than%20one%20class%20to%20use%2C%20add%20multiple%20activatableClass%20tags.%3C%2FP%3E%0A%3CPRE%3E%26lt%3Bfile%20name%3D%22WindowsRuntimeComponent1.dll%22%26gt%3B%0A%20%20%26lt%3BactivatableClass%0A%20%20%20%20%20%20name%3D%22WindowsRuntimeComponent1.Class1%22%0A%20%20%20%20%20%20threadingModel%3D%22both%22%0A%20%20%20%20%20%20xmlns%3D%22urn%3Aschemas-microsoft-com%3Awinrt.v1%22%20%2F%26gt%3B%0A%26lt%3B%2Ffile%26gt%3B%3C%2FPRE%3E%0A%3CP%3EThen%20add%20a%20NuGet%20package%20named%20Microsoft.VCRTForwarders.140%20to%20your%20WPF%20project.As%20of%20May%2013%2C%202019%2C%20it%20is%20still%20a%20preview%2C%20so%20check%20to%20include%20a%20preview%20when%20searching%20in%20NuGet%20Package%20Manager.%3C%2FP%3E%0A%3CP%3E%3CSPAN%20class%3D%22lia-inline-image-display-wrapper%20lia-image-align-inline%22%20style%3D%22width%3A%20999px%3B%22%3E%3CIMG%20src%3D%22https%3A%2F%2Fgxcuf89792.i.lithium.com%2Ft5%2Fimage%2Fserverpage%2Fimage-id%2F113119iC8E2AADC1A9AA662%2Fimage-size%2Flarge%3Fv%3D1.0%26amp%3Bpx%3D999%22%20alt%3D%22Comments%202019-05-13%201511142.%20jpg%22%20title%3D%22%E3%82%B3%E3%83%A1%E3%83%B3%E3%83%88%202019-05-13%20151142.jpg%22%20%2F%3E%3C%2FSPAN%3E%3C%2FP%3E%0A%3CP%3ESince%20the%20last%20Any%20CPU%20does%20not%20work%2C%20it%20should%20be%20built%20on%20x86%20or%20x64.Let's%20open%20Configuration%20Manager.I'm%20trying%20to%20set%20it%20to%20x86%20here.%3C%2FP%3E%0A%3CP%3E%3CSPAN%20class%3D%22lia-inline-image-display-wrapper%20lia-image-align-inline%22%20style%3D%22width%3A%20424px%3B%22%3E%3CIMG%20src%3D%22https%3A%2F%2Fgxcuf89792.i.lithium.com%2Ft5%2Fimage%2Fserverpage%2Fimage-id%2F113120i5A4528012F807D47%2Fimage-size%2Flarge%3Fv%3D1.0%26amp%3Bpx%3D999%22%20alt%3D%22Comments%202019-05-13%20151517.jpg%22%20title%3D%22%E3%82%B3%E3%83%A1%E3%83%B3%E3%83%88%202019-05-13%20151517.jpg%22%20%2F%3E%3C%2FSPAN%3E%3C%2FP%3E%0A%3CP%3EMake%20the%20Active%20solution%20platform%20x86.At%20this%20point%2C%20the%20WPF%20project%20is%20still%20in%20the%20Any%20CPU%2C%20so%20let's%20make%20it%20x86.%3C%2FP%3E%0A%3CP%3E%3CSPAN%20class%3D%22lia-inline-image-display-wrapper%20lia-image-align-inline%22%20style%3D%22width%3A%20999px%3B%22%3E%3CIMG%20src%3D%22https%3A%2F%2Fgxcuf89792.i.lithium.com%2Ft5%2Fimage%2Fserverpage%2Fimage-id%2F113121i161119B18DFB6847%2Fimage-size%2Flarge%3Fv%3D1.0%26amp%3Bpx%3D999%22%20alt%3D%22Comments%202019-05-13%20151735.jpg%22%20title%3D%22%E3%82%B3%E3%83%A1%E3%83%B3%E3%83%88%202019-05-13%20151735.jpg%22%20%2F%3E%3C%2FSPAN%3E%3C%2FP%3E%0A%3CP%3EThe%20Windows%20runtime%20components%20are%20now%20available%20from%20the%20WPF%20project.Let's%20use%20it%20immediately.%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3EEdit%20the%20MainPage.xaml%20as%20follows...%3C%2FP%3E%0A%3CPRE%3E%26lt%3BWindow%20x%3AClass%3D%22WPFandWinRTComponent.MainWindow%22%0A%20%20%20%20%20%20%20%20xmlns%3D%22http%3A%2F%2Fschemas.microsoft.com%2Fwinfx%2F2006%2Fxaml%2Fpresentation%22%0A%20%20%20%20%20%20%20%20xmlns%3Ax%3D%22http%3A%2F%2Fschemas.microsoft.com%2Fwinfx%2F2006%2Fxaml%22%0A%20%20%20%20%20%20%20%20xmlns%3Ad%3D%22http%3A%2F%2Fschemas.microsoft.com%2Fexpression%2Fblend%2F2008%22%0A%20%20%20%20%20%20%20%20xmlns%3Amc%3D%22http%3A%2F%2Fschemas.openxmlformats.org%2Fmarkup-compatibility%2F2006%22%0A%20%20%20%20%20%20%20%20xmlns%3Alocal%3D%22clr-namespace%3AWPFandWinRTComponent%22%0A%20%20%20%20%20%20%20%20mc%3AIgnorable%3D%22d%22%0A%20%20%20%20%20%20%20%20Title%3D%22MainWindow%22%20Height%3D%22450%22%20Width%3D%22800%22%26gt%3B%0A%20%20%20%20%26lt%3BStackPanel%26gt%3B%0A%20%20%20%20%20%20%20%20%26lt%3BTextBox%20x%3AName%3D%22textBox%22%20%2F%26gt%3B%0A%20%20%20%20%20%20%20%20%26lt%3BButton%20Content%3D%22Button%22%20Click%3D%22Button_Click%22%20%2F%26gt%3B%0A%20%20%20%20%20%20%20%20%26lt%3BTextBlock%20x%3AName%3D%22textBlock%22%20%2F%26gt%3B%0A%20%20%20%20%26lt%3B%2FStackPanel%26gt%3B%0A%26lt%3B%2FWindow%26gt%3B%3C%2FPRE%3E%0A%3CP%3EThen%2C%20in%20the%20code-behind%2C%20write%20the%20process%20using%20the%20Windows%20runtime%20components%20as%20follows%3A%3C%2FP%3E%0A%3CPRE%3Eusing%20System.Windows%3B%0A%0Anamespace%20WPFandWinRTComponent%0A%7B%0A%20%20%20%20%2F%2F%2F%20%26lt%3Bsummary%26gt%3B%0A%20%20%20%20%2F%2F%2F%20Interaction%20logic%20for%20MainWindow.xaml%0A%20%20%20%20%2F%2F%2F%20%26lt%3B%2Fsummary%26gt%3B%0A%20%20%20%20public%20partial%20class%20MainWindow%20%3A%20Window%0A%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20public%20MainWindow()%0A%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20InitializeComponent()%3B%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20private%20void%20Button_Click(object%20sender%2C%20RoutedEventArgs%20e)%0A%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20textBlock.Text%20%3D%20new%20WindowsRuntimeComponent1.Class1().GenerateMessage(textBox.Text)%3B%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%7D%3C%2FPRE%3E%0A%3CP%3ELet's%20run.%3C%2FP%3E%0A%3CP%3E%3CSPAN%20class%3D%22lia-inline-image-display-wrapper%20lia-image-align-inline%22%20style%3D%22width%3A%20613px%3B%22%3E%3CIMG%20src%3D%22https%3A%2F%2Fgxcuf89792.i.lithium.com%2Ft5%2Fimage%2Fserverpage%2Fimage-id%2F113122i4829CA4E10354EC4%2Fimage-size%2Flarge%3Fv%3D1.0%26amp%3Bpx%3D999%22%20alt%3D%22Comments%202019-05-13%20152704.jpg%22%20title%3D%22%E3%82%B3%E3%83%A1%E3%83%B3%E3%83%88%202019-05-13%20152704.jpg%22%20%2F%3E%3C%2FSPAN%3E%3C%2FP%3E%0A%3CP%3EYou%20can%20see%20that%20the%20WPF%20app%20calls%20the%20process%20that%20you%20made%20with%20the%20Windows%20runtime%20components.%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%3CSTRONG%3ESummary%3C%2FSTRONG%3E%3C%2FP%3E%0A%3CP%3EEven%20if%20you%20don't%20want%20to%20make%20it%20in%20the%20UWP%2C%20you're%20getting%20a%20lot%20of%20%22easy%22%20access%20to%20the%20features%20that%20are%20available%20for%20Windows%2010.%3C%2FP%3E%0A%3CP%3EWhen%20Windows%207%20support%20expires%2C%20Windows%2010%20will%20be%20able%20to%20focus%20considerably%2C%20so%20I%20think%20that%20you%20can%20make%20a%20desktop%20app%20that%20made%20various%20features%20of%20Windows%2010%20using%20the%20features%20of%20this%20neighborhood.%3C%2FP%3E%3C%2FLINGO-BODY%3E
Microsoft

しばらく前に以下のような記事が上がってました。

Enhancing Non-packaged Desktop Apps using Windows Runtime Components

 

特に msix や appx などにパッケージングされてないアプリから Windows Runtime コンポーネントの呼び出しが可能になってます。

 

試してみよう

ということで試してみたいと思います。

普通の .NET Framework の WPF アプリケーションを作成します。そして、Windows Runtime Component (Universal Windows - C++/CX) のプロジェクトを追加します。そして、WPF アプリケーションから Windows Runtime Component プロジェクトへの参照を追加します。以下のような感じになります。

コメント 2019-05-13 125611.jpg

 

Class1 に簡単な処理を追加します。名前を受け取って簡単なメッセージを返す処理を追加しました。

#pragma once

namespace WindowsRuntimeComponent1
{
    public ref class Class1 sealed
    {
    public:
        Class1();
		Platform::String^ GenerateMessage(Platform::String^ name);
    };
}
#include "pch.h"
#include "Class1.h"

using namespace WindowsRuntimeComponent1;
using namespace Platform;

Class1::Class1()
{
}

Platform::String^ Class1::GenerateMessage(Platform::String^ name)
{
	return "Hello" + name;
}

ビルドすると winmd ファイルや dll ファイルが生成されます。プロジェクト参照を追加してるので WPF プロジェクトの出力フォルダーにも関連ファイルが追加されています。

コメント 2019-05-13 145811.jpg

 

.NET 側から Windows ランタイム コンポーネントを呼ぶには dll も必要なので WPF のプロジェクトのプロパティのビルドイベントのビルド後のイベントとして以下のようなコマンドを追加して dll をコピーするようにしておきます。

copy /Y $(SolutionDir)\$(Configuration)\WindowsRuntimeComponent1\*.dll $(TargetDir)

dll が出力フォルダーにコピーされるようになったので、使う Windows ランタイム コンポーネントをマニフェストに指定します。WPF プロジェクトに app.manifest を追加します。

コメント 2019-05-13 144906.jpg

マニフェストの assembly タグの子として以下のようなタグを追加します。使うクラスが複数ある場合は activatableClass タグを複数追加してください。

<file name="WindowsRuntimeComponent1.dll">
  <activatableClass
      name="WindowsRuntimeComponent1.Class1"
      threadingModel="both"
      xmlns="urn:schemas-microsoft-com:winrt.v1" />
</file>

そして、Microsoft.VCRTForwarders.140 という名前の NuGet パッケージを WPF プロジェクトに追加します。2019 年 5 月 13 日時点では、まだプレビューなので NuGet パッケージマネージャーで検索するときはプレビューを含めるにチェックを入れて検索してください。

コメント 2019-05-13 151142.jpg

最後に Any CPU では動かないので x86 か x64 でビルドするようにします。Configuration Manager を開きましょう。ここでは x86 に設定しようと思います。

コメント 2019-05-13 151517.jpg

Active solution platform を x86 にします。この時点では、まだ WPF のプロジェクトが Any CPU になってるので、ここを x86 にしましょう。

コメント 2019-05-13 151735.jpg

これで、WPF プロジェクトから Windows ランタイム コンポーネントが使えるようになりました。早速使ってみましょう。

 

MainPage.xaml を以下のように編集して…

<Window x:Class="WPFandWinRTComponent.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WPFandWinRTComponent"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <StackPanel>
        <TextBox x:Name="textBox" />
        <Button Content="Button" Click="Button_Click" />
        <TextBlock x:Name="textBlock" />
    </StackPanel>
</Window>

そして、コードビハインドで以下のように Windows ランタイムコンポーネントを使って処理を書きます。

using System.Windows;

namespace WPFandWinRTComponent
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            textBlock.Text = new WindowsRuntimeComponent1.Class1().GenerateMessage(textBox.Text);
        }
    }
}

実行してみましょう。

コメント 2019-05-13 152704.jpg

WPF アプリから Windows ランタイムコンポーネントで作った処理が呼べていることがわかります。

 

まとめ

UWP でつくらなくても Windows 10 向けに用意されている機能に色々"簡単に"アクセスできるような下回りが揃ってきています。

Windows 7 のサポートが切れると、Windows 10 にかなりフォーカス出来るようになってくるので、ここらへんの機能を使って Windows 10 の機能を色々作ったデスクトップアプリが作っていけるようになると思います。