A. 如何将自己的程序做成windows服务
1、安装自己的软件,我们把软件安装到“C:\Program Files (x86)\***\”这个目录下。
2、下载Instsrv.exe和Srvany.exe。Instsrv.exe可以给系统安装和删除服务,Srvany.exe可以让程序以服务的方式运行。
2、将Instsrv.exe和Srvany.exe放置到某目录下,我们把它们保存在“C:\Program Files (x86)\***\”目录下。
3、打开CMD,输入以下内容:
"C:\Program Files (x86)\***\instsrv.exe" 服务名 "C:\ProgramFiles (x86)\***\srvany.exe"
回车后,如果没有错误就会出现如下所示的成功提示:
注意:服务名可以自己定义。上述即使cd到instsrv.exe或srvany.exe所在目录,也需要写instsrv.exe或srvany.exe文件的绝对路径而不能用相对路径,否则会出现如下错误:
The fully qualified path to the .EXE must be given
4、打开regedit注册表编辑器,找到以下目录:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\服务名
如下图所示:
5、鼠标右键单击<ServerName>,创建一个"项",名称为"Parameters"。如下图:
6、鼠标左键单击"Parameters",在右边点击鼠标右键,创建一个"字符串值"(REG_SZ),名称为"Application",数值数据里填写你要执行的程序完整路径。也就是要填上:
C:\Program Files (x86)***\***.exe
如下图所示:
7、鼠标左键单击"Parameters",在右边点击鼠标右键,创建一个"字符串值"(REG_SZ),名称为"AppDirectory",数值数据里填写你要执行的程序的所在目录的路径。
也就是要填上:
C:\Program Files (x86)***\
打开services.msc服务或控制面板,可以看到<ServerName>已经存在了。
鼠标右键-属性-登陆,勾选"允许服务与桌面交互"(一般你要运行的程序都是有界面的吧)。(这个不起作用,本人试过,界面无法出现,貌似服务不支持带界面的)
严格执行上面的步骤,再次开机后;不需要登录软件即可运行起来。
B. 如何编写windows服务程序
Windows提供了一套后台服务程序编程接口,用户在编写后台服务程序时需要遵循一定的编程框架,否则服务程序不能正常运行。
服务程序通常编写成控制台类型的应用程序,总的来说,一个遵守服务控制管理程序接口要求的程序 包含下面三个函数:
1)服务程序主函数(main):调用系统函数 StartServiceCtrlDispatcher 连接程序主线程到服务控制管理程序。
和其它进程一样,Main函数是服务进程的入口函数,服务控制管理器(SCM)在启动服务程序时,会从服务程序的main函数开始执行。在进入点函数里面要完成ServiceMain的初始化,准确点说是初始化一个SERVICE_TABLE_ENTRY结构数组,这个结构记录了这个服务程序里面所包含的所有服务的名称和服务的进入点函数。然后再调用接口StartServiceCtrlDispatcher 。
Main函数的函数框架如下:
int _tmain(int argc, _TCHAR* argv[])
{
//服务入口点函数表
SERVICE_TABLE_ENTRY dispatchTable[]=
{
{TEXT(SZSERVICENAME),(LPSERVICE_MAIN_FUNCTION)Service_Main},
{ NULL,NULL}
};
if((argc>1)&&((*argv[1]==‘-‘)||(argv[1]=="/")))
{
/*
参数个数大于1是安装或者删除服务,该操作是由用户来执行的
当然也可以讲这一部分功能另写一个程序来实现
*/
if(_stricmp("install",argv[1]+1)==0)
{
installService();
}
else if(_stricmp("remove",argv[1]+1)==0)
{
removeService();
}
else if(_stricmp("debug",argv[1]+1)==0)
{
bDebugServer=true;
debugService(argc,argv);
}
}
else
{
/*
如果未能和上面的如何参数匹配,则可能是服务控制管理程序来启动该程序。 立即调用StartServiceCtrlDispatcher 函数
*/
g_logout.Logout("%s\n", "enter StartServiceCtrlDispatcher...");
//通知服务管理器为每一个服务创建服务线程
if(!StartServiceCtrlDispatcher(dispatchTable))
g_logout.Logout("%s\n", "StartServiceCtrlDispatcher failed.");
else
g_logout.Logout("%s\n", "StartServiceCtrlDispatcher OK.");
}
return 0;
}
SCM启动一个服务程序之后,它会等待该程序的主线程去调StartServiceCtrlDispatcher。如果那个函数在两分钟内没有被调用,SCM将会认为这个服务有问题,并调用TerminateProcess去杀死这个进程。这就要求你的主线程要尽可能快的调用StartServiceCtrlDispatcher。
2)服务入口点函数(ServiceMain):执行服务初始化任务,同时执行多个服务的服务进程有多个服务入口函数。
在服务入口函数里,必须立即注册服务控制回调函数。然后调用函数SetServiceStatus 通知SCM 服务现在的状态,否则SCM会认为服务启动失败。
ServiceMain函数框架如下:
void WINAPI Service_Main(Dword dwArgc, LPTSTR *lpszArgv)
{
//注册服务控制处理函数
sshStatusHandle=RegisterServiceCtrlHandler(TEXT(SZSERVICENAME),Service_Ctrl);
//如果注册失败
if(!sshStatusHandle)
{
g_logout.Logout("%s\n", "RegisterServiceCtrlHandler failed...");
return;
}
//初始化 SERVICE_STATUS 结构中的成员
ssStatus.dwServiceType=SERVICE_WIN32_OWN_PROCESS; //可执行文件中只有一个单独的服务
ssStatus.dwServiceSpecificExitCode=0;
ssStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP; //允许用SCP去停止该服务
//更新服务状态
if(ReportStatusToSCMgr(SERVICE_START_PENDING,//服务状态,服务仍在初始化
NO_ERROR,
3000)) //等待时间
SvcInit( dwArgc, lpszArgv ); //服务初始化函数
else
g_logout.Logout("%s\n", "ReportStatusToSCMgr SERVICE_START_PENDING failed...");
}
服务初始化函数SvcInit:
该函数的写法比较重要。在函数中创建一个等待事件,然后一直等待该事件。该线程在服务接到请求之前一直处于挂起状态,直到接到服务停止消息。
VOID SvcInit( DWORD dwArgc, LPTSTR *lpszArgv)
{
/*创建事件*/
ghSvcStopEvent = CreateEvent(
NULL, // default security attributes
TRUE, // manual reset event
FALSE, // not signaled
NULL); // no name
if ( ghSvcStopEvent == NULL)
{
ReportSvcStatus( SERVICE_STOPPED, NO_ERROR, 0 );
return;
}
// Report running status when initialization is complete.
ReportSvcStatus( SERVICE_RUNNING, NO_ERROR, 0 );
// 在这里执行服务线程的创建...
while(1)
{
// 等待停止事件被触发
WaitForSingleObject(ghSvcStopEvent, INFINITE);
ReportSvcStatus( SERVICE_STOPPED, NO_ERROR, 0 );
return;
}
}
3)控制服务处理程序函数(Handler):在服务程序收到控制请求时由控制分发线程引用。(此处是Service_Ctrl)。
void WINAPI Service_Ctrl(DWORD dwCtrlCode)
{
//处理控制请求码
switch(dwCtrlCode)
{
//先更新服务状态为 SERVICDE_STOP_PENDING,再停止服务。
case SERVICE_CONTROL_STOP:
ReportStatusToSCMgr(SERVICE_STOP_PENDING,NO_ERROR,500);
ServiceStop(); //由具体的服务程序实现
/*ssStatus.dwCurrentState=SERVICE_STOPPED;*/
//其它控制请求...
default:
break;
}
}
3. 注意事项
1)安装服务可以另写一个程序,也可以并在服务程序当中,比较简单,这里就不介绍了。
2)服务初始化函数SvcInit里创建等待事件比较重要,在服务接收到服务停止消息后,触发该事件。
3)Service_Main在等待事件触发后立即返回,服务进程就会退出了
C. 濡備綍缂栧啓windows鏈嶅姟绋嬪簭
濡備綍缂栧啓windows鏈嶅姟绋嬪簭
By:寮犻箯/Hikvision
杩欎袱澶╂兂瀛︿範鍏充簬濡備綍缂栧啓windows鏈嶅姟绋嬪簭鐨勭煡璇嗭紝灏变笂缃戞煡浜嗕簺璧勬枡銆傜湅浜嗕竴绡囨枃绔犮婄敤C 璇瑷缂栧啓Windows 鏈嶅姟绋嬪簭鐨勪簲涓姝ラゃ嬨備絾鍙鑳界敱浜庤瘧鑰呯殑鐤忓拷锛屽繕璁颁簡灏嗗叧閿浠g爜鏀惧叆璇ユ枃妗o紝瀵艰嚧鍒濆﹁呭彲鑳戒細鐪嬩笉鎳傘傛墍浠ュ張鏌ラ槄浜嗙浉鍏宠祫鏂欍傝嚜宸卞畬鎴愪簡銆婄敤C 璇瑷缂栧啓Windows 鏈嶅姟绋嬪簭鐨勪簲涓姝ラゃ嬩腑鐨勬牱渚嬬▼搴忋
鍦ㄦ湰鏂囦腑鎴戝笇鏈涜兘缁欏垵瀛﹁呬竴浜涘府鍔╋紝澶ц嚧璁蹭竴涓嬬紪鍐檞indows鏈嶅姟绋嬪簭闇瑕佺殑鐭ヨ瘑銆
棣栧厛Microsoft Windows 鏈嶅姟锛堝嵆锛屼互鍓嶇殑 NT 鏈嶅姟锛変娇鎮ㄨ兘澶熷垱寤哄湪瀹冧滑鑷宸辩殑 Windows 浼氳瘽涓鍙闀挎椂闂磋繍琛岀殑鍙鎵ц屽簲鐢ㄧ▼搴忋傝繖浜涙湇鍔″彲浠ュ湪璁$畻鏈哄惎鍔ㄦ椂鑷鍔ㄥ惎鍔锛屽彲浠ユ殏鍋滃拰閲嶆柊鍚鍔ㄨ屼笖涓嶆樉绀轰换浣曠敤鎴风晫闈銆傝繖浣挎湇鍔¢潪甯搁傚悎鍦ㄦ湇鍔″櫒涓婁娇鐢锛屾垨浠讳綍鏃跺欙紝涓轰簡涓嶅奖鍝嶅湪鍚屼竴鍙拌$畻鏈轰笂宸ヤ綔鐨勫叾浠栫敤鎴凤紝闇瑕侀暱鏃堕棿杩愯屽姛鑳芥椂浣跨敤銆傝繕鍙浠ュ湪涓嶅悓浜庣櫥褰曠敤鎴风殑鐗瑰畾鐢ㄦ埛甯愭埛鎴栭粯璁よ$畻鏈哄笎鎴风殑瀹夊叏涓婁笅鏂囦腑杩愯屾湇鍔°
鏈嶅姟鏄鏈夌姸鎬佺殑锛屽綋鎴戜滑浣跨敤windows鑷甯︾殑鏈嶅姟绠$悊绋嬪簭sc.exe鏌ョ湅鏈嶅姟鐘舵佹椂鍙浠ユ樉绀烘湇鍔$殑褰撳墠鐘舵侊紝杩欎釜鐘舵佹槸鐢辨垜浠鍦ㄧ▼搴忎唬鐮佷腑杩涜屾帶鍒剁殑銆備綘鏈濂藉湪鏈嶅姟鍒濆嬪寲鐨勬椂鍊欏皢鏈嶅姟璁剧疆涓篠ERVICE_START_PENDING锛屽綋鍒濆嬪寲瀹屾瘯鏃惰句负SERVICE_RUNNING锛岃繖浜涚姸
鎬佹槸绯荤粺鑷瀹氫箟鐨勭姸鎬侊紝鍙閫氳繃msdn鏌ョ湅鍏朵粬鐘舵併傝繖涓鐘舵佷俊鎭浣犱細鍦╯c.exe涓鐪嬪埌銆
鍦ㄧ紪鍐檞indows鏈嶅姟绋嬪簭杩囩▼涓浣犻渶瑕佸叧娉ㄧ殑鍑芥暟鏈夛細
1.棣栧厛鏄痬ain鍑芥暟锛岀敱浜巜indows鏈嶅姟涓嶉渶瑕佺晫闈锛屾墍浠ュぇ閮ㄥ垎绋嬪簭涓簑in32鎺у埗鍙板簲鐢ㄧ▼搴忥紝鎵浠ョ▼搴忎富鍑芥暟涓簃ain 鑰屼笉鏄疻inMain()銆傚湪涓诲嚱鏁拌佸仛鐨勪富瑕佸伐浣滃氨鏄鍒濆嬪寲涓涓
SERVICE_TABLE_ENTRY 鍒嗘淳琛ㄧ粨鏋勪綋锛岀劧鍚庤皟鐢⊿tartServiceCtrlDispatcher();杩欏皢鎶婅皟鐢ㄨ繘绋嬬殑涓荤嚎绋嬭浆鎹涓烘帶鍒跺垎娲惧櫒銆傝ュ垎娲惧櫒鍚鍔ㄤ竴涓鏂扮嚎绋嬶紝璇ョ嚎绋嬭繍琛屽垎娲捐〃涓瀵瑰簲浜庝綘鐨勬湇鍔$殑ServiceMain锛堬級鍑芥暟銆係erviceMain锛堬級鍑芥暟灏嗗湪涓嬮潰鎻愬埌銆 姝よ繃绋嬬ず渚嬩唬鐮佸備笅锛
SERVICE_TABLE_ENTRY entrytable[2];
entrytable[0].lpServiceName="testservice";
entrytable[0].lpServiceProc=(LPSERVICE_MAIN_FUNCTION)ServiceMain; entrytable[1].lpServiceName=NULL; entrytable[1].lpServiceProc=NULL;
StartServiceCtrlDispatcher(entrytable);
鍦ㄨ繖涔嬪悗绯荤粺灏嗚嚜鍔ㄥ垱寤轰竴涓绾跨▼鍘绘墽琛孲erviceMain鍑芥暟鐨勫唴瀹癸紝浣犲簲璇ュ皢浣犺佹墽琛岀殑浠诲姟
鍦⊿erviceMain涓寰鐜锛岃繖鏍锋湇鍔″氨寮濮嬭繍琛屼簡銆
2锛嶴erviceMain鍑芥暟涓簐oid WINAPI ServiceMain锛坕nt argc, char** argv锛夋牸寮忕殑鍑芥暟锛
鍑芥暟鍚嶅瓧鍙浠ヤ换鎰忓畾涔夈傚畠鐨勪綔鐢ㄥ氨鏄锛氬皢浣犻渶瑕佹墽琛岀殑浠诲姟鏀惧埌璇ュ嚱鏁颁腑寰鐜鎵ц屽嵆鍙銆傝繖灏辨槸鏈嶅姟绋嬪簭鐨勫伐浣滃嚱鏁般傚湪ServiceMain鎵ц屼綘鐨勪换鍔″墠锛岄渶瑕佺粰SERVICE_TABLE_ENTRY 鍒嗘淳琛ㄧ粨鏋勪綋杩涜岃祴鍊硷紝娉ㄦ剰鐢变簬姝ゆ椂鏈嶅姟杩樻病鏈夊紑濮嬫墽琛屼綘鐨勪换鍔℃墍浠ユ垜浠灏嗘湇鍔$殑鐘舵佽剧疆涓篠ERVICE_START_PENDING锛屽嵆姝e湪鍒濆嬪寲銆傛垜浠杩涜屽備笅璧嬪硷細
servicestatus.dwServiceType = SERVICE_WIN32;
servicestatus.dwCurrentState = SERVICE_START_PENDING;
servicestatus.dwControlsAccepted=SERVICE_ACCEPT_SHUTDOWN|SERVICE_ACCEPT_STOP; //鍦ㄦ湰渚嬩腑鍙鎺ュ彈绯荤粺鍏虫満鍜屽仠姝㈡湇鍔′袱绉嶆帶鍒跺懡浠 servicestatus.dwWin32ExitCode = 0;
servicestatus.dwServiceSpecificExitCode = 0; servicestatus.dwCheckPoint = 0;
2014涓嬪崐骞存暀甯堣祫鏍艰瘉缁熻冨ぇ澶囨垬 涓瀛︽暀甯堣祫鏍艰冭瘯 灏忓︽暀甯堣祫鏍艰冭瘯 骞煎効鏁欏笀璧勬牸鑰冭瘯 鏁欏笀璧勬牸璇侀潰璇
servicestatus.dwWaitHint = 0;
hstatus = ::RegisterServiceCtrlHandler("testservice", CtrlHandler);
CtrlHandler涓簐oid WINAPI CtrlHandler(DWORD request)鍨嬬殑鍑芥暟锛屽嚱鏁板悕瀛楀彲浠ヤ换鎰忚惧畾銆傚皢鍦ㄤ笅涓鐐硅插埌銆
Hstatus涓篠ERVICE_STATUS_HANDLE绫诲瀷鐨勫叏灞鍙橀噺銆傚綋闇瑕佹敼鍙樻湇鍔$姸鎬佹椂SetServiceStatus锛堬級鍑芥暟闇瑕佸畠鍋氫负鍙傛暟鏉ユ爣璇嗕竴涓鏈嶅姟銆
3. void WINAPI CtrlHandler(DWORD request)锛屽嚱鏁扮殑涓昏佸姛鑳芥槸锛屾帴鏀剁郴缁熶紶閫掔殑鎺у埗鍛戒护锛屾瘮濡傚綋浣犻氳繃sc.exe鍏抽棴鏈嶅姟鏃讹紝璇ュ嚱鏁颁細鏀跺埌SERVICE_CONTROL_STOP娑堟伅锛屼綘灏卞彲浠ュ规湇鍔¤繘琛屽繀瑕佺殑绠$悊銆傚湪鏈渚嬪瓙绋嬪簭涓灏卞彧鎺ユ敹SERVICE_ACCEPT_SHUTDOWN鍜孲ERVICE_ACCEPT_STOP娑堟伅锛岃繖鏄閫氳繃鍓嶉潰缁檚ervicestatus璧嬪艰惧畾鐨勩
杩欐牱涓涓鍩烘湰鐨勬湇鍔$▼搴忓氨瀹屾垚浜嗐
涓嬮潰璐村嚭鎴戠殑绀轰緥浠g爜浠呬緵鍙傝冦傝ヤ唬鐮佸湪vs2008涓璋冭瘯閫氳繃銆傛湰鏂囩粨鏉熺殑鏃跺欎細闄勪笂濡備綍瀹夎呮湇鍔° #include <stdio.h> #include <Windows.h>
#define SLEEP_TIME 5000 //闂撮殧鏃堕棿
#define FILE_PATH "C:\\log.txt" //淇℃伅杈撳嚭鏂囦欢 bool brun=false;
SERVICE_STATUS servicestatus; SERVICE_STATUS_HANDLE hstatus;
int WriteToLog(char* str);
void WINAPI ServiceMain(int argc, char** argv); void WINAPI CtrlHandler(DWORD request); int InitService();
int WriteToLog(char* str) {
FILE* pfile;
fopen_s(&pfile,FILE_PATH,"a+"); if (pfile==NULL) {
return -1; }
fprintf_s(pfile,"%s\n",str); fclose(pfile); return 0; }
void WINAPI ServiceMain(int argc, char** argv) {
servicestatus.dwServiceType = SERVICE_WIN32;
servicestatus.dwCurrentState = SERVICE_START_PENDING; servicestatus.dwControlsAccepted =
SERVICE_ACCEPT_SHUTDOWN|SERVICE_ACCEPT_STOP;//鍦ㄦ湰渚嬩腑鍙鎺ュ彈绯荤粺鍏虫満鍜屽仠姝㈡湇鍔′袱绉嶆帶鍒跺懡浠
servicestatus.dwWin32ExitCode = 0;
servicestatus.dwServiceSpecificExitCode = 0; servicestatus.dwCheckPoint = 0; servicestatus.dwWaitHint = 0;
hstatus = ::RegisterServiceCtrlHandler("testservice", CtrlHandler); if (hstatus==0) {
WriteToLog("RegisterServiceCtrlHandler failed"); return; }
WriteToLog("RegisterServiceCtrlHandler success"); //鍚慡CM 鎶ュ憡杩愯岀姸鎬
servicestatus.dwCurrentState = SERVICE_RUNNING; SetServiceStatus (hstatus, &servicestatus);
//涓嬮潰灏卞紑濮嬩换鍔″惊鐜浜嗭紝浣犲彲浠ユ坊鍔犱綘鑷宸卞笇鏈涙湇鍔″仛鐨勫伐浣 brun=true;
MEMORYSTATUS memstatus; char str[100]; memset(str,'\0',100); while (brun) {
GlobalMemoryStatus(&memstatus);
int availmb=memstatus.dwAvailPhys/1024/1024;
sprintf_s(str,100,"available memory is %dMB",availmb); WriteToLog(str); Sleep(SLEEP_TIME); }
WriteToLog("service stopped"); }
void WINAPI CtrlHandler(DWORD request) {
switch (request) {
case SERVICE_CONTROL_STOP: brun=false;
servicestatus.dwCurrentState = SERVICE_STOPPED; break;
case SERVICE_CONTROL_SHUTDOWN: brun=false;
servicestatus.dwCurrentState = SERVICE_STOPPED; break;
default: break; }
SetServiceStatus (hstatus, &servicestatus); }
void main() {
SERVICE_TABLE_ENTRY entrytable[2];
entrytable[0].lpServiceName="testservice";
entrytable[0].lpServiceProc=(LPSERVICE_MAIN_FUNCTION)ServiceMain; entrytable[1].lpServiceName=NULL; entrytable[1].lpServiceProc=NULL; StartServiceCtrlDispatcher(entrytable); }
濡備綍瀹夎呮湇鍔★細
杩愯屽懡浠ゆ彁绀虹 cmd.exe
杈撳叆 sc create testservicename binpath= D:\test.exe 杈撳叆 sc start testservicename 鍚鍔ㄦ湇鍔 杈撳叆sc query 浼氬湪鏈搴曢儴鏄剧ず浣犵殑鏈嶅姟褰撳墠鐨勭姸鎬 杈撳叆 sc stop testservicename 鍋滄㈡湇鍔
杈撳叆 sc delete testservicename鍒犻櫎鏈嶅姟锛岃ユ湇鍔″皢鍦ㄤ笅娆¢噸鍚鍚庡垹闄わ紝鍦ㄩ噸鍚涔嬪墠灏嗕笉鑳芥敞鍐屽悓涓涓鍚嶅瓧鐨勬湇鍔°
D. MFC可不可以编写windows服务程序
可以不是控制台的,通过调用CreateService创建服务。
schService = CreateService(
schSCManager, // SCManager database
TEXT("Sample_Srv"), // name of service
lpszDisplayName, // service name to display
SERVICE_ALL_ACCESS, // desired access
SERVICE_WIN32_OWN_PROCESS, // service type
SERVICE_DEMAND_START, // start type
SERVICE_ERROR_NORMAL, // error control type
szPath, // path to service's binary
NULL, // no load ordering group
NULL, // no tag identifier
NULL, // no dependencies
NULL, // LocalSystem account
NULL); // no password
dwServerType的属性要加上SERVICE_INTERACTIVE_PROCESS
这样服务才能显示界面。
通过成功的创建服务,系统就会启动的时候加载你的程序。
E. 濡備綍搴旂敤VS2010涓鏉ュ垱寤篧indows鏈嶅姟绋嬪簭
1锛宯ew project -> 閫夋嫨 ATL Project, 璁剧疆宸ョ▼鍚嶏紝濡傦細PureSsl
2锛屽湪鍚戝肩殑鈥淎pplication Setting鈥濋〉锛屸淎pplication Type鈥濋」閫夋嫨锛 Service(EXE)
3, 鏇存敼涓绘枃浠禤ureSsl.cpp锛屽備笅锛
// PureSsl.cpp : Implementation of WinMain
#include "stdafx.h"
#include "resource.h"
#include "PureSsl_i.h"
#include <atlcomcli.h>
#include <stdio.h>
class CPureSslMole : public ATL::CAtlServiceMoleT< CPureSslMole, IDS_SERVICENAME >
{
public :
DECLARE_LIBID(LIBID_PureSslLib)
DECLARE_REGISTRY_APPID_RESOURCEID(IDR_PURESSL, "{A0D1CDBB-EE9F-4110-9710-498FEB5194F5}")
HRESULT InitializeSecurity() throw()
{
// TODO : Call CoInitializeSecurity and provide the appropriate security settings for your service
// Suggested - PKT Level Authentication,
// Impersonation Level of RPC_C_IMP_LEVEL_IDENTIFY
// and an appropiate Non NULL Security Descriptor.
return S_OK;
}
HRESULT RegisterAppId(bool bService = false) throw ();
HRESULT PreMessageLoop(int nShowCmd) throw();
HRESULT PostMessageLoop() throw();
void OnStop() throw();
void OnPause() throw();
void OnContinue() throw();
};
HRESULT CPureSslMole::RegisterAppId(bool bService ) throw ()
{
HRESULT hr = S_OK;
BOOL res = __super ::RegisterAppId(bService);
if (bService)
{
if (IsInstalled())
{
SC_HANDLE hSCM = ::OpenSCManagerW(NULL, NULL, SERVICE_CHANGE_CONFIG);
SC_HANDLE hService = NULL;
if (hSCM == NULL)
{
hr = ATL::AtlHresultFromLastError();
}
else
{
hService = ::OpenService(hSCM, m_szServiceName, SERVICE_CHANGE_CONFIG);
if (hService != NULL)
{
::ChangeServiceConfig(hService, SERVICE_NO_CHANGE,
SERVICE_AUTO_START,// 淇鏀规湇鍔′负鑷鍔ㄥ惎鍔
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
m_szServiceName); // 閫氳繃淇鏀硅祫婧怚DS_SERVICENAME 淇鏀规湇鍔$殑鏄剧ず鍚嶅瓧
SERVICE_DESCRIPTION Description;
TCHAR szDescription[1024];
ZeroMemory(szDescription, 1024);
ZeroMemory(&Description, sizeof (SERVICE_DESCRIPTION));
lstrcpy(szDescription, _T("娴嬭瘯鏈嶅姟鎻忚堪淇℃伅" ));
Description.lpDescription = szDescription;
::ChangeServiceConfig2(hService, SERVICE_CONFIG_DESCRIPTION, &Description);
::CloseServiceHandle(hService);
}
else
{
hr = ATL::AtlHresultFromLastError();
}
::CloseServiceHandle(hSCM);
}
}
}
return hr;
}
HRESULT CPureSslMole::PreMessageLoop(int nShowCmd) throw()
{
// 璁╂殏鍋滅户缁鎸夐挳鍙浠ヤ娇鐢
m_status.dwControlsAccepted = m_status.dwControlsAccepted | SERVICE_ACCEPT_PAUSE_CONTINUE;
HRESULT hr = __super::PreMessageLoop(nShowCmd);
// 寰杞疊ug
if (hr == S_FALSE)
hr = S_OK;
// 杩欓噷娣诲姞鑷宸辩殑鍒濆嬪寲浠g爜...
if (SUCCEEDED(hr))
{
// 杩欎釜鐘舵佷竴瀹氳佷慨鏀癸紝鍚﹀垯浼氬嚭鐜1053閿欒锛
// 杩欎釜閿欒鎴戣姳浜嗗緢澶氭椂闂存墠鎼炲畾
SetServiceStatus(SERVICE_RUNNING);
}
return hr;
}
HRESULT CPureSslMole::PostMessageLoop() throw()
{
HRESULT hr = __super ::PostMessageLoop();
if (FAILED(hr))
return hr;
// 杩欓噷娣诲姞鑷宸辩殑娓呴櫎浠g爜
return hr;
}
void CPureSslMole::OnStop() throw()
{
__super::OnStop();
SetServiceStatus(SERVICE_STOPPED);
}
void CPureSslMole::OnPause() throw()
{
__super::OnPause();
SetServiceStatus(SERVICE_PAUSED);
}
void CPureSslMole::OnContinue() throw()
{
__super::OnContinue();
SetServiceStatus(SERVICE_RUNNING);
}
CPureSslMole _AtlMole;
//
extern "C" int WINAPI _tWinMain(HINSTANCE /*hInstance*/, HINSTANCE /*hPrevInstance*/,
LPTSTR /*lpCmdLine*/, int nShowCmd)
{
return _AtlMole.WinMain(nShowCmd);
}
4, 缂栬瘧骞惰剧疆鏈嶅姟
褰揂TL COM瀵硅薄鐢熸垚浣滀负鏈嶅姟锛屽畠鎵嶄細娉ㄥ唽涓烘湰鍦版湇鍔″櫒锛屽苟涓旓紝鍦ㄦ帶鍒堕潰鏉夸笉浼氬嚭鐜板湪鏈嶅姟鍒楄〃銆傝繖鏄鍥犱负锛岃皟璇曟湇鍔′綔涓烘湰鍦版湇鍔″櫒涓婁綔涓烘湇鍔℃洿涓烘柟渚裤傝嫢瑕佸畨瑁呭畠浣滀负鏈嶅姟锛岃疯繍琛屼互涓嬪懡浠ゆ彁绀:
YourEXE.exe /Service
鑻ヨ佸嵏杞借ユ枃浠讹紝璇疯繍琛屼互涓嬫搷浣:
YourEXE.exe /UnregServer
鎵撳紑cmd绐楀彛锛岃繘鍏ョ敓鎴愮殑PureSsl.exe鎵鍦ㄧ殑鐩褰曟墽琛岋細
> PureSsl.exe /service
> net start PureSsl
鍗冲彲灏嗘湇鍔¤剧疆鍒版湇鍔$$悊鍣锛屽苟鍚鍔ㄥ畠銆
瑕佸垹闄ゆ湇鍔★細
> sc delete PureSsl
5, 娉ㄦ剰
鏈缁忕4姝ョ洿鎺ヨ繍琛屼細鎶ヤ互涓嬮敊璇锛
The program '[24636] PureSsl.exe: Native' has exited with code 2 (0x2).
鑻ヨ佺洿鎺ュ湪vs涓璋冭瘯杩愯屽簲褰撴墽琛岋細
YourEXE.exe /UnregServer
鍚﹀垯浼氭姤
First-chance exception at 0x75c49673 in CloudS.exe: 0x00000005: 鎷掔粷璁块棶銆.
The thread 'Win32 Thread' (0x314) has exited with code 1063 (0x427).
F. 怎样把程序做成WINDOWS服务
在“开始→运行”中键入“regedit.exe”,打开“注册表编辑器”,展开分支“HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services”,在右侧窗格中显示的就是本机安装的服务项。
如果要新建服务,只须点击“编辑→新建→项”,然后为此项命名,如“test”;然后右击该项,选择“新建→字符串值”或“新建→DWORD值”即可。添加一个服务项目具体需要添加的键值如下:
“DisplayName”,字符串值,对应服务名称;
“Description”,字符串值,对应服务描述;
“ImagePath”,字符串值,对应该服务程序所在的路径;
“ObjectName”,字符串值,值为“LocalSystem”,表示本地登录;
“ErrorControl”,DWORD值,值为“1”;
“Start”,DWORD值,值为2表示自动运行,值为3表示手动运行,值为4表示禁止;
“Type”,DWORD值,应用程序对应10,其它对应20。
G. c#编写windows服务程序怎么自动安装程序
创建项目
1
创建windows服务项目
2
右键点击Service1.cs,查看代码,
用于编写操作逻辑代码
3
代码中OnStart用于执行服务事件,一般采用线程方式执行方法,便于隔一段事件执行一回
END
安装服务配置
1
打开Service1.cs视图界面
2
在视图内右键-->添加安装程序
3
项目中添加了ProjectInstaller.cs文件,该文件中视图自动会添加俩个组件
serviceProcessInstaller1
serviceInstaller1
4
选中serviceProcessInstaller1组件,查看属性,设置account为LocalSystem
5
选中serviceInstaller1组件,查看属性
设置ServiceName的值,
该值表示在系统服务中的名称
设置StartType,
如果为Manual则手动启动,默认停止,如果为Automatic为自动启动
设置Description,添加服务描述
6
重新生成项目
END
安装服务
1
点击
开始,运行中输入cmd,获取命令提示符
win7需要已管理员的身份启动,否则无法安装
2
输入
cd
C:\Windows\Microsoft.NET\Framework\v4.0.30319
回车
切换当前目录,此处需要注意的是,在C:\Windows\Microsoft.NET\Framework目录下有很多类似版本,具体去哪个目录要看项目的运行环境,例
如果是.net
framework2.0则需要输入
cd
C:\Windows\Microsoft.NET\Framework\v2.0.50727
3
输入
InstallUtil.exe
E:\TestApp\Winform\WinServiceTest\WinServiceTest\bin\Debug\WinServiceTest.exe
回车
说明:E:\TestApp\Winform\WinServiceTest\WinServiceTest\bin\Debug\WinServiceTest.exe表示项目生成的exe文件位置
4
打开服务,就可以看到已经安装的服务了
END
卸载服务
1
卸载很简单,打开cmd,
直接输入
sc
delete
WinServiceTest便可