C# 如何循环浏览文件夹和更新XML文件

C# 如何循环浏览文件夹和更新XML文件,c#,.net,xml,loops,foreach,C#,.net,Xml,Loops,Foreach,我有一个软件,在安装时要求提供服务器的IP地址,并将该地址存储到不同文件夹中的多个配置文件中 我对C#还是有点陌生,但我创建了一个实用程序,在这个实用程序中,无论出于何种原因,如果他们的IP地址要更改或想要更改,存储的IP地址都将更新为当前的IP地址 using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Net; using System.Net.Netwo

我有一个软件,在安装时要求提供服务器的IP地址,并将该地址存储到不同文件夹中的多个配置文件中

我对C#还是有点陌生,但我创建了一个实用程序,在这个实用程序中,无论出于何种原因,如果他们的IP地址要更改或想要更改,存储的IP地址都将更新为当前的IP地址

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.NetworkInformation;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Xml;
using System.Xml.Linq;


namespace ConfigTool
{
    class Class1
    {
        //Not sure if this would work since this is just a path to a bunch of folders and not the actual xml files within those folders
        const string FILENAME = @"C:\Program Files (x86)\Stuff\Noodles"; 

        public static IPAddress GetIPAddress(string hostName)
        {
            Ping ping = new Ping();
            var replay = ping.Send(hostName);

            if (replay.Status == IPStatus.Success)
            {
                return replay.Address;
            }
            return null;
        }

