2011-04-06 73 views
1

我现在有一个运行了很长的步骤列表,例如C#程序:C#解决方案系统的命令列表

  • 副本的文件从这里到那里 即: 的foreach(文件列表) File.Copy()
  • 创建一批目录的 的foreach(目录列表) Directory.Create
  • 循环进入目录的列表,并创建一个文件。 的foreach(在列表目录) File.Create()
  • 取得文件的列表知道,更换内 的foreach(文件列表) 执行( “REPLACE.EXE”,文本1,文本2)
一些文本

我所做的就是把所有这些步骤,并创建一批在C#是做那些步骤的方法。这样做的好处是,我可以检查每个运行的命令,记录任何问题等。它的缺点是,它是硬编码的。

我想(我需要)将这些步骤从代码中移出,如在配置文件或xml文件中,然后逐个读取命令并在c#中运行它们。通过这种方式,我仍然可以检查返回错误,创建日志等,但我没有实际的列表和命令硬编码。

我不想使用脚本(如Perl或批处理),因为我希望能够监视我所做的一些步骤。换句话说,我真的想在c#程序中保留实际的执行,但是程序由我提供给它的配置文件指导。

xml非常灵活,但我不确定我可以用它做所有事情。例如 我怎么变成XML是这样的:

list1 = {file1, file2}; 
list2 = {dir1,dir2,dir3}; 
foreach (file in list1) 
File.Copy(file,dir2\\file); 
File.Copy(file,dir3\\file); 

什么我可以/应该使用来实现这一目标的任何想法?

感谢 托尼

+5

考虑使用PowerShell的呢? – 2011-04-06 16:49:00

+0

我还没有想过,但这将是一个外部过程(我认为)。我老实说从来没有使用过PowerShell,所以我不知道这对我有什么帮助。 Tony – tony 2011-04-07 21:37:12

+0

PowerShell可以作为外部进程启动,也可以从其他进程托管。例如,SQL Server Management Studio中允许在树视图中,您可以右键单击一个节点,并启动PowerShell的与该节点作为当前项目运行。 – 2011-04-07 21:46:49

回答

1

这里是我的循环任务

[XmlAttribute] 
    public string DataTableName { get; set; } 

    public TaskListClass TaskList { get; set; } 

    public override void Execute(WorkContainer container) 
    { 
     int iteration = 0; 
     string originalTaskName=String.Empty; 

     // Log Start 
     base.Execute(container); 

     // Get the Data Table Based upon the ContainerKey 
     DataTable loopTable = container.GetKeyValue<DataTable>(DataTableName); 

     // If not found throw exception and exit 
     if (loopTable == null) 
     { 
      throw new ArgumentException(
       "DataTable Not Found or Initialized For Loop Variable", 
       DataTableName); 
     } 

     // For each row returned run the task in order as a mini-process 
     foreach (DataRow row in loopTable.Rows) 
     { 
      iteration++; 

      foreach (TaskBase task in TaskList.Tasks) 
      { 
       // If it is the first iteration then create a new string with the iteration number 
       // else just replace the last iteration number with the current iteration number 
       if (iteration == 1) 
       { 
        task.Name = String.Format("Iteration {0} - {1}", iteration, task.Name); 
       } 
       else 
       { 
        task.Name = task.Name.Replace(String.Format("Iteration {0}",iteration-1),String.Format("Iteration {0}",iteration)); 
       } 

       // Call the task Constructor to Initialize the object 
       task.GetType().GetConstructor(new Type[0]).Invoke(null); 

       foreach (DataColumn dc in loopTable.Columns) 
       { 
        // Store in Stack Variable 
        string propertyName = dc.ColumnName; 

        // If a field in the table matches a 
        // property Name set that property 
        PropertyInfo propInfo = task.GetType().GetProperty(propertyName); 
        if (propInfo != null) 
        { 
         propInfo.SetValue(task, row[dc], null); 
        }       
        else 
        { 
         // Else if the task has a Parameters collection add the 
         // name of the column and value to the Parameter Collection 
         propInfo = task.GetType().GetProperty("Parameters"); 

         if (propInfo != null) 
         { 
          List<Parameter> parameters = propInfo.GetValue(task, null) as List<Parameter>; 

          // If the parameter Name already Exist then Override it 
          // This means that the values in the DataTable override the values in the XML 
          if (parameters.Contains(new Parameter { Name = propertyName })) 
          { 
           parameters.Remove(new Parameter { Name = propertyName }); 
          } 

          parameters.Add(new Parameter { Name = propertyName, Value = row[dc].ToString(), Type="String" }); 
         } 
         else 
         { 
          ParameterNotFoundException pExp = new ParameterNotFoundException(propertyName, task.GetType().ToString()); 
          throw new TaskException("Unable to assign a Parameter", pExp.Message, pExp); 
         } 

        } 
       } 

       task.Execute(container); 
      } 
     } 

     base.Finish(container); 
    } 

