我正试图从我写的服务中获取Windows桌面的大小(整个而不仅仅是一个屏幕)。
在WinForms中 - 标准的C#方法:
SystemInformation.VirtualScreen.Width
SystemInformation.VirtualScreen.Height
似乎工作(如果你导入Winforms DLL,我想避免) - 但它返回错误的值。桌面大小为2048x768
(2个屏幕),但服务报告1024x768
(可能只会在其中一个屏幕上显示。)
检查服务与桌面交互的选项无效。
有什么想法吗?
修改
在C#: Get complete desktop size?发布的解决方案在服务内部无效。他们都报告错误的价值。
有趣的是,报告的值似乎有所不同,与实际桌面大小无关(有些机器报告800x600
,即使该机器上的单个显示器的分辨率要高得多。)
那么 - 还有什么想法吗?删除到注册表和/或命令行是可以的。唯一的限制是我无法启动winforms应用程序来解决它。
答案 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);