0

我正在开发一个应用程序,该应用程序将在打开的任何程序中触发 UAC 提示ShellExecute

我不知道如何硬编码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;
}
4

1 回答 1

1

简单来说:

char path[] = "C:\\program.exe";
sinfo.lpFile = path;
于 2012-11-27T00:02:29.553 回答