2014-01-16 17 views
11

私は、FTP操作を実行するc#.Netコンソールアプリケーションを持っています。 現在、カスタム設定セクションで設定を指定しています。外部設定ファイルを読む

<?xml version="1.0" encoding="utf-8" ?> 
<configuration> 
    <configSections> 
    <section name="ftpConfiguration" type="FileTransferHelper.FtpLibrary.FtpConfigurationSection, FileTransferHelper.FtpLibrary" /> 
    </configSections> 

    <ftpConfiguration> 
     <Environment name="QA"> 
     <sourceServer hostname="QA_hostname" 
         username="QA_username" 
         password="QA_password" 
         port="21" 
         remoteDirectory ="QA_remoteDirectory" /> 
     <targetServer downloadDirectory ="QA_downloadDirectory" /> 

     </Environment> 
    </ftpConfiguration> 

</configuration> 

私は、コマンドラインで外部構成ファイルを指定したいと考えています。

しかし!!! ...

私は上記の「FtpConfiguration」セクションには、本当に、アプリケーションのapp.configをに属していないことに気づきました。

FileTransferHelper.exe -c FtpApplication1.config 
FileTransferHelper.exe -c FtpApplication2.config 
... 
FileTransferHelper.exe -c FtpApplication99.config 

その結果、私は私が間違ったパスの下行ってきたと考えていると私が本当にしたいことは、私のカスタムに読み込むためのものです:私の究極の目標は、私はこのように私のコンソールアプリケーションを実行し、多くのスケジュールされたタスクを持っているということですXmlDocumentを読み込み、それを直列化してノード/要素/属性を取得するのではなく、値を取得するためにSystem.Configurationを使用し続けます。 (誰かが私にいくつかの簡単なコードを表示することができれば、私は後者に反対するわけではないが)

ポインターをいただければ幸いです。ありがとう。

アップデート:私は受け入れ 答えは私のコードをここでは繰り返さ別にStackOverflowの質問へのリンクだった - 私が探していたまさにでした下に - 私の外部設定ファイルを開くにはOpenMappedExeConfigurationを使用して

ExeConfigurationFileMap configFileMap = new ExeConfigurationFileMap(); 
configFileMap.ExeConfigFilename = @"D:\Development\FileTransferHelper\Configuration\SampleInterface.config"; 

Configuration config = ConfigurationManager.OpenMappedExeConfiguration(configFileMap, ConfigurationUserLevel.None); 

FtpConfigurationSection ftpConfig = (FtpConfigurationSection)config.GetSection("ftpConfiguration"); 
+1

だけのノートとして、あなただけのXMLを解析することを決定しない場合:XmlDocumentオブジェクトは、C#でXMLを扱う古い方法で、あなたは確かにそれを行うことができますが、私はXDocumentを使用してお勧めしたいです、pa Linq-to-Xmlのrt。 – Magus

答えて

11

System.Configurationを使用してカスタムファイルを開く場合は、Loading custom configuration filesをチェックしてください。オリバーはそれを非常に簡単な方法で釘付けにします。

コマンドラインからアプリケーションに渡されるパラメータを読みたいので、このMSDNポストを訪れてください:Command Line Parameters Tutorial

カスタムアプローチを使用する場合は、これを実現する方法がいくつかあります。 1つの可能性は、ローダークラスを実装し、カスタム構成ファイルを使用することです。

たとえば、のは、次のようになり、単純な設定ファイルを想定してみましょう:

spec1.config

<?xml version="1.0" encoding="utf-8"?> 
<Settings> 
    <add key="hostname" value="QA_hostname" /> 
    <add key="username" value="QA_username" /> 
</Settings> 

非常に単純な、ハッシュテーブルのような(キーと値のペア)構造。

Anは、パーサ/読者は、このようなものになります実装:一方

 private Hashtable getSettings(string path) 
     { 
      Hashtable _ret = new Hashtable(); 
      if (File.Exists(path)) 
      { 
       StreamReader reader = new StreamReader 
       (
        new FileStream(
         path, 
         FileMode.Open, 
         FileAccess.Read, 
         FileShare.Read) 
       ); 
       XmlDocument doc = new XmlDocument(); 
       string xmlIn = reader.ReadToEnd(); 
       reader.Close(); 
       doc.LoadXml(xmlIn); 
       foreach (XmlNode child in doc.ChildNodes) 
        if (child.Name.Equals("Settings")) 
         foreach (XmlNode node in child.ChildNodes) 
          if (node.Name.Equals("add")) 
           _ret.Add 
           (
            node.Attributes["key"].Value, 
            node.Attributes["value"].Value 
           ); 
      } 
      return (_ret); 
     } 

