NT服务程序我会做了,但服务功能怎么实现我不知道。请高手帮忙(急)

Kaile 2000-07-13 05:27:00
我想自启动一个服务 服务功能程序是d:\temp\zbserver.exe 代码如下: SC_HANDLE schService;
SC_HANDLE schSCManager;

TCHAR szPath[512];
/*
if ( GetModuleFileName( NULL, szPath, 512 ) == 0 )
{
_tprintf(TEXT("Unable to install %s - %s\n"), TEXT(SZSERVICEDISPLAYNAME), GetLastErrorText(szErr, 256));
return;
}
*/
strcpy(szPath,"D:\\temp\\zbserver.exe");
schSCManager = OpenSCManager(
NULL, // machine (NULL == local)
NULL, // database (NULL == default)
SC_MANAGER_ALL_ACCESS // access required
);
if ( schSCManager )
{
schService = CreateService(
schSCManager, // SCManager database
TEXT(SZSERVICENAME), // name of service
TEXT(SZSERVICEDISPLAYNAME), // 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, // service's binary
NULL, // no load ordering group
NULL, // no tag identifier
TEXT(SZDEPENDENCIES), // dependencies
NULL, // LocalSystem account
NULL); // no password

if ( schService )
{
if(StartService(schService,0,0))
printf("%s started.\n", SZSERVICEDISPLAYNAME);
else
printf("StartService failed \n" );

_tprintf(TEXT("%s installed.\n"), TEXT(SZSERVICEDISPLAYNAME) );
CloseServiceHandle(schService);
}
else
{
_tprintf(TEXT("CreateService failed - %s\n"), GetLastErrorText(szErr, 256));
}

CloseServiceHandle(schSCManager);
}
else
_tprintf(TEXT("OpenSCManager failed - %s\n"), GetLastErrorText(szErr,256));
每次运行都无法启动zbserver.exe ,如果不用zbserver.exe用上三行则可以启动服务但实现不了我的功能,请高手指点
...全文
609 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
zwok 2000-07-21
  • 打赏
  • 举报
回复
做SOCKET的服务注意在服务进程启动时调用WAStartup()初始化,
如果用MFC的CSocket或CAsyncSocket的话要调用那个AfxSockInit()初始化。
然后最后把服务进程阻塞在一个WINDOWS消息循环处,不要阻塞在accept那里,
因为还要等待WM_QUIT消息。

BTW: 我最近刚完成的一个SOCKET的服务程序,欢迎各位CSDN专家到小弟站上评批指点。
http://www.ichat.net.cn

Kaile 2000-07-21
  • 打赏
  • 举报
回复
我的水平太臭以至现在还没有解决服务功能(Create,Listen Socket端口服务)怎么写的问题但我仍然感谢各位特别是zwok的精彩回答分数请接好了
sean 2000-07-17
  • 打赏
  • 举报
回复
http://www.codetools.com/system/
中有文件CNTService v1.06 - NT Service Framework
你看看能否满足要求!
这个网站不错呀!
Kaile 2000-07-17
  • 打赏
  • 举报
回复
zwok:
我前两天没上网,我现在正抓紧完善你的CNTService,请放心,你对我帮助很大肯定会给你高分的.但我想把NT服务讨论透彻,请稍安勿燥
zwok 2000-07-16
  • 打赏
  • 举报
回复
怎么还不给分,管理员呢?
Kaile 2000-07-14
  • 打赏
  • 举报
回复
softdoctor :
因为我没有做过ATL ,能给我一个Demo吗??
softdoctor 2000-07-14
  • 打赏
  • 举报
回复
服务功能是借助COM对象来实现的。
服务启动以后,我们用CoCreateInstance或CoCreateInstanceEx创建该服务中的对象并获得其接口指针,有了这个接口指针,该对象的功能就可以任意调用了。
Exe本身的函数是无法给外界直接调用的。
具体使用ATL可轻松搞定。
Kaile 2000-07-14
  • 打赏
  • 举报
