Is it possible to determine if another process/window was started using a shortcut?
Yes, but not easily.
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:
GetStartupInfo function
Retrieves the contents of the STARTUPINFO
structure that was specified when the calling process was created.
STARTUPINFO structure
dwFlags
A bitfield that determines whether certain STARTUPINFO
members are used when the process creates a window. This member can be one or more of the following values.
...
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.
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).
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).
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: 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).
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…