アーカイブ

Archive for the ‘Visual Studio’ Category

.NET Framework → .NET Coreの移行可能難易度を評価してくれるAWSのPorting Assistant for .NET

AWSのブログでPorting Assistant for .NET といAWS製のツールが紹介されていました。

このツールは既存の.NET Frameworkのソリューションを読み取り、その中で利用されているNugetライブラリーの.NET Core対応状況や、ソースコードそのものがどれだけ移植しやすい状況かを確認するツールのようです。

ポートソリューションの機能を使うと、参照しているライブラリで移行可能なライブラリのバージョンを調整したり、プロジェクトファイルの構成を変更してくれるようです。

カテゴリー:ASP.NET, AWS, Visual Studio

Visual Studio Version 16.4.0のコンテナ用ツール

2019年12月4日 コメントを残す

.NET Core 3.1 に合わせて Visual Studio 2019 の最新版である Version 16.4.0 が同時に公開されましたが、このバージョンに含まれるコンテナ用のツールが結構よさげです。Kitematicでもいいんですが、表示されている情報が古かったりして微妙なことが多いので結構いいかも。

ツールメニュー > その他のウインドウ > コンテナー から起動できるこの子ですが、
vs20191204

コンテナを起動したり、起動しているコンテナの環境変数やポート情報を確認したり、
docker-env2

ログを表示したり、
docker-env

コンテナの中身のファイルして開いたり(!!)が簡単にできます。
残念ながらホストにファイルをコピーするなどは、ここからは行えないみたいですね。
docker-file

必要になったらコマンドアイコンをクリックすれば、コマンドプロンプトが開きます。
docker-terminal

統合ターミナル(Whack Whack Terminal)がインストールされていればそちらを起動してくれるみたいです。
docker-terminal2

Riderのコンテナツールもいい感じですよね

カテゴリー:Docker, Visual Studio

Viewのマイグレーションを考える

2019年3月18日 コメントを残す

異なるスキーマを参照するViewを作って、Entity Frameworkから参照したいという要件があって、Viewの更新管理をどうにかしたいなーと思っていたんだけれど、だいたい固まったのでメモしておく

方針としてはこんな感じ

  1. Viewの形のEntityを作り、DbContextにDbQueryとして公開する
  2. OnModelCreatingで、Query~ToViewで関連付ける
  3. 空のマイグレーションファイルを作り、upでcreate viewを、downでdrop viewを行う。スキーマの差し替えもこのタイミングで行う。

サンプル
https://github.com/karuakun/EntityFrameworkSchemaAcrossDbViewSample

EntityとDbContext

1,2はササッとこんな感じで
Data/Entities/QueryTest.cs

    public class Test1
    {
        [Key]
        public string Id { get; set; }

        public string Name { get; set; }
        public string QueryTest2Id { get; set; }
    }

Data/SampleDbContext.cs

    public class SampleDbContext: DbContext
    {
        public const string DefaultConnectionStringName = "sampledb";

        public SampleDbContext(DbContextOptions options) : base(options)
        {
        }

        public virtual DbQuery QueryTest2 { get; set; }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);
            modelBuilder.Query(entity =>
            {
                entity.ToView("v_seconddb_test2");
            });
        }
    }

マイグレーションの作成

DbContextにマイグレーションに関わる変更がない状態で、マイグレーションファイルを追加すると、空のマイグレーションファイルが出来上がるので、この子にViewの作成と削除を書いてあげる。

dotnet migrations add addsampleview

追加されたマイグレーションファイル

    public partial class addview : Migration
    {
        protected override void Up(MigrationBuilder migrationBuilder)
        {
        }

        protected override void Down(MigrationBuilder migrationBuilder)
        {
        }
    }

まずは単純に

create view にスキーマ名が入っているので気持ち悪い。。。

    public partial class addview : Migration
    {
        protected override void Up(MigrationBuilder migrationBuilder)
        {
            migrationBuilder.Sql(
                "create view v_seconddb_test2 as select Id, Name, Property1 from schema2.test2");
        }

        protected override void Down(MigrationBuilder migrationBuilder)
        {
            migrationBuilder.Sql("drop view v_seconddb_test2");
        }
    }

Configurationもしくは環境変数から、マッピングを取得する

Startup時に作るIConfigurationRootにアクセスできれば良いんだけれど、MigrationだとDIでConfigurationを受け取ることができない。
ConfigurationをStartupのstaticにしてあげるのは嫌なので、、、DesignTimeContextを使う