的XML看起来像这样

<LoopTask Name="Loop Report Creation" DataTableName="[? DistributionList ?]"> 
     <TaskList> 
     <ReportBatchTask Name="Report In Loop"> 
      <ConnectionName>xxx</ConnectionName> 
      <Parameters /> 
     </ReportBatchTask> 
     </TaskList> 
    </LoopTask> 
1

要做到你的要求,你就必须在代码中定义的每个可能的行动,因此,如果您创建一个新的动作,这将需要编辑的程序。尽管如此,配置现有操作不会有任何问题。

<TaskList> 
    <MyTask> 
    <Action type="CreateDirectory"> 
     <target>dir1</target> 
     <target>dir2</target> 
    </Action> 
    </MyTask> 
    <MyTask> 
    <SourceFiles> 
     <file>mypath\file1.txt</file> 
     <file>mypath\file2.txt</file> 
    </SourceFile> 
    <Action type="Replace"> 
     <originalText>Text to replace</originalText> 
     <replacementText>Some new text</replacementText> 
    </Action> 
    <Action type="Copy"> 
     <target>dir1</target> 
     <target>dir2</target> 
    </Action> 
    </MyTask> 
</TaskList> 

如果你有一个单独的类为每一个可能Action那么你将创建和使用你从XML在读什么执行适当Action

+0

我真的很喜欢这个建议。我需要弄清楚循环,但大多数解决了我的问题。 感谢 托尼 – tony 2011-04-07 21:30:46

1

是的,我做了一个类似的项目:这里有一些想法,而不必键入整个事情。

我创建的任务,每个任务由Task类inherieted基本记录和

public virtual void Execute(WorkContainer container) 

但每类做了这样的复制类将有一个来源,目的地和覆盖性能。

那我就创造出当时可能被序列化到XML任务列表的任务列表

看起来像

<TaskList> 
    <TransactionSqlTask Name="Get Interest Register Data"> 
     <Parameters> 
     <Parameter> 
      <Type>String</Type> 
      <Value>M</Value> 
      <Name>PaymentInd</Name> 
     </Parameter> 
     </Parameters> 
     <DataTableName> 
     <string>InterestRegisterData</string> 
     </DataTableName> 
     <IgnoreOutputDataTable>false</IgnoreOutputDataTable> 
     <StoredProcName>proc_Report_NotesInterestRegister</StoredProcName> 
     <ConnectionName>xxx</ConnectionName> 
    </TransactionSqlTask> 

...

XML可以是一个命令行参数将被读入,反序列化并返回到任务列表

然后,我只是循环访问List和Call。执行

现在还有一个工作容器将值从一个任务传递到另一个。看到这个帖子

Using Generics to return a literal string or from Dictionary<string, object>

后,我可以提供更多的细节,现在我没有这个项目盈我的,但希望这给了你一些想法。

+0

这是一个很好的建议,它有一定的相似之处下一个建议。 感谢 托尼 – tony 2011-04-07 21:32:01

0

您是否考虑过将函数重写为MSBuild任务?

通过这种方式,您可以利用预先存在的msbuild任务,并将脚本编写为msbuild文件(它非常适合于任何构建过程)。 You can even debug MSBuild tasks

+0

我还没有想过,但后来它可以追溯到我不必运行外部过程,就像是一个黑盒给我的最初的问题。 Perl脚本或批处理文件与使用msbuild相同。 Perl绝对是可调试的。我确实看到你在构建过程中很好地适应了msbuild。 感谢 托尼 – tony 2011-04-07 21:35:07

+0

您不必调用外部程序..的MSBuild暴露了一个C#库,在这里看到:http://stackoverflow.com/questions/536539/how-to-call-msbuild-from-c – 2011-04-08 08:40:39

相关问题