2012-09-27 34 views
13

TL; DRTrong Windows, điều gì sẽ xảy ra rõ ràng khi tôi nhấp đúp vào một tệp trong Windows Explorer?

gì là chính xác, các cuộc gọi ở mức độ thấp OS kernel & đang được thực hiện khi người dùng hoặc click đúp chuột hoặc chọn một tập tin và nhấn phím Enter từ bên trong Windows Explorer?


Chi tiết

Điều này có vẻ như một câu hỏi khá kỳ quặc, nhưng tôi tò mò về các chi tiết rất "nitty-gritty" mở một tập tin từ Windows Explorer. Cụ thể, những gì tôi muốn biết là các cuộc gọi HĐH chính xác, cấp thấp & đang được thực hiện khi người dùng nhấp đúp hoặc chọn tệp và nhấn phím Enter từ bên trong Windows Explorer.

Lý do tôi hỏi là vì tôi có một ứng dụng cho phép người dùng duyệt và tìm kiếm các tệp dựa trên siêu dữ liệu được lưu trữ trong cơ sở dữ liệu. Khi người dùng nhấp vào nút Open mà tôi đã cung cấp, tôi bắt đầu quá trình trong đó tệp gốc là đường dẫn đến tệp đã được chọn. Ngoài ra, điều đáng nói là các tệp này nằm trên một mạng chia sẻ.

Điều này đã hoạt động trong nhiều năm, tuy nhiên, gần đây công ty của tôi đã di chuyển sang máy chủ Active Directory mới và bây giờ ứng dụng bị hỏng cho một số ít người dùng (1-2%.) người dùng không thể mở tệp này từ ứng dụng của tôi, nhưng họ có thể duyệt đến vị trí và mở nó từ Windows Explorer. Khi ứng dụng của tôi cố gắng mở tệp, nó nhận được một ngoại lệ rất chung chung cho biết rằng không thể tìm thấy tệp.

Tôi đã ba kiểm tra đường dẫn mà ứng dụng đang sử dụng (cho nhiều tệp) và đường dẫn không chính xác. Tôi đã xác minh rằng người dùng của mình đã và đang kết nối với các ổ đĩa mạng này trước khi mở tệp. Mọi thứ đều được thiết lập chính xác và sẽ hoạt động nhưng ứng dụng của tôi (hoặc System.Process) không thể "xem" hoặc mở các tệp này.

Ứng dụng Windows Explorer hoạt động khác với cách sử dụng System.Process từ bên trong ứng dụng là gì?


Đối với những người phải có mã trước khi trả lời, đây là mã đặc biệt mà tôi sử dụng để mở tệp. Một lần nữa, điều này đã làm việc trong nhiều năm và, tốt nhất tôi biết, là cách bạn để Windows mở một tệp từ bên trong .Net.

//From within my Button-Click Event... 
string file = e.Cell.Value.ToString(); 
try 
{ 
    Process p = new Process(); 
    p.StartInfo.FileName = file; 
    p.StartInfo.Verb = "Open"; 
    p.Start(); 
} 
catch (Exception ex) 
{ 
    MessageBox.Show("A problem has occurred while trying to open the doccument." 
    + "Please make sure that the file below exists and that you have permission " 
    + "to view it." 
    + Environment.NewLine + Environment.NewLine 
    + file 
    + Environment.NewLine + "---------------" + Environment.NewLine + 
    ex.Message 

    ); 
    //ex.Message states "The system cannot find the file specified" 
} 

Một điều nữa. Tôi tìm thấy this question trên SO nhưng nó không/không nên áp dụng cho câu hỏi này. Ứng dụng của tôi chỉ đơn giản là cố gắng mở các tệp PDF và một số tệp vẽ kỹ thuật. Không có gì lạ mắt và không nên yêu cầu quyền truy cập quản trị. Ngoài ra, tôi không tin rằng bất kỳ xác thực người dùng nào cũng được yêu cầu vì hầu hết người dùng không bao giờ nhận được thông báo này và họ đã tự xác thực trên mạng bằng cách đăng nhập và duyệt đến vị trí mạng.

