膨張空間

開発日記を中心に、時々雑記を投稿します。よろしく

Could not find 'aspnetcorev2_inprocess.dll'. Exception messageの対処法

環境

事象

NetCore3.1を対象としたASP.NetCore WebApiをIIS上に公開して、アクセスするとイベントビュワーに以下のメッセージが表示されて、IISが正常に起動しない。 WebApiからのレスポンスはHTTP500が返ってくる

Could not find 'aspnetcorev2_inprocess.dll'. Exception message:
指定されたコマンドまたはファイルが見つからなかったため、実行できませんでした。
次のような原因が考えられます:
  * 組み込みの dotnet コマンドのスペルが間違っている。
  * .NET Core プログラムを実行しようとしたが、dotnet-.\NarumiyaMobile.WebApi.dll が存在しない。
  * グローバル ツールを実行しようとしたが、プレフィックスとして dotnet が付いたこの名前の実行可能ファイルが PATH に見つからなかった。

原因

アプリケーションプールのIDが仮想フォルダに対してアクセス権を持っていない

  1. wwwroot以外の場所にファイルを置いていた。
  2. そのフォルダのセキュリティに明示的なIIS_IUSERSのアカウントを追加していた。
  3. アプリケーションプールのIDはデフォルトの「AppicationPoolIdentity」で設定されていた。

対応方法

アプリケーションプールのアクセス権とサイトを配置するフォルダのセキュリティが問題となっているため、考えられる対象方法はいくつかある。 1. フォルダをwwwrootに移す。wwwrootに置くとフォルダに対してIIS_IUSERS権限が付与されるのでアクセスできるようになる。

f:id:gshota:20210716163108p:plain
wwwrootフォルダパス
2. フォルダに対して「IIS_IUSERS」の権限を追加する。 - wwwroot上にフォルダが移動できない場合は、フォルダにIIS_IUSERSのアクセスを明示的に許可する
f:id:gshota:20210716163108p:plain
フォルダのセキュリティに明示的なユーザーを追加する
3. アプリケーションプールのIDをサイトを配置しているフォルダにアクセス可能なユーザーに明示的に設定する。明示的にユーザーを切りたい場合はこの方法で対応する。
f:id:gshota:20210716163246p:plain
アプリケーションプールのIDを明示的なユーザーにする

終わりに

表示されるメッセージとエラーの内容が合わなすぎて、解決するまで時間がかかった。インプロセスなんて全然関係ないじゃん…。調べて良くてできたのが、SDK SDKを2.2から3.1にアップデートしようとして、サーバー上に両方インストールされている場合にも発生するようだった。弊社の秘伝でIISにサイトを立てる時にIISユーザーを明示的に作成して指定する運用だったので、はまった。IIS7.0以上では明示的なユーザーの追加は必要ないらしい。フォルダも素直にwwwroot上に置いた方がいいということを学んだ。

参考

IISのIDについて Could not find 'aspnetcorev2_inprocess.dll'. Exception message .NET ツールの使用に関する問題のトラブルシューティング

スマホのバッチ表示をOFFにしたらQOLが上がった話

私はアプリケーションの通知が嫌いで基本的にOFFにしている。新しいアプリケーションをインストールした時もすぐにOFFにする。 数年前からIOSはアプリの初回起動時に通知を許可するか確認してくれるようになったらので、わざわざ設定からOFFしに行かなくてよくなり大変助かっている。 アプリケーションからの通知はいくつか種類があり、バッチ、バナー表示、ロック画面での表示などなどなどアプリケーション毎に、これはバナー表示していいですよ。これは何も通知しないでねと細かく設定が可能だ。 初回起動時の確認で許可しないにするとすべての通知がOFFになる。 今回、今まであまり制限していなかったバッチ表示の通知をOFFにしてみた。バッチ表示とはアプリケーションのアイコンの右上に表示される数字のことだ。あれも立派な通知である。 基本的に通知と言えばロック画面に浮かび上がってきたり、画面の上から垂れ下がってくるバナー表示を思い浮かべる。 あれは画面が動くのでとても目に付きやすく、とても邪魔なやつだ。 そんな目立つ邪魔者だけOFFにしてあまり目立たないバッチ表示は見逃して来た。 しかし、バッチ表示も立派な通知と前述したように目立たないだけで立派な邪魔者だった。 私が画面を開く度に赤く目立つ文字で、決して動くことはないが、しっかりとこちらに通知を送っていたのだ。 気が付かない間に「バッチ表示=タップする」と習慣付けられた私はまんまとアプリケーションを開いてしまい。 そのままおすすめ表示で縛り付けられる。バッチ表示の内容だけ確認するつもりが、気が付いたら1時間以上アプリケーションを触り続けていることもある。 これは本当に恐ろしい話だ。これに気が付いた私はすぐにバッチ表示をOFFにした。 結果としてこの行いは大成功だと確信している。 バッチ表示に操られていたころの私はいなくなり、ホーム画面を表示しても私を誘惑する物はない。 なにもバッチ表示までOFFにする必要はないじゃないかと思うかもしれない。しかし、すべての通知をOFFにして実感したことは、本当に必要な通知など、そうそうないということだ。 通知に操られることがなくなったので私の意思でアプリケーションをすることができるようになった。 便利なものも使い方次第で、自分で使っているようで、自分が使われているだけなのかもしれないという気持ちでうまく付き合っていきたい。

