Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/300.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 从Windows服务获取桌面大小?_C#_Windows Services - Fatal编程技术网

C# 从Windows服务获取桌面大小?

C# 从Windows服务获取桌面大小?,c#,windows-services,C#,Windows Services,我正试图了解整个Windows桌面的大小,而不仅仅是我编写的服务中的一个屏幕 WinForms中的标准C方法: SystemInformation.VirtualScreen.Width SystemInformation.VirtualScreen.Height 如果您导入Winforms DLL(我希望避免这样做),它似乎可以工作,但它返回了错误的值。桌面大小为2048x768 2个屏幕,但服务报告为1024x768,可能仅在其中一个屏幕上拾取 选中服务与桌面交互的选项无效 有什么想

我正试图了解整个Windows桌面的大小,而不仅仅是我编写的服务中的一个屏幕

WinForms中的标准C方法:

SystemInformation.VirtualScreen.Width   
SystemInformation.VirtualScreen.Height
如果您导入Winforms DLL(我希望避免这样做),它似乎可以工作,但它返回了错误的值。桌面大小为2048x768 2个屏幕,但服务报告为1024x768,可能仅在其中一个屏幕上拾取

选中服务与桌面交互的选项无效

有什么想法吗

编辑:

发布在的解决方案在服务内部不起作用。它们都报告了错误的值

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


那么-还有什么想法吗?放入注册表和/或命令行即可。唯一的限制是我无法启动winforms应用程序来解决这个问题。

虽然我自己没有遇到过这个问题,但我怀疑使用多个监视器可能需要深入到Win32API级别—很多边缘情况都需要这样做

看看user32中的函数,特别是一个


或者,您也可以将不希望导入的Winforms DLL用作快速检查的一部分,以查看您希望执行的操作是否可以作为Windows服务。我几乎可以肯定,这个WinForms方法在内部依赖于EnumDisplayMonitors。

您可以添加所有屏幕的大小来确定桌面的总大小,如中的p所述


您不能在服务内部执行此操作。服务在会话0中运行,其中没有GDI函数工作。创建流程后,您不能更改会话,也不能在不同会话中使用UI

其中一个可能的解决方案是在用户会话中启动一个新流程。你可以开始看这个。此方法的另一个先决条件是您的服务必须作为本地系统运行,这样您就可以通过调用AdjustTokenPrivilegies来启用SE_TCB_名称权限。因为您说您已经连接到用户登录通知,所以您应该能够提取您感兴趣的会话的会话ID


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

以下代码在我在sharpAvi中找到的服务中工作:


您是否考虑到服务可能在无头系统上运行这一事实?或者根本没有用户登录?我希望这会对你有所帮助。我应该澄清一下。无头系统在此设置中不受关注。其次,我附加到登录事件-因此我知道只有在有人登录后才尝试计算桌面大小。您也可以让多个用户同时登录到系统,其中一些用户在本地,一些用户通过RDC登录。他们可能有不同的分辨率和不同数量的监视器。是的。。。我看到了一个,在windows服务中不起作用。结果是相同的-1024x768,而它应该是2048x768。谢谢。我发现了一篇关于查询WMI以计算桌面大小的有趣帖子,比如从Win32_DesktopMonitor选择*然后查询[ScreenWidth]。你知道这在服务中是否有效吗?不幸的是,我现在不在工作,所以我不能尝试它-我明天会尝试它和你的建议,并报告回来。看起来Win32_DesktopMonitor为你提供了物理硬件的参数,即实际连接到视频卡的线缆。它不报告RDP会话的屏幕大小。这取决于你的要求-你需要物理硬件规格还是用户实际使用的任何屏幕。这是一个好问题,我想我最初的问题不清楚。我更关心硬件可以显示的最大分辨率。用户实际看到的东西也可能是有用的,但我认为他们更关心我能显示的最高分辨率
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); 
        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);