C++ 登录任务计划错误:未完成帐户名称和安全 ID 之间的映射

问题描述 投票:0回答:2

我正在尝试在 Windows 7 上使用 C++ 编写一个 Windows 登录触发任务。

我正在关注这个微软教程

但是我在将任务保存到根文件夹时遇到问题。 这里:

//  ------------------------------------------------------
    //  Save the task in the root folder.
    IRegisteredTask *pRegisteredTask = NULL;

    hr = pRootFolder->RegisterTaskDefinition(
            _bstr_t( wszTaskName ),
            pTask,
            TASK_CREATE_OR_UPDATE, 
            _variant_t(L"Builtin\\Administrators"), 
            _variant_t(), 
            TASK_LOGON_GROUP,
            _variant_t(L""),
            &pRegisteredTask);

hr
出现错误:帐户名称和安全 ID 之间未进行映射

我还尝试用

_variant_t(L"Builtin\\Administrators")
替换
_variant_t(L"S-1-5-32-544")
以 NULL 消除语言硬编码问题,但仍然没有运气。

我怎样才能让它发挥作用?

c++ windows winapi scheduled-tasks
2个回答
6
投票

在 Windows 启动时创建任务计划程序任务的最终解决方案

(具有管理员权限,适用于 Windows 7、8 等。请注意,这不会在 Windows 启动时显示 UAC 弹出窗口“您确定以管理员权限运行此软件吗?”,这就是为什么任务计划程序方法更在这种情况下比旧的 HKEY_LOCAL_MACHINE\...\CurrentVersion\Run 解决方案更有趣)

本教程中有一些需要更新的内容 使其发挥作用:

  • _variant_t(L"S-1-5-32-544")
    而不是
    _variant_t(L"Builtin\\Administrators")
    
    
  • _CRT_SECURE_NO_WARNINGS
  • 在 VC++ 中,项目属性 > 配置属性 > 链接器 > 清单文件 > UAC 执行级别 > requireAdministrator
  • 删除现已过时的日期界限!
  • 用硬编码的域\用户名或某些
  • 域\用户名检测代码
    替换
    hr = pLogonTrigger->put_UserId(_bstr_t(L"DOMAIN\\UserName"));(我无法使其工作),或者只需注释此行,它对我有用!
  • 添加一些代码
  • TASK_RUNLEVEL_HIGHEST
    
    
  • 添加一些代码以启用任务
  • 即使从使用电池的笔记本电脑运行(默认为“如果使用电池则不要运行任务”!),以及一些代码以防止 .exe 一段时间后被杀死( 默认情况下,任务开始运行72小时后会停止)等
然后你就会得到著名的:

成功!任务注册成功。


唷!经过每天几个小时和一些编辑,现在这是一个完整的工作

main.cpp

