2012-02-29 61 views
5

我試圖從我寫的服務中獲取Windows桌面的大小(整個事情,不只是一個屏幕)。從Windows服務獲取桌面大小?

在的WinForms - 標準C#方法:

SystemInformation.VirtualScreen.Width 
SystemInformation.VirtualScreen.Height 

似乎工作(如果導入的WinForms DLL,我想避免的) - 但它返回錯誤的值。桌面大小爲2048x768(2個屏幕),但服務報告1024x768(大概只能在其中一個屏幕上顯示)。

檢查服務與桌面交互的選項沒有效果。

有什麼想法?

編輯:

C#: Get complete desktop size?貼不服務的內部工作的解決方案。他們都報告錯誤的價值。

有趣的是,這似乎是一種報道的價值變化,是沒有任何關係的實際桌面大小的(有些機器報告800x600即使那臺機器上的單個顯示器是更高的分辨率。)

所以 - 還有什麼想法?放入註冊表和/或到命令行是可以的。唯一的限制是我無法啓動一個winforms應用程序來解決它。

+1

你考慮到一個事實,即該服務可能會一具無頭的系統上運行?或者根本沒有用戶登錄? – Dmitry 2012-02-29 22:29:11

+0

我希望這個http://stackoverflow.com/questions/1317235/c-get-complete-desktop-size會幫助你。 – 2012-02-29 22:29:29

+0

我應該澄清。無頭系統在這種設置中不是一個問題。其次,我附加到登錄事件 - 所以我知道什麼時候嘗試計算出桌面大小(僅在有人登錄後)。 – debracey 2012-02-29 22:39:44

回答

3

你不能在服務中這樣做。服務在會話0中運行,其中沒有GDI功能。一旦創建過程,您將無法更改會話,並且無法在不同的會話中使用UI。

您可能的解決方案之一是在用戶會話中啓動新的進程。你可以開始看這SO question。此方法的其他先決條件是您的服務必須以本地系統的身份運行,以便您可以啓用SE_TCB_NAME權限(通過調用AdjustTokenPrivilegies)。既然你說你已經連接到用戶登錄通知,你應該能夠提取你感興趣的會話的會話ID。

一旦你在用戶會話中啓動了一個進程,你必須通過從新流程返回到您的服務流程。因爲可以使用任何種類的IPC機制。

+0

謝謝。我發現了一個關於查詢WMI以找出桌面大小的有趣帖子(類似於「SELECT * FROM Win32_DesktopMonitor」,然後是'queryObj [「ScreenWidth」])。你知道這是否可以在服務中使用?不幸的是,我現在不在工作,所以我無法嘗試 - 我會在明天試試這個和你的建議並回報。 – debracey 2012-03-01 03:21:56

+0

看起來Win32_DesktopMonitor爲您提供了物理硬件的參數,即實際連接到帶有線纜的視頻卡。它不報告RDP會話的屏幕大小。這取決於您的要求 - 您是否需要物理硬件規格或用戶實際使用的任何屏幕。 – 2012-03-01 03:36:34

+0

這是一個好點,我想我的原始問題並不清楚。我更關心硬件可以顯示的最大分辨率。用戶實際看到的內容也可能是有用的報告 - 但我認爲他們更關心「我能展示的最高分辨率是什麼」 – debracey 2012-03-01 03:39:22

1

雖然我自己沒有遇到這個確切的問題,但我懷疑使用多個顯示器可能需要深入到Win32API級別(許多邊緣情況下)。

查看user32中的EnumDisplayMonitors功能,特別是example in C#

或者,您可以使用Screen.AllScreens(作爲您不想導入的Winforms DLL的一部分)作爲快速檢查,以查看您希望做什麼可以作爲Windows服務。我幾乎可以肯定,這個WinForms方法在內部依賴於EnumDisplayMonitors

+0

與託管呼叫相同,報錯值... – debracey 2012-02-29 23:08:29

1

您可以添加所有屏幕的大小以確定桌面總大小,如P Daddy在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

是的...我看到一個,不能在Windows服務中工作。結果是相同的 - 1024x768應該是2048x768。 – debracey 2012-02-29 22:54:19

0

下面的代碼工作的服務,我在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);