回复
感谢各位。但那些网址只是怎么做服务,而不是在服务里怎样加服务功能。我想服务功能无非有两种方法,1 在服务本身里加,用函数来实现(不需要界面) 怎样写这个函数?有什么要注意的地方? 2 服务程序里调用某个EXE文件 怎样调用?EXE文件有什么讲究??
希望有大虾尽快解决, 200分随时侍候
zwok 2000-07-14
  • 打赏
  • 举报
回复
to: Kaile

SERVICE管理界面和SERVICE功能不要做在一个EXE里。
应该做成两个EXE,中间通过管通、SOCKET、或者COM等形式通信。

安装用上面例子的: InstallService 函数就可以了。
启动不是用m_lpServicePathName,是用m_lpServiceName。
如我上面的程序名字是 aaatest,安装成功后,
如果在命令行下启动输入: NET START aaatest
就可以启动了。同时在控制面板的服务管理器里也会找到 aaatest 这一项。

代码最说明问题了,感觉你似乎对SERVICE还没有整体概念,
你不想认真看代码那谁也帮不了你。

我的代码是完整地封装了一系列SERVICE调用的类,
在main()里调用:
CNTService s ;
s.InstallService()
就可以安装到服务管理器里,启动用NET START就可以。
Kaile 2000-07-14
  • 打赏
  • 举报
回复
zwok兄:
我不但不骂您还要感谢您.你的发言启示了我。我的ZBServer.exe就是我想安装到服务管理器并想启动的服务.但我不知道怎么按 Service 方式写它???
是不是按Service 方式写过后,在m_lpServicePathName中设定包含ZBServer.exe的
路径名和文件名就可以了?
再有我要把服务管理和服务功能做成一个EXE,可以用MFC显示对话框界面吗?
因为你的代码太长,我看了半天没有看明白,只好又来麻烦你。
zwok 2000-07-14
  • 打赏
  • 举报
回复
to: softdoctor
NT SERVICE概念早在ATL出来之前就有了,所以用API实现更容易一些。
程序跑起来也不用管当前系统有没有装COM服务。

to: Kaile
我上面给的例子RUN()函数是功能实现的核心,主要部分其实是一个WINDOWS的消息循环,不过注意抓取ThreadId的位置,否则Post Quit消息会发不RUN里面的消息队列里去。
调EXE文件的话也要保证在RUN里面调,调完之后必须要阻塞程序, 用户按下STOP按钮时也要通过发消息控制EXE文件结束。

to: All
谁要是把上面的例子更进一步完善了,记得EMAIL一份给我,不用保留我的名字。
zwok 2000-07-14
  • 打赏
  • 举报
回复
看不明白您具体想实现什么功能,
你是要把zbserver.exe安装到SERVICE管理器里然后启动他吗?
abserver.exe是按SERVICE模式写的吗?
贴段代码看看能否帮到你,如果帮不到别骂我就行了。

// NTService.h: interface for the CNTService class.
//
//////////////////////////////////////////////////////////////////////

#if !defined(AFX_NTSERVICE_H__4EF874F0_2934_11D3_AFC2_5254ABDD3C8E__INCLUDED_)
#define AFX_NTSERVICE_H__4EF874F0_2934_11D3_AFC2_5254ABDD3C8E__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include <windows.h>
#include <winsvc.h>
#include <stdio.h>
#include <tchar.h>

class CNTService
{
public:
static DWORD WINAPI ThreadFunc(LPVOID pvParam);
BOOL m_bService;
virtual void Continue();
virtual void Pause();
virtual void Stop();
virtual void UnInitialize();
virtual void Run();
virtual BOOL Initialize();

static CNTService * m_pService;
static void WINAPI ServiceHandle(DWORD dwControl);
static void WINAPI ServiceMain(DWORD dwArgc, LPTSTR *lpszArgv);
static BOOL SetSCMStatus(DWORD dwCurrentState, DWORD dwWin32ExitCode, DWORD dwWaitHint);
static void AddToMessageLog(LPCTSTR lpszMsg);
static void AddToErrorMessageLog(LPCTSTR lpszMsg) ;

BOOL LoadINIFile(CString strFilename, CMapStringToString &mapVariable);
BOOL StartDispatch();
int RemoveService(); //将服务程序从SCM管理器中删除掉
int InstallService(); //将服务程序安装进SCM管理器中

LPTSTR GetLastErrorText(LPTSTR lpszBuf, DWORD dwSize);

CNTService(); //构造
virtual ~CNTService(); //析构

static LPSTR m_lpServiceName; //服务程序内部名称,名字不能有空格
static LPSTR m_lpServiceDisplayName; //SERVICE程序在管理器中的显示名称,任意字符
private:
static DWORD dwThreadId ;
static TCHAR m_lpServicePathName[512]; //SERVICE程序的EXE文件路径
static SERVICE_STATUS m_ssServiceStatus ;//SERVICE程序的状态struct
static SERVICE_STATUS_HANDLE m_sshServiceStatusHandle ;//SERVICE程序状态的HANDLE
};

