rksoftware

Visual Studio とか C# とかが好きです

.NET Core 3.0 プロジェクトの発行でエラーになる

.NET Core 3.0 プロジェクトを Visual Studio 2019 Preview で発行をしようとすると、次のエラーが発生することがあります。

プロジェクト システムでエラーが発生しました。
ターゲット フレームワーク '.NETCoreApp,Version=v3.0' の mscorlib を解決できませんでした。これは、ターゲット フレームワークがインストールされていない場合、またはフレームワーク モニカーの形式が正しくない場合に発生する可能性があります。

診断ログは次の場所に書き込まれました: "XXXXXXXXX\VsProjectFault_XXXXXXXXXX.failure.txt"。

■ 対策

最新の .NET Core 3.0 SDK をインストールします。
発生時の私の環境では .NET Core 3.0 として 3.0.100-alpha1-009622 がインストールされていましたが、現時点のバージョン 3.0.100-preview-009812 をインストールすることで解決しました。

秋葉原 C# もくもく会 #67 勉強会を開催しました

■ C# もくもく会

C# もくもく会 #67 を開催しました。

C# もくもく会 は東京の秋葉原で毎週木曜日に開催している .NET 系の勉強会です。
もくもく自習を基本とし、分からないことを教えあったり情報共有したりしている会です。 定期開催していますので、お時間のある時に遊びに来ていただければと思います。
ちょっと詰まった時、ネット上で聞くのははずかしいなぁ、という課題のできた時などにも思い出していただけると嬉しいです。
f:id:rksoftware:20181214062037j:plain

■ 今週の成果発表

今週も成果を出された方の多い会でした。

  • Alexa スキルを申請寸前まで行きました
  • ブログを公開しました
  • GitHub にプッシュしました
  • 発表資料を作っていました
  • アドベントカレンダー書きました
  • MySQL のデータの復元に成功しました

ちなみに本会ですが、実は公序良俗に反しなければどのような技術を扱っても大丈夫です。そもそも C# エンジニアが C# だけしか使わないというわけではありませんし。

■初心者歓迎

このもくもく会には、入門者の方も多くご参加いただいています。 突然 C# やらなければならなくなって途方に暮れている方、何となく C# をやってきたけど改めて見直してみたい方なども大歓迎です。
入門セミナー代わりでのご参加も歓迎です。プログラミング入門者の方も是非遊びに来てください。

特に C# で課題をお持ちでなくても是非遊びに来てください。

■ 目指す勉強会スタイル

世界一敷居の低い勉強会を目指しています。

何か聞きたいことがある場合は、聞く相手を決めずに独り言のようにつぶやくと誰かが拾ってくれる

何か共有したい情報を見つけた場合も、聞く相手を決めずに独り言のようにつぶやくと誰かが拾ってくれる

そんなスタイルでやっています。

■ 次回予定

次回は 2019/01 に開催予定ですが日は確定していません。
代わりに、年末企画として3連休の最終日に C# の勉強会を開催します。C# 入門/再入門者向けのゆるふわな勉強会です。C# 2.0 ~ 7.0 までに追加された仕様の概要を勉強します。

C# に関心のある方、是非遊びに来てください。

Visual Studio の 15.9.4 がリリースされました

Visual Studio のアップデート 15.9.4 がリリースされました。
今回はすでに日本語が公開されています。しかし、ちょっとわかりにくいですね。

■ 更新内容

