在任务栏中从 C# 应用程序聚焦 Windows 资源管理器 [英] Focus Windows Explorer From C# App In Task Bar

查看:72
本文介绍了在任务栏中从 C# 应用程序聚焦 Windows 资源管理器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们公司有作为任务栏图标运行的应用程序 - 除了任务栏图标之外没有 UI.

Our company has application that runs as a task bar icon - there is no UI besides the task bar icon.

某些事件会导致任务栏启动 explorer.exe 以显示目录.用户交互不会导致这种情况,因此我们的应用程序没有焦点.

Certain events cause the task bar to launch a explorer.exe to show a directory. User interaction does not cause this, so our application does not have focus.

我可以使用如下代码在 Windows 资源管理器中显示目录:

I am able to show the directory in windows explorer using code like this:

Process.Start("explorer.exe", "c:\somedirectory");

问题是,文件夹在后台启动,我似乎无法集中注意力.

The problem is, the folder launches in the background and I can't seem to give it focus.

部分问题是explorer.exe进程立即退出,单独启动explorer.exe进程.我可以使用 Process.processes() 找到启动的窗口,并查看窗口标题和进程的开始时间.

Part of the problem is that the explorer.exe process exits immediately, launching the explorer.exe process separately. I am able to find the launched window using Process.processes() and looking at the window title and start time of the process.

一旦我最终掌握了流程(并等待它打开),我就会尝试集中精力.这是我尝试过的:

Once I finally get a handle on the process (and wait for it to open), I'm trying to focus it. Here's what I've tried:

//trying to bring the application to the front
form.TopMost = true;
form.Activate();
form.BringToFront();
form.Focus();

Process process = ...;

ShowWindow(process.Handle, WindowShowStyle.ShowNormal);
SetForegroundWindow(process.Handle);
SwitchToThisWindow(process.Handle, true);  

ShowWindow(process.MainWindowHandle, WindowShowStyle.ShowNormal);
SetForegroundWindow(process.MainWindowHandle);
SwitchToThisWindow(process.MainWindowHandle, true);  

这会使任务栏中的窗口闪烁,但它仍然没有聚焦.

This makes the window blink in the task bar, but it still isn't focused.

如何让窗口出现在屏幕的前面?

How can I get the window to come to the front of the screen?

推荐答案

要聚焦 explorer.exe,应用程序本身需要聚焦.WinForms 故意让这件事变得困难,因为它可能会被滥用.

To focus explorer.exe, the application itself needed focus. WinForms intentionally makes this difficult since it could be abused.

以下是在 WinForms 中窃取焦点的方法.请记住,它可能会产生不良后果.

一旦您的应用程序获得焦点,您就可以专注于另一个进程:

Once your application has focus, you can focus another process:

[DllImport("user32.dll")]
private static extern bool SetForegroundWindow(IntPtr hWnd);

SetForegroundWindow(otherProcess.MainWindowHandle);

这是我找到资源管理器进程的方式.就像我说的,explorer.exe 似乎启动了另一个进程并关闭,所以最好的选择似乎是找到最近启动的 explorer.exe 进程:

Here's how I found the explorer process. Like I said, the explorer.exe seems to launch another process and close, so the best option seemed to be to find the most recently launched explorer.exe process:

public static Process GetExplorerProcess()
{
    var all = Process.GetProcessesByName("explorer");
    Process process = null;
    foreach (var p in all)
        if (process == null || p.StartTime > process.StartTime)
            process = p;
    return process;
}

另一个不需要窃取焦点的选项是从托盘图标显示一条消息.然后你可以设置一个点击处理程序来打开/聚焦文件夹.应用程序自然会从点击中获得焦点.

Another option that wouldn't require stealing focus is to show a message from your tray icon. Then you can setup a click handler to open/focus the folder. The application would naturally have focus from the click.

trayIcon.ShowBalloonTip(3000, "", msg, ToolTipIcon.Info);

这更符合不要惹恼用户",但在我的情况下,用户对必须点击气泡更恼火.

This falls more in line with "don't annoy the user" but in my case the user is far more annoyed at having to click the bubble.

查找资源管理器进程需要您的应用的管理员权限.我发现如果您首先关注自己的应用程序,然后启动文件夹,则该文件夹会自动获得关注.换句话说,不需要搜索当前进程并调用SetForegroundWindow.

Finding the explorer process requires admin privileges for your app. I've found that if you focus your own application first, then launch the folder, then the folder is automatically focused. In other words, there is no need to search through the current processes and call SetForegroundWindow.

这篇关于在任务栏中从 C# 应用程序聚焦 Windows 资源管理器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