#endif // !defined(AFX_NTSERVICE_H__4EF874F0_2934_11D3_AFC2_5254ABDD3C8E__INCLUDED_)




// NTService.cpp: implementation of the CNTService class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "NTService.h"

#include "ChatRoom.h"

DWORD CNTService::dwThreadId ;
LPSTR CNTService::m_lpServiceName; //服务程序内部名称,名字不能有空格
LPSTR CNTService::m_lpServiceDisplayName; //SERVICE程序在管理器中的显示名称,任意字符
TCHAR CNTService::m_lpServicePathName[512]; //SERVICE程序的EXE文件路径
CNTService * CNTService::m_pService;
SERVICE_STATUS CNTService::m_ssServiceStatus ;//SERVICE程序的状态struct
SERVICE_STATUS_HANDLE CNTService::m_sshServiceStatusHandle ;//SERVICE程序状态的HANDLE

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CNTService::CNTService()
{
// TCHAR szPath[512]; //取路径时用的局部变量

GetModuleFileName(NULL, m_lpServicePathName, 512); //取当前执行文件路径

m_lpServiceName = "aaatest"; //服务名称
m_lpServiceDisplayName = "aaaZhang Wei's Service Test"; //显示的名称
// m_lpServicePathName = szPath; //EXE文件路径
// printf("%s\r\n%s\r\n", szPath, m_lpServicePathName ) ;
m_pService = this ;
m_ssServiceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
m_ssServiceStatus.dwServiceSpecificExitCode = 0 ;
}

CNTService::~CNTService()
{

}

/***************************************************************** 函数名称:InstallService()
功能说明:将执行文件安装进NT SERVICE管理器内
注意事项:
函数作者:张 伟
创建日期:1999/06/23
\*****************************************************************/
int CNTService::InstallService()
{
SC_HANDLE schSCManager; //打开SCM用的句柄
SC_HANDLE schService; //建立SERVICE用的句柄

schSCManager = OpenSCManager( //调用打开SERVICE管理器API
NULL, //机器名称,设置NULL为本地机器
NULL, //数据库名称,NULL为缺省数据库
SC_MANAGER_CREATE_SERVICE //或 SC_MANAGER_ALL_ACCESS
); //希望打开的操作权限,详见MSDN

if( schSCManager ) // 如果打开SERVICE管理器成功
{
schService = CreateService( //调用建立SERVICE的API
schSCManager, //SERVICE管理器数据库的句柄
TEXT(m_lpServiceName), //服务名称
TEXT(m_lpServiceDisplayName), //显示的名称
SERVICE_ALL_ACCESS, //希望得到的运行权限
SERVICE_WIN32_OWN_PROCESS, //SERVICE的类型
SERVICE_DEMAND_START, //启动的方式
SERVICE_ERROR_NORMAL, //错误控制类型
TEXT(m_lpServicePathName), //可执行文件的路径名
NULL, //一组服务装入时的顺序
NULL, //检查人标记
_T("RPCSS\0"), //从属
NULL, //本地USER名
NULL); //密码

if( schService ) //如果建立SERVICE成功
{
CloseServiceHandle(schService); //释放SERVICE句柄,准备退出
}else
{
return FALSE ; //建立SERVICE失败返回
}
CloseServiceHandle(schSCManager); //释放SERVICE管理器句柄
}else
{
return FALSE; //打开管理器失败返回
}
return TRUE; //一切正常返回
}

