2008-10-07 22 views
37

Làm cách nào để lấy danh sách các tệp xử lý mở bằng id tiến trình trong C#?Làm cách nào để có danh sách các xử lý tệp đang mở theo quy trình trong C#?

Tôi cũng muốn tìm hiểu về tên tệp.

Tìm kiếm tương đương có lập trình của trình thám hiểm quy trình nào.

Rất có thể điều này sẽ yêu cầu interop.

Xem xét việc thêm tiền thưởng vào việc này, việc triển khai khó thực hiện phức tạp.

+4

bất kỳ giải pháp cuối cùng với mã nguồn đầy đủ? – Kiquenet

Trả lời

22

Ouch điều này sẽ khó thực hiện từ mã được quản lý.

Có một sample on codeproject

Hầu hết những thứ có thể được thực hiện trong interop, nhưng bạn cần một trình điều khiển để có được tên tập tin vì nó sống trong không gian địa chỉ của kernel. Process Explorer nhúng trình điều khiển vào tài nguyên của nó. Bắt tất cả điều này được nối từ C# và hỗ trợ 64 bit cũng như 32, sẽ là một nhức đầu lớn.

+1

Ai quan tâm đến mã, điều đó rất hữu ích! Thậm chí đẹp hơn Process Explorer, cho những gì nó làm. – Brian

+0

Giải pháp không tốt chỉ sử dụng mã được quản lý? – Kiquenet

+0

đây không phải là cái gì đó dễ dàng trong quản lý mã, tôi có lẽ sẽ chỉ đơn giản là shell ra một chương trình C++ nếu tôi đã phải xây dựng một cái gì đó như thế này @Kiquenet –

10

Bạn có thể P/INVOKE vào chức năng NtQuerySystemInformation để truy vấn tất cả các tay cầm và sau đó đi từ đó. Điều này Google groups discussion có chi tiết.

+0

Nội dung hay. Tôi thấy nếu tôi có thể nhận được interop đi –

+1

bất kỳ mã mẫu trong C#? – Kiquenet

12

Bạn cũng có thể chạy ứng dụng dòng lệnh, Handle, bởi Mark Rusinovich và phân tích đầu ra.

+0

bất kỳ mã mẫu cho phân tích đầu ra trong C#? – Kiquenet

+3

Đó là một giải pháp khủng khiếp. –

+2

Tại sao @bruce? bất kỳ lý do xin vui lòng? – Kiquenet

2

Xử lý là chương trình tuyệt vời và liên kết đến lập trình là tốt.

@Brian Lý do cho mã là handle.exe KHÔNG thể phân phối lại. Họ cũng không phát hành nguồn của họ.

Dường như nếu .Net sẽ không dễ dàng thực hiện việc này vì dường như ổ đĩa thiết bị được nhúng lại được truy cập lại thông tin. Điều này không thể được thực hiện trong. Net mà không có một DLL unmanged. Đó là mã hạt nhân tương đối sâu khi so sánh với mã hóa .net điển hình. Tôi ngạc nhiên khi WMI không vạch trần điều này.

+0

Tương thích với x64. – ElektroStudios

6

Hãy nhìn vào tập tin này: http://vmccontroller.codeplex.com/SourceControl/changeset/view/47386#195318

Và sử dụng:

DetectOpenFiles.GetOpenFilesEnumerator(processID); 

Demo:

using System; 
using System.Diagnostics; 

namespace OpenFiles 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      using (var openFiles = VmcController.Services.DetectOpenFiles.GetOpenFilesEnumerator(Process.GetCurrentProcess().Id)) 
      { 
       while (openFiles.MoveNext()) 
       { 
        Console.WriteLine(openFiles.Current); 
       } 
      } 
      Console.WriteLine(); 
      Console.ReadKey(); 
     } 
    } 
} 

Nó có phụ thuộc so với lắp ráp System.EnterpriseServices

+0

bất kỳ mẫu đầy đủ nào có mã nguồn ?? – Kiquenet

+0

Chạy nó như bạn đã đề cập GetOpenFilesEnumerator trả về một đối tượng với 2 thành viên:
ERROR_ACCESS_DENIED và ERROR_INVALID_PARAMETERS – Lucian

+0

Chỉ cần kiểm tra và mã này hoạt động tốt. có thể bạn thực sự không có quyền truy cập. – Mehran

0

Để kiểm tra xem có tệp nào đang được sử dụng hay không (mở), hãy sử dụng File Stream.

Ví dụ:

Giả sử bạn có một đường dẫn tập tin lưu trữ trong txtAttachPath.Text và bạn muốn mở tập tin đó nếu nó chưa được mở, bạn cần phải kiểm tra xem các tập tin được mở đầu tiên sau đó mở nó, đây là làm thế nào để làm điều đó:

tạo ra một phương pháp để kiểm tra xem tập tin đang mở:

private bool attachedFileIsOpen(FileInfo file) 
{ 
    FileStream fs = null; 
    try 
    { 
     fs = file.Open(FileMode.Open, FileAccess.ReadWrite, FileShare.None); 
    } 
    catch (IOException ioe) 
    { 
    MessageBox.Show("The attachment file is already open!, can't open more than once!", "AMP Warning", MessageBoxButtons.OK, MessageBoxIcon.Information); 
    return true; 
    } 
    finally 
    { 
     if (fs != null) fs.Close(); 
    } 
    return false; 
    } 

phương pháp này sẽ kiểm tra nếu tập tin được mở và retrun đúng với một thông điệp tới người dùng rằng tập tin là aleardy mở, nếu không nó sẽ trả về false (tập tin là không sử dụng).

Tiếp theo sử dụng phương pháp kích hoạt bởi bất kỳ sự kiện bạn chọn:

FileInfo filePath = new FileInfo(txtAttachPath.Text); 
if (!txtAttachPath.Text.Equals("No Attachment") 
    && attachedFileIsOpen(filePath) == false 
    && processIsRunning("notepad") == false) 
{ 
    Process openFilebyExtension = Process.Start(txtAttachPath.Text); 
      openFilebyExtension.WaitForInputIdle(); 
      NativeWindow.FromHandle(this.Handle); 
} 

Note một số được xây dựng trong chương trình cửa sổ như notepad cho phép nhiều trường hợp của cùng một tập tin được mở ra, do đó không thể phát hiện theo phương pháp File Stream, giải pháp khác cho nó là để phát hiện nếu quá trình đang chạy.

bạn sẽ cần phải thêm một phương pháp khác để kiểm tra quá trình kết hợp với loại tập tin bạn đang cố gắng để mở chạy:

private bool processIsRunning(string process) 
     { 
      Process[] runningProcesses = Process.GetProcessesByName(process); 
      bool processIsRunning = false; 
      if(runningProcesses.Length == 0) 
      { 
       processIsRunning = false; 
      } 
      else 
      { 
       processIsRunning = true; 
       MessageBox.Show("The attachment file is already open!, can't open more than once!", "AMP Warning", 
        MessageBoxButtons.OK, MessageBoxIcon.Information); 
      } 
      return processIsRunning; 
     } 
Các vấn đề liên quan