potisanのプログラミングメモ

プログラミング素人です。昔の自分を育ててくれたネット情報に少しでも貢献できるよう、情報を貯めていこうと思っています。Windows環境のC++やC#がメインです。

C#

C# ファイナライザは基本的に呼び出されない

C#

C++の感覚でC#のファイナライザもプログラム終了時に呼び出されると思い込んでいたのですが、ファイナライザは基本的に呼び出されません。呼び出されるのはGCの実行時に対象となった場合のみです。Windowsのプロセス終了時に関連リソースを解放する設計によ…

C# プラットフォーム呼び出しはローカル関数として書ける

C#

ネット投稿を読んで知ったのですが、最近のC#ではプラットフォーム呼び出し (P/Invoke)をローカル関数として書けます。ローカル関数のドキュメントには確かにexternの記載があります。通常のローカル関数を書ける部分なら書けるので、メソッド、プロパティ、…

C# シェルの「shell:~」形式からパスを取得する2

過去の投稿では関数を小分けにしていましたが、一つの機能としてまとめる関数を作成しても良いと思います。ついでに投稿後に追加されたトップレベルステートメントも使用しています。 using System.Runtime.InteropServices; Console.WriteLine(ShellIDListU…

C#&.NET 8.0 WinFormsプロジェクトの依存フレームワークにMicrosoft.Windows.SDK.NET.Refが追加された。

以下の手順でWinFormsプロジェクトの依存フレームワークにMicrosoft.Windows.SDK.NET.Refが追加されて、ビルド後のファイルにWinRT.Runtime.dll (391 KB)とMicrosoft.Windows.SDK.NET.dll (200,076 KB)が追加されました。DLLは両方削除してもおそらく対応す…

C# Parallel.For/ForEachとConcurrentBagによる同期化

C#

C#における同期処理の知識がBackgroundWorkerやTaskで止まっていたのですが、ParallelとConcurrentBagを使ったら非同期処理を簡単に同期処理に変更できました。マルチスレッドになるのでリソースの同時アクセスには注意が必要ですが、各スレッドでそれぞれフ…

C# ReSharper 2024.2.3はVisual Studioのコード分析+少々αだと感じた。

C#

浮動小数点計算やPEファイルの解析クラスを高速化しようとしてReSharperを導入してみました。 Trial版を30分ほど使った感想は以下の通りです。使用期間は30日ですが、既にアンインストールしたので項目は増えません。 WinFormsやWindows依存クラスライブラリ…

C#&Windows ディレクトリの循環シンボリックリンクによるIOException

ディレクトリ中のファイルを列挙するプログラムで列挙後のコードが実行されずに悩んでいたのですが、原因は検索ディレクトリ以下に含まれる循環したディレクトリのシンボリックリンクとtry構文による例外の握りつぶしでした。 ディレクトリに循環したシンボ…

C# ビットフィールドは整数か構造体かクラスか

C#

C++では容量削減のためにビットフィールドが多用されました。これをC#でどのように表すべきか、答えのない問題に悩んでいます。 背景:C++のビットフィールド C++のビットフィールドは以下の形式で表されます。組み込み整数のビット演算の糖衣構文です。 // …

C# ImmutableArrayは配列のムーブで作成可能

C#

ImmutableCollectionsMarshal.AsImmutableArray<T>静的メソッドを使えば配列をラップするImmutableArray<T>を直接作成できます。配列のToImmutableArrayによる要素コピーを回避できます。C++のムーブに該当します。 なお、ImmutableCollectionsMarshalにはAsImmuta</t></t>…

C# COMオブジェクトのメソッドをデリゲート経由で呼び出す。

8/30追記 下記のthiscall呼び出し規約を指定したコードはx64で動作しますが誤りです。COMメソッドはSTDMETHODやSTDMETHOD_マクロによりstdcall呼び出し規約が指定されます。x86ではECXレジスタ上のthisが無視されてエラーになるはずです。 WindowsのCOMオブ…

Visual Studio 2022 C#のクラスライブラリをローカルリポジトリで再利用する

クラスライブラリは作っても場所を忘れて使わなくなってしまうことがありますが、ローカルリポジトリを作ってまとめておけば忘れにくくなり、管理も楽になります。 Visual Studio 2022でのローカルリポジトリへのクラスライブラリ登録は次の手順で可能です。…

C# imageres.dll.munからProgressRingのリソース(PNGデータ)を読み込む C#12 (.NET 8)版

過去の投稿のコードをC# 12 (.NET 8)版に書き換えたものです。nintやオブジェクト初期化子により少し簡潔になります。 非unsafe版 unsafe版 非unsafe版 using System.ComponentModel; using System.Runtime.InteropServices; [assembly: DefaultDllImportSea…

Win API SetupDi系関数とデバイスインターフェイスクラスのメモ

SetupDi系関数でデバイスインターフェイスクラスGUIDが取得できずに悩んだので、学んだことを記録します。結論、デバイスインターフェイスクラスGUIDはSDKヘッダーファイルの定数使用が正攻法です。cfgmgr32も使えるならCM_Enumerate_Classesで列挙できます…

C# 12&Win API NVMe接続SSDのS.M.A.R.T.情報を取得するコード

C# 12 (.NET 8.0)でNVMe接続されたSSDのS.M.A.R.T.情報を取得するコードです。前回のC++23用コードをほぼそのままC#へ移植したものです。詳細は前回記事をご参照ください。 プロジェクトは暗黙的なglobal usingの有効なコンソールプロジェクトでターゲットOS…

C# Firefox(Windows版)のプロファイルからSQLiteデータを読み込む

Firefox(Windows版)の閲覧履歴がSQLite形式で保存されることを知ったのですが、SQLite自体もそれをC#から触ったこともありませんでした。この記事はSQLiteを勉強しながら分かったことを追記する予定です。開発環境はMicrosoft Visual Studio 2022です。 SQ…

雑記 C#でC++ほど個人開発ライブラリが流行らないのは言語の設計思想や時代背景の違い?

個人開発のライブラリ(クラスライブラリやヘッダーオンリーライブラリ)が多数存在するC++に対して、C#ではあまり見かけない気がします。数学や統計、機械学習に関する大規模なライブラリはGitHubで複数公開されていますが、特定機能に絞ったものは特に見か…

C#&Win API MDI子フォームのStatusStripにサイズグリップを強制表示する。

以前の投稿でMDI子フォームはMDI親フォームの最大化時にサイズグリップが非表示になるWinFormsの仕様を紹介しました。この記事ではウィンドウメッセージとToolStripRendererを利用したサイズグリップの強制表示を紹介します。動作確認環境は.NET 8.0ですが、…

C#&WinForms MDI子フォームのStatusStripでサイズグリップが消える。

追伸:解決方法を別の記事に記載しました。 WinFormsでMDI子フォームにStatusStripを置くとMDI親フォームの最大化時にサイズグリップが消えます。GitHub上のソースコードを調べると設計上の仕様です。具体的には次の通りです。 StatusStripはサイズグリップ…

C# WinFormsのクリップボード監視コンポーネント

WinFormsのFormへのクリップボード監視機能の追加、コンポーネントとNativeWindowで思ったより簡単に実装できました。NativeWindowの理解が浅いので問題が残っているかもしれませんが、とりあえず動きはします。動作確認はC# 12 (.NET 8.0)ですが、名前空間…

C#11 配列の入ったobject型をstring.Joinで結合する

C#

配列の入ったobject型をstring.Join()で結合するにはIEnumerableにキャストしてからOfType<T>()を使います。キャストせず渡すと可変長引数の最初の引数として素直にToString()されます。ちなみにIEnumerableへキャストすると文字列(char[]配列)も分割されるの</t>…

C#&MSVS 17.5.0 Preview 3.0 ユーザーコントロールのobject、nint、nuint型プロパティはプロパティウィンドウで読み取り専用

C#

ユーザーコントロールのobject、nint、nuint型プロパティはプロパティウィンドウで読み取り専用になります。 // UserControl1.Designer.csとUserControl1.resxは既定値なので省略します。 namespace UserControlTest1; public partial class UserControl1 : …

C# クラスに属性でIIDを持たせる

C#

C#ではカスタム属性でクラス自体にIIDを持たせられます。ただし静的メンバーより動作は遅く、Guidのような非標準型は属性定義時の引数に渡せないようです。 using System.Reflection; Console.WriteLine(IIDAttribute.Of<ClassWithIPersistIID>()?.ToString("B") ?? "(未定義)"); C</classwithipersistiid>…

C# HRESULTパターン、例外パターン、Nullableパターンのどれを使うかで悩む

C#

C#で自分用のクラスライブラリを作るとき、最中にもエラー対処パターンで悩みます。COM開発で使えるデザインパターンはおそらくHRESULTパターン、例外パターン、Nullableパターン(適当に名付けました)なのですが、一長一短です。 HRESULTパターン エラーを…

C# ジェネリック関数でEnum型を整数へ変換する

C#

ジェネリック関数ではenum型は通常の方法((int)...)で整数へ変換できません。 Convert.ToInt32やConvert.ToUInt32等を使えばジェネリック関数でもenum型を整数へ変換できます。 using System; Console.WriteLine(f(Enum1.A)); string f<T>(T t) where T : Enu</t>…

ImageSharpがライセンス変更により.NET財団を離脱

C#

ImageSharpがライセンス変更により.NET財団を離脱したそうです。AngleSharpが.NET財団のメンバープロジェクトであることに安堵していましたが、こういうこともあるみたいです。 経緯や.NET財団のコメントは公式ブログで確認できます。OSSや年間総売上が一定…

AngleSharp、JSON.NET、ML.NET、Infer.NETは.NET財団のプロジェクト

C#

AngleSharp、Json.NET、ML.NET、Infer.NET、気づいたらMicrosoft主導の.NET財団のプロジェクトになっていました。AngleSharpは企業ベースだと思いこんでいたので、これまでより使いやすくなりました。 .NET Bioなどの知らなかったプロジェクトもあるので、時…

C# JPEGファイルEXIFデータのWindows用評価とキーワードを取得・設定・削除する

追記2024/10/6:FormatterServices等のクラスはObsoluteになりました。FormatterServices.GetUninitializedObject(Type)よりもRuntimeHelpers.GetUninitializedObject(Type)が推奨されます(ソース)。 JPEGファイルEXIFデータのWindows用評価とキーワードを…

C# System.Drawing.Imaging.PropertyDataのインスタンスを作成する

System.Drawing.Imaging.PropertyDataはJPEGファイルのEXIFデータを取得・設定する際に必要ですが、コンストラクタが非公開なので通常の方法ではインスタンスを作成できません。これはSystem.Runtime.Serialization.FormatterServicesのGetSafeUninitialized…

C# P/InvokeとCOM呼び出し時、UnmanagedType.LPWStrはout指定でMarshal.FreeCoTaskMemされる

P/InvokeとCOM呼び出し時、UnmanagedType.LPWStrのMarshal.FreeCoTaskMemは不要らしいです。CoTaskMemFreeが必要なLPWSTRはout IntPtrやout SafeHandleで受け取らなくても、out stringで受け取れば自動でMarshal.FreeCoTaskMemされるそうです。 ただし複数回…

C#9&Win API ドロップされたオブジェクトの表示名を取得する。

Windows APIを使用してごみ箱やPCのような特殊オブジェクトの表示名を取得するコードです。SHCreateShellItemArrayFromDataObject関数を使用しています。 #nullable enable using System; using System.Collections.Generic; using System.Runtime.InteropSe…