2010-08-17 33 views
5

ứng dụng của chúng tôi có một sợi nền mà spawns một quá trình thông qua System.Diagnostics.Process:Process sinh ra thông qua Process.Start trong .NET treo sợi

Process.Start(
    new ProcessStartInfo 
    { 
     FileName = url, 
     UseShellExecute = true 
    } 
); 

này sử dụng để không có vấn đề gì cả. Nhưng bây giờ, sợi nền đang âm thầm chết; nó không bao giờ trở về từ cuộc gọi đến Process.Start. Khối catch cho mã này, xử lý System.Exception, cũng không đạt được. Ngay cả khi tôi cho phép xử lý ngoại lệ khi được ném vào trình gỡ rối Visual Studio, tôi không thấy ngoại lệ. Kỳ lạ thay, quá trình này được sinh ra tốt; trình duyệt mặc định cho người dùng được khởi chạy với URL dự kiến.

Điểm nhập của quy trình của chúng tôi được đánh dấu là [STAThread] như được đề xuất.

Điều gì có thể khiến chuỗi của chúng tôi bị chấm dứt âm thầm? Có bất kỳ kỹ thuật tôi có thể sử dụng để gỡ lỗi những gì đang xảy ra trong quá trình chấm dứt thread?

Cập nhật:

Dường như sợi chỉ còn sống sau khi tất cả; nó chỉ không quay trở lại từ cuộc gọi. Dưới đây là stack trace của nó:!

  • [Trong một chờ đợi giấc ngủ hoặc tham gia]
  • System.dll System.Diagnostics.ShellExecuteHelper.ShellExecuteOnSTAThread() + 0x63 byte
  • System.dll System.Diagnostics.Process .StartWithShellExecuteEx (System.Diagnostics.ProcessStartInfo StartInfo) + 0x19d byte
  • System.dll! System.Diagnostics.Process.Start() + 0x39 byte
  • System.dll! System.Diagnostics.Process.Start (System.Diagnostics .ProcessStartInfo startInfo) + 0x32 bytes
  • .210
  • Phương pháp của tôi

Cập nhật 2:

Lễ ra mắt cmd.exe mà không sử dụng vỏ để thực hiện hoạt động như một workaround. Cảm ơn nhiều! Tuy nhiên, tôi vẫn muốn biết lý do tại sao cuộc gọi không trả lại.

Cập nhật 3:

Shell móc làm âm thanh như một lời giải thích hợp lý cho những gì có thể gây ra các cuộc gọi đến không quay trở lại. Tôi không thể tìm thấy mô-đun giả mạo, nhưng sau lần thử cuối cùng để chạy mọi thứ thông qua thực thi trình bao, cuộc gọi đã thực hiện trả lại.

Trong mọi trường hợp, có thể người dùng có thể đã tải tiện ích mở rộng có thể gây rối với quá trình khởi chạy và khiến mã của tôi không trả lại. Chúng tôi không thể thực hiện bất kỳ điều gì về rằng, vì vậy, câu trả lời đúng là sử dụng giải pháp thay thế quy trình cmd.exe.

Trả lời

4

Như đã đề cập bởi Hans Passant, cuộc gọi treo số Process.Start có thể là lý do. Khi sử dụng Process.Start với UseShellExecute đặt thành true, chức năng API của Windows ShellExecuteEx được gọi dưới mui xe có thể không trả về trong một số trường hợp nhất định.

Bạn có thể kiểm tra xem đây là trường hợp bằng cách thêm thông điệp dấu vết để mã của bạn:

System.Diagnostics.Trace.WriteLine("About to start process."); 
Process.Start(
    new ProcessStartInfo 
    { 
     FileName = url, 
     UseShellExecute = true 
    } 
); 
System.Diagnostics.Trace.WriteLine("Process started."); 

Để nghe các thông điệp theo dõi bạn có thể sử dụng một TraceListener, kiểm tra các cửa sổ đầu ra của Visual Studio hoặc sử dụng một công cụ như DebugView.

Giải pháp thay thế bạn có thể sử dụng lệnh start. Đoạn mã sau khởi chạy một cửa sổ shell ẩn mà "bắt đầu" url:

Process.Start(
    new ProcessStartInfo() 
    { 
     FileName = "cmd.exe", 
     Arguments = "/c start http://www.google.com", 
     WindowStyle = ProcessWindowStyle.Hidden, 
     UseShellExecute = false 
    }); 
+0

Không có gì ngạc nhiên với việc bổ sung 'Trace.WriteLine'; "Quá trình đã bắt đầu". không đạt được dòng. – Jacob

+0

Khi bắt đầu cmd.exe, cuộc gọi vẫn không quay trở lại. – Jacob

+0

Bah, nhưng nếu tôi chuyển UseShellExecute thành false. – Jacob

4

Không, chủ đề không âm thầm chấm dứt, chúng tạo ra âm thanh kaboom lớn. Ít nhất bạn sẽ thấy thông báo thoát khỏi luồng trong cửa sổ Output. Quá trình chặn phương thức Process.Start() sẽ là một giải thích khác, mặc dù không có lời giải thích nào cho nó. Đoạn trích của bạn quá ngắn để đưa ra một chẩn đoán tốt. Một cái gì đó môi trường có lẽ.


Dấu vết ngăn xếp của bạn giúp, ShellExecuteOnSTAThread() thực tế thực hiện chặn chủ đề.Join() trên một chuỗi trợ giúp nhỏ. Chủ đề này là cần thiết để gọi hàm ShellExecuteEx() API, nó chỉ có thể được gọi từ một luồng STA. Nó có một lỗ hổng mặc dù, một thread STA cũng phải bơm một vòng lặp tin nhắn. Helper nhỏ này không.

Điều này gây ra sự cố trên máy tính của bạn vẫn chỉ ra vấn đề môi trường, một số loại phần bổ sung hệ thống xâm nhập vào cuộc gọi ShellExecuteEx(). Và đếm trên chạy một thread STA thực sự. Bạn sẽ có thể tìm thấy chuỗi trợ giúp đó trong cửa sổ Debug + Windows + Threads. Nó phải chứa "ShellExecuteFunction" trên ngăn xếp. Loại 'add-on hệ thống' kéo các pha nguy hiểm như thế này là các máy quét vi-rút, chẳng hạn. Bạn sẽ có thể tìm thấy rằng phần mềm độc hại trở lại trong cửa sổ Debug + Windows + Mô-đun sau khi bạn đã chọn "Bật gỡ lỗi không được quản lý" trong tab Gỡ lỗi của dự án.

Cách giải quyết để sử dụng UseShellExecute = false là khá chấp nhận được ở đây btw. Chỉ cần thực tế là máy của bạn là kinda sai lầm, bởi vẻ ngoài của nó, không phải là tất nhiên.

+0

Tôi đã kiểm tra cửa sổ đầu ra trong Visual Studio, và không có đầu ra nào sau khi khởi chạy 'Process.Start'. Tôi đã xem xét khả năng cuộc gọi bị chặn, nhưng ngay cả sau khi chấm dứt tất cả các phiên bản của Chrome, cuộc gọi không bao giờ được trả về (mặc dù với 'UseShellExecute' Tôi không biết tại sao cuộc gọi lại chặn) – Jacob

+0

Vâng, hãy sử dụng trình gỡ rối. Nhìn vào ngăn xếp cuộc gọi. Trình gỡ lỗi không được quản lý với máy chủ biểu tượng Microsoft được định cấu hình có thể là tốt nhất. –

+0

Lời khuyên tuyệt vời, @Hans. Tìm thêm thông tin. Xem cập nhật cho câu hỏi của tôi. – Jacob

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