BIG NOTE

After messing with this API for the last 2 months, the solution/s below are all not stable solutions, but they work in some/most cases, depends on your environment, so keep that in mind.

The solution

The trick is to make windows ‘think’ that our process and the target window (hwnd) are related by attaching the threads (using AttachThreadInput API) and using an alternative API: BringWindowToTop.

 

Forcing Window/Internet Explorer to the foreground

private static void ForceForegroundWindow(IntPtr hWnd)
{
uint foreThread = GetWindowThreadProcessId(GetForegroundWindow(),
IntPtr.Zero);
uint appThread = GetCurrentThreadId();
const uint SW_SHOW = 5;
if (foreThread != appThread)
{
AttachThreadInput(foreThread, appThread, true);
BringWindowToTop(hWnd);
ShowWindow(hWnd, SW_SHOW);
AttachThreadInput(foreThread, appThread, false);
}
else
{
BringWindowToTop(hWnd);
ShowWindow(hWnd, SW_SHOW);
}
}

A more advanced implementation of AttachedThreadInputAction pattern

The idea is to attach to the target process thread and preform an action.

public static void AttachedThreadInputAction(Action action)
{
var foreThread = GetWindowThreadProcessId(GetForegroundWindow(),
IntPtr.Zero);
var appThread = GetCurrentThreadId();
bool threadsAttached = false;
try
{
threadsAttached =
foreThread == appThread ||
AttachThreadInput(foreThread, appThread, true);
if (threadsAttached) action();
else throw new ThreadStateException("AttachThreadInput failed.");
}
finally
{
if (threadsAttached)
AttachThreadInput(foreThread, appThread, false);
}
}

Usage

public const uint SW_SHOW = 5;
///<summary>
/// Forces the window to foreground.
///</summary>
///hwnd”>The HWND.</param>
public static void ForceWindowToForeground(IntPtr hwnd)
{
AttachedThreadInputAction(
() =>
{
BringWindowToTop(hwnd);
ShowWindow(hwnd, SW_SHOW);
});
}
public static IntPtr SetFocusAttached(IntPtr hWnd)
{
var result = new IntPtr();
AttachedThreadInputAction(
() =>
{
result = SetFocus(hWnd);
});
return result;
}

Importing Win32-API to do the job

[DllImport("user32.dll", SetLastError = true)]
public static extern uint GetWindowThreadProcessId(IntPtr hWnd,
out uint lpdwProcessId);
// When you don't want the ProcessId, use this overload and pass
// IntPtr.Zero for the second parameter
[DllImport("user32.dll")]
public static extern uint GetWindowThreadProcessId(IntPtr hWnd,
IntPtr ProcessId);
[DllImport("kernel32.dll")]
public static extern uint GetCurrentThreadId();
/// The GetForegroundWindow function returns a handle to the
/// foreground window.
[DllImport("user32.dll")]
public static extern IntPtr GetForegroundWindow();
[DllImport("user32.dll")]
public static extern bool AttachThreadInput(uint idAttach,
uint idAttachTo, bool fAttach);
[DllImport("user32.dll", SetLastError = true)]
public static extern bool BringWindowToTop(IntPtr hWnd);
[DllImport("user32.dll", SetLastError = true)]
public static extern bool BringWindowToTop(HandleRef hWnd);
[DllImport("user32.dll")]
public static extern bool ShowWindow(IntPtr hWnd, uint nCmdShow);

Abstract

After an interesting research, a solution found to force a window to the top in order to simulate user key presses using SendKeys.

Problem description

We want to type-keys to simulation user key presses like: strings, enters, tabs…

We are using SendKeys API. This API require that the wanted target window will be in the foreground and the wanted control will be in focus.

Seems that since 2007, Vista added  UAC (User Account Control) and , in a nutshell, SetForegroundWindow is not working as expected.

After researching the problem, the behavior is that calling SetForegroundWindow for the first time fails (returns false).

