2014-01-16 5 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 

따라서, 내가 잘못된 경로 내려 갔어요 믿고 내가 정말 원하는 것은 내 사용자 지정에서 읽을 수있는 무언가이다 : 내 궁극적 인 목표는이 같은 내 콘솔 응용 프로그램을 실행 많은 예약 된 작업을해야한다는 것입니다 XML 문서하지만 System.Configuration을 사용하여 값을 얻으십시오 ... XmlDocument를 읽고 직렬화하여 노드/요소/특성을 가져 오는 것과 반대입니다. (비록 누군가가 나에게 간단한 코드를 보여줄 수 있다면 후자에 반대하지 않는다.)

포인터가 크게 감사 할 것입니다. 감사.

업데이트 : 내 코드를 여기에 반복 내가 다른 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를 사용하는 것이 좋습니다 것 , 파 rt of Linq-to-Xml. – Magus

답변

11

System.Configuration을 사용하여 사용자 정의 파일을 열려면 Loading custom configuration files을 확인하십시오. 올리버는 아주 직설적 인 방법으로 그것을 못 박는 다.

명령 줄을 통해 응용 프로그램에 전달 된 매개 변수를 읽으려는 것이므로 Command Line Parameters Tutorial을 방문하십시오.

맞춤형 접근 방식을 사용하려는 경우이를 수행 할 수있는 몇 가지 방법이 있습니다. 하나의 가능성은 로더 클래스를 구현하고 사용자 정의 구성 파일을 사용하는 것입니다.

예를 들어, 다음과 같습니다 간단한 설정 파일을 가정 해 봅시다 :

spec1.config

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

아주 간단한, 해시 테이블처럼 (키 - 값 쌍) 구조.

 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이 같을 것이다 : 당신은 같은 객체로 설정 절약 할 수

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; } 
} 

: 같은

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

수업이 보일 것이다 이 :

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" 
      } 
     } 
    } 
}; 

그런 다음 (A Stream의 경우 더 큰 파일을 사용하거나)이 같은 파일에을 작성할 수

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

을 당신은 다음과 같은 파일 (다시 사용할 수에을 읽을 수 대신 Stream) :

string json = File.ReadAllText("config.json"); 
Config config = JsonConvert.DeserializeObject<Config>(json);