/***************************************************************** 函数名称:RemoveService()
功能说明:将SERVICE程序从SCM管理器中移走
注意事项:
函数作者:张 伟
创建日期:1999/06/23 傍晚
\*****************************************************************/
BOOL CNTService::RemoveService()
{
SC_HANDLE schSCManager; //打开SCM用的句柄
SC_HANDLE schService; //建立SERVICE用的句柄

schSCManager = OpenSCManager( //调用打开SERVICE管理器API
NULL, //机器名称,设置NULL为本地机器
NULL, //数据库名称,NULL为缺省数据库
SC_MANAGER_ALL_ACCESS //希望打开的操作权限,详见MSDN
);

if( schSCManager ) // 如果打开SERVICE管理器成功
{
schService = OpenService( //获取SERVICE控制句柄的API
schSCManager, //SCM管理器句柄
m_lpServiceName, //SERVICE内部名称,控制名称
SERVICE_ALL_ACCESS); //打开的权限,删除就要全部权限

if( schService ) //如果获取SERVICE句柄成功
{
if( ControlService(schService, SERVICE_CONTROL_STOP, &m_ssServiceStatus) )
{ //直接向SERVICE发STOP命令,如果能够执行到这里,说明SERVICE正运行
//那就需要停止程序执行后才能删除
Sleep(3000) ; //等3秒使系统有时间执行STOP命令
while( QueryServiceStatus(schService, &m_ssServiceStatus) )
{ //循环检查SERVICE状态
if(m_ssServiceStatus.dwCurrentState == SERVICE_STOP_PENDING)
{ //如果SERVICE还正在执行(PENDING)停止任务
Sleep(1000) ; //那就等1秒钟后再检查SERVICE是否停止OK
}else break ;//STOP命令处理完毕,跳出循环
}//循环检查SERVICE状态结束
if(m_ssServiceStatus.dwCurrentState != SERVICE_STOPPED)
{ //如果SERVICE接受STOP命令后还没有STOPPED
return FALSE; //那就返回FALSE报错,用GetLastError取错误代码
}
}
//删除指令在这里
if(! DeleteService(schService) ) //删除这个SERVICE
{
CloseServiceHandle(schService); //释放SERVICE控制句柄
return FALSE; //如果删除失败返回
}else CloseServiceHandle(schService); //释放SERVICE控制句柄
}else //取SERVICE句柄不成功
{
return FALSE; //获取SERVICE句柄失败,或没有找到SERVICE名字返回
}
CloseServiceHandle(schSCManager); //释放SCM管理器句柄
}else //打开管理器不成功
{
return FALSE; //打开管理器失败返回
}
return TRUE; //正常删除返回
}

/***************************************************************** 函数名称:GetLastErrorText( LPTSTR lpszBuf )
功能说明:从系统中取最后一次错误代码,并转换成字符串返回
注意事项:参数lpszBuf必须预先留好存储空间,如:TCHAR szBuf[256] ;
函数作者:张 伟 摘自MSDN "Simple Service and Client SDK Sample"
创建日期:1999/06/24 上午
\*****************************************************************/
LPTSTR CNTService::GetLastErrorText( LPTSTR lpszBuf, DWORD dwSize )
{
DWORD dwRet;
LPTSTR lpszTemp = NULL;

dwRet = FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |FORMAT_MESSAGE_ARGUMENT_ARRAY,
NULL,
GetLastError(),
LANG_NEUTRAL,
(LPTSTR)&lpszTemp,
0,
NULL );

// supplied buffer is not long enough
if ( !dwRet || ( (long)dwSize < (long)dwRet+14 ) )
lpszBuf[0] = TEXT('\0');
else
{
lpszTemp[lstrlen(lpszTemp)-2] = TEXT('\0'); //remove cr and newline character
_stprintf( lpszBuf, TEXT("%s (%ld)"), lpszTemp, GetLastError() );
}

if ( lpszTemp )
LocalFree((HLOCAL) lpszTemp );

return lpszBuf;
}