issue やフィードバックにリンクされている項目のリンク先を見てみましょう。
※項目名は前述のページよりの引用です。

  • Visual Studio 15.9 でソリューションのリロード時に開いているファイルが重複して読み込まれる。
    なんか前回のアップデート時に同じ項目を見た気がします。前回のアップデートでは Visual Studio の外で .csproj が更新されるなどして再読み込みされると、読み込み後に開いていたファイルが2重に開かれる問題が解消したと書いてありました。

  • すべてのユーザーがチーム エクスプローラーからオンプレミスの TFS サーバーに接続できる。
    刺激的な文言ですが、フィードバック(英語)を見ると逆の様です。特定の設定の TFS に接続できなくなる問題が解消されたようです。

  • GUI のビルド中にプロジェクトで定義されている項目の ItemDefinitionGroup のメタデータを Visual Studio 15.8.3 が拡張しない (Visual Studio 15.8.2 では可能)。
    Directory.Build.props ファイル内でメタデータが展開されない問題が解消されたようです。

  • Visual Studio で同じファイルに対する複数のタブがある。
    また一つのファイルが複数のタブで表示される問題ですね。このパターン人気ですね。

  • System.ArgumentException: パラメーターが正しくありません。(HRESULT からの例外: 0x80070057 (E_INVALIDARG))。
    Visual Studio を開くたびにエラーが表示される方がいたようです。Docker を使用するしていると発生していた...?

  • LNK4099 PDB が見つからない。
    ビルドをすると LNK4099 PDB 'xxxx.pdb' was not found. というエラーが発生する事があったようです。フィードバックを見てみると C++ っぽいですね。

  • 資産カタログが空になる。
    Xamarin.iOS でアセットカタログが表示されない問題があったようです。

  • /ZW を使用した C++ コードで /analyze が失敗する。
    C++ の UWP と Xbox One XDK でビルドに失敗することがあったようです。

  • C++ コンパイラのコード最適化のバグ。
    C++ の DirectX でデバッグ実行時?にクラッシュする問題があったようです(クラッシュするのが実行したアプリなのか VS なのか読み取れませんでした)。

  • Xamarin.iOS でイメージ表示のイメージ資産を選択できない。
    前述のアセットカタログが読めない、の一種の様ですね。

  • 資産カタログのイメージ資産が含まれる共有プロジェクトを参照する iOS プロジェクトが Windows での読み込めない。
    これも前述のアセットカタログが読めない、の一種の様ですね。

  • VS 15.8.6 の iOS のスプラッシュスクリーンにイメージが読み込まれない。
    これも前述のアセットカタログが読めない、の一種の様ですね。

  • VS2017 15.8 の和集合/ビットフィールドの割り当てで bad codegen が発生することがある。
    C++ で 16ビット幅のビットフィールドに定数を代入すると 8ビットレジスタが使用されるパターンがあったらしいです。

  • C# UWP ストア 1201 送信の問題の修正。
    作った UWP アプリをストアにサブミットするとエラーになる問題があったようです。

  • C# UWP パッケージ作成エラー APPX1101: ペイロードに同じ宛先パス 'System.Runtime.CompilerServices.Unsafe.dll' のファイルが 2 つ以上含まれている問題の修正。
    UWP でアンセーフコードを含んだライブラリを使用していると System.Runtime.CompilerServices.Unsafe.dll が重複してコンパイルエラーになる問題があったようです。

  • エラー MT2002: Xamarin.iOS プロジェクトの構築時に 'System.Threading.Tasks.Extensions...' を参照して 'System.Runtime.CompilerServices.AsyncValueTaskMethodBuilder' を解決できない。
    15.9 で含まれた System.Threading.Tasks.Extensions が不完全でビルドができない問題があったようです。

  • AndroidClientHandler を使用すると相対 URL へのリダイレクトが動作しない。
    モバイルアプリで AndroidClientHandler を使用した場合に問題があったようです。

その他

修正された脆弱性があります。 なるべく早くにアップデートするようにしましょう!

■ 更新方法

Visual Studio の更新はメニューの ツール > ツールと機能を取得 で開くインストーラーから行えます。

Xamarin で PApiHelper を使ってみる

以前に「プリザンターの API を扱う .NET ライブラリを書いてみた」記事を書きました。

今回は、このライブラリを Xamarin.Forms アプリで使ってみます。

■ 完成イメージ

一覧ページ

テーブルの ID を入力して [ 検索 ] ボタンでテーブルのデータをリスト表示します。
f:id:rksoftware:20181213013106j:plain
テーブルの ID を直接入力するスタイルでは少々アプリとして使い勝手は良くないかもしれませんが、テーブルを検索する API がないので今はこれが限界です。

詳細ページ

