我过去曾使用setargv.obj linking for Expanding Wildcard Arguments用于许多C和C ++应用程序,但我找不到.net应用程序的任何类似提及。
是否有标准方法让您的应用程序的命令行参数自动扩展通配符?(即将* .doc从args参数中的一个条目扩展到所有匹配的条目通配符)。
P.S。我已经使用Directory.GetFiles()为我当前的小项目攻击了一些东西,但是它没有覆盖带路径的通配符(还有),如果没有自定义代码,那就很好。
更新:这是我粗暴的黑客,为了说明。它需要拆分GetFiles的路径和名称参数,但这是一般的想法。将setargv.obj链接到C或C ++应用程序基本上会进行所有通配符扩展,使用户只能遍历argv数组。
static void Main(string[] args)
{
foreach (String argString in args)
{
// Split into path and wildcard
int lastBackslashPos = argString.LastIndexOf('\\') + 1;
path = argString.Substring(0, lastBackslashPos);
filenameOnly = argString.Substring(lastBackslashPos,
argString.Length - lastBackslashPos);
String[] fileList = System.IO.Directory.GetFiles(path, filenameOnly);
foreach (String fileName in fileList)
{
//do things for each file
}
}
}
答案 0 :(得分:9)
我们这是粗暴的黑客。我喜欢它是递归的。在遇到Windows通配符的缺点后,我可能决定使用正则表达式,而不是让GetFiles()为我做。
using System.IO;
public static string[] ExpandFilePaths(string[] args)
{
var fileList = new List<string>();
foreach (var arg in args)
{
var substitutedArg = System.Environment.ExpandEnvironmentVariables(arg);
var dirPart = Path.GetDirectoryName(substitutedArg);
if (dirPart.Length == 0)
dirPart = ".";
var filePart = Path.GetFileName(substitutedArg);
foreach (var filepath in Directory.GetFiles(dirPart, filePart))
fileList.Add(filepath);
}
return fileList.ToArray();
}
答案 1 :(得分:4)
我不确定你究竟是在追求什么......但是如果我得到你所提到的Directory.GetFiles()“hack”的地方,那么这样的事情可能有用:
var Dirs = Directory.GetDirectories(@"C:\Windows", "sys*",
SearchOption.TopDirectoryOnly).ToList();
var Files = new List<String>();
Dirs.ForEach(dirName => Files.AddRange(Directory.GetFiles(dirName, "*.sys", SearchOption.AllDirectories)));
GetDirectories调用上的通配符选项将允许您[直接]获取与“sys *”模式匹配的Windows文件夹中包含的所有目录。
然后,您可以遍历那些文件夹,抓取所有匹配模式“* .sys”的文件。
这是你要找的那种东西吗?要自动扩展args,您必须以某种有意义的方式提取通配符并将它们应用于该模型...
例如:
RunMyApp“C:\ Windows \ Sys * \ * .sys”
您将提取字符串C:\ Windows - 可能使用正则表达式,找到不包含通配符的最低级别目录并将其应用于GetDirectories方法,并将通配符字符串作为搜索参数附加。
然后,如果您的字符串结尾(在本例中为* .sys)作为Directory.GetFiles的搜索模式。
如果你想变得更复杂并做类似的事情:
C:\Windows\*\Sys*\*.sys
您可以使用SearchOptions设置此行为:
Directory.GetDirectories(@"C:\Windows", "sys*", SearchOptions.AllDirectories)
这将获取与Windows目录中的sys *通配符及其下面的所有目录匹配的所有目录。
如果你想要比这更复杂,那么我不确定你会怎么做...例如,假设你想要直接在Windows目录中的文件夹包含的文件夹 - 我不知道你怎么会这样做我害怕...我不认为将整个树结构导出到XML并使用XPath来实现它会非常有效 - 使用通配符解析XPath非常简单 - 但转换为XML效率不高......
答案 2 :(得分:3)
在Microsoft.Build.dll中查看反汇编的Microsoft.Build.Shared.FileMatcher类的源代码 你可以从方法GetFiles的实现中得到一些想法。
作为客户,您可以使用以下方法
var filelist = FileMatcher.GetFiles(@"c:\alaki",@"c:\alaki\**\bin\*.dll");
答案 3 :(得分:2)
您的代码看起来就像您应该这样做。