After extensive research and readings, it seems that ‘SetForegroundWindow’ have new rules (for security reasons) and the main idea is that ‘An application can’t force another application to be in the foreground, unless it created it or related to it somehow’ (the full rules can be found here: http://msdn.microsoft.com/en-us/library/windows/desktop/ms633539(v=vs.85).aspx, see ‘Rules’)

Resources

SetForegroundWindow Win32-API not always works on Windows-7的更多相关文章

  1. C#调用Win32 api学习总结

    从.NET平台调用Win32 API Win32 API可以直接控制Microsoft Windows的核心,因为API(Application Programming Interface)本来就是微 ...

  2. 【.Net】从.NET平台调用Win32 API

    小序        Win32 API可以直接控制Microsoft Windows的核心,因为API(Application Programming Interface)本来就是微软留给我们直接控制 ...

  3. Win32 API编程——前言

    一丶什么是Win32 API? 微软为了保护操作系统的安全性和稳定性,把系统分为内核层和用户层(内核层的代码只能在当CPU的特权级为R0状态下执行,用户层的代码在CPU特权级为R0和R3都能执行),w ...

  4. How to change windows applicatioin's position via Win32 API

    可以使用的Win32 API是: [DllImport("user32.dll")] private extern static bool SetWindowPos(IntPtr ...

  5. WIN32 API ------ 最简单的Windows窗口封装类

    1 开发语言抉择 1.1 关于开发Win32 程序的语言选择 C还是C++ 在决定抛弃MFC,而使用纯Win32 API 开发Window桌面程序之后,还存在一个语言的选择,这就是是否使用C++.C+ ...

  6. 初次认识 C# win32 api

    第一次接触win32api,刚开始的时候有点迷迷糊糊的. Windows API 就是windows应用程序接口. win api向上就是windows应用程序,向下就是windows操作系统核心. ...

  7. Serial Port Programming using Win32 API(转载)

    In this tutorial we will learn How to communicate with an external device like a microcontroller boa ...

  8. 【温故Delphi】GAEA用到Win32 API目录

    Delphi是Windows平台下著名的快速应用程序开发工具,它在VCL中封装并使用了大量的Win32 API. GAEA基于VCL开发的工具类产品,在程序中使用了大量的Win32 API,将经常用到 ...

  9. 【C#】分享基于Win32 API的服务操作类(解决ManagedInstallerClass.InstallHelper不能带参数安装的问题)

    注:这里的服务是指Windows 服务. ------------------201508250915更新------------------ 刚刚得知TransactedInstaller类是支持带 ...

  10. C#中导入Win32 API函数

    C#中导入Win32 API的方法: 1.引用命名空间 using System.Net.Security; using System.Runtime.InteropServices; 2. [Dll ...

随机推荐

  1. 问题记录 --Error parsing column 1 (Function_Num=10 - String)”

    当C#查询数据库出现Error parsing column ## 的时候,首先去看看数据库里面该字段是什么类型,然后在看看你在创建model 的时候是什么类型,如果model的类型和数据库字段类型不 ...

  2. python多进程并发和多线程并发和协程

    为什么需要并发编程? 如果程序中包含I/O操作,程序会有很高的延迟,CPU会处于等待状态,这样会浪费系统资源,浪费时间 1.Python的并发编程分为多进程并发和多线程并发 多进程并发:运行多个独立的 ...

  3. PowerBI更新2019/04 - 解决方案架构 - PowerBI Solution Architecture(一图胜万字!)

    Power BI 架构图 (2019/04) 1) Power BI Desktop 是一个免费的工具.它可以用来准备和管理数据模型:包括链接各种数据:做数据清洗:定义关系:定义度量值和层级关系:应用 ...

  4. VS2017 异常 Editor or Editor Extension

    KE遇到的第一个问题 VS 2017 打开文件的时候, 遇到异常 检查 activity_log发现是 Editor or Editor Extension, 解决办法: 安装插件, Clear ME ...

  5. vue+element-ui实现表格checkbox单选

    公司平台利用vue+elementui搭建前端页面,因为本人第一次使用vue也遇到了不少坑,因为我要实现的效果如下图所示 实现这种单选框,只能选择一个,但element-ui展示的是多选框,check ...

  6. Mac OS X 下安装使用 Docker (2017年7月)

    两年前的一篇 Mac OS X 下安装使用 Docker 安装时还是用的 boot2docker, 如今进化到了在 Mac OS X 下用 Docker Toolbox, 而且命令也由 boot2do ...

  7. JAVA常用加密解密算法Encryption and decryption

    加密,是以某种特殊的算法改变原有的信息数据,使得未授权的用户即使获得了已加密的信息,但因不知解密的方法,仍然无法了解信息的内容.大体上分为双向加密和单向加密,而双向加密又分为对称加密和非对称加密(有些 ...

  8. docker实战---初级<1>

    第1章 docker容器 1.1 什么是容器 容器就是在隔离的环境运行的一个进程,如果进程停止,容器就会销毁.隔离的环境拥有自己的文件系统,ip地址,主机名等 1.2 容器与虚拟化的区别 linux容 ...

  9. java23种设计模式之: 策略模式,观察者模式

    策略模式  --老司机开车,但是他今天想到路虎,明天想开奔驰...针对他不同的需求,来产生不同的应对策略    策略类是一个接口,定义了一个大概的方法,而实现具体的策略则是由实现类完成的,这样的目的是 ...

  10. zw版足彩大数据&报价

    zw版足彩大数据&报价 ::zw增强版足彩大数据,文件名后缀是'.dat' ::文件格式是标准文本格式,逗号分隔 ::zw增强版,在标准版赔率基础上,增加了倒数.比率两组归一化数据 ::zw版 ...