От: http://go.microsoft.com/fwlink/?LinkId=81232
Часто задаваемый вопрос в том, как запустить маркированные повышенные приложения от повышенного процесс, или более принципиально, как я запускаю процесс с использованием моего не поднятого токена после того, как я выполняю повышение. Поскольку нет прямого способа сделать это, ситуацию обычно можно избежать путем запуска исходного приложения в качестве стандартного пользователя и только подъемного тех частей приложения, которые требуют прав администратора. Этот способ всегда имеет невыполненный процесс , который можно использовать для запуска дополнительных приложений , поскольку в настоящее время вошел в систему на рабочем столе пользователя. Иногда, однако, при повышенном процессе необходимо получить еще одно приложение , работающее не приподнятое. Этот может быть выполнен с использованием планировщика задачи в Windows Vista. Приостановленный процесс может зарегистрировать задачу для запуска в качестве текущего пользователя .
Ниже приведен пример того, как планировать процесс не-повышенным (опять-таки из той же ссылки)
//---------------------------------------------------------------------
// This file is part of the Microsoft .NET Framework SDK Code Samples.
//
// Copyright (C) Microsoft Corporation. All rights reserved.
//
//This source code is intended only as a supplement to Microsoft
//Development Tools and/or on-line documentation. See these other
//materials for detailed information regarding Microsoft code samples.
//
//THIS CODE AND INFORMATION ARE PROVIDED AS IS WITHOUT WARRANTY OF ANY
//KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
//IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
//PARTICULAR PURPOSE.
//---------------------------------------------------------------------
/****************************************************************************
* Main.cpp - Sample application for Task Scheduler V2 COMAPI * Component: Task Scheduler
* Copyright (c) 2002 - 2003, Microsoft Corporation
* This sample creates a task to that launches as the currently logged on deskup user. The task launches as soon as it is registered. *
****************************************************************************/
#include "stdafx.h"
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <comdef.h>
#include <comutil.h>
//Include Task header files - Included in Windows Vista Beta-2 SDK from MSDN
#include <taskschd.h>
#include <conio.h>
#include <iostream>
#include <time.h>
using namespace std;
#define CLEANUP \
pRootFolder->Release();\
pTask->Release();\
CoUninitialize();
HRESULT CreateMyTask(LPCWSTR, wstring);
void __cdecl wmain(int argc, wchar_t** argv)
{
wstring wstrExecutablePath;
WCHAR taskName[20];
HRESULT result;
if(argc < 2)
{
printf("\nUsage: LaunchApp yourapp.exe");
return;
}
// Pick random number for task name
srand((unsigned int) time(NULL));
wsprintf((LPWSTR)taskName, L"Launch %d", rand());
wstrExecutablePath = argv[1];
result = CreateMyTask(taskName, wstrExecutablePath);
printf("\nReturn status:%d\n", result);
}
HRESULT CreateMyTask(LPCWSTR wszTaskName, wstring wstrExecutablePath)
{
// ------------------------------------------------------
// Initialize COM.
TASK_STATE taskState;
int i;
HRESULT hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
if(FAILED(hr))
{
printf("\nCoInitializeEx failed: %x", hr);
return 1;
}
// Set general COM security levels.
hr = CoInitializeSecurity(
NULL,
-1,
NULL,
NULL,
RPC_C_AUTHN_LEVEL_PKT_PRIVACY,
RPC_C_IMP_LEVEL_IMPERSONATE,
NULL,
0,
NULL);
if(FAILED(hr))
{
printf("\nCoInitializeSecurity failed: %x", hr);
CoUninitialize();
return 1;
}
// ------------------------------------------------------
// Create an instance of the Task Service.
ITaskService *pService = NULL;
hr = CoCreateInstance(CLSID_TaskScheduler,
NULL,
CLSCTX_INPROC_SERVER,
IID_ITaskService,
(void**)&pService);
if (FAILED(hr))
{
printf("Failed to CoCreate an instance of the TaskService class: %x", hr);
CoUninitialize();
return 1;
}
// Connect to the task service.
hr = pService->Connect(_variant_t(), _variant_t(), _variant_t(), _variant_t());
if(FAILED(hr))
{
printf("ITaskService::Connect failed: %x", hr);
pService->Release();
CoUninitialize();
return 1;
}
// ------------------------------------------------------
// Get the pointer to the root task folder. This folder will hold the
// new task that is registered.
ITaskFolder *pRootFolder = NULL;
hr = pService->GetFolder(_bstr_t(L"\\") , &pRootFolder);
if(FAILED(hr))
{
printf("Cannot get Root Folder pointer: %x", hr);
pService->Release();
CoUninitialize();
return 1;
}
// Check if the same task already exists. If the same task exists, remove it.
hr = pRootFolder->DeleteTask(_bstr_t(wszTaskName), 0 );
// Create the task builder object to create the task.
ITaskDefinition *pTask = NULL;
hr = pService->NewTask(0, &pTask);
pService->Release(); // COM clean up. Pointer is no longer used.
if (FAILED(hr))
{
printf("Failed to CoCreate an instance of the TaskService class: %x", hr);
pRootFolder->Release();
CoUninitialize();
return 1;
}
// ------------------------------------------------------
// Get the trigger collection to insert the registration trigger.
ITriggerCollection *pTriggerCollection = NULL;
hr = pTask->get_Triggers(&pTriggerCollection);
if(FAILED(hr))
{
printf("\nCannot get trigger collection: %x", hr);
CLEANUP
return 1;
}
// Add the registration trigger to the task.
ITrigger *pTrigger = NULL;
hr = pTriggerCollection->Create(TASK_TRIGGER_REGISTRATION, &pTrigger);
pTriggerCollection->Release(); // COM clean up. Pointer is no longer used.
if(FAILED(hr))
{
printf("\nCannot add registration trigger to the Task %x", hr);
CLEANUP
return 1;
}
pTrigger->Release();
// ------------------------------------------------------
// Add an Action to the task.
IExecAction *pExecAction = NULL;
IActionCollection *pActionCollection = NULL;
// Get the task action collection pointer.
hr = pTask->get_Actions(&pActionCollection);
if(FAILED(hr))
{
printf("\nCannot get Task collection pointer: %x", hr);
CLEANUP
return 1;
}
// Create the action, specifying that it is an executable action.
IAction *pAction = NULL;
hr = pActionCollection->Create(TASK_ACTION_EXEC, &pAction);
pActionCollection->Release(); // COM clean up. Pointer is no longer used.
if(FAILED(hr))
{
printf("\npActionCollection->Create failed: %x", hr);
CLEANUP
return 1;
}
hr = pAction->QueryInterface(IID_IExecAction, (void**) &pExecAction);
pAction->Release();
if(FAILED(hr))
{
printf("\npAction->QueryInterface failed: %x", hr);
CLEANUP
return 1;
}
// Set the path of the executable to the user supplied executable.
hr = pExecAction->put_Path(_bstr_t(wstrExecutablePath.c_str()));
if(FAILED(hr))
{
printf("\nCannot set path of executable: %x", hr);
pExecAction->Release();
CLEANUP
return 1;
}
hr = pExecAction->put_Arguments(_bstr_t(L""));
if(FAILED(hr))
{
printf("\nCannot set arguments of executable: %x", hr);
pExecAction->Release();
CLEANUP
return 1;
}
// ------------------------------------------------------
// Save the task in the root folder.
IRegisteredTask *pRegisteredTask = NULL;
hr = pRootFolder->RegisterTaskDefinition(
_bstr_t(wszTaskName),
pTask,
TASK_CREATE,
_variant_t(_bstr_t(L"S-1-5-32-545")),//Well Known SID for \\Builtin\Users group
_variant_t(),
TASK_LOGON_GROUP,
_variant_t(L""),
&pRegisteredTask);
if(FAILED(hr))
{
printf("\nError saving the Task : %x", hr);
CLEANUP
return 1;
}
printf("\n Success! Task successfully registered. ");
for (i=0; i<100; i++)//give 10 seconds for the task to start
{
pRegisteredTask->get_State(&taskState);
if (taskState == TASK_STATE_RUNNING)
{
printf("\nTask is running\n");
break;
}
Sleep(100);
}
if (i>= 100) printf("Task didn't start\n");
//Delete the task when done
hr = pRootFolder->DeleteTask(
_bstr_t(wszTaskName),
NULL);
if(FAILED(hr))
{
printf("\nError deleting the Task : %x", hr);
CLEANUP
return 1;
}
printf("\n Success! Task successfully deleted. ");
// Clean up.
CLEANUP
CoUninitialize();
return 0;
}
детали, включая примеры кода, здесь: http://blogs.msdn.com/b/aaron_margosis/archive/2009/06/06/faq-how-do-i-start-a-program- as-the-desktop-user-from-an-elevated-app.aspx – 2012-11-29 23:43:44
любое окончательное решение с полным образцом исходного кода, работающим над этим? – Kiquenet 2013-07-10 09:03:31
Принятый ответ работал на меня в то время. – idstam 2013-07-24 07:41:39