+0

Có sự tương đồng nào giữa các máy khách không hoạt động ở cấp PC không? Họ đang ở trên một hệ điều hành khác với những người đang làm việc? –

+0

Thật khó để nói. CNTT của chúng tôi đã thực hiện chuyển đổi MASSIVE Windows 7 ngay trước khi di chuyển AD. Người dùng có tài khoản người dùng mới và nhiều người dùng đã sẵn sàng nâng cấp máy tính hoặc gần với thời gian đã lên kế hoạch của họ, được cấp máy tính mới với Win 7. Người quản lý đang gặp sự cố và nói chuyện với tôi nhiều nhất vẫn bị kẹt với Windows XP. Tuy nhiên, nó luôn luôn làm việc cho anh ta trên máy tính này trong quá khứ - anh ta vừa được cấp một tài khoản mới trên miền AD mới để bắt đầu sử dụng. Chúng tôi đã kiểm tra ba lần quyền của anh ấy. Anh ấy có thể duyệt đến vị trí và mở các tệp này, nhưng ứng dụng của tôi không thể? – RLH

+0

Có phải chỉ thất bại trên PDF? Bạn đang sử dụng Acrobat? Acrobat không hoạt động tốt với .NET. Nó là đơn .exe mà từ bên ngoài sẽ chỉ mở một tập tin tại một thời điểm. Và nếu nó hoạt động đôi khi sẽ không phản hồi. Cố gắng để lưu trữ xem trong. NET là vấn đề lúc tốt nhất - cho một trong những nó ăn key xuống sự kiện. – Paparazzi

Trả lời

5

Các cuộc gọi HĐH chính xác, cấp thấp & đang được thực hiện khi người dùng nhấp đúp hoặc chọn tệp và nhấn phím Enter từ trong Windows Explorer?

Bạn có thể tự mình thử nghiệm. Đây là cách tôi đã làm: một mẫu mã C# mẫu

class Program 
{ 
    static void Main(string[] args) 
    { 

    }   
} 

Bây giờ bạn có thể chạy ứng dụng này từ vị trí được xác định trước. Sau đó, bạn có thể sử dụng ứng dụng ProcMon từ SysInternals để quan sát các cuộc gọi cấp thấp. Đây là ảnh chụp nhanh của tệp csv được tạo bởi ProcMon trên máy của tôi. Tôi đã đặt một bộ lọc chỉ bao gồm path đến tập tin, đó là c:\test.exe

"Time of Day","Process Name","PID","Operation","Path","Result","Detail" 
"14:57:55.3495633","Explorer.EXE","2568","CreateFile","C:\Test.exe","SUCCESS","Desired Access: Generic Read, Disposition: Open, Options: Open Requiring Oplock, Attributes: N, ShareMode: Read, AllocationSize: n/a, OpenResult: Opened" 
"14:57:55.3498808","Explorer.EXE","2568","FileSystemControl","C:\Test.exe","SUCCESS","Control: FSCTL_REQUEST_FILTER_OPLOCK" 
"14:57:55.3507711","Explorer.EXE","2568","CreateFile","C:\Test.exe","SUCCESS","Desired Access: Read Attributes, Disposition: Open, Options: Open Reparse Point, Attributes: n/a, ShareMode: Read, Write, Delete, AllocationSize: n/a, OpenResult: Opened" 
... 

Phiên bản đầy đủ của csv có sẵn trên pastebin. Mỗi dòng trong tệp csv tương ứng với một cuộc gọi cấp thấp, cộng với có các loại lông tơ khác bị loại trừ do bộ lọc nghiêm ngặt trên đường dẫn.

6

Chế độ lỗi rất phổ biến và có trong mã của bạn, không đặt đúng ProcessStartInfo.WorkingDirectory. Một tập hợp con của các chương trình dựa vào Explorer thiết lập thư mục làm việc mặc định vào thư mục chứa tệp và rơi xuống khi nó không được thiết lập.Họ sẽ làm một cái gì đó không khôn ngoan như cố gắng để mở một tập tin cấu hình mà không chỉ định tên đường dẫn đầy đủ, mà chỉ hoạt động nếu thư mục làm việc được thiết lập chính xác.

