読者です 読者をやめる 読者になる 読者になる

アズタケの開発日誌

備忘録を兼ねて作ってしまいました。さて、今回は何日坊主になるか・・・

UWPで透過ウィンドウを作る

おはようございます。

ついにWindows10 Creators Updateが4/11(上級者向け手動インストールは4/5)から一般公開されます。

CreatorsUpdateでは、UWPに関する様々な更新があります。
その中でグラフィック面で面白いものがありましたので備忘録がてら紹介します。

事前準備

現時点ではCreatorsUpdate自体もまだInsiderPreviewとなります。
CreatorsUpdate関係のAPIを使うためにはWindows10 SDK Insider 15063 などのSDKを入れましょう。
Download Windows Insider Preview SDK

Composition(Windows.UI.Composition)

Compositionを使用することでグラフィックに関する処理を行うことが出来、その一つには透過ウィンドウがあります。

http://gyazo.ingen084.net/data/2372467f42577d3ba1f7288aeccee3c1.png

このようにすりガラスのようにウィンドウの裏側を透過してくれます*1
また、この透過はアクティブウィンドウであることが条件であり、アクティブでなくなると数秒で透過状態ではなくなります。もしUIとして使うのであればエフェクトで透過のレベルを下げたり、アニメーションを使用しなければ違和感が出てしまうことに注意が必要そうですね。

透過には、 `Windows.UI.Composition.Compositor` が提供している `CreateHostBackdropBrush()` を使用することによりウィンドウの裏に対してぼかしをかけたブラシを得ることが出来ます。

具体的にサンプルとして示すとこのようになります。

var _compositor = ElementCompositionPreview
	.GetElementVisual(this).Compositor;
var _hostSprite = _compositor.CreateSpriteVisual();
_hostSprite.Size = new Vector2(
	(float)対象とする要素.ActualWidth,
	(float)対象とする要素.ActualHeight);

ElementCompositionPreview.SetElementChildVisual(
	grid, _hostSprite);
			
_hostSprite.Brush = _compositor.CreateHostBackdropBrush();

だいぶ簡単に組めますね。エフェクトを付けるとさらに面倒になるけど今回は割愛します。いつかかけたら書きます。

尚実際に実行可能なサンプルは以下のGitHub上にアップしてあります
github.com

次あたりはもう少しきちんとした記事を書きたい…

追記(04/03 16:29): Windows 10 Mobile は現時点では透過されません。今後行われるかもしれませんが…。(理想はホームの背景が表示されたりとか)

*1:完全透過は今の所出来ません。ソースは定かではありませんが、セキュリティ上の都合というのをどこかで見かけた覚えがあります[信用できない言葉]

CoreRTでnugetのパッケージ参照を自動的にIlcReferenceさせる話

昨日に続いて.NetNative(CoreRT)に関するものです。

現在の最新版(master)ではパッケージ参照を追加したとしてもIlcReferenceを行わないため、仮にパッケージ参照を行い、Program.csで該当メソッドを使用したとしても以下のようにFileNotFoundExceptionが発生してしまいます。

Unhandled Exception: System.IO.FileNotFoundException: Could not load file or assembly '<社内ライブラリ>.Context'. The system cannot find the file specified.
File name: '<社内ライブラリ>.Context'
   at corerttest!<BaseAddress>+0x2e291806
   at corerttest!<BaseAddress>+0x2e29010f
   at corerttest!<BaseAddress>+0x2e27216a
   at corerttest!<BaseAddress>+0x2e271cce
   at corerttest!<BaseAddress>+0x2e261064
--------------------------------------------------
Debug Assertion Violation

Message: FailFast

Expression: 'ASSERT_UNCONDITIONALLY'

File: C:\corert\src\Native\Runtime\EHHelpers.cpp, Line: 498
--------------------------------------------------