/***************************************************************** 函数名称:StartDispatch()
功能说明:执行缺省的服务控制Dispatcher,服务开始前执行的缺省注册
注意事项:
函数作者:张 伟
创建日期:1999/06/24 上午
\*****************************************************************/
BOOL CNTService::StartDispatch()
{
SERVICE_TABLE_ENTRY DispatchTable[] =
{
{m_lpServiceName,ServiceMain},
{NULL, NULL}
}; //如果只有一个SERVICE就定义成2,如果有
//二个以上的SERVICE在一个文件里,这个
//表就要定义成3维或更多
m_bService = TRUE ;
if( !StartServiceCtrlDispatcher(DispatchTable))
return FALSE;
return TRUE;
}

/***************************************************************** 函数名称:ServiceMain(DWORD dwArgc, LPTSTR *lpszArgv)
功能说明:服务程序开始的主程序,主要的初始化及主体服务程序均在此
注意事项:此函数内须处理STOP、PAUSE、CONTINUE等事件
函数作者:张 伟
创建日期:1999/06/24 上午 11:53
\*****************************************************************/
void WINAPI CNTService::ServiceMain(DWORD dwArgc, LPTSTR *lpszArgv)
{
m_sshServiceStatusHandle =
RegisterServiceCtrlHandler(m_lpServiceName, ServiceHandle);
if(!m_sshServiceStatusHandle)
{
AddToMessageLog("RegisterServiceCtrlHandler Error!");
return ;
}

if(SetSCMStatus(SERVICE_START_PENDING, NO_ERROR,3000))
{
m_pService->dwThreadId = GetCurrentThreadId() ;
if(m_pService->Initialize())
{
m_pService->Run();
m_pService->UnInitialize();
}
}
SetSCMStatus(SERVICE_STOPPED, NO_ERROR, 0);
}

/***************************************************************** 函数名称:ServiceHandle(DWORD dwControl)
功能说明:此函数接受系统发来的STOP、PAUSE,并做出相应处理发给Service_Main
注意事项:每一个指令执行后需报告当前状态给SCM管理器
函数作者:张 伟
创建日期:1999/06/24 上午
\*****************************************************************/
void WINAPI CNTService::ServiceHandle(DWORD dwControl)
{
switch(dwControl)
{
case SERVICE_CONTROL_STOP:
m_pService->Stop() ;
SetSCMStatus(SERVICE_STOP_PENDING, NO_ERROR, 3000);
PostThreadMessage(m_pService->dwThreadId, WM_QUIT, 0, 0 ) ;
break;
case SERVICE_CONTROL_PAUSE:
m_pService->Pause() ;
break;
case SERVICE_CONTROL_CONTINUE:
m_pService->Continue() ;
break;
case SERVICE_CONTROL_INTERROGATE:
break;
default:
break;
}
}

/***************************************************************** 函数名称:AddToMessageLog(
功能说明:将错误信息或其它提示信息加进系统EVENT管理器中
注意事项:
函数作者:张 伟 摘自MSDN "Simple Service and Client SDK Sample"
创建日期:1999/06/24 下午
\*****************************************************************/
void CNTService::AddToMessageLog(LPCTSTR lpszMsg)
{
TCHAR szMsg[256];
HANDLE hEventSource;
LPCTSTR lpszStrings[2];

if(!m_pService->m_bService)
{
printf("%s", lpszMsg) ;
return ;
}

// Use event logging to log the error.
//
hEventSource = RegisterEventSource(0, m_lpServiceName);

_stprintf(szMsg, TEXT("%s error: %d"), m_lpServiceName, GetLastError());
lpszStrings[0] = szMsg;
lpszStrings[1] = lpszMsg;

if(hEventSource != NULL)
{

ReportEvent(hEventSource, // handle of event source
EVENTLOG_INFORMATION_TYPE, // event type
0, // event category
0, // event ID
NULL, // current user's SID
2, // number of strings in lpszStrings
0, // no bytes of raw data
lpszStrings, // array of error strings
NULL); // no raw data
(VOID) DeregisterEventSource(hEventSource);
}
// EVENTLOG_ERROR_TYPE Error event
// EVENTLOG_WARNING_TYPE Warning event
// EVENTLOG_INFORMATION_TYPE Information event
// EVENTLOG_AUDIT_SUCCESS Success audit event
// EVENTLOG_AUDIT_FAILURE Failure audit event
}

