GetPrivateProfileString

今の部署、お客様に入れているモノは過去に開発したモノを適宜カスタマイズや新しい環境への移行を図って10年以上も保守と拡張を続けてきたものを商品として扱っている。まあ、いわゆる「秘伝のタレ」というやつだ。で、.NETになって困り始めているのがいわゆるiniファイルの取扱。.NET Frameworkではiniファイルを扱うための簡単関数がないんだよね。MSDNによると、「そもそもiniファイルなんてWin16のAPIで、Win32の頃からレジストリにしろつってるべ? .NETじゃXML推奨だよ。」と。

でもまあ、今いる現場では困ってたみたいなので、C#の勉強がてら書いてみた。

        static String GetPrivateProfileString(String SecName,String KeyName,String FileName)
        {
            String line;
            String Value;
            bool SecFound;
            bool KeyFound;
            Value = "";
            SecName = "[" + SecName + "]";
            try
            {
                using (StreamReader sr = new StreamReader(FileName,System.Text.Encoding.GetEncoding("shift_jis")))
                {
                    SecFound = false;
                    line = "";
                    //セクション名による頭出し
                    while (!SecFound && ((line = sr.ReadLine()) != null))
                    {
                        line = line.Trim();
                        if ((line.Length >= SecName.Length) 
                        && (line.Substring(0, SecName.Length).Equals(SecName)))
                        {
                            SecFound = true;
                        }
                    }
                    KeyFound = false;
                    SecFound = false;
                    //セクション内のキーを探索。途中で他のセクションを発見したら終了。
                    while (!SecFound && !KeyFound && ((line = sr.ReadLine()) != null))
                    {
                        line = line.Trim();
                        if ((line.Length > 2) 
                        && (line.Substring(0, 1).Equals("["))
                        && (line.Substring(line.Length - 1, 1).Equals("]")))
                        {
                            SecFound = true;
                        }
                        else
                        {
                            if ((line.Length >= KeyName.Length)
                            && (line.Substring(0, KeyName.Length).Equals(KeyName)))
                            {
                                KeyFound = true;
                                Value = line.Substring(line.IndexOf("=") + 1
                                                      , line.Length - (line.IndexOf("=") + 1)
                                                      ).Trim();
                            }
                        }
                    }
                }
                return Value;
            }
            catch (Exception e)
            {
                return Value;
            }
        }

StreamReaderのコンストラクタの第二引数に、ファイルのエンコード情報を指定していなくて、最初ちょっとハマった。これを指定しないと、カナやら漢字やらが読めない。
もっとナイスな実装もあるとは思う。でも今はこれが精一杯だ。