Project Sdk形式のビルドイベント

MSBuild プロジェクト形式から新しいProject Sdk形式にした場合に、ビルドイベントについてはコンバートされないようです。

MSBuild プロジェクト形式のときは以下のような形でした。

<Project>
<PropertyGroup>
 <PreBuildEvent>
 ビルド前イベント
 </PreBuildEvent>

 <PostBuildEvent>
 ビルド後イベント
 </PostBuildEvent>
</PropertyGroup>
</Project>

Project Sdk形式では以下のような形になります。

<Project>
  <Target Name="PreBuild" BeforeTargets="PreBuildEvent">
    <Exec Command="ビルド前イベント" />
  </Target>
  <Target Name="PostBuild" AfterTargets="PostBuildEvent">
    <Exec Command="ビルド後イベント" />
  </Target>
</Project>

ダブルクォーテーション”(")や改行( )はHTMLエンティティに変換されて記述されます。
.csprojを直接変更するのは到底無理でしょう・・・

問題点

Project Sdk形式では実行されるのですが、$(ProjectDir)のようなマクロが空欄の状態で実行されてしまいます。

プロジェクト形式を変換したあとは気をつけましょう。

追記 2025/02/26

それぞれの形式が混ざるとマクロが空欄になるようです。
<PreBuildEvent> <PostBuildEvent> の状態であれば問題ありませんでした。

以下のような形で混ざってしまうとだめでした。

<PropertyGroup>
  <PreBuildEvent>
  ビルド前イベント
  </PreBuildEvent>
</PropertyGroup>
<Target Name="PostBuild" AfterTargets="PostBuildEvent">
  <Exec Command="ビルド後イベント" />
</Target>

Project Sdk形式にして新しくなったプロジェクト デザイナーでマクロを編集するとこの問題が発生するので気をつけましょう

[WPF] 特定のXamlがデザイナーで開いてくれない問題

とりあえず殴り書き、

MSBuild プロジェクト形式から新しいProject Sdk形式にした場合、特定のXaml(Window)がデザイナーモードで表示されずにXmlエディターとして開いてしまう事がありました。

結論としては
.vs フォルダを削除したら直りました!

[VS2022] 現在のドキュメントの変更履歴をクリア

Visual Studioで編集していると、ファイルの変更履歴として黄色や緑のバーが表示されます。
この変更履歴をリセットする方法が意外にも用意されていません。

一応方法としては、
ファイルを開き直す、変更履歴の設定をON/OFFする

探していたらVisualCommanderでこの機能のコマンドが公開されていました。
How to reset track changes in Visual Studio? - Stack Overflow

Visual Commander - Visual Studio Marketplace
https://vlasovstudio.com/visual-commander/commands.html#ClearChanges

ただ、古いバージョンでしか動かないコードだったので、
VS2022で動作するように修正しました。

using EnvDTE80;
using System;
using System.Runtime.InteropServices;
using Microsoft.VisualStudio;
using Microsoft.VisualStudio.Shell;
using Microsoft.VisualStudio.Shell.Interop;

public class C  :VisualCommanderExt.ICommand {
	public void Run( DTE2 DTE, Package package ) {
		serviceProvider = package;
		Reload( DTE.ActiveDocument.FullName );
	}
	private void Reload( string file ) {
		ThreadHelper.ThrowIfNotOnUIThread();

		var rdt = (IVsRunningDocumentTable)serviceProvider.GetService( typeof( SVsRunningDocumentTable ) );
		IVsHierarchy h;
		uint id;
		IntPtr data;
		uint cookie;
		ErrorHandler.ThrowOnFailure( rdt.FindAndLockDocument(
			(uint)_VSRDTFLAGS.RDT_NoLock,
			file,
			out h,
			out id,
			out data,
			out cookie ) );
		try {
			var persistDocData = (IVsPersistDocData)Marshal.GetObjectForIUnknown( data );
			{
				int dirty;
				ErrorHandler.ThrowOnFailure( persistDocData.IsDocDataDirty( out dirty ) );
				if( dirty != 0 )
					return;
			}
			ErrorHandler.ThrowOnFailure( persistDocData.ReloadDocData( (uint)_VSRELOADDOCDATA.RDD_RemoveUndoStack ) );
		} finally {
			Marshal.Release( data );
		}
	}
	private IServiceProvider serviceProvider;
}


追加するコマンドの [References..] に1つ追加します。

Microsoft.VisualStudio.Shell.Framework

こんな感じ


以上です。


最新のVS2022だと変更記録の表示がGitの履歴になってしまうから使うかな?

[Git] コミットのAuthorDateとCommitDateを合わせる方法

git rebase をすると CommitDate が今の時間に変更されます。
AuthorDateと同一にしたい場合は --committer-date-is-author-date オプションを使用します。

git rebase HEAD~10 --committer-date-is-author-date

git - インタラクティブリベースしたコミットのタイムスタンプを戻す #Git - Qiita
Git のコミットのタイムスタンプには author date と committer date の 2 種類があるという話 - ひだまりソケットは壊れない
コミットのAuthorDateとCommitDateを合わせる方法 | 全国個人事業主支援協会

[.NET] 出力フォルダにターゲットフレームワークのフォルダを作らない

プロジェクト ファイルの形式がProject SDKに変更されたことで、
出力フォルダにターゲットフレームワークのフォルダが作成されるようになりました。

 <Project Sdk="Microsoft.NET.Sdk">

複数のターゲットフレームワークの場合は有効ですが、一つの場合はフォルダが深くなるだけで正直必要ありません。
この機能を無効化するプロパティを設定しましょう。

<PropertyGroup>
  <AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
</PropertyGroup>

これで今まで通りbin\debug\フォルダに出力されるようになります。

Project SDK形式になってから直接編集する設定が多いのでどうにかしてほしいところ。。。
 
 
ビルド出力ディレクトリを変更する - Visual Studio (Windows) | Microsoft Learn
Microsoft.NET.Sdk の MSBuild プロパティ - .NET | Microsoft Learn
[.NET5] 出力フォルダの中に「net5.0-windows」フォルダができないようにする #.NET5 - Qiita

PowerPoint ストーリーボードのアドイン

Visual Studio をインストールするとPowrPointのアドイン(ストーリーボード)も追加されて便利な図形が使用できました。
作成するアプリケーションのイメージ図を作るときに重宝します。

Visual Studio 2015ではPowerPoint用ストーリーボード・アドオンが下位エディションでも使える - きよくらの備忘録

残念ながらVS2019からはこのアドインは廃止されたようです。
使用するためにはVS2015、VS2017のどちらかのインストールでアドインが含まれています。


そもそもがTeam Foundation Serverに含まれているようで、
2019年にAzure DevOps Server にブランドを変更したときにサポートを終了したようです。
Connect Azure Boards to an Office client to track your work - Azure Boards | Microsoft Learn
Storyboard your ideas with Microsoft PowerPoint - TFS | Microsoft Learn

なので、古いVisual Studioをインストールしたくない場合は、Team Foundation Server Office Integration 2015、2017でも大丈夫です。
MSアカウントがあるならmy.visualstudio.comからダウンロードできます。
https://my.visualstudio.com/Downloads?q=Team%20Foundation%20Server

.NET6、.NET7のインテリセンス(IntelliSense)やツールチップを日本語の表記にする

.NET5 まで

.NETからインテリセンスの表示が英語のみになってしまいました。
.NET Core 3.0、.NET Core 3.1、.NET 5まではローカライズされたファイルを配置すれば日本語化できます。
learn.microsoft.com

ただし、.NET 6.0からはローカライズされたファイルの配布が無くなってしまいました。

.NET6以降

探していたら中国の方がいいツールを作られていました。
github.com
Githubでは中国語のファイルしか配布されていませんが、自分でビルドすることで指定した言語のファイルを作成することができるようです。
オンラインドキュメントからインテリセンスのファイルを作成するみたいで、すごく時間がかかりますが自分で作成して使いましょう!

使うオプションの説明

ContentCompareType (デフォルトはOriginFirst)
-cc, --content-compare

OriginFirst 英語原文と翻訳後の順で表記します
LocaleFirst 翻訳後と英語原文の順で表記します
None 翻訳後の説明のみ表記します

使い方

1. dotnet ツールとしてインストール
dotnet tool install -g islocalizer
2. 日本語のインテリセンスファイルを作成

net7.0 のファイルを作ります。
日本語 英語の順で表示するようにオプションを付けました。

islocalizer build -m net7.0 -cc LocaleFirst

以下のような感じで処理が進みます。

[10:10:10 I] Start generate. PackName: null, Moniker: net7.0, Locale: ja-jp, ContentCompareType: LocaleFirst.
[10:10:10 I] Processing pack [Microsoft.AspNetCore.App.Ref:net7.0]. Progress 1/3.
[10:10:10 I] Progress PackRef[1/3]->File[1/132]. Processing [Microsoft.AspNetCore.App.Ref:7.0.13:Microsoft.AspNetCore.Antiforgery] now.
[10:10:10 I] Progress PackRef[1/3]->File[2/132]. Processing [Microsoft.AspNetCore.App.Ref:7.0.13:Microsoft.AspNetCore.Authentication.Abstractions] now.
[10:10:10 I] Progress PackRef[1/3]->File[3/132]. Processing [Microsoft.AspNetCore.App.Ref:7.0.13:Microsoft.AspNetCore.Authentication.Cookies] now.
[10:10:10 I] Progress PackRef[1/3]->File[4/132]. Processing [Microsoft.AspNetCore.App.Ref:7.0.13:Microsoft.AspNetCore.Authentication.Core] now.
[10:10:10 I] Progress PackRef[1/3]->File[5/132]. Processing [Microsoft.AspNetCore.App.Ref:7.0.13:Microsoft.AspNetCore.Authentication.OAuth] now.
[10:10:10 I] Progress PackRef[1/3]->File[6/132]. Processing [Microsoft.AspNetCore.App.Ref:7.0.13:Microsoft.AspNetCore.Authentication] now.
・・・(略)

オンラインドキュメントをダウンロードして生成しているので、全部で1時間ぐらいはかかります。
--parallel-count オプションを付けて並列処理数を増やせば早くなるかも?
あまり多すぎるとMicrosoftへのアクセスが遮断されちゃうぞ!

2回目からはキャッシュされているのでちょっとマシになる。

処理が終わるとzipファイルが生成されます。

[10:20:09 W] localization pack is saved at C:\Users\********\AppData\Local\Temp\IntelliSenseLocalizer\output\net7.0@ja-jp@None.zip.

ここのパスは覚えておきましょう。

3. 生成したインテリセンスのファイルをインストール
islocalizer install C:\Users\********\AppData\Local\Temp\IntelliSenseLocalizer\output\net7.0@ja-jp@None.zip

既定の場所にファイルを配置してくれます。

いくつかのテキストがうまく取得できていなかったので、修正プルリクしてみました

Fixed some text that was not retrieved from the Japanese online doc. by kttFox · Pull Request #7 · stratosblue/IntelliSenseLocalizer · GitHub

Visual Studioの設定ファイル

Visual Studioの設定ファイルは2つの場所に保存されています。
CurrentSettings.vssettings
===
1つ目は CurrentSettings.vssettings です。
中はXML形式になっています。

VisualStudioの [ツール → オプション] から [環境 → 設定のインポートとエクスポート] で保存先を確認できます。

また、VisualStudioの ツール に [設定のインポートとエクスポート] のウイザードがあります。

Visual Studioの環境を移動させたいときに便利です。

プライベートレジストリ
===

2つ目はプライベートレジストリです。
以下の場所に保存されており、レジストリエディターより[ハイブの読み込み]で読み書きできます。
```
%LOCALAPPDATA%\Microsoft\VisualStudio\[VSバージョン]\privateregistry.bin
```
※ アンロードして開放しておかないとVisualStudioが起動できなくなるので注意



拡張機能を作っていると ShellSettingsManager がよく出てきますが、このプライベートレジストリに対して読み書きしているようです。
Microsoft.VisualStudio.Shell.Settings.ShellSettingsManager
ShellSettingsManager Class (Microsoft.VisualStudio.Shell.Settings) | Microsoft Learn

Git fatal: unsafe repository ('xxxxxxxxx' is owned by someone else)

fatal: unsafe repository ('xxxxxxxxx' is owned by someone else)

git v2.35.2 でセキュリティアップデートが入ったようで、コミットが開けなくなりました。
gitの対象フォルダの所有者が自分では無いことが原因のようで、まずはフォルダの所有者を確認しましょう。

どうしても所有者が自分以外になってしまう場合は、safe.directoryの設定をして例外的に許可を出せば大丈夫です。

バージョン管理システム「Git」にセキュリティ上の脆弱性、Git for Windowsユーザーやマルチユーザー環境利用者が取るべき対処法は? - GIGAZINE
いきなりgitが使えなくなった - 2022(山崎はるかのメモ)
TortoiseGitで「fatal: unsafe repository」なエラー #Git - Qiita


事の発端:
VisualStudio内のGitが開けなくなって困った
→ SourceTreeでは開ける (内蔵Gitのためバージョンが低い)
→ VisualStudioのGitのバージョンがわからんぞ
  ↓ここにあるっぽい VisualStudioも内蔵Gitでした…

VisualStudio 2017だとGitのエラー表示してくれるけど、VS2019だと「エラーが1つあります」しかなくて困った困った

ソリューションを.Net Frameworから.NETへバージョンアップする方法

.NET5からソリューションの記述方法が変わりました。
今までのソリューションを.NET5、.NET6にするには結構めんどくさかったり。。。

マイクロソフトから「.NET アップグレード アシスタント」としてツールが出ています。

インストール

// インストール
dotnet tool install -g upgrade-assistant

// アップデート
dotnet tool update -g upgrade-assistant

使い方:

upgrade-assistant upgrade <MySolution.sln>
または
upgrade-assistant upgrade <MyProject.csproj>

後は英語の説明で動かしていけばコンバート完了です。


WPF アプリを .NET 7 にアップグレードする - WPF .NET | Microsoft Learn
.NET アップグレード アシスタントを利用して .NET Framework から .NET 5 に超簡単アップグレード 【Windows Forms】 #.NET - Qiita

.NET Framework から .NET 6 に移植する - .NET Core | Microsoft Learn

[WPF] 編集可能なComboBoxのTextが消える問題

編集可能なComboBox (IsEditable="True")のItemsSorceを変更したときに、ItemsSorceから現在の項目が消えた場合にTextも消滅してしまう問題です。
あくまでもComboBoxのメニュー(DropDown)は「選択もできるよ!」のつもりなのに、メニューから消えるとTextも消えてしまいます。

<ComboBox IsEditable="True" ItemsSorce="{Binding Items}" Text="{Binding Item}" />
class vm {
  public string Item { get; set; }
  public IEnumerable<string> Items { get; set; } = new []{ "みかん", "りんご", "ぶどう" };
}

例えば ItemsSorce :[みかん、りんご、ぶどう] 、 Text:[みかん] の状態で、
ItemsSorce を [りんご、ぶどう] に変更すると Text が空欄になってしまうわけです。

イベント的にSelectionChangedしか無いのでこんな感じで対応しました。

public IEnumerable ItemsSource { get; set; }

void OnSelectionChanged( object sender, SelectionChangedEventArgs e ) {
	var comboBox = (ComboBox)sender;

	if( this.ItemsSource != comboBox.ItemsSource ) {
		this.ItemsSource = comboBox.ItemsSource;

		if( comboBox.SelectedItem == null ) {
			var text = comboBox.Text;
			comboBox.Dispatcher.BeginInvoke( (Action)( () => {
				comboBox.Text = text;
			} ) );
		}
	}
}

comboBox.Dispatcher.BeginInvoke がミソで、一旦comboBox.Textは空欄になってしまいますが再度入力し直す動きなります。
SelectedItemは先にNullになるけど、Textはまだ残っている不思議

参考:
ikriv.com

.Net 5 でインテリセンス(IntelliSense)やツールチップを日本語の表記にする

Visual Studio 2019を使い始めました。
というか.Net 5 を使い始めました。

.Net 5の初期状態だとツールチップが英語です😥

.Net Framework 4.5のときも同じような状態でしたが、これはバグだったみたい。
Visual StudioのIntelliSenseが英語になっていたので日本語に戻した - tmegos blog
c# - Visual Studio 2015 ツールチップ(summary)の日本語化 - スタック・オーバーフロー
.NET Framework 4.5でIntelliSenseのツールチップが英語になる理由 - The Grimoire of Nonsense

.Net 5(.NET Core 3.0以降)ではそもそも初期状態は英語のようです。

日本語化

日本語化する手順は公式でしっかり書かれていました。
ただ、インストールする場所(jaフォルダを配置する場所)がよくわからなくて苦労しました。
docs.microsoft.com


日本語のインテリセンスファイルをダウンロード以下のサイトよりダウンロードします。
dotnet.microsoft.com


解凍したフォルダの各jaフォルダを規定の位置にコピーします。

初期インストール場所は「%ProgramFiles%\dotnet\packs」なので、
例えば「Microsoft.WindowsDesktop.App.Ref」だと

C:\Program Files\dotnet\packs\Microsoft.WindowsDesktop.App.Ref\5.0.0\ref\net5.0

の中にjaフォルダをコピーしてください。

Microsoft.NETCore.App.Ref のほうも同じように

C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\5.0.0\ref\net5.0

の中にjaフォルダをコピーしてください。

ただ、NETStandard.Library.Ref には 5.0.0 がないんだけど、使わないから必要ないかな?

日本語化できました!

他の設定はデフォルトのままでした。
VisualStudioを起動している場合は、再起動が必要です。


参考サイト:
Visual Studio 2019 での .NET Core のインテリセンスを日本語化する - Alternative Architecture DOJO

[Visual Studio 2019] ソリューションエクスプローラーでAltキードラッグで、リンクファイルが作成できない

Visual Studio 2019で、リンクファイルのショートカット操作が消されてしまったようです。


https://social.msdn.microsoft.com/Forums/en-US/66715ed6-ed1b-4922-be5c-d79d3f3c22b8/altdrag-to-create-a-link-to-a-file?forum=visualstudiogeneral
https://developercommunity.visualstudio.com/t/ctrl-shift-drag-and-altdrag-could-not-add-the-exis/760536


そろそろ 2019 移行するかと思ったらしっかり踏んだ
DLL化して参照しろってことかな・・・

WPFでWindows Runtime API の Windows.winmd について

WPFWindows 8、8.1、10 のAPIを呼ぶことができます。
デスクトップ アプリからのWinRT API利用 | ++C++; // 未確認飛行 C ブログ

WPFのプロジェクトで Windows.winmd を参照するとライブラリとして使えるようになります。
WPF などの .NET Framework のアプリから UWP の API を呼ぶ - かずきのBlog@hatena
WPFアプリ(.Net Framework)でUWPのAPIを使う #WPF - Qiita

Windows SDKのインストール場所は C:\Program Files (x86)\Windows Kits\ になります。
Windows 8、8.1 はいいのですが、Windows 10 になるとメジャーアップデート毎にSDKのバージョンが違うため気をつける必要があります。

(ここからの部分を書きたいだけ)

Windows 10 のSDKをインストールすると C:\Program Files (x86)\Windows Kits\10\ にインストールされます。

Windows 10 SDK (10.0.10240) ~ (10.0.15063.468) (1507~1703)では Windows.winmd が同じ場所にインストールされてしまうので注意です。
最後にインストールしたSDKWindows.winmd が上書きされるようで、
Windows.winmd の違いはファイルの見た目では分からないので、どのバージョンのファイルか分からなくなります。

Windows 10 SDK (10.0.16299.91) (1709) からそれぞれのバージョンでフォルダ分けされるようになったのでこの問題は解決しています。

(ここまで)


まあ、Win10のサポート期間があるので、サポート対象のバージョンを使えばよさそうです。


ついでに、、、
特定のバージョンしか対応していませんが、NuGet から追加できるようになったようです。
こっちを使ったほうが簡単ですね。
.NET のプロジェクトから WinRT API を呼ぶのが凄く簡単になってます - かずきのBlog@hatena