Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/jquery-ui/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何获得;“应用程序名称”;来自适用于Windows 10应用商店应用的hWnd(例如Edge)_C#_Windows_Windows 10_Kernel32 - Fatal编程技术网

C# 如何获得;“应用程序名称”;来自适用于Windows 10应用商店应用的hWnd(例如Edge)

C# 如何获得;“应用程序名称”;来自适用于Windows 10应用商店应用的hWnd(例如Edge),c#,windows,windows-10,kernel32,C#,Windows,Windows 10,Kernel32,我正在尝试为Windows 10应用程序获取一个可理解的“进程名称”。目前,它们都使用ApplicationFrameHost,所以我想我可以使用ModelId或PackageName,但似乎Windows 10应用商店应用程序(我尝试了Mail、Store和Edge)无法与 使用kernel32.dll,GetApplicationUserModelId返回APPMODEL\u ERROR\u NO\u APPLICATION和GetPackageId返回APPMODEL\u ERROR\u

我正在尝试为Windows 10应用程序获取一个可理解的“进程名称”。目前,它们都使用
ApplicationFrameHost
,所以我想我可以使用
ModelId
PackageName
,但似乎Windows 10应用商店应用程序(我尝试了
Mail
Store
Edge
)无法与

使用
kernel32.dll
GetApplicationUserModelId
返回
APPMODEL\u ERROR\u NO\u APPLICATION
GetPackageId
返回
APPMODEL\u ERROR\u NO\u PACKAGE

如何获取Windows 10应用商店应用程序的标识符,以便我可以唯一地标识(例如)任何其他Windows 10应用商店应用程序


更新 我从
hWnd
(窗口句柄)获取进程ID,因此我认为我的问题实际上是如何从窗口句柄获取“真实”进程ID。从那时起,使用这些方法可能会起作用。

您可以使用和

例如:

HANDLE hProcess=OpenProcess(
处理查询有限的信息,
假,,
pe32.th32ProcessID);
UINT32缓冲长度=0;
LONG result=GetPackageId(hProcess,&bufferLength,nullptr);
字节*buffer=(PBYTE)malloc(bufferLength);
结果=GetPackageId(hProcess和bufferLength,buffer);
PACKAGE_ID*packageId=重新解释转换(缓冲区);
wprintf(L“名称:%s\n”,packageId->Name);

GetPackageFullName/FamilyName/Id(HPProcess,…)等如果进程没有包标识,则返回APPMODEL\u ERROR\u NO\u包。同上,GetApplicationUserModelId(HPProcess…)返回APPMODEL\u ERROR\u NO\u APPLICATION,因为该进程同样没有应用程序标识

听起来您有一个HWND,它代表应用程序工作,但不是应用程序。这是很常见的-RuntimeBroker和其他进程作为“桌面应用程序”(即进程w/o包或应用程序标识)运行,作为代理为应用程序进程执行它们自己无法执行的操作


对于您最初的问题,“我从hWnd(窗口句柄)获取进程ID,所以我认为我的问题实际上是如何从窗口句柄获取“真实”的进程ID”这是一种根本上有缺陷的方法。您有一个来自HWND的pid,但是如果进程是一个代理,它可以代表多个应用程序工作-代理进程没有标识;它知道*per-request/WinRT-API-call/etc调用方是谁,并将其工作范围限定为该标识。您无法在进程级别发现这一点。

因此,首先有一个东西叫做,它是任务栏用来对窗口进行分组的窗口ID。因为所有WinRT窗口都来自同一进程,但它们没有分组,这意味着每个应用程序都有自己的UserModelID

要从HWND获取UserModelID,可以使用中的方法

#包括“Propsys.h”
#包括
#pragma注释(lib,“Shell32.lib”)
//.........
IPropertyStore*propStore;
自动weatherWnd=FindWindow(L“应用程序框架窗口”,L“天气”);
SHGetPropertyStoreForWindow(weatherWnd、IID_IPropertyStore、(void**)和propStore);
道具变体道具;
propStore->GetValue(PKEY\u AppUserModel\u ID和prop);
prop
将包含值
LPWSTR=0x00838f68 L“Microsoft.BingWeather\u 8wekyb3d8bbwe!App”
。这是格式为
的完整入口点名称。启动的应用程序的入口点通常称为
App
。入口点在应用程序清单中定义

还有一件有趣的事——应用程序拥有的子窗口并没有被破坏,而是从应用程序框架主机移到了桌面窗口。我不知道为什么会发生这种情况,但您必须小心,因为
FindWindow(nullptr,L“Weather”)
返回的是子应用程序窗口,而不是appframehost窗口

p.S.AppUserModelID只是一个字符串,其格式没有文档记录,因此此方法并非最可靠的方法


p.p.S.我还注意到,你想要有图标和名称,你可以使用它,它要求你引用winmd程序集,如何做这个看起来是一个类似的获得实际进程名称的方法,

使用Spy++实用程序,确认Windows.Core.UI.CoreWindow是天气的子窗口,它是我们感兴趣的窗口。(在Win10 10563上验证)

应用程序被包装到其他应用程序/进程中。如果有焦点,那么尝试找到子UWP进程

您将需要一些p/Invoke方法。看看这个类,它提供了完成这项工作所需的所有代码:

使用系统;
使用System.IO;
使用System.Runtime.InteropServices;
使用系统文本;
命名空间堆栈溢出
{
内部结构WINDOWINFO
{
公共单位所有者ID;
公共部门;
}
公共类计算机
{
#区域用户32
[DllImport(“user32.dll”)]
公共静态外部IntPtr GetForegroundWindow();
[DllImport(“user32.dll”,SetLastError=true)]
公共静态外部单元GetWindowThreadProcessId(IntPtr hWnd,out单元lpdwProcessId);
//当您不需要ProcessId时,请使用此重载并将IntPtr.Zero传递给第二个参数
[DllImport(“user32.dll”,SetLastError=true)]
公共静态外部IntPtr GetWindowThreadProcessId(IntPtr hWnd,IntPtr ProcessId);
/// 
///EnumChildWindows方法的委托
/// 
///窗把手
///调用方定义的变量;我们使用它作为指向列表的指针
///如果为True,则继续枚举,如果为false,则为bail。
公共委托bool EnumWindowProc(IntPtr hWnd,IntPtr参数);
[DllImport(“user32”,SetLastError=true)]
[返回:Marshallas(UnmanagedType.Bool)]
公共静态外部bool EnumChildWindows(IntPtr hwndpresent、EnumWindowProc lpEnumFunc、IntPtr lParam);
#端区
#区域核32
公安部门32过程查询信息
HANDLE hProcess = OpenProcess(
    PROCESS_QUERY_LIMITED_INFORMATION,
    false,
    pe32.th32ProcessID);

UINT32 bufferLength = 0;

LONG result = GetPackageId(hProcess, &bufferLength, nullptr);

BYTE* buffer = (PBYTE) malloc(bufferLength);
result = GetPackageId(hProcess, &bufferLength, buffer);

PACKAGE_ID* packageId = reinterpret_cast<PACKAGE_ID*>(buffer);
wprintf(L"Name: %s\n", packageId->name);
#include "Propsys.h"
#include <propkey.h>

#pragma comment (lib, "Shell32.lib")

//.........

IPropertyStore* propStore;

auto weatherWnd = FindWindow(L"ApplicationFrameWindow", L"Weather");
SHGetPropertyStoreForWindow(weatherWnd, IID_IPropertyStore, (void**)&propStore);

PROPVARIANT prop;
propStore->GetValue(PKEY_AppUserModel_ID, &prop);