Hatena::ブログ(Diary)

ウィモバの日々

2017-04-17

UWPアプリではdllimportは使えるがWin32APIを自由に使えるわけではないらしい

UWPアプリのWebviewを色々と試してたんだけども、非常に残念なことになってしまった。。。

http://d.hatena.ne.jp/rideonshooting/20170324/1490350407

以前調べたら出てきた、UAを変更出来るUrlMkSetSessionOption関数は非常に便利に使えたんだけども

DebugビルドからReleaseビルドに変更してみると、Exception例外を吐いてアプリが動かなくなってしまった。

f:id:rideonshooting:20170417182138p:image:w640

この現象はWin10環境でもW10M端末でも同様に発生して困ってしまったぞい。


ビルドオプションを色々といじったり、DebugビルドとReleaseビルドオプションを比較してみると

どうやら[.NETネイティブツールチェーンでコンパイルする]のチェックを外すと問題なく動く、ということが分かった。

f:id:rideonshooting:20170417182741p:image:w320

なのでこの状態で動作確認し続けることにしたんだけども・・・


ネットを調べているとストアアプリを公開するために必要な手順があるという話を見つけたので

アプリパッケージを作成して「アプリ認定キット」でのテストを実施してみたところ

なんと「Binary Analyzer」と「サポートされている API」が不合格になってしまった。

f:id:rideonshooting:20170417191720p:image

f:id:rideonshooting:20170417191900p:image


確認のためにデフォルトのUWPプロジェクトを新規作成して確認したところ、リソースの既定イメージでの不合格だけが出るが

UrlMkSetSessionOption関数を追加+実行出来るように[.NETネイティブツールチェーンでコンパイルする]の

チェックを外したところ、同じように「Binary Analyzer」と「サポートされている API」が発生してしまった。

Windows ストア アプリ用の Windows SDK の一部ではない API を使用することは Windows ストアの認定要件に違反しています」という一文がヘヴィーだねえ。


うーん。dllimport自体は提供されていて機能として使えるけど、APIによってはストアアプリに公開するのは無理っぽい。

まぁ低レベルなWin32API自由に扱えちゃったらUWPのセキュリティ的な問題が危ないし仕方ないのかなー。

UserAgentをどう偽装すればいいのか・・・

UWPアプリ難しいね。

2017-03-29

UWPアプリのボタン等に表示しているアイコンをプログラムで変更する方法

絶賛迷走中の俺、参上!なんだか謎のプログラム意欲が出てきてUWPアプリの作り方を勉強中。

今更Windows10Mobileの誰も望んでいない劣化パクリなアプリを作ることに意味はあるのか分からないけどがんばるぞい!


ということでUWPで画面に表示しているボタンのアイコンの変更方法についてのメモ。

xaml上にボタンを配置する場合には

<AppBarButton Icon="Refresh" x:Name="buttonRefresh" Tapped="buttonRefresh_Tapped" />

といったようにIcon=〜でアイコン名を指定することで予め用意されているシンボルアイコンが表示される。

それをプログラム中に画面の状態なんかによって変更したい場合には

buttonRefresh.Icon = new SymbolIcon(Symbol.Cancel);

buttonRefresh.Icon = new SymbolIcon(Symbol.Refresh);

というようにシンボルアイコンを指定し直せば切り替わる。

定義されているアイコン一覧は下記にまとまっている。

https://msdn.microsoft.com/en-us/library/windows/apps/hh770557.aspx


シンボルアイコン以外にも独自のアイコンを作って表示も出来るようだけどそれはまた別の話。

2017-03-24

UWPアプリでWebViewを使ってブラウザを作りたいメモ

VisualStudioでWindows10とWindows10Mobile向けにUWPアプリを作れるようにはなったけど

盆暗な自分にいいアイディアがあるわけもなく・・・とりあえず簡単な勉強でもしてみるかーということで

そういえばW10M向けにはOpera miniがあるんだけど、何故かストアからインストール出来ない状態になっている。

のでなんかそういうのを作れたらいいなー?と、なんとなくWebブラウザの作り方を調べてみる。



  • シンプルなブラウザは参考サイトを見れば作れる

