WebSurfer's Home

Filter by APML

System.Drawing 名前空間のグラフィックス機能

by WebSurfer 14. May 2025 14:45

.NET Framework ではない .NET 8.0 とか .NET 9.0 などでは Windows OS の GDI+ に依存する System.Drawing 名前空間のグラフィックス機能は Visual Studio のテンプレートで作るプロジェクトには含まれてないと思っていたのですが、Windows Forms アプリの場合は例外のようです。そのことを備忘録として書いておきます。

アプリの実行結果

そもそも Windows Forms は Windows API(GDI/GDI+)をマネージコードでラップし、Windows のユーザーインターフェイス要素へのアクセスを提供するアプリケーションフレームワークということなので、System.Drawing 名前空間のグラフィックス機能が使えないということはあり得ず、特別な配慮がされているようです。

下は Visual Studio 2022 のテンプレートを使ってターゲットフレームワーク .NET 9.0 で作成した Windows Forms アプリのプロジェクトのサンプルコードです。

using ClassLibrary;

namespace WinFormsApp1
{
    public partial class Form1 : Form
    {
        PictureBox pictureBox1 = new();
        PictureBox pictureBox2 = new();
        Class1 classLibrary = new();

        public Form1()
        {
            InitializeComponent();

            pictureBox1.Size = new Size(210, 110);
            this.Controls.Add(pictureBox1);
            pictureBox1.Image = CreateBitmap();

            pictureBox2.Size = new Size(210, 110);
            pictureBox2.Location = new Point(0, 120);
            this.Controls.Add(pictureBox2); ;
            pictureBox2.Image = classLibrary.CreateBitmapAtRuntime();
        }

        // WinForms は Windows API(GDI/GDI+)をマネージコードでラップし、
        // Windows のユーザーインターフェイス要素へのアクセスを提供するアプリ
        // ケーションフレームワーク・・・ということなので、System.Drawing
        // 名前空間のグラフィックス機能はデフォルトで使える設定になり、以下の
        // コードは問題なく動く。NuGet の System.Drawing.Common は不要。
        public Bitmap CreateBitmap()
        {
            Bitmap flag = new(200, 100);
            Graphics flagGraphics = Graphics.FromImage(flag);
            int blue = 0;
            int white = 11;
            while (white <= 100)
            {
                flagGraphics.FillRectangle(Brushes.Blue, 0, blue, 200, 10);
                flagGraphics.FillRectangle(Brushes.White, 0, white, 200, 10);
                blue += 20;
                white += 20;
            }
            return flag;
        }
    }
}

上のコードの CreateBitmap メソッドで使っている System.Drawing 名前空間の Bitmap, Graphics, Brushes クラスはデフォルトで使える設定になっており、期待通り青白の横線が描画された Bitmap が生成されます。 この記事の一番上の画像の青白の旗が CreateBitmap メソッドで生成された Bitmap を PictureBox に表示したものです。

では、同じソリューションの中にクラスライブラリのプロジェクトを追加し、そこで上と同様に Bitmap, Graphics, Brushes クラスを使ったらどうなるでしょう?

クラスライブラリ

その場合、Bitmap, Graphics, Brushes クラスを利用するためには、クラスライブラリのプロジェクトに NuGet パッケージ System.Drawing.Common をインストールする必要があります。

NuGet パッケージ System.Drawing.Common

