Khi nào chúng ta cần đặt UseShellExecute thành True?


134
//
// Summary:
//     Gets or sets a value indicating whether to use the operating system shell
//     to start the process.
//
// Returns:
//     true to use the shell when starting the process; otherwise, the process is
//     created directly from the executable file. The default is true.
[DefaultValue(true)]
[MonitoringDescription("ProcessUseShellExecute")]
[NotifyParentProperty(true)]
public bool UseShellExecute { get; set; }

Nếu chúng ta sinh ra một quy trình mới, khi nào chúng ta cần đặt UseShellExecute thành True?

Câu trả lời:


202

Các UseShellExecutetài sản boolean có liên quan đến việc sử dụng các cửa sổ ShellExecute chức năng vs các CreateProcess chức năng - câu trả lời ngắn gọn là nếu UseShellExecutelà đúng thì các Processlớp học sẽ sử dụng các ShellExecutechức năng, nếu không nó sẽ sử dụng CreateProcess.

Câu trả lời dài hơn là ShellExecutehàm được sử dụng để mở một chương trình hoặc tệp được chỉ định - nó gần như tương đương với việc gõ lệnh sẽ được thực thi trong hộp thoại chạy và nhấp vào OK, có nghĩa là nó có thể được sử dụng để (ví dụ):

  • Mở tệp .html hoặc web bằng trình duyệt mặc định mà không cần biết trình duyệt đó là gì,
  • Mở một tài liệu word mà không cần biết đường dẫn cài đặt cho Word là gì
  • Chạy bất kỳ lệnh nào trên PATH

Ví dụ:

Process p = new Process();
p.StartInfo.UseShellExecute = true;
p.StartInfo.FileName = "www.google.co.uk";
p.Start();

Nó rất dễ sử dụng, linh hoạt và mạnh mẽ tuy nhiên đi kèm với một số nhược điểm:

  • Không thể chuyển hướng xử lý đầu vào / đầu ra / lỗi tiêu chuẩn

  • Không thể chỉ định các mô tả bảo mật (hoặc những thứ hay ho khác) cho quy trình con

  • Có khả năng giới thiệu các lỗ hổng bảo mật nếu bạn đưa ra các giả định về những gì sẽ thực sự được chạy:

     // If there is an executable called "notepad.exe" somewhere on the path 
     // then this might not do what we expect
     p.StartInfo.FileName = "notepad.exe";
     p.Start();
    

CreateProcesslà một cách chính xác hơn nhiều để bắt đầu một quy trình - nó không tìm kiếm đường dẫn và cho phép bạn chuyển hướng đầu vào hoặc đầu ra tiêu chuẩn của quy trình con (trong số những thứ khác). CreateProcessTuy nhiên, nhược điểm là không có ví dụ nào trong 3 ví dụ tôi đưa ra ở trên sẽ hoạt động (hãy thử và xem).

Tóm lại, bạn nên đặt UseShellExecutethành false nếu:

  • Bạn muốn chuyển hướng đầu vào / đầu ra / lỗi tiêu chuẩn (đây là lý do phổ biến nhất)
  • Bạn không muốn tìm kiếm đường dẫn cho tệp thực thi (ví dụ: vì lý do bảo mật)

Ngược lại, bạn nên giữ UseShellExecuteđúng nếu bạn muốn mở tài liệu, url hoặc tệp bó, v.v ... thay vì phải cung cấp đường dẫn rõ ràng để thực thi.


2
Great Stuff, nhưng bạn viết rằng (với ShellExecute), "Nó [bạn tuyên bố] không thể chuyển hướng xử lý đầu vào / đầu ra / lỗi tiêu chuẩn" <- Chắc chắn là không chính xác hoặc không chính xác. Ngay cả khi useShellExecute được đặt thành true, trong khi thực sự bạn không thể làm được processStartInfo.RedirectStandardOutput=true, đối với tôi, bạn vẫn có thể chuyển hướng đầu ra tiêu chuẩn bằng cách thực hiện process.Arguments= "cmd /c dir >c:\\crp\\a.a". Tương tự như vậy từ một hộp thoại chạy bạn có thể làmcmd /c dir>c:\crp\a.a
barlop