.NetCore3.1とDapperでOracleに接続する

未だに.NetFrameWorkを使用することが多く、.NetCoreでOracleに接続をしたことがなかった。 調べてみると以外と自分の環境とバッチリあっている記事が見当たらなかったので、自分用にサンプルを作成した。

ここにサンプルを配置した。

この記事で確認できること

.NetCore3.1でDapperを使用してOracleに接続できる

環境

C# Visualstudio2019 Comunity .NetCore 3.1 Dapper(軽量ORM:SQLは自分で書く。Modelのマッピングはして欲しいくらいの人が使いやすい)

ソース

ConnectionString は各環境に合わせて変更してください。 特別なことはしてしないので見てもらえばすぐに理解できるかと思う。 引数のParamをT(ジェネリック)で宣言してるが、DynamicParameterで宣言しても問題ない。 シンプルな環境であればClassをそのまま使った方がお手軽に使うことができる。

    public class DbClient
    {
        //接続情報保持用
        private DbConnection Connection { get; } = new Oracle.ManagedDataAccess.Client.OracleConnection();

        //コンストラクタ
        public DbClient()
        {
            //ここで接続情報を設定する
            Connection.ConnectionString = @"Data Source = (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=192.168.0.1)(PORT=1521))(CONNECT_DATA=(SERVICE_NAME=hoge))) ; User ID = foo; Password = tiger;";
            //接続開始
            Connection.Open();
        }

       //Select
        public IEnumerable<T> Select<T>(string sql, T param)
        {
            return Connection.Query<T>(sql, param);
        }

        //Update、Delete
        public void Update<T>(string sql, T param)
        {
            using (var trun = Connection.BeginTransaction())
            {
                Connection.Execute(sql, param);

                trun.Commit();
            }
        }
    }

【Alibaba】RDS for PPASでPostgresSQLの拡張機能を追加する方法

数時間単位ではまったので記録しておく。前にDB作成した時もはまったなこれ…

PostgresSQLには拡張機能が用意されている。通常はSuperUser権限を持ったアカウントで以下のコマンドを実行すると追加できる。

--SuperUserで実行する
create extension dblink
;
create extension pgcrypto
;

RDS for PPAS上のPostgresSQLにも、上記のSQLで追加したいところだが、 RDS for PPASにはSuperUser権限を持ったアカウントを作成することができない。

そのためコマンドを実行してもSuperUser権限持ってから出直してこい的なメッセージで弾かれてしまう。

詳しくは公式サイトを確認して欲しい。(このサイトもなかなか見つけにくいよ…)

RDS for PPASでは拡張機能を追加するための 共通管理関数 という関数で一般権限でも拡張機能を追加することができる 上記のコマンドは以下のように書く

-- create:追加する dblink:追加するオプション名 hoge:database名
select rds_manage_extension('create','dblink','hoge')
:
select rds_manage_extension('create','pgcrypto','hoge')
;

この関数の存在を忘れて何とかSuperUser権限を持ったユーザーが作成できないか。 それともログインパスワードを忘れただけなのかで数時間つぶしてしまった。

【EDB】関数dblink_exec()は存在しませんの解決策