void CNTService::AddToErrorMessageLog(LPCTSTR lpszMsg)
{
TCHAR szMsg[256];
HANDLE hEventSource;
LPCTSTR lpszStrings[2];

if(!m_pService->m_bService)
{
printf("%s", lpszMsg) ;
return ;
}
// Use event logging to log the error.
//
hEventSource = RegisterEventSource(0, m_lpServiceName);

_stprintf(szMsg, TEXT("%s error: %d"), m_lpServiceName, GetLastError());
lpszStrings[0] = szMsg;
lpszStrings[1] = lpszMsg;

if(hEventSource != NULL)
{

ReportEvent(hEventSource, // handle of event source
EVENTLOG_ERROR_TYPE, // event type
0, // event category
0, // event ID
NULL, // current user's SID
2, // number of strings in lpszStrings
0, // no bytes of raw data
lpszStrings, // array of error strings
NULL); // no raw data
(VOID) DeregisterEventSource(hEventSource);
}
// EVENTLOG_ERROR_TYPE Error event
// EVENTLOG_WARNING_TYPE Warning event
// EVENTLOG_INFORMATION_TYPE Information event
// EVENTLOG_AUDIT_SUCCESS Success audit event
// EVENTLOG_AUDIT_FAILURE Failure audit event

}

/***************************************************************** 函数名称:SetSCMStatus(DWORD dwCurrentState, DWORD dwWin32ExitCode, DWORD dwWaitHint)
功能说明:将程序当前状态报告给SCM管理器,使管理器的显示与当前程序同步
注意事项:
函数作者:张 伟 摘自MSDN "Simple Service and Client SDK Sample"
创建日期:1999/06/28 下午
\*****************************************************************/
BOOL CNTService::SetSCMStatus(DWORD dwCurrentState,
DWORD dwWin32ExitCode,
DWORD dwWaitHint)
{
static DWORD dwCheckPoint = 1;
BOOL fResult = TRUE;

// if ( !bDebug ) // when debugging we don't report to the SCM
// {
if (dwCurrentState == SERVICE_START_PENDING)
m_ssServiceStatus.dwControlsAccepted = 0;
else
m_ssServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;

m_ssServiceStatus.dwCurrentState = dwCurrentState;
m_ssServiceStatus.dwWin32ExitCode = dwWin32ExitCode;
m_ssServiceStatus.dwWaitHint = dwWaitHint;

if ( ( dwCurrentState == SERVICE_RUNNING ) ||
( dwCurrentState == SERVICE_STOPPED ) )
m_ssServiceStatus.dwCheckPoint = 0;
else
m_ssServiceStatus.dwCheckPoint = dwCheckPoint++;


// Report the status of the service to the service control manager.
//
if (!(fResult = SetServiceStatus( m_sshServiceStatusHandle, &m_ssServiceStatus))) {
AddToMessageLog(TEXT("SetServiceStatus"));
}
// }
return fResult;
}

BOOL CNTService::Initialize()
{
if(!AfxSocketInit())
{
AddToErrorMessageLog("iChat Service Can not initialize Winsock") ;
return FALSE;
}
if(!SetSCMStatus(SERVICE_RUNNING, NO_ERROR, 0))
return FALSE ;
AddToMessageLog("iChat Service started") ;
return TRUE ;
}