こんなクラスをプロジェクトのルートに置いておくと、dotnet efで起動した場合にこっちのコンテキストで初期化してくれる。これなら多少無茶してもいいかなぁ、、、と言うことで、IConfigurationRootをstaticで生やしてあげる。

    public class DesignTimeSampleDbContextFactory : IDesignTimeDbContextFactory
    {
        public static IConfigurationRoot DesignTimeConfiguration { get; private set; }

        public SampleDbContext CreateDbContext(string[] args)
        {
            DesignTimeConfiguration = DesignTimeConfigurationBuilder.BuildConfiguration(args);
            var builder = new DbContextOptionsBuilder()
                .UseMySql(DesignTimeConfiguration.GetConnectionString(SampleDbContext.DefaultConnectionStringName)
                );
            return new SampleDbContext(builder.Options);
        }
    }

Configurationを参照できれば、あとはJSONと環境変数の世界なので、appsettings.jsonにこんな感じでエントリを追加して

  "MigrationSettings": {
    "MigrationType": "Local",

    "SchemaMappings": {
      "Local": {
        "AppDb": "appdb", 
        "SecondDb": "seconddb"
      },
      "Stating": {
        "AppDb": "stg_appdb",
        "SecondDb": "stg_seconddb"
      }
    }
  },

設定を受けるようにこんなクラスを作っておく

    public class MigrationSchemaMappings
    {
        public string AppDb { get; set; }
        public string SecondDb { get; set; }
    }

で、手作業で作ったSQLがマイグレーションの海に埋もれるのは悲しいので、手作業で作った子はマイグレーション配下にこんな感じでmanualフォルダーを作って、そこに物理ファイルとしておいておきたい。
無題

マイグレーションの拡張メソッドとして、こんな感じのものを作っておけば、

    public static class MigrationExtensions
    {
        public static string GetSqlText(this Migration source, string migrationId, string fileName)
        {
            var sqlPath = Path.Combine(Environment.CurrentDirectory, "Migrations", "manual", migrationId, fileName);
            if (!File.Exists(sqlPath))
                throw new FileNotFoundException(sqlPath);

            var sqlText = File.ReadAllText(sqlPath);
            if (string.IsNullOrEmpty(sqlText))
                throw new InvalidOperationException($"sqlfile is empty: {sqlText}");

            var settings = GetMigrationSettings();
            var schemaReplacedSqlText = sqlText.Replace("$SecondDb$", settings.SecondDb);
            return schemaReplacedSqlText;
        }

        private static MigrationSchemaMappings GetMigrationSettings()
        {
            var configuration = DesignTimeSampleDbContextFactory.DesignTimeConfiguration;
            var migrationType = configuration.GetValue("MigrationSettings:MigrationType");
            return configuration.GetSection($"MigrationSettings:SchemaMappings:{migrationType}")
                .Get();
        }
    }

マイグレーションスクリプトはこうかける。

    public partial class addview : Migration
    {
        protected override void Up(MigrationBuilder migrationBuilder)
        {
            migrationBuilder.Sql(this.GetSqlText(this.GetId(), "up.v_seconddb_test2.sql"));
        }

        protected override void Down(MigrationBuilder migrationBuilder)
        {
            migrationBuilder.Sql(this.GetSqlText(this.GetId(), "down.v_seconddb_test2.sql"));
        }
    }
カテゴリー:ASP.NET, Visual Studio

ソリューションファイルとプロジェクトファイルが同じディレクトリにある状態で、Dockerサポート(Dockerfile)を作成すると、docker build時にビルドが失敗する。

2018年12月17日 コメントを残す

Visual StudioのソリューションエクスプローラーからDockerサポートの追加をして、docker build をしたところ、こんなエラーが出ました。
ログの全体はこんな感じ。

> docker build . -t sample
Sending build context to Docker daemon  339.5MB
Step 1/16 : FROM microsoft/dotnet:2.2-aspnetcore-runtime AS base
 ---> df0d46ff6229
Step 2/16 : WORKDIR /app
 ---> Using cache
 ---> e6407778a2d1
Step 3/16 : EXPOSE 80
 ---> Using cache
 ---> a17ec6fc7197
Step 4/16 : FROM microsoft/dotnet:2.2-sdk AS build
 ---> 343e2dc38168
Step 5/16 : WORKDIR /src
 ---> Using cache
 ---> 064e8cb7ff8d
Step 6/16 : COPY signalsample.csproj ./
 ---> 3361ca72b93c
Step 7/16 : RUN dotnet restore /signalsample.csproj
 ---> Running in d5b618d70751
MSBUILD : error MSB1001: Unknown switch.
Switch: /signalsample.csproj

For switch syntax, type "MSBuild /help"
The command '/bin/sh -c dotnet restore /signalsample.csproj' returned a non-zero code: 1

msbuild 時によくわからないスイッチがあると言われる。

