从Windows服务获取桌面大小?

时间:2012-02-29 22:24:56

标签: c# windows-services

我正试图从我写的服务中获取Windows桌面的大小(整个而不仅仅是一个屏幕)。

在WinForms中 - 标准的C#方法:

SystemInformation.VirtualScreen.Width   
SystemInformation.VirtualScreen.Height

似乎工作(如果你导入Winforms DLL,我想避免) - 但它返回错误的值。桌面大小为2048x768(2个屏幕),但服务报告1024x768(可能只会在其中一个屏幕上显示。)

检查服务与桌面交互的选项无效。

有什么想法吗?

修改

C#: Get complete desktop size?发布的解决方案在服务内部无效。他们都报告错误的价值。

有趣的是,报告的值似乎有所不同,与实际桌面大小无关(有些机器报告800x600,即使该机器上的单个显示器的分辨率要高得多。)

那么 - 还有什么想法吗?删除到注册表和/或命令行是可以的。唯一的限制是我无法启动winforms应用程序来解决它。

4 个答案:

答案 0 :(得分:3)

您无法在服务中执行此操作。服务在会话0中运行,其中没有GDI功能。创建进程后,您无法更改会话,也无法在不同的会话中使用UI。

您可能的解决方案之一是在用户会话中启动新流程。您可以开始查看此SO question。此方法的其他先决条件是您的服务必须作为本地系统运行,以便您可以启用SE_TCB_NAME权限(通过调用AdjustTokenPrivilegies)。由于您说您已经连接到用户登录通知,因此您应该能够提取您感兴趣的会话的会话ID。

在用户会话中启动流程后,您必须将新流程的结果传递回服务流程。为此,可以使用任何类型的IPC机制。

答案 1 :(得分:2)

您可以添加所有屏幕的大小以确定总桌面大小,如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); 

答案 2 :(得分:1)

虽然我自己没有遇到过这个问题,但我怀疑使用多个监视器可能需要你深入研究Win32API级别(很多边缘情况都可以)。

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

或者,您可以使用Screen.AllScreens(作为Winforms DLL的一部分,您不想导入)作为快速检查,以查看您是否可以将其作为Windows服务。我几乎可以肯定这个WinForms方法在内部依赖于EnumDisplayMonitors

答案 3 :(得分: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);