4
Ngoài ra, bạn nói rằng khi UseShellExecute=falsetức là CreatProcess, sẽ không kiểm tra đường dẫn, nhưng tôi thấy rằng ngay cả khi tôi thực hiện "UseShellExecute = false" tức là không kiểm tra đường dẫn, thì process.FileName = "cmd.exe" vẫn hoạt động. kiểm tra c: \ windows \ system32. Và nếu tôi sao chép cmd.exe sang c: \ windows và đặt tên là cmmmd.exe thì tôi thực hiện process1.FileName = "cmmmd.exe" cũng hoạt động để nó kiểm tra c: \ windows để có vẻ như nó đang kiểm tra đường dẫn, hoặc một số thư mục.
barlop

2
Các tài liệu MSDN đồng ý với @barlop: "Khi UseShellExecute sai, thuộc tính FileName có thể là đường dẫn đủ điều kiện đến tệp thực thi hoặc tên thực thi đơn giản mà hệ thống sẽ cố gắng tìm trong các thư mục được chỉ định bởi biến môi trường PATH."
Bob

Bằng cách đặt UseShellExecutethành truetôi đã có thể chia sẻ một biến môi trường (chỉ được tạo trong quá trình gọi). Rất tiện dụng
Mitkins

14

Tôi nghĩ chủ yếu là cho những người không thực thi. Chẳng hạn, nếu đang cố mở một .htmltệp, nếu bạn sẽ phải đặt UseShellExecutethành truevà nó sẽ mở .htmltrong trình duyệt được người dùng đặt làm mặc định.


12

Từ MSDN :

Đặt thuộc tính này thành false cho phép bạn chuyển hướng các luồng đầu vào, đầu ra và lỗi.

UseShellExecute phải sai nếu thuộc tính UserName không phải là null hoặc một chuỗi rỗng, hoặc một UnlimitedOperationException sẽ bị ném khi phương thức Process.Start (ProcessStartInfo) được gọi.

Khi bạn sử dụng shell hệ điều hành để bắt đầu các quy trình, bạn có thể bắt đầu bất kỳ tài liệu nào (là bất kỳ loại tệp đã đăng ký nào được liên kết với tệp thực thi có hành động mở mặc định) và thực hiện các thao tác trên tệp, như in, với thành phần Quy trình. Khi UseShellExecute sai, bạn chỉ có thể bắt đầu thực thi với thành phần Process.

UseShellExecute phải đúng nếu bạn đặt thuộc tính ErrorDialog thành true.


0

Nếu chúng ta muốn ẩn cửa sổ thực thi Ứng dụng hiện tại, thì UseShellExecute phải được đặt thành true


0

Khi đường dẫn chứa một khoảng trắng hoặc một số ký tự đặc biệt (có dấu), CreatProcess (UseShellExecute = false) dường như đang sử dụng tên tệp ngắn (ký hiệu "DOS" 8.3), ShellExecute (UseShellExecute = true) sử dụng tên tệp dài. Vì vậy, khi bạn sử dụng UseShellExecute = false, hãy đảm bảo chuyển đổi tên thư mục và tệp của bạn thành tên 8.3 (google ".net cách lấy tên tệp 8.3"). (Không chắc chắn những phiên bản Windows và / hoặc hệ thống tệp nào thực hiện theo cách này, đã được thử nghiệm trên Windows 7, NTFS.)


Có thể là nó chỉ đang cắt đứt con đường ở không gian? Đặt dấu ngoặc kép quanh "tên đường dẫn / chương trình" sẽ giải quyết điều này.
gbarry
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.