これを解決するために探した結果、昨日も記載してあるこ↑こ↓に行きつくわけですが、nugetパッケージ参照は手動でIlcReferenceを記載しなくてはなりません。
イッシューでメンバーの方が「そんなに難しくないからtargetsリバースエンジニアリングしてみ!」と言っている*1し、今までMSBuildファイル等はいじったことがない*2ので、どうせなのでやってみようってことでやってみました。

Targetの構文が変わっているのか、Stackoverflowなど参考にしても中々うまくいかなかったのが印象的でしたが、MSBuildファイルは操作できることが多く、結構複雑なことまで*3出来ることに驚きました。まるで簡単なスクリプトエンジンみたい。

さて本題に戻すと、以下のような記載をcsproj内に追加すれば出来ました。

  <Target Name="SetReferences" BeforeTargets="IlcCompile">
    <ItemGroup>
      <IlcReference Include="%(ReferencePath.Identity)" />
    </ItemGroup>
  </Target>

サンプルとして全体としてはこうなります。

<Project ToolsVersion="15.0">
  <Import Project="$(MSBuildSDKsPath)\Microsoft.NET.Sdk\Sdk\Sdk.props" />
  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>netcoreapp1.1</TargetFramework>
  </PropertyGroup>
  <ItemGroup>
  	<PackageReference Include="[社内ライブラリ].Context" Version="0.1.0-alpha-000022" />
  </ItemGroup>
  <Target Name="SetReferences" BeforeTargets="IlcCompile">
    <ItemGroup>
      <IlcReference Include="%(ReferencePath.Identity)" />
    </ItemGroup>
  </Target>
  <Import Project="$(MSBuildSDKsPath)\Microsoft.NET.Sdk\Sdk\Sdk.targets" />
  <Import Project="$(IlcPath)\Microsoft.NETCore.Native.targets" />
</Project>

出来れば最新のdotnet cliで生成されたものをベースにしたい所ではありますが、最新のdotnet cliベースで作成して.NETCore.Nativeをインポートしてビルドするとこうなります。

IlcCompile:
  ディレクトリ "native\" を作成しています。
  "C:\corert\bin\Product\Windows_NT.x64.Release\packaging\publish1\CoreRun.exe" "C:\corert\bin\Product\Windows_NT.x64.
  Release\packaging\publish1\ilc.dll" @"native\dotnetnewtest.ilc.rsp"
LinkNative:
  link  @"native\link.rsp"
LINK : fatal error LNK1181: 入力ファイル 'native\.obj' を開けません。 [C:\Users\azuta\Downloads\dtnt\dotnetnewtest\dotnetnewtest.cs
proj]
C:\corert\bin\Product\Windows_NT.x64.Release\packaging\publish1\Microsoft.NETCore.Native.targets(151,5): error MSB3073
: コマンド "link  @"native\link.rsp"" はコード 1181 で終了しました。 [C:\Users\azuta\Downloads\dtnt\dotnetnewtest\dotnetnewtest.csproj
]
プロジェクト "C:\Users\azuta\Downloads\dtnt\dotnetnewtest\dotnetnewtest.csproj" (LinkNative ターゲット) のビルドが終了 しました -- 失敗。


ビルドに失敗しました。

"C:\Users\azuta\Downloads\dtnt\dotnetnewtest\dotnetnewtest.csproj" (LinkNative ターゲット) (1) ->
(LinkNative ターゲット) ->
  LINK : fatal error LNK1181: 入力ファイル 'native\.obj' を開けません。 [C:\Users\azuta\Downloads\dtnt\dotnetnewtest\dotnetnewtest.
csproj]
  C:\corert\bin\Product\Windows_NT.x64.Release\packaging\publish1\Microsoft.NETCore.Native.targets(151,5): error MSB30
73: コマンド "link  @"native\link.rsp"" はコード 1181 で終了しました。 [C:\Users\azuta\Downloads\dtnt\dotnetnewtest\dotnetnewtest.cspr
oj]

    0 個の警告
    2 エラー

経過時間 00:00:17.14

まだプレビュー版なので致し方無いでしょうが、構文などが結構シンプルになっているので、早めに対応してほしいですね。

