确定进程是否从快捷方式启动 [英] Determine if process started from shortcut
问题描述
是否可以确定是否使用快捷方式启动了另一个进程/窗口?目的是然后读取该快捷方式以获取启动设置:启动文件夹、以管理员身份运行等.也许有办法找出程序的催化剂/调用者(用户/应用程序 w 管理员权限/快捷方式)?
Is it possible to determine if another process/window was started using a shortcut? The purpose being to then read that shortcut to obtain the startup settings: start-in folder, run as admin, etc. Maybe there is a way to find out the catalyst/caller of the program (User/Application w admin privileges/shortcut)?
我知道使用 Windows 驱动程序工具包来确定.尽管在其他方面开发起来相当棘手.
I'm aware of using the Windows Driver Kit to determine it. Although this is rather tricky to develop in among other things.
推荐答案
是否可以确定是否使用快捷方式启动了另一个进程/窗口?
Is it possible to determine if another process/window was started using a shortcut?
是的,但并不容易.
如答案中所述,类似的问题,进程可以通过调用 GetStartupInfo()
并检查 STARTF_TITLEISLINKNAME
标志来确定自己是否由快捷方式启动.这在 MSDN 上有记录:
As mentioned in an answer to a similar question, a process can find out if itself was started by a shortcut by calling GetStartupInfo()
and checking for the STARTF_TITLEISLINKNAME
flag. This is documented on MSDN:
检索在创建调用进程时指定的 STARTUPINFO
结构的内容.
Retrieves the contents of the
STARTUPINFO
structure that was specified when the calling process was created.
dwFlags
确定在进程创建窗口时是否使用某些 STARTUPINFO
成员的位域.该成员可以是以下一个或多个值.
dwFlags
A bitfield that determines whether certainSTARTUPINFO
members are used when the process creates a window. This member can be one or more of the following values.
...
STARTF_TITLEISLINKNAME
0x00000800
lpTitle 成员包含用户调用以启动此进程的快捷方式文件 (.lnk) 的路径.这通常是在调用指向已启动应用程序的 .lnk
文件时由 shell 设置的.大多数应用程序不需要设置此值.
...
STARTF_TITLEISLINKNAME
0x00000800
The lpTitle member contains the path of the shortcut file (.lnk) that the user invoked to start this process. This is typically set by the shell when a .lnk
file pointing to the launched application is invoked. Most applications will not need to set this value.
获得 .lnk
文件的路径后,您可以使用 IShellLink
界面(请参阅 Shell 链接 了解更多详情).
Once you have the path to the .lnk
file, you can parse it using the IShellLink
interface as needed (see Shell Links for more details).
现在,话虽如此,您不能直接检索另一个进程的STARTUPINFO
结构.但是,您可以通过将代码注入目标进程来间接检索它(使用 CreateRemoteThread()
或 SetWindowsHookEx()
),然后让该代码调用 GetStartupInfo()
并将所需信息返回给您的流程使用您选择的 IPC 机制(WM_COPYDATA
、命名管道、邮槽、套接字、COM、RPC 等).
Now, that being said, you cannot directly retrieve the STARTUPINFO
structure of another process. However, you can retrieve it indirectly, by injecting code into the target process (using CreateRemoteThread()
or SetWindowsHookEx()
), and then have that code call GetStartupInfo()
and communicate the desired information back to your process using an IPC mechanism of your choosing (WM_COPYDATA
, named pipe, mailslot, socket, COM, RPC, etc).
或者,有一种非官方的方法(取决于操作系统版本)来获取许多相同的 STARTUPINFO
字段值,包括 .lnk
文件名,而无需注入任何代码进入目标进程.使用 NtQueryInformationProcess()
获取指向目标进程的PEB
1 结构,其中有一个 ProcessParameters
字段,该字段是一个指向 RTL_USER_PROCESS_PARAMETERS
1 结构,它有一个 WindowTitle
字段(包含来自 STARTUPINFO
的值的其他字段).您可以使用 OpenProcess()
获取目标进程的 HANDLE
(您可以使用 GetWindowThreadProcessId()
),然后使用 ReadProcessMemory()
读取的内容根据需要,PEB
和 RTL_USER_PROCESS_PARAMETERS
结构.
Or, there is an unofficial way (subject to OS version) to get many of the same STARTUPINFO
field values, including the .lnk
filename, without injecting any code into the target process. Use NtQueryInformationProcess()
to get a pointer to the target process's PEB
1 structure, which has a ProcessParameters
field that is a pointer to an RTL_USER_PROCESS_PARAMETERS
1 structure, which has a WindowTitle
field (amongst other fields that contain values from STARTUPINFO
). You can use OpenProcess()
to get a HANDLE
to the target process (you can get the process ID of an HWND
using GetWindowThreadProcessId()
), and then use ReadProcessMemory()
to read the contents of the PEB
and RTL_USER_PROCESS_PARAMETERS
structures as needed.
1:PEB
和 RTL_USER_PROCESS_PARAMETERS
结构的大部分内容没有记录在 MSDN 中,而是记录在 http://undocumented.ntinternals.net (这里 和 此处).
1: Most of the content of the PEB
and RTL_USER_PROCESS_PARAMETERS
structures are not documented by MSDN, but are documented on http://undocumented.ntinternals.net (here and here).
这篇关于确定进程是否从快捷方式启动的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!