Home > Software engineering >  Shell Execute From Explorer
Shell Execute From Explorer

Time:09-30

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 the ShellExecute?

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;
}
  • Related