So Im trying to create a camo unlocker but I have never had trouble with getting process id through findwindow
but now Im trying to find black ops 2's proc id but the window name doesn't work
Call of Duty®: Black Ops II
CODE:
#include <iostream>
#include <Windows.h>
#include <tchar.h>
using namespace std;
int main(){
HWND hWnd = FindWindow(0, _T("Call of Duty®: Black Ops II - Multiplayer"));
if(hWnd){
cout << "window found" << endl;
}
return 0;
}
It looks like the registered symbol could be unicode, you'll want to use FindWindowW():
Unicode and ANSI names
FindWindowW (Unicode) and FindWindowA (ANSI)
Alternatively, you could use FindWindowEx() and search for the window class name.
FindWindow works correctly. The possible causes for your problem are:
You have an encoding error. You should use the Unicode API:
HWND hWnd = FindWindowW(NULL, L"Call of Duty®: Black Ops II - Multiplayer");
There is no top level window with that window text. Use a tool like Spy++ to check that.
You should also make sure that you read the documentation carefully. Specifically it states the following:
If the function fails, the return value is NULL. To get extended error information, call GetLastError.
You should do as it says and call GetLastError in event of failure.
I would try to find the window by class as an application may change its title and class names usually do not have fancy characters. If you do not know them look for some tool (Spy++ + i think it comes with Visual Studio) or create a list with a simple tool using EnumWindows and GetClassName
FindWindowA worked for me :) so I just changed from tchar to the normal HWND hWnd = FindWindowA(0, ("Call of Duty®: Black Ops II - Multiplayer"));
Related
I'm a little bit confused about how to notify my c++ application with event that the user has plugged in a device (USB, HID etc.). Application type is not defined. I'm trying to play around with console/message-only/service example apps, but there is no result. I'm using VS2015 and Windows 10.
I've found out that there are multiple ways to deal with it:
Using WMI like here. But I can not actually understand where is WMI here.
Using RegisterDeviceNotification and WM_DEVICECHANGE. As far as I can understand, there is no way to do that for the console applications, only for once with the GUI (real window) or for the message-only window. I've tried the last one with the example from this answer but my app doesn't receive any notifications when I plug in my USB flash drive. I've found this answer (from the same question as the answer mentioned above) and tried to use ChangeWindowMessageFilterEx() function with GetProcAddress from user32.dll to load it without connection dll to my app in such way:
BOOL InitInstance(HWND hWnd)
{
HMODULE hDll = GetModuleHandle(TEXT("user32.dll"));
if (hDll)
{
typedef BOOL(WINAPI *MESSAGEFILTERFUNCEX)(HWND hWnd, UINT message, DWORD action, VOID* pChangeFilterStruct);
const DWORD MSGFLT_ALLOW = 1;
MESSAGEFILTERFUNCEX ChangeWindowMessageFilterEx= (MESSAGEFILTERFUNCEX)::GetProcAddress(hDll, "ChangeWindowMessageFilterEx");
if (ChangeWindowMessageFilterEx) return func(hWnd, WM_COPYDATA, MSGFLT_ALLOW, NULL);
}
return FALSE; }
And the usage of this function is:
hWnd = CreateWindowEx(0, CLS_NAME, "DevNotifWnd", WS_ICONIC,
0, 0, CW_USEDEFAULT, 0, HWND_MESSAGE,
NULL, GetModuleHandle(0), (void*)&guid);
InitInstance(hWnd);
But there is no effect.
Using while(true){...} loop and call appropriate Win API functions like in this answer. But this way seems not be a perfect solution for my problem.
My questions are:
Could anybody explain me what is the best way? And if it is the second one with RegisterDeviceNotification, why it's not working in case of message-only window app?
Do other ways exist? And if not, what can I do, for example, to notify application when some certain software was installed?
Any comments are appreciated.
So I've finally found sort of answers to the questions.
The issue was with the GUID I've provided for the NotificationFilter. So I've set it to receive notifications from all devices with this code:
DEV_BROADCAST_DEVICEINTERFACE NotificationFilter;
ZeroMemory(&NotificationFilter, sizeof(NotificationFilter));
NotificationFilter.dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE);
NotificationFilter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
// No need to set up dbcc_classguid as it is ignored when
// DEVICE_NOTIFY_ALL_INTERFACE_CLASSES is setted (see line down below)
HDEVNOTIFY dev_notify = RegisterDeviceNotification(hwnd, &NotificationFilter, DEVICE_NOTIFY_ALL_INTERFACE_CLASSES);
As far as for other types of notifications in windows that the app could sign up for, I found only one partially deprecated list of all Win32 API functions, where I found some new Notifications with Ctrl+F search :)
Hope this could save somebody's time.
I am trying to retrieve the text of a button on Calculator (calc.exe) using Winapi. I have hooked WH_CALLWNDPROC and the hook works fine. But I am unable to retrieve the text of any button (say numeric 7). I am using GetDlgItemText:
TCHAR text[256];
GetDlgItemText((HWND)0x7068c, 0x89, text, strlen(text));
Here 0x7068c is the parent window handle of the numeric 7 button, while 0x89 is its control id. No text is returned, though I am able to click it programmatically.
What am I doing wrong? I tried to use SendMessage with WM_GETTEXT, but it still doesnt work. I want to take this approach and retrieve the text from buttons, textboxes in other applications.
You could simply use Accessibility:
#include "windows.h"
#include "Oleacc.h"
#include "atlbase.h"
#pragma comment(lib,"Oleacc.lib")
int main()
{
CComPtr<IAccessible> pAcc;
VARIANT varChild;
if (SUCCEEDED(AccessibleObjectFromWindow((HWND)0x000d18e0,
OBJID_WINDOW,IID_IAccessible, reinterpret_cast<void**>(&pAcc))))
{
CComBSTR bstrName;
varChild.vt = VT_I4;
varChild.lVal = CHILDID_SELF;
if (SUCCEEDED(pAcc->get_accName(varChild, &bstrName)))
{
wprintf(L"%s", bstrName.m_str);
}
}
return 0;
}
I finally succeeded in doing this by using EasyHook for hooking DrawTextW, DrawTextExW, ExtTextOutW API functions for retrieving the text off buttons, labels, etc. In the hooked functions I was able to retrieve the text. This SO thread was a great help to me.
The following sample has reliably returned the name of the process that is associated with the active window, but does not work with the newer modern/universal apps because it returns the name of a helper process WWAHost.exe on Windows 8 and ApplicationFrameHost.exe on Windows 10 rather than the name of the app.
HWND active_window = GetForegroundWindow();
GetWindowThreadProcessId(active_window, &active_process_id);
HANDLE active_process = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, active_process_id);
GetProcessImageFileName(active_process, image_name, 512);
With Windows 10 the ApplicationFrameHost.exe is the process that creates the window handles and is what gets returned by GetWindowThreadProcessId(), is there another Win32 API that can be used to get the active process of universal app that is active?
Also tried using GetApplicationUserModelId() and GetPackageFullName() with no success as they return APPMODEL_ERROR_NO_APPLICATION and APPMODEL_ERROR_NO_PACKAGE respectively because the active_process handle is just the helper process and not the process of the active application.
Any other APIs to use to get the process name of a Modern/Universal application given the hwnd of the window, or otherwise figure out the process name of the universal app is active.
Thanks in advance!
Be sure to use the Spy++ utility when you want to reverse-engineer something like this. Included with Visual Studio, you need the 64-bit version in Common7\Tools\spyxx_amd64.exe. Use Search > Find Window and drag the bullseye to a UWP app, like Weather.
You'll see the window you'll find with GetForegroundWindow(), it has at least 3 child windows:
ApplicationFrameTitleBarWindow
ApplicationFrameInputSinkWindow
Windows.Core.UI.CoreWindow, that's the host window for the UWP app and the one you are interested in. Right-click it and select Properties, Process tab, click the Process ID. That takes you to the real owner process you want to know.
So you just need to make an extra step from the code you already have, you just have to enumerate the child windows and look for one with a different owner process. Some C code, trying to make it as universal as possible without making too many assumptions and not enough error checking:
#include <stdio.h>
#include <Windows.h>
typedef struct {
DWORD ownerpid;
DWORD childpid;
} windowinfo;
BOOL CALLBACK EnumChildWindowsCallback(HWND hWnd, LPARAM lp) {
windowinfo* info = (windowinfo*)lp;
DWORD pid = 0;
GetWindowThreadProcessId(hWnd, &pid);
if (pid != info->ownerpid) info->childpid = pid;
return TRUE;
}
int main()
{
Sleep(2000);
HWND active_window = GetForegroundWindow();
windowinfo info = { 0 };
GetWindowThreadProcessId(active_window, &info.ownerpid);
info.childpid = info.ownerpid;
EnumChildWindows(active_window, EnumChildWindowsCallback, (LPARAM)&info);
HANDLE active_process = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, info.childpid);
WCHAR image_name[MAX_PATH] = { 0 };
DWORD bufsize = MAX_PATH;
QueryFullProcessImageName(active_process, 0, image_name, &bufsize);
wprintf(L"%s\n", image_name);
CloseHandle(active_process);
return 0;
}
Output on the Weather program:
C:\Program Files\WindowsApps\Microsoft.BingWeather_4.5.168.0_x86__8wekyb3d8bbwe\
Microsoft.Msn.Weather.exe
Here is a small console app application that continuously (so you can test it easily selecting different windows on your desktop) display information about the current foreground window process and store process, if any.
Apps can have a window hierarchy that can span multiple processes. What I do here is search the first sub window that has the 'Windows.UI.Core.CoreWindow' class name.
This app uses the UIAutomation API (and also smart pointers, smart BSTRs and smart VARIANTs provided by the #import directive). I suppose you can do the same with standard Windows SDK, but I find the UIAutomation used this way quite elegant.
#include "stdafx.h"
#import "UIAutomationCore.dll"
using namespace UIAutomationClient;
int main()
{
// initialize COM, needed for UIA
CoInitialize(NULL);
// initialize main UIA class
IUIAutomationPtr pUIA(__uuidof(CUIAutomation));
do
{
// get the Automation element for the foreground window
IUIAutomationElementPtr foregroundWindow = pUIA->ElementFromHandle(GetForegroundWindow());
wprintf(L"pid:%i\n", foregroundWindow->CurrentProcessId);
// prepare a [class name = 'Windows.UI.Core.CoreWindow'] condition
_variant_t prop = L"Windows.UI.Core.CoreWindow";
IUIAutomationConditionPtr condition = pUIA->CreatePropertyCondition(UIA_ClassNamePropertyId, prop);
// get the first element (window hopefully) that satisfies this condition
IUIAutomationElementPtr coreWindow = foregroundWindow->FindFirst(TreeScope::TreeScope_Children, condition);
if (coreWindow)
{
// get the process id property for that window
wprintf(L"store pid:%i\n", coreWindow->CurrentProcessId);
}
Sleep(1000);
} while (TRUE);
cleanup:
CoUninitialize();
return 0;
}
Does taking snapshot of running processes and pulling the name out of it by comparing process id not work?
Full reference here:
https://msdn.microsoft.com/en-us/library/windows/desktop/ms686837(v=vs.85).aspx
But you fix the snapshot with CreateToolhelp32Snapshot().
Or from WTSEnumerateProcesses() and surrounding API?
Pretty sure it worked in Win 8. Is it broken in 10?
Starting from Win10 Anniversary Update ApplicationFrameHost child window return anything but UWP application. It worked only in Tablet mode after relogon.
I want to make the most simplest application that can communicate via windows send messages (and parse json). I have found a sample code:
CWnd* pWnd = FindWindow("old title");
pWnd->SendMessage(WM_SETTEXT,0,(LPARAM)"New title");
That works... but only if I use MS Visual Studios "create new MFC form application" wizard. How can I make a console application that sends messages to my program? Or can I? What do I need to include/link if I start an empty project or console application?
The goal in pseudocode:
a = ""
while !EOF
a += read(stdin)
commandArray = jsonToArray(a)
CWnd* pWnd = FindWindow("program");
pWnd->SendMessage(WM_COPYDATASTRUCT,0,commandArrayWrappedInCOPYDATASTRUCT);
exit
The annoyance is that the effective part of the code is roughly 20 lines (above), but the wizard generated part is hundreds of lines. And most of them is stuff that I don't understand. Plus, I get a window that I don't need.
EDIT
Final main.cpp (without the json stuff):
/*
This closes calculator
*/
#include <Windows.h>
#include <atlstr.h>
int main (void)
{
HWND HWnd = FindWindow(NULL, CStringW("Calculator"));
SendMessage(HWnd, WM_CLOSE, 0, 0);
return 0;
}
br,
Juha
If you want something so simple, then I'd just forget all about MFC and start with a basic console app from the New Project Wizard. MFC seems rather heavy duty for something so simple.
How to set the console window title in C?
printf("%c]0;%s%c", '\033', "My Console Title", '\007');
This works only under linux, not in windows.
Does anybody know a "cross-platform" solution? (of course not system ( title=blah ))
windows.h defines SetConsoleTitle().
You could use that everywhere, and declare your own function for linux platforms that does the same thing.
Sounds similar to this posting: (Which is for Java, but the accepted answer uses JNI [ie a C Native call].
How to change command prompt (console) window title from command line Java app?
You can do this by calling SetConsoleTitle.
Maybe you have to implement a "cross-playform" solution yourself.
For windows 2000+, you can use SetConsoleTitle(), more imformation can be found on MSDN.
The most easy way to achieve this in C is to use windows.h header and use the SetConsoleTitle function
Simple Script
#include <stdio.h>
#include <windows.h>
#include <conio.h>
int main()
{
HANDLE handleConsole = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleTitle("Mini Desktop App"); // Here add the title of the window
while(1){
printf("Works as expected\n");
printf("Press any Key to exit :)\n");
getch();
break;
}
return 0;
}