2012-11-26 41 views
0

我正在研究一个应用程序,它将在由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; 
} 
+0

我建议你看看下面的代码:http://code.msdn.microsoft.com/windowsdesktop/CppUACSelfElevation-5bfc52dd,而不是使用Mozilla的开源废话。 – Soonts

回答

1

简称为:

char path[] = "C:\\program.exe"; 
sinfo.lpFile = path; 
+0

当我使用上述行时,出现错误。 – blackDog

+0

类型“字符”不能被设置为键入LPCWSTR – blackDog

+0

好吧,我只是铸造它到LPCWSTR,它工作得很好,谢谢你的帮助 – blackDog