2008-12-19 25 views
15

Tôi đã sử dụng setargv.obj linking for Expanding Wildcard Arguments trong quá khứ cho một số ứng dụng C và C++, nhưng tôi không thể tìm thấy bất kỳ đề cập tương tự nào cho các ứng dụng .net.Có tùy chọn mở rộng ký tự đại diện cho ứng dụng .net không?

Có cách nào tiêu chuẩn cách để tự động mở rộng các thông số dòng lệnh của ứng dụng? (nghĩa là mở rộng * .doc từ một mục nhập trong tham số args thành tất cả khớp với ký tự đại diện đó).

P.S. Tôi đã hack một cái gì đó cùng với Directory.GetFiles() cho dự án nhỏ hiện tại của tôi, nhưng nó không bao gồm các ký tự đại diện với các đường dẫn (chưa), và nó sẽ là tốt đẹp để làm điều đó mà không có mã tùy chỉnh.

Cập nhật: đây là lỗi thô của tôi, để minh hoạ. Nó cần phải phân tách các tham số cho đường dẫn và tên cho GetFiles, nhưng đây là ý tưởng chung. Liên kết setargv.obj thành một ứng dụng C hoặc C++ về cơ bản sẽ làm tất cả việc mở rộng ký tự đại diện, để người dùng chỉ lặp qua mảng 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

Bằng cách đó bạn có nghĩa là không chỉ tên tập tin ký tự đại diện nhưng tên thư mục wildcard quá? Ví dụ: C: \ Windows \ System32 \ * \ Test * .doc? – BenAlabaster

+0

Tập tin "ban đầu" setargv.obj sẽ chỉ hoạt động với các ký tự đại diện trong tên tệp, vì vậy đó là những gì tôi đang tìm kiếm. – crashmstr

+0

không giống như hack chút nào, có vẻ khá thẳng về phía trước. –

Trả lời

1

Mã của bạn trông giống như cách bạn định làm.

+0

Đúng, nhưng trong C/C++ có một cơ chế trong trình biên dịch để thực hiện công việc cho bạn. Ít nhất nó cũng dễ dàng hơn trong .net để làm điều này. – crashmstr

4

Tôi không chắc chắn bạn đang làm gì ... nhưng nếu tôi đến nơi bạn đang đi với Directory.GetFiles() "hack" bạn đã đề cập, sau đó một cái gì đó như thế này có thể hoạt động:

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

Tùy chọn ký tự đại diện trong thư mục Windows [trực tiếp] khớp với mẫu "sys *".

Sau đó, bạn có thể lặp qua các thư mục đó để lấy tất cả các tệp khớp với mẫu "* .sys".

Đó có phải là loại điều bạn đang tìm kiếm không? Để tự động mở rộng args, bạn phải trích xuất các ký tự đại diện trong một số loại cách có ý nghĩa và áp dụng chúng vào mô hình mà ...

Ví dụ:

RunMyApp "C: \ Windows \ Sys * \ * .sys "

Bạn muốn kéo chuỗi C: \ Windows - có thể với cụm từ thông dụng, tìm thư mục cấp thấp nhất không chứa ký tự đại diện và áp dụng nó vào phương thức GetDirectories, đính kèm chuỗi ký tự đại diện làm thông số tìm kiếm.

Sau đó, nếu kết thúc chuỗi của bạn (trong trường hợp này là * .sys) làm mẫu tìm kiếm cho Directory.GetFiles.

Nếu bạn muốn trở nên phức tạp hơn và làm điều gì đó như:

C:\Windows\*\Sys*\*.sys 

Bạn sẽ sử dụng SearchOptions để thiết lập hành vi này:

Directory.GetDirectories(@"C:\Windows", "sys*", SearchOptions.AllDirectories) 

này sẽ lấy tất cả các thư mục đó xuất hiện các sys * ký tự đại diện trong thư mục Windows và tất cả các thư mục bên dưới nó.

Nếu bạn muốn phức tạp hơn nhiều, thì tôi không chắc chắn bạn sẽ làm như thế nào ... ví dụ, bạn muốn các thư mục nằm trong thư mục trực tiếp bên trong thư mục Windows - tôi không có ý tưởng làm thế nào bạn sẽ đi về một cái gì đó như thế tôi sợ ...Tôi không tưởng tượng việc xuất toàn bộ cấu trúc cây thành XML và việc sử dụng XPath để thực hiện nó sẽ rất hiệu quả - XPath sẽ đơn giản để phân tích cú pháp bằng cách sử dụng ký tự đại diện - nhưng chuyển đổi sang XML sẽ không hiệu quả ...

+0

Cảm ơn các ví dụ. Phương thức C/C++ sẽ chỉ mở rộng tên tệp, theo như tôi nhớ. Câu hỏi chính của tôi là nếu có một cách để làm điều đó giống như phương pháp C/C++ mà không cần viết mã của riêng bạn (như tôi đã làm). Mặc dù. Net giúp dễ dàng hơn trong C/C++! – crashmstr

+0

@crashmstr: Tôi sẽ không nói chắc chắn là không - có quá nhiều góc ẩn của khuôn khổ .NET. Theo như tôi nhận thức Tuy nhiên, không có cách nào tự nhiên để làm điều đó một cách tự động. – BenAlabaster

+0

Đây là cách phù hợp để thực hiện việc này. –

9

Tại đây, chúng tôi đã thực hiện một cú tấn công thô lỗ. Tôi rất muốn nó được đệ quy. Và có kinh nghiệm thiếu sót của Windows ký tự đại diện tôi có thể quyết định sử dụng biểu thức thông thường hơn là cho phép GetFiles() làm điều đó cho tôi.

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(); 
} 
3

xem mã nguồn của lớp Microsoft.Build.Shared.FileMatcher tháo rời trong Microsoft.Build.dll bạn có thể nhận được một số ý tưởng từ việc thực hiện GetFiles phương pháp.

như một khách hàng mà bạn có thể sử dụng phương pháp này như sau

var filelist = FileMatcher.GetFiles(@"c:\alaki",@"c:\alaki\**\bin\*.dll"); 
+1

Tìm được ... nếu chỉ lớp đó không phải là 'nội bộ'. –

Các vấn đề liên quan