リストのタップで詳細を表示します。
f:id:rksoftware:20181213013127j:plain
API で取ってきた値を表示しているだけです。状況や管理者、担当者を表示していますが API で取ってくる値が名前でなくコード値なので若干アプリとしての使い勝手に難があるかもしれませんが、今はこれが限界です。
管理者、担当者は別途一覧で取得できる API があるので組み合せれば何とかなりそうですが、独自に作った選択肢項目などは頑張っても API 現状の API だけでは取れません。

■ ソリューションの作成

ソリューションは普通に Xamarin.Forms の空白ページのテンプレートで作成します。
今回は名前を PApiClient で作成しました。

■ NuGet の管理

今回のメイン。NuGet で PApiHelper を検索してすべてのプロジェクトにインストールします。
f:id:rksoftware:20181213013325j:plain

■ コード(App.xaml.cs)

まずは複数ページアプリにするいつもの手順です。 App.xaml.cs で MainPage に NavigationPage を設定します。

MainPage = new NavigationPage(new MainPage());

ファイル全体では次のようになります。

using System;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;

[assembly: XamlCompilation(XamlCompilationOptions.Compile)]
namespace PApiClient
{
    public partial class App : Application
    {
        public App()
        {
            InitializeComponent();

            MainPage = new NavigationPage(new MainPage());
        }

        protected override void OnStart()
        {
            // Handle when your app starts
        }

        protected override void OnSleep()
        {
            // Handle when your app sleeps
        }

        protected override void OnResume()
        {
            // Handle when your app resumes
        }
    }
}

■ 一覧ページ(MainPage.xaml/MainPage.xaml.cs)

一覧表示の画面です。プロジェクト新規作成時に作成された MainPage を書き換えて行きます。
UI には普通に ID を入力する Entry、API を叩く Button、一覧表示する ListView を並べています。

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:PApiClient"
             x:Class="PApiClient.MainPage">
    <StackLayout>
        <Label Text="ID:" HorizontalOptions="Start"/>
        <Entry x:Name="idEntry"/>
        <Button Text="検索" Clicked="Button_Clicked"/>
        <ListView HorizontalOptions="Fill" VerticalOptions="Fill"
                  x:Name="listView" ItemSelected="ListView_ItemSelected">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <ViewCell>
                        <StackLayout Orientation="Horizontal">
                            <Label Text="{Binding ResultId}"/>
                            <Label Text="{Binding ItemTitle}"/>
                        </StackLayout>
                    </ViewCell>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
    </StackLayout>
</ContentPage>

今回はサンプルコードを少なくするためにコードビハインドに書いています。
Button の Clicked で普通に API を叩いています。 注意点としては、ホストのアドレスと APIKey の設定があります。

ホストのアドレス

今回のテーマでの開発の場合、通常は Windows 10 Pro 環境を使っていると思います。その場合、Web のプロジェクトは IIS Express ではなく、ローカル IIS で実行する必要があります。アプリから Web へのアクセスは localhost ではなく、PC のアドレスを指定します(Android のエミュレーターの場合でも、ホストを指す 10.0.2.2 ではつながりません)。
mac と iOS シミュレーターの組み合わせの場合は、localhost でも行けるかもしれませんが、今回は Web が mac で動作しないため考える必要がありません。

ローカル IIS で実行する手順は別の記事に書いているので、準備の整っていない方は参考にしてください。

APIKey の取得

APIKey はメニューの [ API 設定 ] から取得します。APIKey は誤って公開しても何度でも [ 再作成 ] できるので恐れず GitHub を使って行きましょう。
f:id:rksoftware:20181213013355j:plain f:id:rksoftware:20181213013409j:plain

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms;

namespace PApiClient
{
    public partial class MainPage : ContentPage
    {
        public MainPage()
        {
            InitializeComponent();
        }

        // 検索ボタン
        private async void Button_Clicked(object sender, EventArgs e)
        {
            // 取得する ID
            long.TryParse(idEntry.Text, out var id);

            // Api クライアント準備
            var helper = new PApiHelper.PApiClient()
            {
                BaseUrl = "http://<ホストのアドレス>/Implem.Pleasanter",
                ApiKey = "<あなたのAPIKey>"
            };

            // 取得
            var items = await helper.PostGetItemsAsync(id, new PApiHelper.Models.PGetApiRequest());

            // View に表示
            listView.ItemsSource = items.Response.Data;
        }