*1:英語力ガバガバなので信用してはいけない

*2:編集させる系は今まで全部外部ツールに投げたりPowershell実行させたり

*3:一定の水準超えたらタスクとしてdllファイル作った方が早いかもしれませんが

CoreRTで外部ライブラリを使用する際に詰まった件

(新年)初投稿です。
相当期間が開いてしまいましたが…

.NetNativeがどこまで使用できるかをリサートしている時に、外部ライブラリの参照で詰まったのでメモ程度に書き残しておきます。
昔のバージョンのdotnet cliではそのまま --native をつけることによりネイティブでビルド出来ていたようですが、今は分離されているようです。
github.com

この記事ではVisual Studio 2017をビルドツールとして使用しています。
また、CoreRTをクローンしてきてCドライブ直下に展開しています(書きやすくするため)

まずは結論から。
CoreRTのビルドがReleaseだろうが、アプリケーションのビルドがReleaseだろうが、外部ライブラリはDebugである必要があるみたい。おそらく方法はあると思うのでわかり次第記事にします

どうやらReleaseビルドでかつ、awaitを外部ライブラリで使用しているとこの問題が起きる模様。サンプル作成しました
github.com

PS C:\corert> .\build.cmd vs2017

このようにvs2017をつけることによりVisual Studio 2017 RCを使用してデバッグビルドでビルドさせることを*1明示しています。尚この記載が無く、Visual Studio 2015がインストールされていない場合はビルドが行われません。
ビルドが終わるまで結構時間がかかるので待ちましょう。日本語環境だとUnicodeの関係でテストに失敗するのが現れますが気にしない方針で行きます。

まずはここのテンプレートを見ながらcsprojを生成していじってみます。
安易な考えで

<Project ToolsVersion="15.0">
  <Import Project="$(MSBuildSDKsPath)\Microsoft.NET.Sdk\Sdk\Sdk.props" />
  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>netcoreapp1.1</TargetFramework>
  </PropertyGroup>
  <ItemGroup>
  	<PackageReference Include="<社内ライブラリ>.Context">
      <Version>0.1.0-alpha-000022</Version>
      <PrivateAssets>All</PrivateAssets>
    </PackageReference>
  </ItemGroup>
  <Import Project="$(MSBuildSDKsPath)\Microsoft.NET.Sdk\Sdk\Sdk.targets" />
  <Import Project="$(IlcPath)\Microsoft.NETCore.Native.targets" />
</Project>

のようにして、Program.csでテストコードでも書いてビルドを行ってみます。
ここで行うビルドは、Visual Studio についてる開発者コマンドプロンプトを使いましょう。x64でビルドしたらx64の開発者コマンドプロンプトを使用してください。

C:\Users\azuta\Downloads\dtnt\corerttest>dotnet restore /p:IlcPath=C:\corert\bin\Product\Windows_NT.x64.Debug\packaging\publish1
dotnet build /t:LinkNative /p:IlcPath=C:\corert\bin\Product\Windows_NT.x64.Debug\packaging\publish1

これでビルドは通るはずです(執筆時点)

Microsoft (R) Build Engine version 15.1.545.13942
Copyright (C) Microsoft Corporation. All rights reserved.

  corerttest -> C:\Users\azuta\Downloads\dtnt\corerttest\bin\x64\Debug\netcoreapp1.1\corerttest.dll

Build succeeded.
    0 Warning(s)
    0 Error(s)

Time Elapsed 00:00:24.11

結果の表示で.dllとなっているのは気にせず、そのまま bin\x64\Debug\netcoreapp1.1\native\ を見てみるとexeとpdbだけの2つが存在します。

試しにこのまま実行しようとしてみると例外が発生しました。

