19

過去に多くのCおよびC++アプリでワイルドカード引数の拡張にsetargv.objリンクを使用しましたが、.netアプリケーションについて同様の言及は見つかりません。

アプリのコマンドラインパラメーターを自動的にワイルドカード展開する標準的な方法はありますか?(つまり、*。docをargsパラメーターの1つのエントリーから、そのワイルドカードに一致するすべてのエントリーに展開します)。

PS私は現在の小さなプロジェクトのために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
        }
    }
}
4

4 に答える 4

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();
}
于 2010-05-12T13:23:19.180 に答える
4

あなたが何を求めているのか正確にはわかりません...しかし、あなたが言及したDirectory.GetFiles()の「ハック」でどこに行くのかがわかれば、次のようなことがうまくいくかもしれません:

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」に一致するすべてのファイルを取得して、それらのフォルダーを反復処理できます。

それはあなたが探しているものですか?引数を自動的に展開するには、何らかの意味のある方法でワイルドカードを抽出し、それらをそのモデルに適用する必要があります...

例えば:

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 を使用することが非常に効率的であるとは思いません。 XMLはそれほど効率的ではありません...

于 2008-12-19T16:37:14.443 に答える
3

Microsoft.Build.dll の逆アセンブルされた Microsoft.Build.Shared.FileMatcher クラスのソース コードを参照してください。メソッド GetFiles の実装からいくつかのアイデアを得ることができます。

クライアントとして、次のようにメソッドを使用できます

var filelist = FileMatcher.GetFiles(@"c:\alaki",@"c:\alaki\**\bin\*.dll");
于 2012-07-16T04:39:43.507 に答える
1

あなたのコードは、まさにあなたがやるべきことのように見えます。

于 2008-12-23T00:51:24.053 に答える