เราต้องตั้ง UseShellExecute เป็น True เมื่อใด


135
//
// 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; }

ถ้าเราเกิดกระบวนการใหม่เมื่อไหร่เราต้องตั้ง UseShellExecute เป็น True?

คำตอบ:


204

UseShellExecuteคุณสมบัติบูลเป็นเรื่องที่เกี่ยวข้องกับการใช้หน้าต่างShellExecuteฟังก์ชั่นครับCreateProcessฟังก์ชั่น - คำตอบสั้น ๆ ก็คือว่าถ้าUseShellExecuteเป็นจริงแล้วProcessชั้นจะใช้ฟังก์ชั่นมิฉะนั้นจะใช้ShellExecuteCreateProcess

คำตอบที่ยาวกว่าคือShellExecuteฟังก์ชันนี้ใช้เพื่อเปิดโปรแกรมหรือไฟล์ที่ระบุโดยประมาณเท่ากับการพิมพ์คำสั่งที่จะเรียกใช้ในกล่องโต้ตอบการเรียกใช้และคลิกตกลงซึ่งหมายความว่าสามารถใช้เพื่อ (ตัวอย่าง):

  • เปิดไฟล์. html หรือเว็บโดยใช้เบราว์เซอร์เริ่มต้นโดยไม่จำเป็นต้องรู้ว่าเบราว์เซอร์นั้นคืออะไร
  • เปิดเอกสารคำโดยไม่จำเป็นต้องรู้ว่าเส้นทางการติดตั้งสำหรับ Word คืออะไร
  • เรียกใช้คำสั่งใด ๆ บนไฟล์ PATH

ตัวอย่างเช่น:

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

ใช้งานง่ายมากใช้งานได้หลากหลายและทรงพลัง แต่มาพร้อมกับข้อบกพร่องบางประการ:

  • ไม่สามารถเปลี่ยนเส้นทางที่จับอินพุต / เอาต์พุต / ข้อผิดพลาดมาตรฐานได้

  • เป็นไปไม่ได้ที่จะระบุตัวบ่งชี้ความปลอดภัย (หรือสิ่งที่น่าสนใจอื่น ๆ ) สำหรับกระบวนการย่อย

  • มีความเป็นไปได้ที่จะทำให้เกิดช่องโหว่ด้านความปลอดภัยหากคุณตั้งสมมติฐานเกี่ยวกับสิ่งที่จะเรียกใช้จริง:

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

CreateProcessเป็นวิธีเริ่มต้นกระบวนการที่แม่นยำกว่ามาก - ไม่ค้นหาเส้นทางและอนุญาตให้คุณเปลี่ยนเส้นทางอินพุตหรือเอาต์พุตมาตรฐานของกระบวนการย่อย (เหนือสิ่งอื่นใด) อย่างไรก็ตามข้อเสียCreateProcessคือไม่มี 3 ตัวอย่างที่ฉันให้ไว้ข้างต้นจะใช้งานได้ (ลองใช้ดู)

โดยสรุปคุณควรตั้งค่าUseShellExecuteเป็นเท็จถ้า:

  • คุณต้องการเปลี่ยนเส้นทางอินพุต / เอาต์พุต / ข้อผิดพลาดมาตรฐาน (นี่คือสาเหตุที่พบบ่อยที่สุด)
  • คุณไม่ต้องการค้นหาเส้นทางสำหรับปฏิบัติการ (เช่นเพื่อเหตุผลด้านความปลอดภัย)

ในทางกลับกันคุณควรรักษาUseShellExecuteความจริงไว้หากคุณต้องการเปิดเอกสาร URL หรือไฟล์แบตช์ ฯลฯ ... แทนที่จะต้องระบุเส้นทางไปยังไฟล์ปฏิบัติการอย่างชัดเจน


2
Great Stuff แต่คุณเขียนว่า (ด้วย ShellExecute) ว่า "[คุณอ้างว่า] ไม่สามารถเปลี่ยนเส้นทางการจัดการอินพุต / เอาต์พุต / ข้อผิดพลาดมาตรฐานได้" <- แน่นอนว่าไม่ถูกต้องหรือไม่ถูกต้อง ถึงแม้จะมี useShellExecute ตั้งค่าเป็นจริงในขณะที่แน่นอนคุณไม่สามารถทำ มันดูเหมือนว่าฉันคุณยังสามารถเปลี่ยนเส้นทางออกมาตรฐานโดยการทำprocessStartInfo.RedirectStandardOutput=true process.Arguments= "cmd /c dir >c:\\crp\\a.a"ในทำนองเดียวกันจากกล่องโต้ตอบการเรียกใช้คุณสามารถทำได้cmd /c dir>c:\crp\a.a
barlop

