- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我到处搜索,试图找到解决我的困境的答案,但似乎找不到有效的答案。我正在尝试用 Xlib 编写一些等效的 user32.dll 代码,以便我可以支持 Linux 用户。我当然在运行 Linux,所以我使用的是 Mono。当我什至无法从 Process 类中获取窗口句柄时,问题就出现了,因为它甚至从未实现过:
[MonoTODO]
[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
[MonitoringDescription ("The handle of the main window of the process.")]
public IntPtr MainWindowHandle {
get {
return((IntPtr)0);
}
}
( Source )
这尤其令人沮丧,因为似乎别无选择。我正在尝试像这样捕获一个窗口句柄:
[DllImport("libX11")]
private static extern IntPtr XOpenDisplay(IntPtr display);
[DllImport("libX11")]
private static extern int XRaiseWindow(IntPtr display, IntPtr window);
private IntPtr ApplicationHandle;
private IntPtr Display;
private void TestXlib() {
Process process = Process.GetProcessById(myPid);
ApplicationHandle = process.MainWindowHandle;
Display = XOpenDisplay(IntPtr.Zero);
XRaiseWindow(Display, ApplicationHandle);
}
注意:代替“myPid”的是一个正确的进程 ID。将“myPid”替换为有效的进程 ID。是的,我确实确保替换的“myPid”是一个有效的进程 ID,并且我的代码没有抛出任何错误,表明我使用的任何进程 ID 都是无效的。
这不会使我的应用程序崩溃,但几乎每次我调用 XRaiseWindow 时它都会打印:
X11 Error encountered:
Error: BadWindow (invalid Window parameter)
Request: 12 (0)
Resource ID: 0x0
Serial: 121
Hwnd: <null>
Control: <null>
这显然是因为 Process.MainWindowHandle 返回 IntPtr.Zero。没有其他方法可以获取窗口句柄吗?提前致谢!
最佳答案
是的,我知道我很久以前就问过这个问题,但我现在正在回答这个问题,因为在我自己找到解决方案后,我一直忘记回答这个问题。我最初使用@SushiHangover 的解决方案但并不是很喜欢它,因为我觉得依赖外部程序 (xwininfo
) 是一个修补程序,最终只是添加了另一个依赖项。希望这可以帮助其他使用 Mono 的 C# 开发人员。此代码最初是为 .NET Framework 2.0 编写的。它并不花哨,也没有很好地记录下来。我的解决方案是自己使用 Xlib 本地枚举窗口,并返回标题与描述的标题匹配的所有窗口。
在 X11Wrapper.cs 中:
using System;
using System.Runtime.InteropServices;
namespace Program.PInvoke.Xlib {
public static class X11Wrapper {
public const string SOName = "libX11.so";
[DllImport(SOName)]
// See: https://tronche.com/gui/x/xlib/display/display-macros.html#DefaultRootWindow
public static extern IntPtr XDefaultRootWindow(IntPtr display);
[DllImport(SOName)]
// See: https://tronche.com/gui/x/xlib/window-information/XQueryTree.html
public static extern int XQueryTree(IntPtr display, IntPtr w,
out IntPtr root_return, out IntPtr parent_return,
out IntPtr[] children_return, out int nchildren_return);
[DllImport(SOName)]
// See: https://tronche.com/gui/x/xlib/ICC/client-to-window-manager/XFetchName.html
public static extern int XFetchName(IntPtr display, IntPtr w,
out string window_name_return);
}
}
在 Linux.Utilities.cs 中:
using Program.PInvoke.Xlib;
namespace Program {
public static partial class Utilities {
public static bool IsUnix {
get {
return Environment.OSVersion.
Platform == PlatformID.Unix;
}
}
private static IntPtr[] FindChildWindows(IntPtr display, IntPtr window,
string title, ref List<IntPtr> windows) {
IntPtr rootWindow;
IntPtr parentWindow;
IntPtr[] childWindows = new IntPtr[0];
int childWindowsLength;
X11Wrapper.XQueryTree(display, window,
out rootWindow, out parentWindow,
out childWindows, out childWindowsLength);
childWindows = new IntPtr[childWindowsLength];
X11Wrapper.XQueryTree(display, window,
out rootWindow, out parentWindow,
out childWindows, out childWindowsLength);
string windowFetchedTitle;
X11Wrapper.XFetchName(display, window, out windowFetchedTitle);
if(title == windowFetchedTitle &&
!windows.Contains(window)) {
windows.Add(window);
}
for(int childWindowsIndexer = 0;
childWindowsIndexer < childWindows.Length;
childWindowsIndexer++) {
IntPtr childWindow = childWindows[childWindowsIndexer];
string childWindowFetchedTitle;
X11Wrapper.XFetchName(display, childWindow,
out childWindowFetchedTitle);
if(title == childWindowFetchedTitle &&
!windows.Contains(childWindow)) {
windows.Add(childWindow);
}
FindChildWindows(display, childWindow, title, ref windows);
}
windows.TrimExcess();
return windows.ToArray();
}
public static IntPtr[] FindWindows(IntPtr display, string title) {
List<IntPtr> windows = new List<IntPtr>();
return FindChildWindows(display,
X11Wrapper.XDefaultRootWindow(display),
title,
ref windows);
}
}
}
脚注:我最初声明我不是 C 开发人员(从那以后情况发生了变化,我已经学习了 C)所以我对使用互操作自己实现功能犹豫不决。如果你最终像我一样更多地使用 Xlib 那么考虑使用 tronche作为 Xlib API 引用。它在 C 中,但我发现它很容易转换为 C# 中的 PInvokable 函数和可编码结构。也有一些好的注释需要考虑。另一个有助于翻译的好资源是直接使用源代码查找低级类型的定义,以帮助找到 C# 等效项。像这样的东西应该对你有很大帮助:http://refspecs.linuxbase.org/LSB_4.0.0/LSB-Desktop-generic/LSB-Desktop-generic/libx11-ddefs.html
关于c# - 无法获取窗口句柄?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42449050/
我需要您在以下方面提供帮助。近一个月来,我一直在阅读有关任务和异步的内容。 我想尝试在一个简单的 wep api 项目中实现我新获得的知识。我有以下方法,并且它们都按预期工作: public Htt
我的可执行 jar 中有一个模板文件 (.xls)。不需要在运行时我需要为这个文件创建 100 多个副本(稍后将唯一地附加)。用于获取 jar 文件中的资源 (template.xls)。我正在使用
我在查看网站的模型代码时对原型(prototype)有疑问。我知道这对 Javascript 中的继承很有用。 在这个例子中... define([], function () { "use
影响我性能的前三项操作是: 获取滚动条 获取偏移高度 Ext.getStyle 为了解释我的应用程序中发生了什么:我有一个网格,其中有一列在每个单元格中呈现网格。当我几乎对网格的内容做任何事情时,它运
我正在使用以下函数来获取 URL 参数。 function gup(name, url) { name = name.replace(/[\[]/, '\\\[').replace(/[\]]/,
我最近一直在使用 sysctl 来做很多事情,现在我使用 HW_MACHINE_ARCH 变量。我正在使用以下代码。请注意,当我尝试获取其他变量 HW_MACHINE 时,此代码可以完美运行。我还认为
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 关闭 9 年前。 要求提供代码的问题必须表现出对所解决问题的最低限度的理解。包括尝试过的解决方案、为什么
由于使用 main-bower-files 作为使用 Gulp 的编译任务的一部分,我无法使用 node_modules 中的 webpack 来require 模块code> dir 因为我会弄乱当
关闭。这个问题需要更多focused .它目前不接受答案。 想改进这个问题吗? 更新问题,使其只关注一个问题 editing this post . 关闭 5 年前。 Improve this qu
我使用 Gridlayout 在一行中放置 4 个元素。首先,我有一个 JPanel,一切正常。对于行数变大并且我必须能够向下滚动的情况,我对其进行了一些更改。现在我的 JPanel 上添加了一个 J
由于以下原因,我想将 VolumeId 的值保存在变量中: #!/usr/bin/env python import boto3 import json import argparse import
我正在将 MSAL 版本 1.x 更新为 MSAL-browser 的 Angular 。所以我正在尝试从版本 1.x 迁移到 2.X.I 能够成功替换代码并且工作正常。但是我遇到了 acquireT
我知道有很多关于此的问题,例如 Getting daily averages with pandas和 How get monthly mean in pandas using groupby但我遇到
This is the query string that I am receiving in URL. Output url: /demo/analysis/test?startDate=Sat+
我正在尝试使用 javascript 中的以下代码访问 Geoserver 层 var gkvrtWmsSource =new ol.source.ImageWMS({ u
API 需要一个包含授权代码的 header 。这就是我到目前为止所拥有的: var fullUrl = 'https://api.ecobee.com/1/thermostat?json=\{"s
如何获取文件中的最后一个字符,如果是某个字符,则删除它而不将整个文件加载到内存中? 这就是我目前所拥有的。 using (var fileStream = new FileStream("file.t
我是这个社区的新手,想出了我的第一个问题。 我正在使用 JSP,我成功地创建了 JSP-Sites,它正在使用jsp:setParameter 和 jsp:getParameter 具有单个字符串。
在回答 StoreStore reordering happens when compiling C++ for x86 @Peter Cordes 写过 For Acquire/Release se
我有一个函数,我们将其命名为 X1,它返回变量 Y。该函数在操作 .on("focusout", X1) 中使用。如何获取变量Y?执行.on后X1的结果? 最佳答案 您可以更改 Y 的范围以使其位于函
我是一名优秀的程序员,十分优秀!