我正在研究一個應用程序,它將在由ShellExecute
打開的任何程序中觸發UAC提示。shell使用C++執行
我不知道如何硬編碼ShellExecute
運行的路徑。截至目前,該程序使用arg[0]
中的任何路徑。我怎樣才能建立一個字符串放在arg[0]
的線上sinfo.lpFile = arg[0];
?
我很新,所以如果你不明白爲什麼把字符串放在那一行會解決我的問題,那麼你很可能是正確的。
#include "stdafx.h"
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <shellapi.h>
#include <process.h>
#include "uac-example.h"
int WINAPI WinMain(HINSTANCE inst, HINSTANCE prevInst,LPSTR cmdLine, int nCmdShow){
LPWSTR *arg;
int argc = 0;
HRESULT ret = SUCCESS;
WCHAR imagePath[MAXPATHLEN];
WCHAR workingDir[MAXPATHLEN];
WCHAR uacDir[MAXPATHLEN];
WCHAR uacRunningLockFilePath[MAXPATHLEN];
HANDLE uacRunningLockFileHandle = INVALID_HANDLE_VALUE;
WCHAR elevatedLockFilePath[MAXPATHLEN];
HANDLE elevatedLockFileHandle = INVALID_HANDLE_VALUE;
arg = CommandLineToArgvW(GetCommandLineW(),&argc);
//if(arg == NULL || argc < 2) {
// ERRORBOX("Missing required program arguments.\n\nUsage:\nuac-example.exe <working directory>");
// return FAILURE;
//}
GetModuleFileName(NULL, imagePath, MAXPATHLEN);
arg[0] = imagePath;
wcscpy_s((wchar_t *)uacDir, MAXPATHLEN, arg[1]);
_snwprintf_s(uacRunningLockFilePath, MAXPATHLEN, MAXPATHLEN,
_T("%s/") _T(RUNNING_LOCK_FILE), uacDir);
wcscpy_s(workingDir, MAXPATHLEN, imagePath);
WCHAR *slash = wcsrchr(workingDir, '\\');
wcscpy_s(slash, MAXPATHLEN, _T(""));
_snwprintf_s(elevatedLockFilePath, MAXPATHLEN, MAXPATHLEN,_T("%s/") _T(ELEVATE_LOCK_FILE), workingDir);
uacRunningLockFileHandle = CreateFileW(uacRunningLockFilePath,(GENERIC_READ | GENERIC_WRITE),0,NULL,OPEN_ALWAYS,FILE_FLAG_DELETE _ON_CLOSE,NULL);
if (uacRunningLockFileHandle == INVALID_HANDLE_VALUE) {
if (_waccess(elevatedLockFilePath, F_OK) == 0 &&
_wremove(elevatedLockFilePath) != 0) {
return FAILURE;
}
elevatedLockFileHandle = CreateFileW(elevatedLockFilePath,(GENERIC_READ | GENERIC_WRITE),0,NULL,OPEN_ALWAYS,FILE_FLAG_DELETE _ON_CLOSE,NULL);
if(elevatedLockFileHandle == INVALID_HANDLE_VALUE){
ERRORBOX("Unable to acquire the necessary permissions to run demo app.");
return FAILURE;
}
LPWSTR spawnCmdLine = BuildCommandLine(argc - 1, arg + 1);
if(!spawnCmdLine){
CloseHandle(elevatedLockFileHandle);
ERRORBOX("An error occured while respawning self.");
return FAILURE;
}
SHELLEXECUTEINFO sinfo;
memset(&sinfo, 0, sizeof(SHELLEXECUTEINFO));
sinfo.cbSize = sizeof(SHELLEXECUTEINFO);
sinfo.fMask = SEE_MASK_FLAG_DDEWAIT | SEE_MASK_NOCLOSEPROCESS;
sinfo.hwnd = NULL;
sinfo.lpFile = arg[0];
sinfo.lpParameters = spawnCmdLine;
sinfo.lpVerb = L"runas"; // <<-- this is what makes a UAC prompt show up
sinfo.nShow = SW_SHOWMAXIMIZED;
BOOL result = ShellExecuteEx(&sinfo);
LocalFree(spawnCmdLine);
if(result){
WaitForSingleObject(sinfo.hProcess, INFINITE);
CloseHandle(sinfo.hProcess);
return SUCCESS;
}else{
return FAILURE;
}
}
EXIT_IF_ELEVATED(elevatedLockFilePath,uacRunningLo ckFileHandle,SUCCESS);
LocalFree(arg);
return SUCCESS;
}
// ----------------------------------------------------------------------
// The following code was taken directly from the Mozilla Firefox Updater
// source tree, and slightly modified to support "Wide" strings in
// Visual C++.
// ----------------------------------------------------------------------
LPWSTR
BuildCommandLine(int argc, LPWSTR *argv){
int i;
int len = 0;
// The + 1 of the last argument handles the
// allocation for null termination
for (i = 0; i < argc; ++i) {
len += ArgStrLen(argv[i]) + 1;
}
// Protect against callers that pass 0 arguments
if (len == 0) {
len = 1;
}
LPWSTR s = (LPWSTR)malloc(len * sizeof(LPWSTR));
if (!s) {
return NULL;
}
LPWSTR c = s;
for (i = 0; i < argc; ++i) {
c = ArgToString(c, argv[i]);
if (i + 1 != argc) {
*c = ' ';
++c;
}
}
*c = '\0';
return s;
}
int
ArgStrLen(LPWSTR s) {
int backslashes = 0;
int i = wcslen(s);
BOOL hasDoubleQuote = wcschr(s, L'"') != NULL;
// Only add doublequotes if the string contains a space or a tab
BOOL addDoubleQuotes = wcspbrk(s, L" \t") != NULL;
if (addDoubleQuotes) {
i += 2; // initial and final duoblequote
}
if (hasDoubleQuote) {
while (*s) {
if (*s == '\\') {
++backslashes;
} else {
if (*s == '"') {
// Escape the doublequote and all backslashes preceding the doublequote
i += backslashes + 1;
}
backslashes = 0;
}
++s;
}
}
return i;
}
LPWSTR
ArgToString(LPWSTR d, LPWSTR s) {
int backslashes = 0;
BOOL hasDoubleQuote = wcschr(s, L'"') != NULL;
// Only add doublequotes if the string contains a space or a tab
BOOL addDoubleQuotes = wcspbrk(s, L" \t") != NULL;
if (addDoubleQuotes) {
*d = '"'; // initial doublequote
++d;
}
if (hasDoubleQuote) {
int i;
while (*s) {
if (*s == '\\') {
++backslashes;
} else {
if (*s == '"') {
// Escape the doublequote and all backslashes\
// preceding the doublequote
for (i = 0; i <= backslashes; ++i) {
*d = '\\';
++d;
}
}
backslashes = 0;
}
*d = *s;
++d; ++s;
}
} else {
wcscpy(d, s);
d += wcslen(s);
}
if (addDoubleQuotes) {
*d = '"'; // final doublequote
++d;
}
return d;
}
我建議你看看下面的代碼:http://code.msdn.microsoft.com/windowsdesktop/CppUACSelfElevation-5bfc52dd,而不是使用Mozilla的開源廢話。 – Soonts