#define SECURITY_WIN32 #include <windows.h> #include <iostream> #include <stdio.h> #include <comdef.h> #include <Security.h> #include <taskschd.h> #pragma comment(lib, "taskschd.lib") #pragma comment(lib, "comsupp.lib") using namespace std; #define TASKNAME L"Logon Trigger Test Task" int __cdecl wmain() { // Get the windows directory and set the path to notepad.exe. wstring wstrExecutablePath = _wgetenv(L"WINDIR"); wstrExecutablePath += L"\\SYSTEM32\\NOTEPAD.EXE"; // Initialize COM HRESULT hr = CoInitializeEx(NULL, COINIT_MULTITHREADED); if (FAILED(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)) goto cleanup0; // 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)) goto cleanup0; // Connect to the task service. hr = pService->Connect(_variant_t(), _variant_t(), _variant_t(), _variant_t()); if (FAILED(hr)) goto cleanup1; // 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)) goto cleanup1; // If the same task exists, remove it. pRootFolder->DeleteTask(_bstr_t(TASKNAME), 0); // Create the task builder object to create the task. ITaskDefinition *pTask = NULL; hr = pService->NewTask(0, &pTask); // COM clean up. Pointer is no longer used. pService->Release(); if (FAILED(hr)) { pRootFolder->Release(); CoUninitialize(); return 1; } // Get the registration info for setting the identification. IRegistrationInfo *pRegInfo = NULL; hr = pTask->get_RegistrationInfo(&pRegInfo); if (FAILED(hr)) goto cleanup2; hr = pRegInfo->put_Author(L"Author Name"); pRegInfo->Release(); if (FAILED(hr)) goto cleanup2; // Create the settings for the task ITaskSettings *pSettings = NULL; hr = pTask->get_Settings(&pSettings); if (FAILED(hr)) goto cleanup2; // Set setting values for the task. pSettings->put_DisallowStartIfOnBatteries(VARIANT_FALSE); pSettings->put_StopIfGoingOnBatteries(VARIANT_FALSE); pSettings->put_ExecutionTimeLimit(_bstr_t(L"PT0S")); pSettings->Release(); if (FAILED(hr)) goto cleanup2; // Get the trigger collection to insert the logon trigger. ITriggerCollection *pTriggerCollection = NULL; hr = pTask->get_Triggers(&pTriggerCollection); if (FAILED(hr)) goto cleanup2; // Add the logon trigger to the task. ITrigger *pTrigger = NULL; hr = pTriggerCollection->Create(TASK_TRIGGER_LOGON, &pTrigger); pTriggerCollection->Release(); if (FAILED(hr)) goto cleanup2; ILogonTrigger *pLogonTrigger = NULL; hr = pTrigger->QueryInterface(IID_ILogonTrigger, (void**)&pLogonTrigger); pTrigger->Release(); if (FAILED(hr)) goto cleanup2; hr = pLogonTrigger->put_Id(_bstr_t(L"Trigger1")); if (FAILED(hr)) goto cleanup2; // Define the user. The task will execute when the user logs on. The specified user must be a user on this computer. //hr = pLogonTrigger->put_UserId(_bstr_t(L"DOMAIN\\UserName")); pLogonTrigger->Release(); if (FAILED(hr)) goto cleanup2; IPrincipal *pPrincipal; hr = pTask->get_Principal(&pPrincipal); if (FAILED(hr)) goto cleanup2; hr = pPrincipal->put_RunLevel(TASK_RUNLEVEL_HIGHEST); if (FAILED(hr)) goto cleanup2; // Add an Action to the task. This task will execute .exe IActionCollection *pActionCollection = NULL; // Get the task action collection pointer. hr = pTask->get_Actions(&pActionCollection); if (FAILED(hr)) goto cleanup2; // Create the action, specifying that it is an executable action. IAction *pAction = NULL; hr = pActionCollection->Create(TASK_ACTION_EXEC, &pAction); pActionCollection->Release(); if (FAILED(hr)) goto cleanup2; // QI for the executable task pointer. IExecAction *pExecAction = NULL; hr = pAction->QueryInterface(IID_IExecAction, (void**)&pExecAction); pAction->Release(); if (FAILED(hr)) goto cleanup2; // Set the path of the executable. hr = pExecAction->put_Path(_bstr_t(wstrExecutablePath.c_str())); pExecAction->Release(); if (FAILED(hr)) goto cleanup2; // Save the task in the root folder. IRegisteredTask *pRegisteredTask = NULL; hr = pRootFolder->RegisterTaskDefinition(_bstr_t(TASKNAME), pTask, TASK_CREATE_OR_UPDATE, _variant_t(L"S-1-5-32-544"), _variant_t(), TASK_LOGON_GROUP, _variant_t(L""), &pRegisteredTask); //_variant_t(L"Builtin\\Administrators"), if (FAILED(hr)) goto cleanup2; printf("Success! Task successfully registered."); getchar(); pRootFolder->Release(); pTask->Release(); pRegisteredTask->Release(); CoUninitialize(); return 0; cleanup0: CoUninitialize(); return 1; cleanup1: pService->Release(); CoUninitialize(); return 1; cleanup2: pRootFolder->Release(); pTask->Release(); CoUninitialize(); return 1; }
    

2
投票
我怀疑您的演示代码是 XP 时代的,并且尚未更新以匹配 Vista/Win7 规则。

我在设置登录触发器后更新了示例以设置 LUA 设置,它似乎有效:

hr = pLogonTrigger->put_UserId(_bstr_t(L"DOMAIN\username")); if (FAILED(hr)) { printf("\nCannot add user ID to logon trigger: %x", hr); CoUninitialize(); return 1; } //*** NEW**** Set the LUA settings CComPtr<IPrincipal> pPrincipal; hr = pTask->get_Principal(&pPrincipal); if (SUCCEEDED(hr)) { hr = pPrincipal->put_RunLevel(TASK_RUNLEVEL_LUA); } if (SUCCEEDED(hr)) { hr = pPrincipal->put_GroupId(_bstr_t(L"Builtin\\Administrators")); } if (FAILED(hr)) { printf("\nCannot set runlevel/groupid: %x", hr); CoUninitialize(); return 1; }

如果您需要它在 XP 上运行,那么

get_Principal

 调用很可能会失败,因此请忽略该失败。

© www.soinside.com 2019 - 2024. All rights reserved.