        // リスト選択
        private async void ListView_ItemSelected(object sender, SelectedItemChangedEventArgs e)
        {
            var item = e.SelectedItem as PApiHelper.Models.DataModels.PApiItem;
            if (item == null) return;
            await Navigation.PushAsync(new DetailPage(item));
            listView.SelectedItem = null;
        }
    }
}

■ 詳細ページ(DetailPage.xaml/DetailPage.xaml.cs)

詳細ページは単純にデータを表示しているだけです。特に見どころはありません。
現時点での API では、テーブルの構成(どのようなカラムが使われているか等)を取得できないので、固定で項目を選別しています。
選択項目の値もコード値になっていて、いわゆる名前解決はできていません。
このあたりの解決には API の独自追加が必要になると思います。

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="PApiClient.DetailPage">
    <ContentPage.Content>
        <StackLayout>
            <Label Text="{Binding ResultId}"/>
            <Label Text="{Binding ItemTitle}"/>
            <Label Text="{Binding Status}"/>
            <Label Text="{Binding Manager}"/>
            <Label Text="{Binding Owner}"/>
        </StackLayout>
    </ContentPage.Content>
</ContentPage>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using Xamarin.Forms;
using Xamarin.Forms.Xaml;

namespace PApiClient
{
    [XamlCompilation(XamlCompilationOptions.Compile)]
    public partial class DetailPage : ContentPage
    {
        PApiHelper.Models.DataModels.PApiItem _item { get; }

        public DetailPage (PApiHelper.Models.DataModels.PApiItem item)
        {
            _item = item;
            InitializeComponent ();
            this.BindingContext = item;
        }
    }
}

■ 実行

これで、Xamarin.Froms で API をたたくシンプルなサンプルができました。
f:id:rksoftware:20181213013127j:plain
f:id:rksoftware:20181213013127j:plain

Android Emulator で使う Web サーバー API をデバッグする

Windows で ASP.NET と Android Emulator の組み合わせでデバッグする場合少し準備が必要です。
毎回忘れて苦労するのでメモを残します。

■ ASP.NET をローカル IIS でデバッグする

ASP.NET のデバッグ時、デフォルトでは IIS Express で動作するようになっていますが、ローカル IIS で動作するように設定をする必要があります。

1.ASP.NET プロジェクトのプロパティを開く  
2.左ペインで **Web** を選択  
3.**サーバー** 領域のコンボボックスで「ローカル IIS」を選択  

するのですが、環境を設定しないと選択肢が「IIS Express」「外部ホスト」の二つしかありません。

1.Windows の機能の有効化または無効化  
2.インターネット インフォメーション サービス > World Wide Web サービス のチェックを ON  
3.Visual Studio を管理者モードで再起動  

ここまでの手順を行いプロパティを開くと、選択肢が「IIS Express」「ローカルIIS」「外部ホスト」となります。

■ 実行時にエラー

上記手順を行ってもまだ動作しません。デバッグ実行すると、ブラウザに次のエラーが表示されます。

この構成セクションをこのパスで使用できません。この問題は、親レベルでセクションがロックされているときに発生します。ロック状態は既定で設定されているか (overrideModeDefault="Deny")、または overrideMode="Deny" もしくは従来の allowOverride="false" を含んだ場所タグによって明示的に設定されます。

1.C:\Windows\System32\inetsrv\Config の applicationHost.config ファイルを編集します。
<section name="modules" allowDefinition="MachineToApplication" overrideModeDefault="Deny" />

<section name="modules" allowDefinition="MachineToApplication" overrideModeDefault="Allow" />
2.Windows の機能の有効化または無効化  
3.インターネット インフォメーション サービス > World Wide Web サービス > アプリケーション開発機能 > ASP.NET 4.7 のチェックを ON  
※「.NET 拡張機能 4.7」「ISAPI フィルター」「ISAPI 拡張」も同時に ON になります。  

■ 再度実行

これでデバッグ実行すると ASP.NET アプリをデバッグできました。

参考

次のサイト/記事を参考にさせていただきました。とても助かりました。
https://yohei-nagatani.com/2016/03/500-19-80070021-iis/
https://ips.nekotype.com/4200/