普段Oracleを使用しているのだが、PostgresSqlを使用することになり、既存ソースを使用するためにEDBを選択した。 それからしばらくして新しいDatabaseを作成することになり、元々動いていたDBからテーブルやストアドやらをコピーして大体動いていたのだが、 一部のSQLで「関数dblink_exec()は存在しません」が表示されて結果が返ってこなかった。 コピー元と見比べて原因が分かったので記録しておく。

f:id:gshota:20210321141919p:plain
追加する必要があった拡張機能

拡張機能がDatabaseに追加されていないことが原因だった。 拡張機能が何をしているかは、追加で調べることにして取り急ぎ追加して正常に検索できるようになることを確認した

pgAdmin4で以下のSQLを実行する

CREATE EXTENSION dblink
;
CREATE EXTENSION pgcrypto
;

Windows10のタスクマネージャーを更新しようとするとエラーになる件

事象

Windows10でタスクスケジューラでタスク編集しようとすると以下のメッセージが表示されて更新できない メッセージ内容 「タスク〇〇でエラーが発生しました。エラーメッセージ:1つ以上の指定された引数が有効ではありません。」

f:id:gshota:20210317033745j:plain
タスクを更新しようとするとエラーになる

対応方法

全般タブのセキュリティオプションを確認する。 作者を確認すると「hogehoge¥hogehoge」のようになっている。タスク実行時に使うユーザーアカウントは「hoge」のようになっている。

f:id:gshota:20210317033922j:plain
セキュリティオプションを確認する

ユーザーまたはグループの変更ボタンを押下して、右下に表示される詳細設定ボタンを押す。次に検索ボタンを押す。検索結果のフォルダと一致するユーザーを選択する。

f:id:gshota:20210317035224j:plain
ユーザーまたはグループを変更する手順

以上

ちなみに別タブに移動したり、ポップアップが表示されたりしたら変更したユーザーがもとに戻ることがあった。変更したらすぐにタスクを確定したほうがいいようだ。何が原因なのかOSの不具合なのかわからないがこれでタスクの更新ができることを確認した。大した内容のタスクでなければ削除して作成しなおした方が良いかも。

CsvHelperでダブルクォーテーション付きのCSV出力をする方法(Ver26)

CsvHelperのバージョンを26に上げたら仕様がだいぶ変わってはまったので備忘録として記録する

この記事で達成できること

  1. CsvHelper ver26でダブルクォーテーション付きのCSVが出力できる
  2. 日本語のヘッダーを出力できる

書き方

/// <summary>
/// ファイル書き込み
/// </summary>
/// <returns></returns>
public void Write(IEnumerable<TModel> WriteData)
{
    var config = new CsvConfiguration(CultureInfo.InvariantCulture)
    {
        //ダブルクォーテーション付きにする
        ShouldQuote = (context) => true,
    };
    using (var writer = new StreamWriter(FilePath))
    using (var csv = new CsvWriter(writer, config) )
    {
        csv.Context.RegisterClassMap<FooMap>();
        csv.WriteRecords(WriteData);
    }
}

Class FooMap
{
    Map(m => m.hoge1).Index(0).Name("ヘッダー1");
    Map(m => m.hoge2).Index(1).Name("ヘッダー2");
    Map(m => m.hoge3).Index(3).Name("ヘッダー3");
}

//出力
ヘッダー1,ヘッダー2,ヘッダー3
hoge1の値,hoge2の値,hoge3の値

説明

// ver15の書き方
csv.Configuration.ShouldQuote = (s, context) => true;

こういう書き方をしている記事は古いのでブラウザバックしてください。 version 15では有効でしたがversion26ではConfigurationがReadOnlyプロパティに更新されたため上記のようにCsvConfigurationのコンストラクタで設定する必要があります。 注意するべき罠はもう一つあってShouldQuote の引数が1つになっていました。 公式サイトに書き方が書いてなかった(私は見つけられなかった)のでだいぶ苦労しました。

日本語のヘッダーを出力するために.Nameプロパティを定義します。 個人的にMapperクラスを定義した方が好きなので、アノテーションではなくこちらで書いています。 Indexで列を指定しないと出力順が保証されないそうです。公式サイトをGoogle翻訳した文章で理解したことなので必要があるかは謎ですが、入れていても問題なかったのでお守りだと思って入れたままにしています。 この記事を閲覧している人には釈迦に説法になると思いますが、「FooMap」「m.hoge1」などは説明上の仮値です。使用するクラスに合わせて変更してください。