我們有一個以管理員權限運行的應用程式,其中(除了實際需要管理員權限的其他操作)用戶可以發送電子郵件。
我們的電子郵件系統是這樣作業的:管理員運行的應用程式預編譯電子郵件欄位并啟動(通過CreateProcess)我們呼叫實際電子郵件發送的電子郵件應用程式。如果電子郵件完整且準備就緒,它將直接發送,否則將顯示 Outlook 電子郵件表單,讓用戶填寫缺失的欄位并發送。
我們的電子郵件應用程式用于TJclEmail處理電子郵件發送和顯示 Outlook 電子郵件表單。我的問題是:如果 Outlook 未以管理員身份運行,電子郵件應用程式將不會顯示 Outlook 電子郵件表單,我猜是因為它是從管理員運行的應用程式呼叫的,因此它繼承了權限。由于 Outlook 幾乎從未以管理員身份運行,因此我想找到一種以CreateProcess普通用戶權限呼叫的方法,即從呼叫者那里繼承管理員權限。
有沒有辦法這樣做?
uj5u.com熱心網友回復:
Per如何從提升的流程中啟動未提升的流程,反之亦然?:
從未提升的流程到提升的流程很容易。
runas您可以通過將動詞傳遞給Shell-Executeor來運行具有提升的行程Shell-Execute-Ex。走另一條路更棘手。一方面,要正確洗掉高程特性確實很難使用您的令牌。還有一件事,即使你能做到,也不是正確的做法,因為未提升的用戶可能與提升的用戶不同。
...
這里的解決方案是回傳 Explorer 并要求 Explorer 為您啟動程式。由于 Explorer 以原始未提升用戶身份運行,因此程式(在本例中為 Web 瀏覽器)將以 Bob 身份運行。這在您要打開的檔案的處理程式作為行程內擴展而不是作為單獨行程運行的情況下也很重要,因為在這種情況下,取消提升的嘗試將毫無意義,因為沒有創建新行程第一名。(如果檔案的處理程式試圖與自身的現有未提升副本通信,則可能會因為 UIPI 而失敗。)
然后文章繼續展示了一個示例,該示例獲取桌面的IShellFolderViewDual界面,并從中獲取一個IShellDispatch2界面,然后IShellDispatch2::ShellExecute()以登錄用戶的身份呼叫以執行新行程(這與 MSDN 上提供的示例基本相同:在資源管理器中執行樣品):
#define STRICT
#include <windows.h>
#include <shldisp.h>
#include <shlobj.h>
#include <exdisp.h>
#include <atlbase.h>
#include <stdlib.h>
void FindDesktopFolderView(REFIID riid, void **ppv)
{
CComPtr<IShellWindows> spShellWindows;
spShellWindows.CoCreateInstance(CLSID_ShellWindows);
CComVariant vtLoc(CSIDL_DESKTOP);
CComVariant vtEmpty;
long lhwnd;
CComPtr<IDispatch> spdisp;
spShellWindows->FindWindowSW(
&vtLoc, &vtEmpty,
SWC_DESKTOP, &lhwnd, SWFO_NEEDDISPATCH, &spdisp);
CComPtr<IShellBrowser> spBrowser;
CComQIPtr<IServiceProvider>(spdisp)->
QueryService(SID_STopLevelBrowser,
IID_PPV_ARGS(&spBrowser));
CComPtr<IShellView> spView;
spBrowser->QueryActiveShellView(&spView);
spView->QueryInterface(riid, ppv);
}
void GetDesktopAutomationObject(REFIID riid, void **ppv)
{
CComPtr<IShellView> spsv;
FindDesktopFolderView(IID_PPV_ARGS(&spsv));
CComPtr<IDispatch> spdispView;
spsv->GetItemObject(SVGIO_BACKGROUND, IID_PPV_ARGS(&spdispView));
spdispView->QueryInterface(riid, ppv);
}
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));
}
int __cdecl wmain(int argc, wchar_t **argv)
{
if (argc < 2) return 0;
CCoInitialize init;
ShellExecuteFromExplorer(
argv[1],
argc >= 3 ? argv[2] : L"",
argc >= 4 ? argv[3] : L"",
argc >= 5 ? argv[4] : L"",
argc >= 6 ? _wtoi(argv[5]) : SW_SHOWNORMAL);
return 0;
}
并且根據我如何從我的提升行程 redux 啟動一個未提升的行程:
還有另一種更直接的方式,但它假定您想要做的事情可以通過直接
Create-Process呼叫來完成。換句話說,如果您需要系統查找用戶的檔案關聯或默認瀏覽器,那么此技術不適合您。這個想法是利用
PROCESS_CREATE_PROCESS訪問和伴隨的PROC_THREAD_ATTRIBUTE_PARENT_PROCESS行程執行緒屬性...
Basically, this lets you tell the
Create-Processfunction, "Hey, like, um, pretend that other guy over there is creating the process."
And here is the example from that article:
int main(int, char**)
{
HWND hwnd = GetShellWindow();
DWORD pid;
GetWindowThreadProcessId(hwnd, &pid);
HANDLE process =
OpenProcess(PROCESS_CREATE_PROCESS, FALSE, pid);
SIZE_T size;
InitializeProcThreadAttributeList(nullptr, 1, 0, &size);
auto p = (PPROC_THREAD_ATTRIBUTE_LIST)new char[size];
InitializeProcThreadAttributeList(p, 1, 0, &size);
UpdateProcThreadAttribute(p, 0,
PROC_THREAD_ATTRIBUTE_PARENT_PROCESS,
&process, sizeof(process),
nullptr, nullptr);
wchar_t cmd[] = L"C:\\Windows\\System32\\cmd.exe";
STARTUPINFOEX siex = {};
siex.lpAttributeList = p;
siex.StartupInfo.cb = sizeof(siex);
PROCESS_INFORMATION pi;
CreateProcessW(cmd, cmd, nullptr, nullptr, FALSE,
CREATE_NEW_CONSOLE | EXTENDED_STARTUPINFO_PRESENT,
nullptr, nullptr, &siex.StartupInfo, &pi);
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
delete[] (char*)p;
CloseHandle(process);
return 0;
}
This program runs a copy of
cmd.exeusing the shell process (usuallyexplorer.exe) as its parent, which means that if the shell process is unelevated, then so too will thecmd.exeprocess. Of course, if the user is an administrator and has disabled UAC, then Explorer will still be elevated, and so too will be thecmd.exe. But in that case, the user wants everything to run elevated, so you’re just following the user's preferences.
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/456515.html
標籤:电子邮件 德尔福 温纳皮 delphi-xe3 创建过程
