Trying to follow this sample: https://devblogs.microsoft.com/oldnewthing/20040520-00/?p=39243
void ShellExecuteFromExplorer(PCWSTR pszFile, PCWSTR pszParameters = nullptr, PCWSTR pszDirectory = nullptr, PCWSTR pszOperation = nullptr, int nShowCmd = SW_SHOWNORMAL)
{
CComPtr<IShellFolderViewDual> spFolderView;
GetDesktopAutomationObject(IID_PPV_ARGS(&spFolderView));
CComPtr<IDispatch> spdispShell;
spFolderView->get_Application(&spdispShell);
CComQIPtr<IShellDispatch2>(spdispShell)
->ShellExecute(CComBSTR(pszFile),
CComVariant(pszParameters ? pszParameters : L""),
CComVariant(pszDirectory ? pszDirectory : L""),
CComVariant(pszOperation ? pszOperation : L""),
CComVariant(nShowCmd));
}
In this case, how do i retrieve the pid
from the process being launch from the ShellExecute
?
CodePudding user response:
In this case, how do i retrieve the
pid
from the process being launch from theShellExecute
?
You can't. just like ::ShellExecute()
, IShellDispatch2::ShellExecute()
simply does not provide any information about the new process.
CodePudding user response:
not need use this way for create unelevated process. for instance we can use shell process (explorer) as parent for new process with help PROC_THREAD_ATTRIBUTE_PARENT_PROCESS
. example of code
ULONG ExecFromShell(_In_opt_ PCWSTR lpApplicationName,
_Inout_opt_ PWSTR lpCommandLine)
{
if (HWND hwnd = GetShellWindow())
{
ULONG dwProcessId, dwThreadId;
if (dwThreadId = GetWindowThreadProcessId(hwnd, &dwProcessId))
{
if (HANDLE hProcess = OpenProcess(PROCESS_CREATE_PROCESS|READ_CONTROL,
FALSE, dwProcessId))
{
PROCESS_INFORMATION pi;
STARTUPINFOEXW si { sizeof(si)};
SIZE_T s = 0;
ULONG dwError;
__0:
switch (dwError = InitializeProcThreadAttributeList(
si.lpAttributeList, 1, 0, &s) ? NOERROR : GetLastError())
{
case ERROR_INSUFFICIENT_BUFFER:
if (!si.lpAttributeList)
{
si.lpAttributeList = (LPPROC_THREAD_ATTRIBUTE_LIST)alloca(s);
goto __0;
}
break;
case NOERROR:
if (UpdateProcThreadAttribute(si.lpAttributeList, 0,
PROC_THREAD_ATTRIBUTE_PARENT_PROCESS,
&hProcess, sizeof(hProcess), 0, 0))
{
ULONG cb = 0;
SECURITY_ATTRIBUTES sa = { sizeof(sa) };
__1:
switch (GetKernelObjectSecurity(hProcess,
DACL_SECURITY_INFORMATION|LABEL_SECURITY_INFORMATION,
sa.lpSecurityDescriptor, cb, &cb) ? NOERROR : GetLastError())
{
case ERROR_INSUFFICIENT_BUFFER:
if (!sa.lpSecurityDescriptor)
{
sa.lpSecurityDescriptor = alloca(cb);
goto __1;
}
break;
case NOERROR:
if (CreateProcessW(lpApplicationName, lpCommandLine, &sa, &sa,
FALSE, EXTENDED_STARTUPINFO_PRESENT, 0, 0, &si.StartupInfo, &pi))
{
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
}
else
{
dwError = GetLastError();
}
break;
}
}
else
{
dwError = GetLastError();
}
DeleteProcThreadAttributeList(si.lpAttributeList);
break;
}
CloseHandle(hProcess);
return dwError;
}
return GetLastError();
}
}
return ERROR_NOT_FOUND;
}