Sự cố khi nhận thông tin về các quy trình đang chạy với .GetProcesses () trong Unity3D trên OS X


7

Tôi sẽ hỏi điều này trên Câu trả lời của Unity, nhưng tôi liên tục gặp lỗi khi cố gắng truy cập trang web để nghĩ rằng có lẽ các bạn có thể giúp đỡ. Tôi cũng đã thử subreddit Unity3d và cũng không thể giải quyết vấn đề này.

Tôi đang cố gắng để có được một danh sách tất cả các quy trình đang chạy trên máy Mac của mình từ ứng dụng Unity của tôi. Ý tưởng cuối cùng là kiểm tra xem các ứng dụng nhất định có đang chạy hay không (ví dụ: TextEdit).

Lần đầu tiên tôi đã thử kiểm tra một ứng dụng mở với GetProcessByName, nhưng đã có ngoại lệ này mặc dù quá trình đang chạy:

InvalidOperationException: Process has exited, so the requested information is not available.

Sau đó, tôi quyết định đi đơn giản nhất có thể. Tôi hình dung tôi chỉ cần in ra một danh sách tất cả các quy trình đang chạy để bắt đầu. Đây là mã của tôi:

    Process[] processes = Process.GetProcesses();
    GUI.Label( new Rect(x, y, 100, 20), "Process: " + processes.Length );
    y += 20; 
    foreach (Process process in processes) {
        try
        {
            if (!process.HasExited)
            {
                GUI.Label( new Rect(x, y, 100, 20), "process: " + process.ProcessName );
                y += 20;
            }
        }
        catch (System.InvalidOperationException)
        {
            UnityEngine.Debug.Log("Holy batman we've got an exception!");
        }
    }

Khi tôi chạy nó thông qua trình soạn thảo, đây là những gì tôi thấy:

Số lượng quy trình đang chạy có xu hướng dao động trong khoảng 200, nhưng tên quy trình duy nhất được in trên màn hình là Unity.

Nếu tôi cố gắng in tất cả các quy trình bằng cách xóa câu lệnh HasExited nếu tôi nhận được điều này (tất nhiên chúng không phù hợp trên màn hình):

Điều này khiến tôi nghĩ rằng nó nghĩ rằng mọi quy trình ngoại trừ Unity đã thoát ... nhưng tôi có khá nhiều quy trình bị hủy bỏ đang chạy, vì vậy tôi tự hỏi tại sao nó không liệt kê những quy trình đó? Về cơ bản tôi cần tìm kiếm trong tất cả các quy trình hiện đang chạy . Có ý kiến ​​gì không? Có một số loại vấn đề cấp phép với việc không thể truy cập các thuộc tính của các quy trình không thống nhất bên ngoài?

EDIT: Tôi nên lưu ý rằng tôi đã thử cả hai trong khi chạy qua trình chỉnh sửa và sau khi xây dựng. Khi chạy sau khi xây dựng với! Process.HasExited một quy trình được liệt kê với một tên trống. Tôi đoán đó có thể là ứng dụng hiện đang chạy. Số lượng quá trình dao động khoảng 240.


2 điều: 1) Bạn đang cố gắng tìm gì? 2) Bạn có thể gặp phải các hạn chế của hộp cát: docs.unity3d.com/Documentation/Manual/SecuritySandbox.html
Kirbinator

@Kirbinator Có vẻ như chỉ áp dụng cho trình phát web.
Vaughan Hilts

Câu trả lời:


3

Các tin nhắn ngoại lệ là một chút sai lệch. Trên thực tế, Mono báo cáo cùng một ngoại lệ (Hoạt động không hợp lệ) với các thông báo khác nhau cho nhiều tình huống khác nhau.

GetProcesses nhận được một danh sách tất cả các pids từ hệ thống và tạo một đối tượng Process mới cho từng đối tượng, nhưng tại thời điểm này, nó không kiểm tra xem chúng có thực sự hợp lệ hay không. Khi bạn gọi ProcessName trên một đối tượng Process, nó sẽ:

  1. Kiểm tra xem Quy trình có pid hợp lệ không. Nếu không, nó ném.
  2. Cố gắng để có được tên quá trình từ pid. Nếu nó nhận được giá trị null, nó sẽ ném.

Lưu ý rằng không có điểm nào thực sự kiểm tra xem quá trình đã thoát hay chưa. Cờ HasExited chỉ được đặt khi bạn kiểm tra và ProcessName không kích hoạt điều đó. Điều khó hiểu là có những trường hợp ngoại lệ bị ném nói rằng quá trình đã thoát khi không phải vậy, vì vậy đừng quá tin vào các tin nhắn.

Bạn có thể kiểm tra logic trên repo Mono của Unity trên github .

Nếu bạn cần truy cập nhiều thuộc tính trên các quy trình trong mảng Process [] và / hoặc bạn muốn biết có bao nhiêu quy trình hợp lệ, bạn nên xử lý trước mảng và trích xuất các thuộc tính bạn muốn vào một mảng của riêng bạn, để giảm thiểu số lượng ngoại lệ bạn có khả năng kích hoạt và tách mã đó khỏi mã bản vẽ thực tế, đại loại như:

var procList = Process.GetProcesses();
var validProcesses = new List<Proc>();
for (int i = 0; i < procList.Length; i++) {
    try {
        validProcesses.Add(new Proc(){
            Name = procList[i].ProcessName,
            Pid = procList[i].Id
        });
    } catch {}
}
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.