void CNTService::Run()
{
char str[512] ;
GetSystemDirectory(str, 512) ;
CString strDirectory = str ;
strDirectory += "\\iChat.ini" ; /* http://www.ichat.net.cn */


CMapStringToString mapRoomList ;
CPtrList lRoomList ;
CString strRoomName, strRoomINIFile ;
int nRoomCount = 0 ;

if(LoadINIFile(strDirectory, mapRoomList))
{
if(mapRoomList.GetCount() < 5)
{
for(POSITION pos = mapRoomList.GetStartPosition() ; pos != NULL;)
{
mapRoomList.GetNextAssoc(pos, strRoomName, strRoomINIFile) ;
CChatRoom *pNewRoom = new CChatRoom(strRoomINIFile) ;
if(pNewRoom->StartListen())
{
AddToMessageLog("\r\n" + pNewRoom->m_strRoomTitle + " Loading Successful.") ;
lRoomList.AddTail(pNewRoom) ;
}
else
{
AddToErrorMessageLog("\r\nCan not load " + strRoomName + " = " + strRoomINIFile) ;
AddToErrorMessageLog(pNewRoom->m_strReportError) ;
delete pNewRoom ;
}
}
}else
{
AddToErrorMessageLog("\r\nThis version Support 1-5 chat rooms.") ;
}
}else
{
AddToErrorMessageLog("\r\nCan't open " + strDirectory) ;
return ;
}
if(lRoomList.GetCount() > 0)
{
UINT nCheckUserTimer = SetTimer(NULL, 100, 25000, NULL) ;
UINT nLoadNewsTimer = SetTimer(NULL, 100, 600000, NULL) ;
MSG msg ;
while(GetMessage(&msg, 0, 0, 0))
{
if(msg.message == WM_TIMER)
{
if(msg.wParam == nCheckUserTimer)
{
for(POSITION pos = lRoomList.GetHeadPosition(); pos != NULL;)
{
CChatRoom *pChatRoom = (CChatRoom*)lRoomList.GetNext(pos) ;
pChatRoom->CheckTimeout() ;
}
}else
if(msg.wParam == nLoadNewsTimer)
{
for(POSITION pos = lRoomList.GetHeadPosition(); pos != NULL;)
{
CChatRoom *pChatRoom = (CChatRoom*)lRoomList.GetNext(pos) ;
pChatRoom->LoadNewsFile() ;
}
}
}
DispatchMessage(&msg) ;
}
for(POSITION pos = lRoomList.GetHeadPosition(); pos != NULL;)
{
CChatRoom *pChatRoom = (CChatRoom*)lRoomList.GetNext(pos) ;
delete pChatRoom ;
}
lRoomList.RemoveAll() ;
}else
{
AddToErrorMessageLog("\r\nCan't open any room, please check iChat.ini") ;
}
}

void CNTService::UnInitialize()
{
AfxSocketTerm() ;
AddToMessageLog("iChat Service stopped") ;
}

void CNTService::Stop()
{
}

void CNTService::Pause()
{

}

void CNTService::Continue()
{

}

DWORD WINAPI CNTService::ThreadFunc(LPVOID pvParam)
{
// CString strTemp = ;
CChatRoom *pChatRoom = new CChatRoom("C:\\winnt\\system32\\ichat.ini" ) ;

UINT nCheckUserTimer = SetTimer(NULL, 100, 25000, NULL) ;
UINT nLoadNewsTimer = SetTimer(NULL, 100, 600000, NULL) ;

printf("Thread Start .... \r\n") ;
if(pChatRoom->StartListen())
{
printf("Listen Ok.... \r\n") ;
MSG msg ;
while(GetMessage(&msg, 0, 0, 0))
{
if(msg.message == WM_TIMER)
{
if(msg.wParam == nCheckUserTimer)
pChatRoom->CheckTimeout() ;
if(msg.wParam == nLoadNewsTimer)
pChatRoom->LoadNewsFile() ;
}
DispatchMessage(&msg) ;
}
}else
{
AddToErrorMessageLog("\r\n" + pChatRoom->m_strReportError) ;
}
printf("Thread end .... \r\n") ;
delete pChatRoom ;
return 0;
}
Kaile 2000-07-14
  • 打赏
  • 举报
回复
难道就没有人帮我吗??
土豆 2000-07-13
  • 打赏
  • 举报
回复
我觉得SoftDoctor的方法不是本问题的答案,答非所问.
sean 2000-07-13
  • 打赏
  • 举报
回复
有关于NT服务进程的介绍!
http://www.vchelp.net/source/source_sys.htm
sean 2000-07-13
  • 打赏
  • 举报
回复
Windows NT 下Service 的 编 程
http://www.computerworld.com.cn/99/tips/9904/042601_09.asp
softdoctor 2000-07-13
  • 打赏
  • 举报
回复
利用COM来实现很简单的。
COM借助服务程序建立进程空间实现进程外服务。(DCOM)
具体可使用ATL来实现

16,470

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