を、あなたはまだ、元app.configファイルからの読み込みにConfigurationManager.AppSettings[]を使用することができます。

5

私の好みのソリューションはXDocumentを使用しています。私はそれをテストしていないので、いくつかのわずかな問題があるかもしれませんが、これは私のポイントを示すことです。

public Dictionary<string, string> GetSettings(string path) 
{ 

    var document = XDocument.Load(path); 

    var root = document.Root; 
    var results = 
    root 
     .Elements() 
     .ToDictionary(element => element.Name.ToString(), element => element.Value); 

    return results; 

} 

は、フォームのXMLから要素名と値を含む辞書を返します。

<?xml version="1.0" encoding="utf-8"?> 
<root> 
    <hostname>QA_hostname</hostname> 
    <username>QA_username</username> 
</root> 

それは全体の簡潔だのために、私はこのソリューションは素敵見つけます。

また、これはまったく同じように動作するとは思われません。 XAttributesとXElementsなどを使用すると、これを確実に元のようにすることができます。フィルタリングは簡単です。

+0

+1、私はそれがどのくらいコンパクトであるか好きです。 – OnoSendai

+0

@OnoSendai:これは本当にLinqの私のお気に入りの部分の一つです。私は多くの人がそれがそこにあることに気付いていないと思います。それは比較的新しいですが、私は思います。しかし、名前空間が動作する方法はちょっと混乱するかもしれません。 – Magus

12

カスタムパスをダウンすると、正にJSONを使用して設定を保存し、それを読み込みデシリアライズしてシリアル化して書き込みます。 Json.NETを使用すると、これを非常に簡単に行うことができます。

のあなたのXML:

<ftpConfiguration> 
    <Environment name="QA"> 
    <sourceServer hostname="QA_hostname" 
        username="QA_username" 
        password="QA_password" 
        port="21" 
        remoteDirectory ="QA_remoteDirectory" /> 
    <targetServer downloadDirectory ="QA_downloadDirectory" /> 

    </Environment> 
</ftpConfiguration> 

はJSONで次のようになります。あなたのクラスは次のようになり

{ 
    "FtpConfiguration": { 
    "Environment": { 
     "Name": "QA", 
     "SourceServer": { 
     "HostName": "QA_hostname", 
     "UserName": "QA_username", 
     "Password": "QA_password", 
     "Port": "21", 
     "RemoteDirectory": "QA_remoteDirectory" 
     }, 
     "TargetServer": { 
     "DownloadDirectory": "QA_downloadDirectory" 
     } 
    } 
    } 
} 

class Config 
{ 
    public FtpConfiguration FtpConfiguration { get; set; } 
} 

class FtpConfiguration 
{ 
    public Environment Environment { get; set; } 
} 

class Environment 
{ 
    public SourceServer SourceServer { get; set; } 
    public TargetServer TargetServer { get; set; } 
} 

class SourceServer 
{ 
    public string HostName { get; set; } 
    public string UserName { get; set; } 
    public string Password { get; set; } 
    public int Port { get; set; } 
    public string RemoteDirectory { get; set; } 
} 

class TargetServer 
{ 
    public string DownloadDirectory { get; set; } 
} 

あなたのようなオブジェクトに設定し保存しますこれは:

var config = new Config() 
{ 
    FtpConfiguration = new FtpConfiguration() 
    { 
     Environment = new Environment() 
     { 
      SourceServer = new SourceServer() 
      { 
       HostName = "localhost", 
       UserName = "jaxrtech", 
       Password = "stackoverflowiscool", 
       Port = 9090, 
       RemoteDirectory = "/data", 
      }, 
      TargetServer = new TargetServer() 
      { 
       DownloadDirectory = "/downloads" 
      } 
     } 
    } 
}; 

あなたはその後、このようなファイルへのの書き込み(またはその大きなファイル場合Streamを使用)できます。

string json = JsonConvert.SerializeObject(config); 
File.WriteAllText("config.json", json); 

あなたはその後、が(再び使用することができ、このようなファイルでを読むことができます代わりにStream):

string json = File.ReadAllText("config.json"); 
Config config = JsonConvert.DeserializeObject<Config>(json); 
関連する問題