【问题标题】:How to make C# console application to always be in front?如何使 C# 控制台应用程序始终处于最前面?
【发布时间】:2018-10-27 21:40:58
【问题描述】:

如何确保我的 C# 控制台应用程序始终位于前面? 即如果有人点击离开控制台,我如何检测到控制台失去焦点并将其带回前面? 我有这个 C# 控制台应用程序正在等待用户扫描条形码,如果由于某种原因有人点击离开控制台窗口,那么条形码数据将“丢失”。 我看了一下发布在另一个线程上的这段代码;但是,我似乎无法让它为我工作: bring a console window to front in c# 感谢@ILan,这段代码将控制台保持在所有窗口的顶部,但它没有设置“焦点”来继续捕获传入的数据。

   class Program
{
    [DllImport("user32.dll")]
    static extern bool SetWindowPos(IntPtr hWnd, 
                                    IntPtr hWndInsertAfter, 
                                    int X, 
                                    int Y, 
                                    int cx, 
                                    int cy, 
                                    uint uFlags);
    static readonly IntPtr HWND_TOPMOST = new IntPtr(-1);
    const uint SWP_NOSIZE = 0x0001, SWP_NOMOVE = 0x0002, SWP_SHOWWINDOW = 0x0040;

    [DllImport("kernel32.dll")]
    static extern IntPtr GetConsoleWindow();

    static void Main()
    {
        IntPtr handle = GetConsoleWindow();
        SetWindowPos(handle, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW);
        Console.WriteLine($"Hello handle: {handle}");
        Console.ReadLine();
    }
}

【问题讨论】:

  • @CamiloTerevinto,它在哪里被调用... ;-)
  • 既然你有窗口的句柄,你可以使用this question中的代码把它放在最上面。
  • @CamiloTerevinto,哈哈,我没看到。我刚刚看到 Console.WriteLine 然后掩盖了该行的其余部分。哦,天哪,我很愚蠢 ;-) (现在最好删除我愚蠢的 cmets...)
  • @elgonzo 发生在我们所有人身上 :)

标签: c# console


【解决方案1】:

如果应用程序是附加到控制台的应用程序,则以下内容将完成这项工作。

有关在您的应用程序不是附加到控制台的应用程序的情况下如何获取句柄的完整答案,请参阅https://stackoverflow.com/a/28616832/2370138

class Program
{
    [DllImport("user32.dll")]
    static extern bool SetWindowPos(IntPtr hWnd, 
                                    IntPtr hWndInsertAfter, 
                                    int X, 
                                    int Y, 
                                    int cx, 
                                    int cy, 
                                    uint uFlags);
    static readonly IntPtr HWND_TOPMOST = new IntPtr(-1);
    const uint SWP_NOSIZE = 0x0001, SWP_NOMOVE = 0x0002, SWP_SHOWWINDOW = 0x0040;

    [DllImport("kernel32.dll")]
    static extern IntPtr GetConsoleWindow();

    static void Main()
    {
        IntPtr handle = GetConsoleWindow();
        SetWindowPos(handle, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW);
        Console.WriteLine($"Hello handle: {handle}");
        Console.ReadLine();
    }
}

【讨论】:

  • 这将使窗口位于最顶层(尽管您不拥有控制台窗口,所以我会警惕做任何未明确允许的事情),但不会捕获输入,这就是OP真的很想要。
  • @Ilan 谢谢你把窗户放在前面的好技巧。你是对的,这就是目标。与此同时,它至少会迫使人们看它..到达那里
【解决方案2】:

SetForegroundWindow 此后一直受到限制(请参阅https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-setforegroundwindow 中的备注)。它不再允许你随意将窗口放在前台,正是为了防止你做你想做的事情。

如果您需要在系统上运行其他应用程序,那么您就不走运了。您只需要告诉您的用户在扫描条码时需要让窗口聚焦。

【讨论】:

  • 那么我可以制作另一个控制台程序来监控这个程序并继续把它带到前面吗?这可能吗?
  • @samgoto 不,同样的问题 - 如果您已经在前台,您只能将窗口放在前台(除了少数例外,请参阅文档)。这一切都回到了基本概念——用户拥有计算机,应用程序不拥有。将一个应用程序始终保持在前台会从用户那里获得所有权。想象一下,如果可以做到这一点 - 第一个攻击您计算机的恶意软件将永远获得完全控制权。你会一直被“重要”的应用程序窃取焦点打断。好吧,不用想象 - 试试 Windows 2k/XP :)
猜你喜欢
  • 1970-01-01
  • 2014-05-18
  • 2014-04-30
  • 2015-01-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-04-19
相关资源
最近更新 更多