Unhandled Exception: System.IO.FileNotFoundException: Could not load file or assembly '<社内ライブラリ>.Context'. The system cannot find the file specified.
File name: '<社内ライブラリ>.Context'
   at corerttest!<BaseAddress>+0x2e291806
   at corerttest!<BaseAddress>+0x2e29010f
   at corerttest!<BaseAddress>+0x2e27216a
   at corerttest!<BaseAddress>+0x2e271cce
   at corerttest!<BaseAddress>+0x2e261064
--------------------------------------------------
Debug Assertion Violation

Message: FailFast

Expression: 'ASSERT_UNCONDITIONALLY'

File: C:\corert\src\Native\Runtime\EHHelpers.cpp, Line: 498
--------------------------------------------------

どうやらこのライブラリに存在するメソッドを呼ぼうとしている時に、このライブラリファイルが無いというエラーが発生している模様。PackageReferenceを指定しているのになぜ発生しているのかと気になって調べた所、イッシューに上がってました
どうやらIlcReferenceも一緒に書いてライブラリを指定してやる必要があるんだそうな。
そこで.nugetディレクトリ内にあるdllファイルを指定して再度restore、ビルド*2を行ってみた。

--------------------------------------------------
Debug Assertion Violation

Message: Hardware exception raised inside the runtime.

Expression: 'ASSERT_UNCONDITIONALLY'

File: C:\corert\src\Native\Runtime\EHHelpers.cpp, Line: 486
--------------------------------------------------

( ^ω^)・・・
意味不明なので調べてみたが、特にそれっぽい記事は無い。
仕方がないので試行錯誤してみた所、外部ライブラリが「Release」でビルドされていることに関係しているようだ。
外部ライブラリをDebugに変えてビルドしなおし、参照すると正しく動作する。

てっきりCoreRT側がReleaseビルドでないことが問題かと思い、

PS C:\corert> .\build.cmd vs2017 Release

のようにしてReleaseビルドでビルドして、再度アプリケーションのビルドを行っても変わらず*3
現在はローカルでビルドしたDebugビルドを使用していますが、出来ればnugetから取得したReleaseビルドのライブラリを使用したい所。
P.S. Releaseビルドでかつ、外部ライブラリ内でawaitを使用していると そこでエラー落ちしているようです。

また何か分かったら続きの記事書こうと思います。

*1:勿論インストーラC++選択してないとビルド出来ません

*2:ビルドされている感が無い(妙に早い)とかだったらbinとかobjとか消してみてください

*3:アプリケーション側も -c Release をつけてビルドを行うと、Debug Assertion Violationも出ず、「動作を停止しました」だけが表示されるようになります。

HoloLens Wave 4

おはようございます。

 

予想通りと言っていいものか、初回の記事を書いてから既に20日以上経過してました。

(だんだん書かなくなるまでの日数が減ってる気がする・・・)

 

さて、本題ですが、2~3日前についに公式ページでHoloLens Wave 4の表示になりましたね。

f:id:azutake1135:20160625050601j:plain

前回のWave3からの期間で考えると大体12日~14日ぐらいでしょうか。詳細な開始日を把握していないので気が付いた段階での日数ですが、

Wave1~Wave2の間が1.5ヶ月ほど

Wave2~Wave3の間が3~4週間ほど

Wave3~Wave4の間が12日ほど、といったように明らかにペースが上がっているように見えます。

私はWave 5なのでもう少しだけ先ですが、Wave5は一体どのくらいの日数になってしまうんでしょうかね。

 

てっきり一つのWaveで2~3ヵ月かかると思っていたら結構ペースが速く、HoloLensの購入招待のメールが来るまでにアプリのテスト版を仕上げられるかが少しだけ心配になってきました

ブログ始まってしまいました

5~6回目のブログ新設です。

いつも通りWordpressで立てるかASP.Net MVC5でブログシステムを作成するかでしばらく悩んでましたが、面倒なので前から気になってたはてなブログ使ってみました。

 

記事については基本的にC#XAMLWindowsに関することを書いていこうと思います。

1~2日の頻度で投稿していけたらなぁと思いますが、生暖かい目で見守っていただけると幸いです。

 

さて、今回は一体何日まで続くか・・・