2012-02-29 46 views
5

Tôi đang cố gắng để có được kích thước của máy tính để bàn Windows (toàn bộ điều, không chỉ là một màn hình duy nhất) từ bên trong một dịch vụ mà tôi đã viết.Nhận kích thước màn hình nền từ Dịch vụ Windows?

Trong WinForms - tiêu chuẩn C# phương pháp:

SystemInformation.VirtualScreen.Width 
SystemInformation.VirtualScreen.Height 

dường như làm việc (nếu bạn nhập Winforms DLL, mà tôi muốn tránh) - nhưng nó trả về giá trị sai. Kích thước máy tính để bàn là 2048x768 (2 màn hình), nhưng dịch vụ báo cáo 1024x768 (có lẽ nó chỉ chọn lên trên một trong các màn hình.)

Kiểm tra tùy chọn cho dịch vụ tương tác với máy tính để bàn không có hiệu lực.

Mọi suy nghĩ?

Edit:

Các giải pháp được đăng tại C#: Get complete desktop size? không làm việc bên trong của một dịch vụ. Tất cả đều báo cáo sai giá trị.

Điều thú vị là, nó có vẻ như giá trị được báo cáo khác nhau và là không có liên quan đến kích cỡ màn hình thực tế (một số máy báo cáo 800x600 mặc dù một màn hình duy nhất trên máy tính mà là một độ phân giải cao hơn nhiều.)

Vì vậy, - còn ý tưởng nào nữa không? Việc bỏ đăng ký và/hoặc vào dòng lệnh là OK. Hạn chế duy nhất là tôi không thể khởi chạy một ứng dụng winforms để tìm ra nó.

+1

Cậu đưa vào tài khoản thực tế là các dịch vụ có thể được chạy trên một hệ thống không đầu? Hoặc đơn giản là không có người dùng nào đăng nhập? – Dmitry

+0

Tôi hy vọng http://stackoverflow.com/questions/1317235/c-get-complete-desktop-size này sẽ giúp bạn. –

+0

Tôi nên làm rõ. Hệ thống không đầu không phải là một mối quan tâm trong thiết lập này. Thứ hai, tôi gắn vào sự kiện đăng nhập - vì vậy tôi biết khi nào cố gắng tìm ra kích thước máy tính để bàn (chỉ sau khi ai đó đăng nhập.) – debracey

Trả lời

3

Bạn không thể thực hiện việc này bên trong dịch vụ. Các dịch vụ chạy trong phiên 0, nơi không có chức năng GDI nào hoạt động. Khi quá trình được tạo, bạn không thể thay đổi phiên và không thể sử dụng giao diện người dùng trong phiên khác.

Một trong những giải pháp khả thi cho bạn là khởi chạy một quy trình mới trong phiên người dùng. Bạn có thể bắt đầu xem số SO question này. Các điều kiện tiên quyết khác cho phương thức này là dịch vụ của bạn phải chạy dưới dạng Hệ thống cục bộ, để bạn có thể bật đặc quyền SE_TCB_NAME (bằng cách gọi AdjustTokenPrivilegies). Vì bạn đang nói rằng bạn đã kết nối với thông báo đăng nhập người dùng, bạn sẽ có thể trích xuất ID phiên của phiên mà bạn quan tâm.

Khi bạn đã xử lý xong phiên người dùng, bạn phải chuyển kết quả từ quy trình mới trở lại quy trình dịch vụ của bạn. Đối với bất kỳ loại cơ chế IPC nào có thể được sử dụng.

+0

Cảm ơn. Tôi tìm thấy một bài viết thú vị về truy vấn WMI để tìm ra kích thước máy tính để bàn (một cái gì đó như '" SELECT * FROM Win32_DesktopMonitor "' sau đó 'queryObj [" ScreenWidth "]'). Bạn có biết nếu điều đó sẽ làm việc bên trong một dịch vụ? Thật không may Im không làm việc ngay bây giờ vì vậy tôi không thể thử nó ra --- Tôi sẽ cố gắng đó và đề nghị của bạn vào ngày mai và báo cáo lại. – debracey

+0

Có vẻ như Win32_DesktopMonitor cung cấp cho bạn các thông số về phần cứng vật lý, tức là thực sự được gắn vào thẻ video bằng dây. Nó không báo cáo kích thước màn hình cho các phiên RDP. Nó phụ thuộc vào yêu cầu của bạn - bạn có cần các thông số phần cứng vật lý hay bất kỳ màn hình nào thực sự được người dùng sử dụng. –

+0

Đó là một điểm tốt, tôi đoán câu hỏi ban đầu của tôi không rõ ràng. Tôi quan tâm nhiều hơn đến độ phân giải tối đa mà phần cứng có thể hiển thị. Những gì người dùng thực sự thấy cũng có thể hữu ích khi báo cáo - nhưng tôi nghĩ họ quan tâm nhiều hơn đến "số lần hiển thị cao nhất tôi có thể hiển thị" là gì – debracey

1

Trong khi tôi chưa gặp phải vấn đề chính xác này, tôi nghi ngờ rằng làm việc với nhiều màn hình có thể yêu cầu bạn phải xuống cấp Win32API (rất nhiều trường hợp cạnh).

Hãy xem hàm EnumDisplayMonitors từ user32 và cụ thể là example in C#. Ngoài ra, bạn có thể sử dụng Screen.AllScreens (như một phần của Winforms DLL bạn không muốn nhập) như một kiểm tra nhanh để xem bạn có muốn làm gì với tư cách là một Dịch vụ Windows hay không. Quay lại đầu trang Tôi gần như chắc chắn rằng phương pháp WinForms này dựa trên EnumDisplayMonitors nội bộ.

+0

Cùng một thỏa thuận như cuộc gọi được quản lý, giá trị sai được báo cáo ... – debracey

1

Bạn có thể thêm kích thước của tất cả các màn hình để xác định tổng kích thước màn hình, như được mô tả bởi P Daddy trong this post.

Rectangle rect = new Rectangle(int.MaxValue, 
           int.MaxValue, 
           int.MinValue, 
           int.MinValue); 

foreach (Screen screen in Screen.AllScreens) 
{ 
    rect = Rectangle.Union(rect, screen.Bounds); 
} 

Console.WriteLine("(w, h) = ({0}, {1})", rect.Width, rect.Height); 
+0

Vâng ... Tôi đã thấy điều đó, không hoạt động trong dịch vụ cửa sổ. Kết quả là như nhau - 1024x768 khi nó phải là 2048x768. – debracey

0

Các mã sau đây làm việc trong một dịch vụ mà tôi tìm thấy trong sharpAvi: https://sharpavi.codeplex.com/

 System.Windows.Media.Matrix toDevice; 
     using (var source = new HwndSource(new HwndSourceParameters())) 
     { 
      toDevice = source.CompositionTarget.TransformToDevice; 
     } 
     screenWidth = (int)Math.Round(SystemParameters.PrimaryScreenWidth * toDevice.M11); 
     screenHeight = (int)Math.Round(SystemParameters.PrimaryScreenHeight * toDevice.M22); 
Các vấn đề liên quan