WebViewコントロールで簡易Webブラウザを作るには?[Windows 8.1ストア・アプリ開発]:WinRT/Metro TIPS - @IT

WebViewを使ってHTMLコンテンツを表示させる | Think IT(シンクイット)

WebViewコントロールの簡単な使い方の説明とサンプルソースが記載されているので

どちらかにあるソースをそのままコピペして持ってくれば、シンプルなブラウザは一応出来る。


[Windows 10]UWPアプリでWebViewコントロールを使ってみた。 | 初心者備忘録

こちらはJavaScriptを併用した版。Javaスクリプトでもコントロールを制御出来るっぽい。


Web view - UWP app developer | Microsoft Docs

Microsoftのサイトではさらに細かいWebViewの使い方やイベント等についての説明がある。


このあたりを見ればWebViewコントロールを利用した簡単なブラウザは作成出来る。

ただ、そのままではPC向けサイトが表示されるのでW10M端末で使うためにはモバイル向けサイトを表示させる工夫が必要になる。



  • モバイル向けサイトを表示するためUserAgentでモバイル端末に偽装する

ということで、UserAgentを仕込んでモバイル端末に偽装することにする。

@ITのサンプルだと、Goボタンを押下した場合に

Uri newUri;

〜中略〜

webView1.Navigate(newUri);

という風にNavigate関数で開くページのurlを指定しているので、これを

HttpRequestMessage HttpRequestMessage = new HttpRequestMessage(HttpMethod.Get, newUri);

var add = "Mozilla/5.0 (iPhone; CPU iPhone OS 9_3_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13E238 Safari/601.1";

HttpRequestMessage.Headers.Add("User-Agent", add);

this.webView1.NavigateWithHttpRequestMessage(HttpRequestMessage);

といったようにNavigateWithHttpRequestMessage関数UAを付加してやれば、PC向けでなくモバイル向け(上だとiPhone向け)サイトが表示される。

f:id:rideonshooting:20170324213435p:image:w480

だが、これだとサイト上のリンクを直接クリックした場合にはUAが付加されないため、リンク先の表示はPC向けになってしまう。

そのためリンクをクリックした際もUAを付加する工夫が必要になる。



  • 対応1:NavigationStartingイベントでUA強制付加→問題あり

Navigate〜関数を呼んだり、画面上のリンクをクリックすることでNavigationStartingイベントが走る。

これを利用して、NavigationStartingイベント内でUAを付加しようとする対応策がこちら。


c# - Change default User-Agent in WebView UWP - Stack Overflow

イベント内で強制的にキャンセルし、UAを付けたNavigate〜呼んでイベント処理している。

この方法では確かにYahooサイトがモバイル向け表示になり、ニュース等をクリックして進めていってもモバイル向けのままだった。

しかし、残念ながらイベントを書き換えているせいかヘッダを強引に書き換えて処理しているせいか

画面制御がおかしくなっているようでYahooのログイン処理がうまくいかず、ログインが出来ない状態になってしまった。

なので別に対策が必要な模様。



  • 対応2:UrlMkSetSessionOptionでUAを変更

さらに調べていると、こんな素晴らしいテクニックを公開しているサイト様を発見。

Windows Phone の WebView でUser-Agent を変更する - kazuakix の日記

[DllImport("urlmon.dll", CharSet = CharSet.Ansi)]

private static extern int UrlMkSetSessionOption(int dwOption, string pBuffer, int dwBufferLength, int dwReserved);

const int URLMON_OPTION_USERAGENT = 0x10000001;

public void ChangeUserAgent(string Agent)

{

UrlMkSetSessionOption(URLMON_OPTION_USERAGENT, Agent, Agent.Length, 0);

}

なんと、WinAPIのUrlMkSetSessionOption関数でUserAgentを変更する機能が使えるとのこと。

ていうか、UWPアプリでもdllimportでネイティブAPI呼び出し機能って使えたんだねー、びっくり。

W10MでOpenCVとか外部ライブラリを使う場合はどうするんだろ・・・さすがにARM向けにビルドして取り込んだりするのかな?

f:id:rideonshooting:20170326192721p:image:w180

そんな疑問は置いておいて、この手順を取り入れたら実機のKATANA01でもYahooのモバイル表示&ログインが成功した!すごーい!