For switch syntax, type “MSBuild /help”
The command ‘/bin/sh -c dotnet restore /signalsample.csproj’ returned a non-zero code: 1

dockerfileを見ると、

FROM microsoft/dotnet:2.2-aspnetcore-runtime AS base
WORKDIR /app
EXPOSE 80

FROM microsoft/dotnet:2.2-sdk AS build
WORKDIR /src
COPY signalsample.csproj ./
RUN dotnet restore /signalsample.csproj
COPY . .
WORKDIR /src/
RUN dotnet build signalsample.csproj -c Release -o /app

FROM build AS publish
RUN dotnet publish signalsample.csproj -c Release -o /app

FROM base AS final
WORKDIR /app
COPY --from=publish /app .
ENTRYPOINT ["dotnet", "signalsample.dll"]

8行目の restore でプロジェクトファイルの指定/から始まっていてこいつがスイッチとして認識されているっぽい。

RUN dotnet restore /signalsample.csproj

たぶん、dotnet コマンドからプロジェクトを作ったあとに、同じフォルダーにソリューションフォルダーを作った事が原因だと思われる。(dotnet build や dotnet publish はソリューションフォルダーが無いことを考慮しているのに、dotnet restore は考慮されていのか…)
とりあえず、/を取るか、./とするとdocker buildもdocker-compose buildもうまく通った。

RUN dotnet restore signalsample.csproj
カテゴリー:Visual Studio タグ:

Visual Studio 2017 15.9.2インストール後、15.8以前で作った、docker-composeプロジェクトがあると、ソリューションロード時にエラーダイアログが表示される。

2018年11月20日 コメントを残す

Visual Studio 2017を15.9.2にアップデートした後に、ソリューションを開いたらこんなダイアログが表示されました。
20181120-1

プロジェクト システムでエラーが発生しました。
パラメーターが間違っています。 (HRESULT からの例外:0x80070057 (E_INVALIDARG))
診断ログは次の場所に書き込まれました: “C:\Users\xxxxxxxx\AppData\Local\Temp\VsProjectFault_9eeb5562-6d00-4839-a077-abc0b27b60bf.failure.txt”。

診断ログにはこんなログが記載されていました。

=====================
2018/11/20 14:59:42
Recoverable
System.ArgumentException: パラメーターが間違っています。 (HRESULT からの例外:0x80070057 (E_INVALIDARG))
場所 EnvDTE.Projects.Item(Object index)
場所 Microsoft.VisualStudio.Docker.Shared.HierarchyExtensions.IsInStartupProjects(Hierarchy hierarchy, IServiceProvider serviceProvider)
場所 Microsoft.VisualStudio.Docker.Compose.ProjectSystem.ProjectLoadHandler.d__31.MoveNext()
— 直前に例外がスローされた場所からのスタック トレースの終わり —
場所 System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
場所 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
場所 Microsoft.VisualStudio.ProjectSystem.UnconfiguredProjectImpl.AutoLoadMethodStateMachine.d.MoveNext()
===================

この投稿を見ると、asp.net coreのプロジェクトでdocker-composeが入っているのに、docker-composeをスタートアッププロジェクトに指定してしないソリューションが問題を受けるみたいです。

E_INVALIDARG error when loading solution after upgrading to 15.9 (worked in 15.8)
https://developercommunity.visualstudio.com/content/problem/385450/e-invalidarg-error-when-loading-solution-after-upg.html

テスト用データベースや認証サービス、キャッシュサービスもdockerで起動しているので、asp.netをdocker起動にした場合、docker-composeでdepends_onを指定しないとネットワーク的に通信できないのでdocker-composeを導入したものの、起動に時間がかかるのでとりあえずdockerを使わないでデバックしているソリューションで問題が出ました。

docker-composeをスタートプロジェクトの一つに加えるか、ソリューションから除外したらダイアログは表示されなくなりました。
別にアラートが出てもデバックはできるし問題はないのですが、気になるなら暫くの間はdocker-composeをソリューションから除外しておいても良いかもしれません。

カテゴリー:ASP.NET, Visual Studio

ReSharperの Type in comment は日本語だとちょっと使いにくい

2018年8月23日 コメントを残す

ReShaper 2018.2 で Type in comment という機能が追加されています。
https://blog.jetbrains.com/dotnet/2013/01/14/respeller-a-spell-checking-plugin-for-resharper/

この機能を有効にすると、あらかじめ登録された辞書に基づいてタイプミスがないか指摘してくれるのですが、日本語の場合分かち書きがうまくできていないこともあり、単語の単位が微妙です。

デフォルトのInspectionレベルはSuggestionなので、ビルド自体には影響はないのですが、気になり場合は無効にする場合は、Action Indicatorから Do not Show を選択すれば消えてくれます。
サジェスチョンの無効