さらに、Visual Studio でプロジェクトのプロパティを開いて、Target OS を Windows に設定しないと警告 CA1416 が出ます。(#pragma warning disable CA1416 を追記して警告を抑制することもできますが)

Target OS を Windows に設定

クラスライブラリのコードも以下に参考に載せておきます。上の Form1 のコードでは、下のクラスライブラリを使って取得した Bitmap を PictureBox2 に表示しています。一番上の画像の赤白の旗がそれです。


namespace ClassLibrary
{
    public class Class1
    {
        public Bitmap CreateBitmapAtRuntime()
        {
            Bitmap flag = new(200, 100);
            Graphics flagGraphics = Graphics.FromImage(flag);
            int red = 0;
            int white = 11;
            while (white <= 100)
            {
                flagGraphics.FillRectangle(Brushes.Red, 0, red, 200, 10);
                flagGraphics.FillRectangle(Brushes.White, 0, white, 200, 10);
                red += 20;
                white += 20;
            }
            return flag;
        }
    }
}

Tags: , ,

CORE

ASP.NET Web アプリ開発用サーバー証明書の更新

by WebSurfer 4. April 2025 13:00

Visual Studio Community 2022 Version 17.13.5 で ASP.NET Web アプリを IIS Express 上で動かそうとしたら、開発用のサーバー証明書が期限切れとなっていたので更新したのですが、一筋縄ではいかなかったので、その時の顛末を書いておきます。

開発用のサーバー証明書

上の画像の通り、開発用のサーバー証明書には 2 種類あって、フレンドリ名 IIS Express Development Certificate が IIS Express 用、ASP.NET Core HTTPS development certificate が Kestrel 用です。いずれも自己署名証明書で、Visual Studio で作業を行う際に生成されます。

ちなみに上の画像の証明書は今日 2025/4/4 に新規作成したもので、有効期限は作成日から IIS Express Development Certificate が 5 年、ASP.NET Core HTTPS development certificate が 1 年となっています。

有効期限が切れたら Visual Studio が自動的に更新してくれると思っていたのですが、少なくとも Visual Studio Community 2022 Version 17.13.5 ではそうではなかったということで、どのように対応したかをこのブログに備忘録として書いておくことにした次第です。

古い証明書が残ったままではダメなのかと思って、上の画像の管理コンソールの「信頼されたルート証明書」の「証明書」にある期限切れの IIS Express Development Certificate を削除してから Visual Studio 2022 で ASP.NET Web アプリを起動して IIS Express で動かしてみました。しかしながら、新しい証明書が発行されることはなかったです。さらに、古い証明書は削除済みにもかかわらず、ブラウザ上にはそれを使っているという警告が出ます。Visual Studio 2022 を再起動してから試してみたのですが同じでした。

2025/4/10 追記: 今頃気づいたのですが、期限切れの証明書は削除したのにブラウザ上にはそれを使っているという警告が出るのは、どこかで証明書情報がキャッシュされているからという可能性が高そうです。管理コンソールで期限切れの証明書を削除した後、まずはブラウザのキャッシュの削除と「SSL 状態のクリア(S)」(下の画像参照) を行うべきだったかもしれません。

SSL 状態のクリア

Visual Studio 2022 の不具合かと思って、Visual Studio Community 2019 Version 16.11.45 を起動して試してみました。すると、Microsoft のチュートリアルの「アプリを実行する」のセクションにあるダイアログ(下の画像参照)が出てきたので[Yes]ボタンをクリックして証明書を作成���

確認ダイアログ

Security Warning

・・・できたと思ったのですが、状況は変わらなかったです。

Visual Studio 2022 で ASP.NET Web アプリを起動して IIS Eaxpress で動かしてみると、依然として、ブラウザ上には管理コンソールで削除した期限切れの証明書を使っているという警告が出ます。Visual Studio 2019 と 2015 でも試してみましたが状況は同じでした。管理コンソールで「信頼されたルート証明書」の「証明書」の中身を見ると、削除した期限切れの証明書は存在しませんし、上の Visual Studio 2019 の操作で発行されたと思った新しい証明書もありませんでした。

ググってヒットしたネットの記事を見ると C:\Program Files (x86)\IIS Express フォルダにある IisExpressAdminCmd.exe コマンドを使って対応するという記事を目にしました。調べてみましたがそのコマンドの Microsoft のドキュメントは見つかりませんでしたので、実行結果がどうなるのか詳しいことが分かりません。

そういう訳の分からないコマンドを実行する勇気は自分にはありませんでしたので、さらにググって調べてみると、stackoverflow の記事 How do I restore a missing IIS Express SSL Certificate? の回答に IIS Express を修復して解決したとありましたので試してみました。(回答に "I typically run appwiz.cpl to launch the old control panel applet and run repair from there." とありますが、appwiz.cpl を起動するのは自分の Windows 10 では「コントロールパネル」から「プログラムと機能」を立ち上げたのと同じです)

IIS Express の修復

その後で ASP.NET Web アプリを Visual Studio 2022 から IIS Express 上で実行してみました。やはり、ブラウザ上には証明書が期限切れという警告が出ました。しかしながら、ブラウザに表示された証明書の有効期限は、当初のホントに期限切れとなっていた証明書の日付とは異なり、たぶん Visual Studio 2019 で作業した時に再生されたと思われる新証明書の有効期限 2030/04/04 となっていました。なぜ、ブラウザは有効期限が 2030/04/04 と 5 年も先と認識しているのに、期限切れという警告を出したのか謎です。

Visual Studio 2022 を再起動して試してみると、今度はブラウザ上では警告なしで目的のページが表示されました。管理コンソールで「信頼されたルート証明書」の「証明書」の中身を見ると、この記事の一番上の画像の通り有効期限が 2030/04/04 の IIS Express Development Certificate が含まれていました。

IIS Express Development Certificate は IIS Express が発行するとのことですが、IIS Express に証明書を発行させて所定の証明書ストアに配置し警告を出さずに動くようにするのは Visual Studio の仕事のようです。何故かその連携がうまく行ってなかったのが、IIS Express の修復で解決できたのでしょうか?

一体どうなっているのかは自分には分かりません。これ以上深く追求する気力はありませんので、次回同様な IIS Express Development Certificate 期限切れ問題が出たら、上に書いたことを参考に解決に当たりたいと思っています。


ちなみにですが、Visual Studio 2022 のテンプレートを使って ASP.NET Core アプリのプロジェクトを作成すると、現在のところデフォルトでは Kestrel 上で動くように設定されています。

アプリを IIS Express 上で動かすには下の画像のように Visual Studio のドロップダウンメニューで IIS Express を選びます。

Web サーバーの選択

それにより、IIS Express を使ったインプロセスホスティングモデルで動くようになります。

IIS Express の設定


もう一つ、Kestrel 用の証明書 ASP.NET Core HTTPS development certificate の更新については、たぶん Visual Studio が自動的にやってくれると思いますが、もし自動更新がされない場合は、先の記事「dotnet dev-certs https コマンドについて」に書いたとおり、dev-certs https コマンドを実行して更新できます。

先の記事の手順、(2) dotnet dev-certs https --clean 実行、(4) dotnet dev-certs https 実行、(6) dotnet dev-certs https --trust 実行で新規作成したのがこの記事に一番上の画像にある ASP.NET Core HTTPS development certificate です。

Tags: , , ,

DevelopmentTools

.NET アプリで Shift_JIS を使うには?

by WebSurfer 14. March 2025 13:57

.NET アプリにおいて Encoding.GetEncoding メソッドで Shift_JIS のエンコーディングを取得しようとすると、以下の画像のように ArgumentException 例外がスローされます。

Shift_JIS エンコーディングの取得

これは、.NET では特定の OS に依存する機能はサポートされてないので、Shift_JIS に限らず Windows OS のコードページの中の特定の locale のエンコーディングはデフォルトでは使えないということのようです。(注: .NET Framework ではデフォルトで Windows コードページの大多数のエンコーディングが使えます)

サポートされているエンコーディングは Encoding.GetEncodings メソッドで取得できます。.NET 8.0 の場合、自分の環境で試すと以下の 7 種類になっていました。

  • ASCII (code page 20127)
  • UTF-8 (code page 65001)
  • UTF-16LE (code page 1200)
  • UTF-16BE (code page 1201)
  • UTF-32LE (code page 12000)
  • UTF-32BE (code page 12001)
  • ISO-8859-1 (code page 28591)

UTF-7 も含まれるというMicrosoft のドキュメントを目にしましたが "The UTF-7 encoding is insecure and should not be used." ということで除外されたようです。

では、.NET アプリで上の一覧にないエンコーディングを Encoding.GetEncoding メソッドで取得して使うにはどうするかですが、それについては Microsoft のドキュメント「EncodingProvider クラス」に説明があります。それを参考に以下に Shift_JIS を使う場合の例を書きます。

(1) プロバイダクラスを定義

抽象クラス EncodingProvider を継承したプロバイダクラスを定義します。この例では、プロバイダクラスの名前を ShiftJisEncodingProvider とします。

ShiftJisEncodingProvider クラスで、 継承した抽象クラス EncodingProvider の抽象メソッド GetEncoding(Int32) と GetEncoding(String) を override し、Shift_JIS エンコーディングを返すようにします。

Shift_JIS エンコーディングは CodePagesEncodingProvider クラスのインスタンスから取得します。

ShiftJisEncodingProvider クラスのコード例は以下の通りです。

using System.Text;

public class ShiftJisEncodingProvider : EncodingProvider
{
    public override Encoding? GetEncoding(int codepage)
    {
        var provider = CodePagesEncodingProvider.Instance;
        if (codepage == 932)
        {            
            return provider.GetEncoding(932);
        }

        return null;
    }

    public override Encoding? GetEncoding(string name)
    {
        var provider = CodePagesEncodingProvider.Instance;
        if (name.Equals("shift_jis", StringComparison.CurrentCultureIgnoreCase))
        {                
            return provider.GetEncoding("shift_jis");
        }
        
        return null;
    }
}

(2) ShiftJisEncodingProvider の登録

ShiftJisEncodingProvider のインスタンスを Encoding.RegisterProvider メソッド に渡して、.NET アプリで Shift_JIS エンコーディングを取得できるようにします。

(3) Shift_JIS エンコーディングの取得

.NET アプリでは Encoding.GetEncoding メソッドを使って Shift_JIS エンコーディングを取得します。ステップ (2) と (3) のコード例は以下の通りです。コメントの結果に示すように期待通り Shift_JIS エンコーディングが取得できています。

using System.Text;

namespace ConsoleApp4
{
    internal class Program
    {
        static void Main(string[] args)
        {
            var provider = new ShiftJisEncodingProvider();
            Encoding.RegisterProvider(provider);

            var sjis = Encoding.GetEncoding("shift_jis");
            Console.WriteLine($"{sjis.EncodingName}\t{sjis.CodePage}\t{sjis.WebName}");

            var str = "123abcあいう";
            Console.Write($"{str}: ");

            byte[] bytes = sjis.GetBytes(str);
            foreach (byte b in bytes)
            {
                Console.Write($"[{b:x2}]");
            }            
        }
    }
}

// 結果:
// Japanese (Shift-JIS)    932     shift_jis
// 123abcあいう: [31][32][33][61][62][63][82][a0][82][a2][82][a4]

上で述べたようなカスタムプロバイダクラスを定義しなくても Windows コードページのエンコーディングを簡単に全部使えるようにする方法もあります。

その方法は、Microsoft のドキュメント「CodePagesEncodingProvider クラス」に説明があります。

  1. CodePagesEncodingProvider.Instance 静的プロパティから CodePagesEncodingProvider オブジェクトを取得します。
  2. CodePagesEncodingProvider オブジェクトを Encoding.RegisterProvider メソッドに渡します。

コード例は以下の通りで一行で済みます。必要ないエンコーディングまで使えるようにすることで何か予期せぬ副作用が出るかもしれないという可能性は否定しきれませんが、こちらのが本筋かもしれません。

using System.Text;

namespace ConsoleApp4
{
    internal class Program
    {
        static void Main(string[] args)
        {
            // 以下の一行で OK
            Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);

            var sjis2 = Encoding.GetEncoding("shift_jis");
            Console.WriteLine($"{sjis2.EncodingName}\t{sjis2.CodePage}\t{sjis2.WebName}");

            Console.Write($"{str}: ");

            byte[] bytes2 = sjis2.GetBytes(str);
            foreach (byte b in bytes2)
            {
                Console.Write($"[{b:x2}]");
            }

            Console.WriteLine("\n\nサポートしているすべてのエンコーディングを取得する");
            EncodingInfo[] eis = Encoding.GetEncodings();
            foreach (EncodingInfo ei in eis)
            {
                Console.WriteLine($"{ei.DisplayName}\t{ei.CodePage}\t{ei.Name}");
            }
        }
    }
}

/* 結果
Japanese (Shift-JIS)    932     shift_jis
123abcあいう: [31][32][33][61][62][63][82][a0][82][a2][82][a4]

サポートしているすべてのエンコーディングを取得する
Japanese (Shift-JIS)    932     shift_jis
Portuguese (DOS)        860     IBM860
Icelandic (DOS) 861     ibm861
IBM EBCDIC (Cyrillic Russian)   20880   IBM880
Hebrew (DOS)    862     DOS-862
French Canadian (DOS)   863     IBM863
Chinese Simplified (GB2312)     936     gb2312
Arabic (864)    864     IBM864
Nordic (DOS)    865     IBM865
Cyrillic (DOS)  866     cp866
Cyrillic (KOI8-U)       21866   koi8-u
IBM EBCDIC (US-Canada)  37      IBM037
Greek, Modern (DOS)     869     ibm869
IBM EBCDIC (International)      500     IBM500
Icelandic (Mac) 10079   x-mac-icelandic
IBM EBCDIC (US-Canada-Euro)     1140    IBM01140
IBM EBCDIC (Germany-Euro)       1141    IBM01141
IBM EBCDIC (Denmark-Norway-Euro)        1142    IBM01142
IBM EBCDIC (Germany)    20273   IBM273
IBM EBCDIC (Finland-Sweden-Euro)        1143    IBM01143
IBM EBCDIC (Italy-Euro) 1144    IBM01144
IBM EBCDIC (Spain-Euro) 1145    IBM01145
Central European (Windows)      1250    windows-1250
IBM EBCDIC (UK-Euro)    1146    IBM01146
Cyrillic (Windows)      1251    windows-1251
IBM EBCDIC (France-Euro)        1147    IBM01147
Western European (Mac)  10000   macintosh
Western European (Windows)      1252    windows-1252
Arabic (DOS)    720     DOS-720
IBM EBCDIC (Denmark-Norway)     20277   IBM277
IBM EBCDIC (International-Euro) 1148    IBM01148
Japanese (Mac)  10001   x-mac-japanese
Greek (Windows) 1253    windows-1253
OEM United States       437     IBM437
IBM EBCDIC (Finland-Sweden)     20278   IBM278
IBM EBCDIC (Icelandic-Euro)     1149    IBM01149
Chinese Traditional (Mac)       10002   x-mac-chinesetrad
Turkish (Windows)       1254    windows-1254
Hebrew (Windows)        1255    windows-1255
Korean (Johab)  1361    Johab
Arabic (Windows)        1256    windows-1256
Arabic (Mac)    10004   x-mac-arabic
Baltic (Windows)        1257    windows-1257
Hebrew (Mac)    10005   x-mac-hebrew
Vietnamese (Windows)    1258    windows-1258
Greek (Mac)     10006   x-mac-greek
Cyrillic (Mac)  10007   x-mac-cyrillic
IBM Latin-1     20924   IBM00924
Central European (ISO)  28592   iso-8859-2
Latin 3 (ISO)   28593   iso-8859-3
Baltic (ISO)    28594   iso-8859-4
Cyrillic (ISO)  28595   iso-8859-5
Arabic (ISO)    28596   iso-8859-6
IBM EBCDIC (Multilingual Latin-2)       870     IBM870
Greek (ISO)     28597   iso-8859-7
Hebrew (ISO-Visual)     28598   iso-8859-8
Turkish (ISO)   28599   iso-8859-9
Turkish (Mac)   10081   x-mac-turkish
Croatian (Mac)  10082   x-mac-croatian
Thai (Windows)  874     windows-874
IBM EBCDIC (Greek Modern)       875     cp875
IBM EBCDIC (Arabic)     20420   IBM420
Korean  949     ks_c_5601-1987
IBM EBCDIC (Greek)      20423   IBM423
IBM EBCDIC (Hebrew)     20424   IBM424
IBM EBCDIC (Italy)      20280   IBM280
IBM Latin-1     1047    IBM01047
IBM EBCDIC (Spain)      20284   IBM284
IBM EBCDIC (UK) 20285   IBM285
Romanian (Mac)  10010   x-mac-romanian
Japanese (JIS 0208-1990 and 0212-1990)  20932   EUC-JP
Ukrainian (Mac) 10017   x-mac-ukrainian
Europa  29001   x-Europa
Greek (DOS)     737     ibm737
Western European (IA5)  20105   x-IA5
Chinese Traditional (Big5)      950     big5
Chinese Simplified (GB2312-80)  20936   x-cp20936
German (IA5)    20106   x-IA5-German
Swedish (IA5)   20107   x-IA5-Swedish
Norwegian (IA5) 20108   x-IA5-Norwegian
Cyrillic (KOI8-R)       20866   koi8-r
Baltic (DOS)    775     ibm775
Estonian (ISO)  28603   iso-8859-13
IBM EBCDIC (Japanese katakana)  20290   IBM290
Latin 9 (ISO)   28605   iso-8859-15
Chinese Traditional (CNS)       20000   x-Chinese-CNS
Arabic (ASMO 708)       708     ASMO-708
IBM EBCDIC (France)     20297   IBM297
Thai (Mac)      10021   x-mac-thai
TCA Taiwan      20001   x-cp20001
IBM EBCDIC (Turkish)    20905   IBM905
Chinese Traditional (Eten)      20002   x-Chinese-Eten
IBM EBCDIC (Korean Extended)    20833   x-ebcdic-koreanextended
IBM5550 Taiwan  20003   x-cp20003
TeleText Taiwan 20004   x-cp20004
Wang Taiwan     20005   x-cp20005
Western European (DOS)  850     ibm850
IBM EBCDIC (Thai)       20838   IBM-Thai
Central European (DOS)  852     ibm852
IBM EBCDIC (Icelandic)  20871   IBM871
Central European (Mac)  10029   x-mac-ce
OEM Cyrillic    855     IBM855
IBM EBCDIC (Cyrillic Serbian-Bulgarian) 21025   cp1025
Korean Wansung  20949   x-cp20949
Turkish (DOS)   857     ibm857
OEM Multilingual Latin I        858     IBM00858
T.61    20261   x-cp20261
IBM EBCDIC (Turkish Latin-5)    1026    IBM1026
ISO-6937        20269   x-cp20269
Unicode 1200    utf-16
Unicode (Big-Endian)    1201    utf-16BE
Unicode (UTF-32)        12000   utf-32
Unicode (UTF-32 Big-Endian)     12001   utf-32BE
US-ASCII        20127   us-ascii
Western European (ISO)  28591   iso-8859-1
Unicode (UTF-8) 65001   utf-8
*/

Tags: , , ,

CORE

About this blog

2010年5月にこのブログを立ち上げました。主に ASP.NET Web アプリ関係の記事です。ブログ2はそれ以外の日々の出来事などのトピックスになっています。

Calendar

<<  May 2025  >>
MoTuWeThFrSaSu
2829301234
567891011
12131415161718
19202122232425
2627282930311
2345678

View posts in large calendar