        static void Main(string[] args)
        {
            //XDocument doc =  XDocument.Load(FILENAME); 
            var path = Directory.EnumerateFiles(@"C:\Program Files (x86)\Stuff\Noodles", "*.config");
            foreach (var xmlfile in path)
            {
                XDocument doc = XDocument.Load(xmlfile);
                List<XElement> endpoints = doc.Descendants("endpoint").ToList();
                foreach (var endpoint in endpoints)
                {
                    string address = (string)endpoint.Attribute("address");
                    //string newIp = "10.249.30.4";

                    string pattern = "//[^:]+";
                    address = Regex.Replace(address, pattern, "//" + GetIPAddress(Dns.GetHostName()));

                    endpoint.Attribute("address").SetValue(address);
                }
                doc.Save(FILENAME);
            }
        }
    }
}
使用系统;
使用System.Collections.Generic;
使用System.IO;
使用System.Linq;
Net系统;
使用System.Net.NetworkInformation;
使用系统文本;
使用System.Text.RegularExpressions;
使用System.Threading.Tasks;
使用System.Xml;
使用System.Xml.Linq;
命名空间配置工具
{
一班
{
//不确定这是否可行,因为这只是一个指向一堆文件夹的路径,而不是这些文件夹中的实际xml文件
常量字符串文件名=@“C:\ProgramFiles(x86)\Stuff\Lade”;
公共静态IPAddress GetIPAddress(字符串主机名)
{
Ping Ping=新Ping();
var replay=ping.Send(主机名);
if(replay.Status==IPStatus.Success)
{
返回重播地址;
}
返回null;
}
静态void Main(字符串[]参数)
{
//XDocument doc=XDocument.Load(文件名);
var path=Directory.EnumerateFiles(@“C:\ProgramFiles(x86)\Stuff\Lade”,“*.config”);
foreach(路径中的var xmlfile)
{
XDocument doc=XDocument.Load(xmlfile);
List endpoints=doc.substands(“endpoint”).ToList();
foreach(端点中的var端点)
{
字符串地址=(字符串)endpoint.Attribute(“地址”);
//字符串newIp=“10.249.30.4”;
字符串模式=“//[^::][+”;
address=Regex.Replace(地址,模式,“/”+GetIPAddress(Dns.GetHostName());
endpoint.Attribute(“地址”).SetValue(地址);
}
文件保存(文件名);
}
}
}
}
我的代码正在筛选目录中的所有xml配置文件,并使用新的IP地址更新它。但是,它们是某些文件夹中的一些xml配置文件,我不想更改这些文件,比如说net。tcp://localhost.

<endpoint name="SessionLocal" address="net.tcp://localhost:7732/AuthenticationServices/Secure" binding="netTcpBinding" contract="WelchAllyn.Services.ServiceContracts.IAuthenticationService" bindingConfiguration="TcpCustomSecurity" behaviorConfiguration="SecureBehaviorName">
        <identity>
          <dns value="localhost"/>
        </identity>
      </endpoint>
      <endpoint name="DataLocal" address="net.tcp://localhost:7732/DataServices/Secure" binding="netTcpBinding" contract="WelchAllyn.Services.ServiceContracts.IDataService" bindingConfiguration="TcpCustomSecurity" behaviorConfiguration="SecureBehaviorName">
        <identity>
          <dns value="localhost"/>
        </identity>
      </endpoint>

我要更改的xml文件具有实际的IP地址,如

<endpoint name="SubscriptionLocal" address="net.tcp://10.249.30.4:7732/EventSubscriberServices/Secure" binding="netTcpBinding" contract="WelchAllyn.Services.ServiceContracts.ISubscriptionService" bindingConfiguration="TcpCustomSecurity" behaviorConfiguration="CustomValidator">
        <identity>
          <dns value="localhost" />
        </identity>
      </endpoint>
      <endpoint name="PublishLocal" address="net.tcp://10.249.30.4:7732/EventPublishServices/Secure" binding="netTcpBinding" contract="WelchAllyn.Services.ServiceContracts.IPublishService" bindingConfiguration="TcpCustomSecurity" behaviorConfiguration="CustomValidator">
        <identity>
          <dns value="localhost" />
        </identity>
      </endpoint>


我的问题是如何只使用实际IP地址更新IP地址,而不使用localhost更新IP地址。如何循环遍历目录中的每个文件夹并保存每个文件夹中的每个xml文件?

对于嵌套文件夹,您需要搜索
SearchOption。所有目录

var path = Directory.EnumerateFiles(@"C:\Program Files (x86)\Stuff\Noodles", "*.config", SearchOption.AllDirectories);
对于localhost,您可以这样跳过它们:

string address = (string)endpoint.Attribute("address");
if (new Uri(address).Host == "localhost") continue;

编辑:以下是完整代码:

static void Main(string[] args)
{
    Console.WriteLine("Enter the ip address to update:");
    var ip = Console.ReadLine();
    if (!IsValidIPv4Address(ip))
        throw new ArgumentException("Invalid ip address: " + ip);

    var path = Directory.EnumerateFiles(@"C:\Program Files (x86)\Stuff\Noodles", "*.config", SearchOption.AllDirectories);
    foreach (var xmlfile in path)
    {
        var doc = XDocument.Load(xmlfile);
        var endpointsToUpdate = doc
            .Descendants("endpoint")
            .Where(x => new Uri((string)x.Attribute("address")).Host != "localhost")
            .ToArray();

        // skip if there is nothing to update
        if (!endpointsToUpdate.Any()) return;

        foreach (var endpoint in endpointsToUpdate)
        {
            string address = (string)endpoint.Attribute("address");
            string pattern = "//[^:]+";
            address = Regex.Replace(address, pattern, "//" + GetIPAddress(Dns.GetHostName()));

            endpoint.Attribute("address").SetValue(address);
        }

        doc.Save(xmlfile);
    }
}

bool IsValidIPv4Address(string text)
{
    return text?.Split('.') is string[] parts &&
        parts.Length == 4 &&
        parts.All(x => byte.TryParse(x, out _));
}

edit2:已完成用户输入。

但如何保存?我还会使用doc.Save(Filename)吗?你想保存到
xmlfile
。所以我刚被问到一个问题,如果有人想手动输入IP地址怎么办。如何编写?@Masterolu您可以使用
Console.ReadLine()
获取用户输入。