ReSharperのOptionsから、Spelling issues の Typo in comment を変更してもいいですね。
ReSharperの設定

カテゴリー:Visual Studio, 未分類 タグ:

dotCoverでテストカバレッジが表示されない場合、JetBrainsフォルダーのCoverageDataフォルダーを削除すると解決する

2018年8月22日 コメントを残す

ReSharperを導入してもらたので、UnitTestのカバレッジ表示にdotCoverを使っています。
UnitTestのカバレッジをとったら、UnitTestSessionsウインドウにこんなエラーが表示され、Unit Test Coverageウインドウにカバレッジが表示されなくなってしまいました。

Coverage analysis: Processing coverage snapshots: スナップショットのパス failed: Unknown storage type

キャプチャ

今回はここで触れらているように、%temp%\JetBrains\ReSharperPlatformVs14\vAny\CoverageData フォルダーをリネームしたところ、表示できるようになりました。
https://dotnettools-support.jetbrains.com/hc/en-us/community/posts/360000167744-Continuous-Testing-Failed-to-Process-Coverage-Results-The-given-key-was-not-present-in-the-dictionary-

カテゴリー:Visual Studio タグ:

ReSharperのテストランナーを使うとファイルを見失う、、、

2017年11月9日 コメントを残す

Visual Studioのテストランナーだとうまくいくのに、ReSharperのテストランナーを使うとうまくいかないケースが有った。

デバックでおっていってみると、相対パスにあるユニットテスト用の外部ツールを起動している部分で、ファイルを見失っている感じこんなコードがあるところで、

Process.Start(Path.Combine(Assembly.GetExecutingAssembly().Location, @”..\..\..\..\Hoge.exe”))

Visual StudioのテストランナーだとAssembly.GetExecutingAssembly().Locationには実行しているアセンブリのパスが入るんだけれど、ReSharperのテストランナーから実行するとこんなパスが入ってくる。「%LOCALAPPDATA%\Temp\0ywyjnls.q4g\dbsqoo3y.wab\HogeHoge.Test\assembly\dl3\8aa495c4\efd6deeb_4459d301\」

これは、ReShaperのテストランナーがユニットテスト前にDLLをシャドーコピーしてからテストを実施するためなので、Visual StudioのReSharperメニュー > Options > Tools > UnitTesting > Unit Test Runnerの Shadow-copy assemblies begin tested のチェックを外してあげれば Visual Studioのテストランナーと同じ挙動になる。
Reshaper-Shadow-Copy

カテゴリー:Visual Studio

Visual Studio 2017が起動しない場合、privateregistry.binを消してみよう

2017年9月15日 コメントを残す

どうもVisual Studio 2017を起動してもなかなか立ち上がってこない。タスクマネージャーを見ていると、ほとんどCPUを使わない状態で停止し待っている感じがする。

Visual Studioをログ出力モードで起動したら、「AppId starting registry detouring」ってステップで動作が止まっているようなので、キーワードに入れて検索してみたら%LOCALAPPDATA%\Microsoft\VisualStudio\配下のprivateregistry.binを消したら解決したという情報があったので、とりあえずリネームしたら動いた。

VS2017 version 15.1 (26403.0) will only start as administrator.

privateregistory.binって何者?

まぁ、なんとなく名前から検討はつくんですが、Visual Studio インスタンスの検出および管理用のツールのVisual Studio インスタンスのレジストリの編集をみると、

Visual Studio 2017 ではレジストリ設定はプライベートな場所に保存されているため、同じバージョンの Visual Studio の複数のインスタンスを side-by-side で同じコンピューターで使用できます。

ってなっているので、レジストリ情報が何らかの原因で壊れていたのが原因なのかな。

カテゴリー:Visual Studio, 未分類 タグ:

No EditorOptionDefinitionと表示され、Visual Studioでソースコードが開けなくなった場合の対応

2017年5月17日 コメントを残す

Windows Update をしたら、こんなダイアログが表示されソースコードが表示できなくなってしまいました。

image

No EditorOptionDefinition export found for the given option name: TextViewHost/ChangeTracking

パラメーター名:optionId

ぐぐると、似たような事例が。

http://stackoverflow.com/questions/23893497/no-editoroptiondefinition-export-found-error

Visual Studioを閉じた後、%LocalAppData%\Microsoft\VisualStudio\12.0\のフォルダーをリネームしたら直りました。

Microsoft.VisualStudio.Default.cacheで検索すると、該当フォルダーを消すと言うのは一般的?な対応みたいですね。

https://www.google.co.jp/search?q=Microsoft.VisualStudio.Default.cache

カテゴリー:Visual Studio タグ: