LoginSignup
6

More than 1 year has passed since last update.

posted at

今年業務で使ったc#のスキルまとめ

C# Advent Calendar 2020の17日目の記事です。

はじめに

今年は業務でwindowsアプリを開発したので、今回は備忘録的に今年使ったスキルを書きます。
多分基礎的なことばっかりです。

  • 開発環境
    • VisualStudio 2019

レジストリ操作

インストーラーを使って開発したwindowsアプリをインストールしてもらう想定だったため、インストール時にインストーラーがレジストリ登録したバージョン情報などをアプリで表示する必要などがありました。

インストーラーとは?

windowsでレジストリを開く場合は win + R キーを押してregeditと入力する方法が一般的だと思います。

image.png

image.png

次はc#でHKEY_USERSのサブキーの一覧(.DEFAULT, S-1-5-XX)を取得します。
using Microsoft.Win32を追加することに注意です。

            // サブキーの一覧を取得
            var keys = Registry.Users.GetSubKeyNames();
            foreach (var key in keys)
            {
                Console.WriteLine($"取得したサブキー : {key}");
            }

Registry.Users でHKEY_USERSを読み込んで、GetSubKeyNames()でサブキーの一覧(string型の配列)を取得しています。

取得したサブキー : .DEFAULT
取得したサブキー : S-1-5-19
取得したサブキー : S-1-5-20
取得したサブキー : S-1-5-21-3102848314-395816088-1389192899-1001
取得したサブキー : S-1-5-21-3102848314-395816088-1389192899-1001_Classes
取得したサブキー : S-1-5-18

次はキーに書かれている値を取得してみましょう。
HKEY_CURRENT_USER のサブキー Software\Microsoft\Edge\BLBeaconversion の値をc#で読み込みます。
image.png

            using (var regkey2 = Registry.CurrentUser.OpenSubKey(@"Software\Microsoft\Edge\BLBeacon", false))
            {
                var ver = (string)regkey2.GetValue("version");
                Console.WriteLine($"BLBeacon ver : {ver}");
            }

先ほどと違うのはRegistry.CurrentUserHKEY_CURRENT_USERを指定して、OpenSubKey()Software\Microsoft\Edge\BLBeacon のサブキーを開きます。

GetValue()の引数に取得したい名前を渡します。今回はREG_SZの値が欲しいので、stringでcastします。

BLBeacon ver : 87.0.664.60

最後にサブキーを作る例です。
32bit/64bitアプリでサブキーを作成する場所が変わったりするので注意が必要です。

            try
            {
                using(var prevKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64))
                using(var error = prevKey.OpenSubKey("Software", true))
                {
                    var _ = error?.CreateSubKey("test");
                    Console.WriteLine("レジストリに書き込み出来ました。");
                }
            }
            catch(Exception e)
            {
                Console.WriteLine(e.ToString());
            }

レジストリへのサブキー・値の作成(Create)には管理者権限が必要なので、上記のコードを管理者権限以外で実行するとCreateSubKeyで例外が発生することになります。

System.Security.SecurityException: 要求されたレジストリ アクセスは許可されていません。
   場所 System.ThrowHelper.ThrowSecurityException(ExceptionResource resource)
   場所 Microsoft.Win32.RegistryKey.OpenSubKey(String name, Boolean writable)

管理者権限で実行した場合 HKEY_LOCAL_MACHINE\SOFTWARE\testが作成されます。
レジストリへの書き込みを行うアプリを作る場合は、管理者権限が必要になることを注意しましょう。

レジストリへの読み込み、書き込み

json操作

設定画面でパラメータを反映できるアプリでは、起動するたびに初期値を表示するのではなく、前回アプリ終了時の設定をそのまま表示させたいと思います。
そのような場合に、どのように設定値を保存するかでJSON(JavaScript Object Notation)形式でデータを保持しておいて、アプリ終了時にファイルへ書き込みし、アプリ起動時にファイルを読み込むという手法がよくとられます。(少なくとも私の会社のアプリはjsonにデータもたせてます。)

jsonのライブラリはいくつかありますが、Nugetから簡単に使用できるNewtonsoft.Jsonで例を出します。

    [JsonObject("target")]
    public class TargetJson
    {
        [JsonProperty("happy")]
        public bool Boolean { get; set; }

        [JsonProperty("name")]
        public string Name { get; set; }

        [JsonProperty("pi")]
        public double Number { get; set; }

        [JsonProperty("list")]
        public List<int> List { get; set; }

        [JsonProperty("object")]
        public ObSample ObS { get; set; }
    }

    public class ObSample
    {
        [JsonProperty("currency")]
        public string Name { get; set; }

        [JsonProperty("value")]
        public double Value { get; set; }
    }

TargetJsonクラスはbool、string、double、List<int>、stringとdoubleのプロパティをもつObSampleクラスの プロパティをもつクラスになります。

このようなオブジェクトをjsonに書き込むようにする処理をシリアライズとよぶそうです。

            var t = new TargetJson()
            {
                Boolean = true,
                Name = "arisugawa",
                Number = 3.14,
                List = new List<int> { 3, 3, 4 },
                ObS = new ObSample()
                {
                    Name = "USB",
                    Value = 33.45,
                },
            };
            // 第二引数でインデントをつけれる
            string j = Newtonsoft.Json.JsonConvert.SerializeObject(t, Newtonsoft.Json.Formatting.Indented);
            // file書き込み
            File.WriteAllText(@"write.json", j);

変数tにTargetJsonクラスのインスタンスを代入し、Newtonsoft.Json.JsonConvert.SerializeObject()で変数tのオブジェクトをjsonに書き込める形式に変換(string型へ)してあげています。
最後に、File.WriteAllText() でwrite.json という名前のファイルに書き込んでいます。

image.png

上の画像がwrite.jsonに書き込まれている内容です。
JSONは key : value の組み合わせになり、 valueは各プロパティにセットした値ですが、keyの名前(例えばbool型のhappy)はどこで設定しているのでしょうか。

        [JsonProperty("happy")]
        public bool Boolean { get; set; }

Booleanプロパティに JsonPropertyという属性がついていますね。ここで設定した値がjsonのkeyになります。

ファイルなどに書かれたjsonオブジェクトを読み込んで活用したい場合はデシリアライズとよばれる動作が必要になります。

            var sr = new StreamReader("write.json");
            // ファイルの内容をすべて読み込みます。
            string j = sr.ReadToEnd();
            // string型の文字列をもとにTargetJson型のオブジェクトにデシリアライズ
            TargetJson s = Newtonsoft.Json.JsonConvert.DeserializeObject<TargetJson>(j);
            // オブジェクトのプロパティにアクセス
            Console.WriteLine(s.ObS.Name);

バージョニング

個人でつくるHelloWorldやサンプルアプリならバージョンについて深く考えることはないかと思いますが、お客様提供するアプリの場合は障害発生したときの解析や問い合わせ対応のためにバージョンを付与するのは必須かと思います。

image.png

VisualsStudio2019(devenv.exe)のファイルバージョン

バージョニングのルールやどのタイミングでどの番号をいくつ上げるかなどは所属する組織で違うはずですが、
windowsアプリの場合はMicrosoftのドキュメントに倣っているところが多いのではないでしょうか。

// AssemblyInfo.csの内容
// アセンブリのバージョン情報は次の 4 つの値で構成されています:
//
//      メジャー バージョン
//      マイナー バージョン
//      ビルド番号
//      リビジョン
//
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

バージョン情報の更新は、Properties\AssemblyInfo.csの"1.0.0.0"の内容を直接書き換えても反映されます。が、プロジェクト-右クリック、プロパティ-アプリケーション-アセンブリ情報で表示されるGUI上で変更するほうが楽かと思います。ちなみにこのGUIで変更した内容はAssemblyInfo.csに反映されます。

image.png

アプリのアイコン設定

visualstudioで作成したアプリはデフォルトのアイコンになります。
image.png

アイコンを変更する場合は
プロジェクト-右クリック、プロパティ-アプリケーション-リソース-アイコンとマニフェストicoファイルを指定します。

icoファイルはjpgやpngをコンバートして作成しましょう。
アイコンファイル(*.ico)作成

icoファイルを設定後は、プロジェクトにicoファイルが追加されます。
image.png

ビルドしてexeを生成・実行すると指定したicoがアイコンとして表示されているはずです。

まとめ

コーディング的なスキルというより、リリースまでの設定に近い部分が多くなりました。
windowsアプリだとUWPによるアプリ開発が主流と思いますが、今回はいわゆるレガシーアプリ開発で、開発のルールなどもUWP開発とは少し違うことになりました。(UWPだとマニフェストの設定やstoreへの登録などが必要ですね。)

正直、ドキュメントがチームに充実しているかで変わってきますね。
以上になります。

備考

インストールシールド12
業務ではIS12を使ってインストーラーを開発してます。

きまま研究所(WOW64で起動した際に64bitレジストリへアクセスする)

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
6