很多时候,有些程序希望它开机自动运行。当然实现的方式有很多种,如:注册表项、开始-程序-启动文件夹、计划任务、系统服务程序等等。
然而,计划任务是一般用户了解最少的一种。并且前两种是很容易修改和通过杀毒软件禁用的。
【This code is Task schedul 1.0 for Win XP】整理来自官网示例: http://msdn.microsoft.com/en-us/library/windows/desktop/aa383581(v=vs.85).aspx
#include <windows.h>
#include
<initguid.h>
#include
<ole2.h>
#include
<mstask.h>
#include
<msterr.h>
#include
<objidl.h>
#include
<wchar.h>
#include
<stdio.h>
void
WGetUserName(WCHAR * username,
int
len)
{
//
Get and display the name of the computer.
char
szName[
255
];
ULONG nLen
=
sizeof
(szName);
::GetUserNameA(szName,
&
nLen);
for
(unsigned
int
i =
0
; i < strlen(szName); i++
)
{
username[i]
=
szName[i];
}
username[strlen(szName)]
=
'
\0
'
;
}
int
main(
int
argc,
char
**
argv)
{
HRESULT hr
=
S_OK;
ITaskScheduler
*
pITS;
///////////////////////////////////////////////////////////////
//
//
Call CoInitialize to initialize the COM library and then
//
call CoCreateInstance to get the Task Scheduler object.
///////////////////////////////////////////////////////////////
//
hr =
CoInitialize(NULL);
if
(SUCCEEDED(hr))
{
hr
=
CoCreateInstance(CLSID_CTaskScheduler,
NULL,
CLSCTX_INPROC_SERVER,
IID_ITaskScheduler,
(
void
**) &
pITS);
if
(FAILED(hr))
{
CoUninitialize();
return
1
;
}
}
else
{
return
1
;
}
///////////////////////////////////////////////////////////////
//
///
Get user name of the computer
///////////////////////////////////////////////////////////////
//
WCHAR username[
512
];
memset(username,
0
,
sizeof
(username));
WGetUserName(username,
sizeof
(username));
///////////////////////////////////////////////////////////////
//
//
Call ITaskScheduler::NewWorkItem to create new task.
///////////////////////////////////////////////////////////////
//
WCHAR pwszTaskName[
512
] = L
"
Veno Server WD_TEST_
"
;
ITask
*
pITask;
wcscat(pwszTaskName, username);
hr
= pITS->NewWorkItem(pwszTaskName,
//
Name of task
CLSID_CTask,
//
Class identifier
IID_ITask,
//
Interface identifier
(IUnknown**)&pITask);
//
Address of task
//
interface
pITS
->Release();
//
Release object
if
(FAILED(hr))
{
CoUninitialize();
fprintf(stderr,
"
Failed calling NewWorkItem, error = 0x%x\n
"
,hr);
return
1
;
}
//////////////////////////////////////////////////////////////////
/
//
Call ITask::SetApplicationName to specify the Application name
//
for Test Task.
//////////////////////////////////////////////////////////////////
/
LPCWSTR pwszApplicationName = L
"
C:\\Windows\\System32\\notepad.exe
"
;
hr
= pITask->
SetApplicationName(pwszApplicationName);
if
(FAILED(hr))
{
wprintf(L
"
Failed calling ITask::SetApplicationName:
"
);
wprintf(L
"
error = 0x%x\n
"
,hr);
pITask
->
Release();
CoUninitialize();
return
1
;
}
////////////////////////////////////////////////////////////
/
//////
set flag Only if logged on
///
//
////////////////////////////////////////////////////////////
/
hr = pITask->
SetFlags(TASK_FLAG_RUN_ONLY_IF_LOGGED_ON);
if
(FAILED(hr))
{
wprintf(L
"
Failed calling ITask::EditWorkItem,
"
);
wprintf(L
"
error = 0x%x\n
"
,hr);
CoUninitialize();
return
1
;
}
////////////////////////////////////////////////////////////
//
set username for only for logged on
hr = pITask->SetAccountInformation( username, NULL);
//
L"NT AUTHORITY\\SYSTEM";
if
(FAILED(hr))
{
wprintf(L
"
Failed calling ITask::SetApplicationName:
"
);
wprintf(L
"
error = 0x%x\n
"
,hr);
pITask
->
Release();
CoUninitialize();
return
1
;
}
//////////////////////////////////////////////////////////////////
/
//
Call ITask::CreateTrigger to create new trigger.
//////////////////////////////////////////////////////////////////
/
ITaskTrigger
*
pITaskTrigger;
WORD piNewTrigger;
hr
= pITask->CreateTrigger(&
piNewTrigger,
&
pITaskTrigger);
if
(FAILED(hr))
{
wprintf(L
"
Failed calling ITask::CreatTrigger:
"
);
wprintf(L
"
error = 0x%x\n
"
,hr);
pITask
->
Release();
CoUninitialize();
return
1
;
}
//////////////////////////////////////////////////////
//
Define TASK_TRIGGER structure. Note that wBeginDay,
//
wBeginMonth, and wBeginYear must be set to a valid
//
day, month, and year respectively.
//////////////////////////////////////////////////////
TASK_TRIGGER pTrigger;
ZeroMemory(
&pTrigger,
sizeof
(TASK_TRIGGER));
//
Add code to set trigger structure?
pTrigger.wBeginDay =
1
;
//
Required
pTrigger.wBeginMonth =
1
;
//
Required
pTrigger.wBeginYear =
1999
;
//
Required
pTrigger.cbTriggerSize =
sizeof
(TASK_TRIGGER);
pTrigger.wStartHour
=
13
;
pTrigger.TriggerType
= TASK_EVENT_TRIGGER_AT_LOGON;
///
TASK_EVENT_TRIGGER_AT_SYSTEMSTART
pTrigger.Type.Daily.DaysInterval =
1
;
//////////////////////////////////////////////////////////////////
/
//
Call ITaskTrigger::SetTrigger to set trigger criteria.
//////////////////////////////////////////////////////////////////
/
hr
= pITaskTrigger->SetTrigger (&
pTrigger);
if
(FAILED(hr))
{
wprintf(L
"
Failed calling ITaskTrigger::SetTrigger:
"
);
wprintf(L
"
error = 0x%x\n
"
,hr);
pITask
->
Release();
pITaskTrigger
->
Release();
CoUninitialize();
return
1
;
}
//////////////////////////////////////////////////////////////////
/
//
Call IPersistFile::Save to save trigger to disk.
//////////////////////////////////////////////////////////////////
/
IPersistFile
*
pIPersistFile;
hr
= pITask->
QueryInterface(IID_IPersistFile,
(
void
**)&
pIPersistFile);
hr
= pIPersistFile->
Save(NULL,
TRUE);
if
(FAILED(hr))
{
wprintf(L
"
Failed calling IPersistFile::Save:
"
);
wprintf(L
"
error = 0x%x\n
"
,hr);
pITask
->
Release();
pITaskTrigger
->
Release();
pIPersistFile
->
Release();
CoUninitialize();
return
1
;
}
wprintf(L
"
The trigger was created and IPersistFile::Save was \n
"
);
wprintf(L
"
called to save the new trigger to disk.\n
"
);
//////////////////////////////////////////////////////////////////
/
//
Release resources.
//////////////////////////////////////////////////////////////////
/
pITask
->
Release();
pITaskTrigger
->
Release();
pIPersistFile
->
Release();
CoUninitialize();
printf(
"
Created task.\n
"
);
return
0
;
}
【The shellexce command is easy for Win 7, and task scheldul 2.0 is also right.】
VOID Win7SchTasks()
{
TCHAR Location[MAX_PATH];
TCHAR cmd[
255
];
DWORD TapLocLen
=
0
;
TapLocLen
= GetCurrentDirectory(
sizeof
(Location),Location);
if
(TapLocLen ==
0
)
{
printf(
"
GetCurrentDirectory failed! Error is %d \n
"
, GetLastError());
return
;
}
char
temp_path[MAX_PATH];
if
(!GetVenoAppPaths(temp_path,
sizeof
(temp_path)))
//这个函数的功能是得到一个可执文件的路径,可以自己写或者给temp_path赋一个指定的值。
{
printf(
"
GetVenoAppPaths failed\n
"
);
return
;
}
sprintf(cmd,
"
/C schtasks /Create /tn \"Veno Server WD\" /tr \"\'%s\'\" /sc onlogon /rl HIGHEST /F
"
, temp_path);
SHELLEXECUTEINFO sei;
ZeroMemory (
&sei,
sizeof
(SHELLEXECUTEINFO));
sei.cbSize
=
sizeof
(SHELLEXECUTEINFO);
sei.lpVerb
=
"
OPEN
"
;
sei.lpFile
=
"
cmd.exe
"
;
sei.lpParameters
=
cmd;
sei.nShow
=
SW_HIDE;
sei.fMask
=
SEE_MASK_NOCLOSEPROCESS;
ShellExecuteEx(
&
sei);
WaitForSingleObject(sei.hProcess, INFINITE);
printf(
"
Write SchTasks Complete\r\n
"
);
return
;
}
因为在win XP 下ShellExecuteEx 是需要密码才能自动启动,它没有2.0开机启动的命令。而win7 有,所以这个用起来方便点,不过也因此带来其它问题,比如要重复执行,就要先删除再建。