Bạn khắc phục nó như thế này:

Process p = new Process(); 
p.StartInfo.FileName = file; 
p.StartInfo.WorkingDirectory = System.IO.Path.GetDirectoryName(file); 
p.Start(); 

Những giả định rằng bạn không mắc phải sai lầm tương tự không chỉ định tên đường dẫn đầy đủ cho tập tin.

+0

'tệp' hoàn toàn đủ điều kiện. Tôi sẽ thực hiện thay đổi này và xuất bản nó. Cảm ơn bạn! – RLH

+0

Ngoài ra, đây có phải là những gì Windows Explorer có hiệu quả khi bạn khởi chạy một tệp từ nó không? – RLH

+1

Được đề cập rõ ràng trong câu trả lời: 'chương trình dựa vào Explorer thiết lập thư mục làm việc mặc định' –

2

Câu hỏi "TL; DR" ngắn gọn và quan trọng nhưng tôi không chắc chắn trả lời câu hỏi đó sẽ giải quyết được sự cố của bạn. Câu trả lời của Hans Passant có lẽ hữu ích hơn nhiều. Tuy nhiên, tôi sẽ cố gắng cung cấp một ít thông tin.

Windows có một vài lớp và trong trường hợp này hai lớp thú là Windows Shell API và System Services API. Bạn đang sử dụng Process.Start() theo cách sẽ gọi ShellExecuteEx trong Windows Shell. Windows Shell cung cấp một sự trừu tượng trên đỉnh của Windows, nơi bạn có một máy tính để bàn (thực sự là một thư mục trên một số đĩa) và các tập tin được coi là tài liệu với các biểu tượng và động từ để hoạt động trên các tài liệu này. Trong trường hợp của bạn, bạn đang sử dụng động từ Open.

Vỏ Windows khá phức tạp và có thể được mở rộng để những gì ShellExecuteEx đang làm cho một đường dẫn và động từ cụ thể là lưu ý dễ trả lời. Nó phụ thuộc vào những gì được đăng ký trên máy địa phương. Tuy nhiên, nếu tệp là tệp PDF và động từ là Open bạn sẽ mong đợi rằng trình bao sẽ chạy bất kỳ ứng dụng nào được liên kết với tiện ích mở rộng .PDF trong sổ đăng ký.

Trong Windows 7, bạn có thể kiểm tra và sửa đổi các tập tin assocations tại Control Panel>Chương>Mặc định chương trình>Set Hội. Tôi nghi ngờ rằng nếu chương trình liên kết với tiện ích mở rộng .PDF bị thiếu, bạn có thể nhận được FileNotFoundException nhưng tôi chưa xác minh điều đó.

Nếu trình bao quyết định rằng ứng dụng sẽ được thực thi, tại một số điểm, hãy gọi lớp Dịch vụ hệ thống và sử dụng chức năng CreateProcess để tạo quy trình mới.Đối với tệp PDF (tùy thuộc vào đăng ký cho .PDF), quá trình thực thi Acrobat.exe với một đối số dòng lệnh (tệp bạn chỉ định) sẽ được tạo.

Để khắc phục sự cố bạn có thể tại dấu nhắc lệnh viết file.pdf (tệp phải tồn tại) và xem liệu trình bao có thể mở tệp PDF hay không.

0

Bạn có thể thử một cái gì đó như thế này bằng cách sử dụng FileSystemInfo.FullName?

string file = e.Cell.Value.ToString(); 
var fileInfo = new FileInfo(Path.Combine(System.IO.Path.GetDirectoryName(file) + file)); 
if (!fileInfo.Exists) 
{ 
    throw new FileNotFoundException(fileInfo.FullName + " was not found"); 
} 
System.Diagnostics.Process.Start(fileInfo.FullName); 
Các vấn đề liên quan