4
นอกจากนี้คุณบอกว่าเมื่อเป็นUseShellExecute=falseCreateProcess จะไม่ตรวจสอบเส้นทาง แต่ฉันเห็นว่าแม้ว่าฉันจะทำ "UseShellExecute = false" เช่นไม่ควรตรวจสอบเส้นทางจากนั้น process.FileName = "cmd.exe" ก็ทำงานได้ ตรวจสอบ c: \ windows \ system32 และถ้าฉันคัดลอก cmd.exe ไปที่ c: \ windows และตั้งชื่อว่า cmmmd.exe ฉันจะทำ process1.FileName = "cmmmd.exe" ที่ใช้งานได้เช่นกันดังนั้นจึงตรวจสอบ c: \ windows ดังนั้นดูเหมือนว่ากำลังตรวจสอบเส้นทางหรือ ไดเรกทอรีบางกลุ่ม
barlop

2
เอกสาร MSDN เห็นด้วยกับ @barlop: "เมื่อ UseShellExecute เป็นเท็จคุณสมบัติ FileName อาจเป็นพา ธ ที่มีคุณสมบัติครบถ้วนไปยังไฟล์ปฏิบัติการหรือชื่อเรียกทำงานแบบธรรมดาที่ระบบจะพยายามค้นหาภายในโฟลเดอร์ที่ระบุโดยตัวแปรสภาวะแวดล้อม PATH"
Bob

โดยการตั้งค่าUseShellExecuteเป็นtrueฉันสามารถแบ่งปันตัวแปรสภาพแวดล้อม (ที่สร้างขึ้นในกระบวนการเรียกเท่านั้น) มีประโยชน์มาก
Mitkins

14

ฉันคิดว่าส่วนใหญ่เป็นไฟล์ที่ไม่สามารถเรียกใช้งานได้ ตัวอย่างเช่นหากคุณกำลังพยายามเปิด.htmlไฟล์หากคุณต้องตั้งค่าUseShellExecuteเป็นtrueและจะเปิด.htmlในเบราว์เซอร์ที่ผู้ใช้ตั้งเป็นค่าเริ่มต้น


12

จากMSDN :

การตั้งค่าคุณสมบัตินี้เป็นเท็จช่วยให้คุณสามารถเปลี่ยนทิศทางอินพุตเอาต์พุตและสตรีมข้อผิดพลาดได้

UseShellExecute ต้องเป็นเท็จหากคุณสมบัติ UserName ไม่ใช่ null หรือสตริงว่างหรือ InvalidOperationException จะถูกโยนเมื่อเมธอด Process.Start (ProcessStartInfo) ถูกเรียกใช้

เมื่อคุณใช้เชลล์ของระบบปฏิบัติการเพื่อเริ่มกระบวนการคุณสามารถเริ่มเอกสารใด ๆ (ซึ่งเป็นประเภทไฟล์ที่ลงทะเบียนใด ๆ ที่เกี่ยวข้องกับไฟล์ปฏิบัติการที่มีการดำเนินการเปิดเริ่มต้น) และดำเนินการกับไฟล์เช่นการพิมพ์ด้วยองค์ประกอบกระบวนการ เมื่อ UseShellExecute เป็นเท็จคุณสามารถเริ่มต้นไฟล์ปฏิบัติการด้วยคอมโพเนนต์กระบวนการเท่านั้น

UseShellExecute ต้องเป็นจริงถ้าคุณตั้งค่าคุณสมบัติ ErrorDialog เป็น true


0

หากเราต้องการซ่อนหน้าต่างปฏิบัติการของแอปพลิเคชันปัจจุบันควรตั้งค่า UseShellExecute เป็น true


0

เมื่อพา ธ มีช่องว่างหรืออักขระพิเศษอื่น ๆ (เช่นเน้นเสียง) ดูเหมือนว่า CreateProcess (UseShellExecute = false) จะใช้ชื่อไฟล์แบบสั้น (สัญกรณ์ "DOS" 8.3) ShellExecute (UseShellExecute = true) จะใช้ชื่อไฟล์แบบยาว ดังนั้นเมื่อคุณใช้ UseShellExecute = false ตรวจสอบให้แน่ใจว่าได้แปลงไดเร็กทอรีและชื่อไฟล์ของคุณเป็น 8.3 ชื่อแล้ว (google ".net how to get 8.3 filename") (ไม่แน่ใจว่า Windows เวอร์ชันใดและ / หรือระบบไฟล์ทำด้วยวิธีนี้ทดสอบบน Windows 7, NTFS)


เป็นไปได้ไหมว่ามันเป็นเพียงการตัดเส้นทางที่ว่าง? การใส่เครื่องหมายคำพูดรอบ ๆ "path / program name" จะช่วยแก้ปัญหานี้ได้
gbarry
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.