Visual Studio 2019 Preview をインストールする

Visual Studio 2019 Preview が出ているのでインストールしてみました。

Visual Studio 2019 Preview のサイト

[ Download Preview↓ ] リンクでインストーラがダウンロードできます。
リンク先 → https://visualstudio.microsoft.com/ja/thank-you-downloading-visual-studio/?sku=enterprise&ch=pre&rel=16

■ インストール手順

ダウンロードした exe を実行するとインストーラが更新されます。
f:id:rksoftware:20181209192453j:plain

更新完了後、インストーラが立ち上がります。いつものインストーラですね。 f:id:rksoftware:20181209192510j:plain

ちなみにここで × すると、インストーラのメニュー?になります。これもいつもの。
f:id:rksoftware:20181209192529j:plain

インストール中も特に変わらず。
f:id:rksoftware:20181209192543j:plain

スプラッシュ。ちょっとダサい...?
f:id:rksoftware:20181209192601j:plain

Visual Studio 2019 起動。起動直後に新しい画面が追加されています。ソリューション(プロジェクト)の開き方が分かりやすくなっています。
最近開いた項目も引き継がれていますが、最初の起動時にすごい勢いで最近開いた項目が読み込まれて行きます。これまでいろいろ VS を使っていると少し時間がかかるようです。
f:id:rksoftware:20181209192617j:plain

アイコンが VS2017 と違っています。これだけ違えば間違えてしまうこともなさそうですね。
左が 2017、右が 2019 です。
f:id:rksoftware:20181209192435j:plain

■ ソリューション(プロジェクト)を開く

上から選んでいってみましょう。まずは、新機能? [ コードを複製またはチェックアウト ]。
リポジトリの URL とローカル パスを指定します。リポジトリから取得して開く良くある UI ですね。わかりやすくなっていますね。
これなら手順書さえ作っておけば、バージョン管理に不慣れなメンバーでも扱えるかもしれません。
f:id:rksoftware:20181209192632j:plain

[ プロジェクトやソリューションを開く ] と [ ローカル フォルダーを開く ] は普通にファイル選択のダイアログです。
わかりやすいですね。画像は省略。

[ 新しいプロジェクトの作成 ]。こちらはだいぶ変わっています。かつての左ペインのツリービューで選んだカテゴリのテンプレートが右ペインに表示されるスタイルから、画面右上のコンボボックスでカテゴリを選ぶスタイルになっています。
良いですね、これまでよりも素早く選べそうです。
f:id:rksoftware:20181209192703j:plain
f:id:rksoftware:20181209192726j:plain
f:id:rksoftware:20181209192741j:plain
f:id:rksoftware:20181209192754j:plain

しかしそれより一番使いそうなのが、検索ボックスです。画像は Xamarin で検索した様子。基本的にはコンボボックスよりもこっちでしょうね。
f:id:rksoftware:20181209192815j:plain

最後 [ Continue without code ]。ソリューション(プロジェクト)なしで Visual Studio が開きます。
f:id:rksoftware:20181209192828j:plain

インストール直後の状態で一つ通知がありました。Live Share の更新ですね。ぼっちなので更新は後で...。
f:id:rksoftware:20181209192841j:plain

■ インストール完了

ソリューション(プロジェクト)を開く・作成の周りが結構変わっています。リポジトリからコードを取得する手順が分かりやすくなったのが良いですね。
機能については、これからゆっくり見て行こうと思います。

プリザンターの API を扱う .NET ライブラリが使えるようになりました

先日、「プリザンターの API を扱う .NET ライブラリを書いてみました 」記事を書きました。

ライブラリは NuGet で公開したことも書きました。PApiHelper で検索してください。

■ 注意点がありました

公開していたこのライブラリですが、実は全機能は使えませんでした。
プリザンター自体のコードを変更しないと API が機能していないことも前述の記事に書いています。
不具合っぽかったので、実は記事にすると同時に PR も送っていたりしました。

f:id:rksoftware:20181208181111j:plain

■ 使ってみてください

先日送っていた PR を取り込んでいただけました!
これで、ライブラリが動きます。是非ライブラリを使ってアプリを作ってみてください。ライブラリは簡単に扱えると思いますので!