我现在正在编写一个nt服务程序,可是我不知道怎样才能对其调试!我看了SDK中的说明,但是还没有理解他的意思!不知哪位高手能指点小弟一把??
解决方案 »
- 在对话框中加入位图时出现的问题·急
- 高分请教:如何得到视图的句柄?
- 请大伙进来看看,一个编程方面的题目,高手能提供一个解题的思路就行了
- 求解,11对战平台,以及起凡实现原理?
- 操作xml时内存不断增加,请看一下是否有内存泄漏
- 如何编程实现移动屏幕达到移动背景图片的效果呢
- mfc 访问Excel
- 我在做贸易公司管理系统的时候,不知道怎么创建void CTrade_MISView::CreateCustomer(_variant_t strQuery)
- 各位大侠,小妹问一个关于Property Sheet的问题,怎么把下面的“应用,帮助,取消“设置成不显示
- mfc
- 那里有使用vc编数据库程序的好书籍可以下载?烦请告诉一二
- 给俺推荐一个监视网络环境的软件,好吗?
void CmdDebugService(int argc, char ** argv)
{
DWORD dwArgc;
LPTSTR *lpszArgv;#ifdef UNICODE
lpszArgv = CommandLineToArgvW(GetCommandLineW(), &(dwArgc) );
#else
dwArgc = (DWORD) argc;
lpszArgv = argv;
#endif _tprintf(TEXT("Debugging %s.\n"), TEXT(SZSERVICEDISPLAYNAME)); SetConsoleCtrlHandler( ControlHandler, TRUE ); ServiceStart( dwArgc, lpszArgv );
}
这个函数好想找不到啊!楼上的仁兄能否说清楚一点?不胜感激!!
在Build-Debug-Process Attach中,选择System的checkbox
再在ListBox中选择你的服务程序。有些程序是必须作为服务程序才能得到正常的效果,不注册的话就
不是真实的环境,让人不放心呀。
[email protected]
VOID ServiceStart (DWORD dwArgc, LPTSTR *lpszArgv)
{
SOCKET s;
SOCKADDR_IN sin;
SOCKADDR_IN sout;
int sout_size;
char *remoteIp;
unsigned short remoteport;
// char LogMsg[64];
struct LOGINUSER *LoginUser;
int dwSNDBUF=1024;
// int buflen;
int dwRCVBUF=1024;
int err;
DWORD dwThreadId;
HANDLE hThreadHandle;
int ErrorSockCount;
//char cNum[35];
//
// Create a listening socket that we'll use to accept incoming
// conections.
//
// report the status to the service control manager.
//
if (!ReportStatusToSCMgr(
SERVICE_START_PENDING, // service state
NO_ERROR, // exit code
3000)) // wait hint
return; if(!ReadParameters())
{
//printf("read parameter error\n");
return;
} if (!ReportStatusToSCMgr(
SERVICE_START_PENDING, // service state
NO_ERROR, // exit code
3000)) // wait hint
return; if(!CAPIInitKey(szPrvKeyFile))
{
//printf("init key failed.\n");
return;
} if (!ReportStatusToSCMgr(
SERVICE_START_PENDING, // service state
NO_ERROR, // exit code
3000)) // wait hint
return; err = WSAStartup( 0x0101, &WsaData );
if ( err == SOCKET_ERROR ) {
//printf( "WSAStartup failed.\n" );
return;
}
if (!ReportStatusToSCMgr(
SERVICE_RUNNING, // service state
NO_ERROR, // exit code
0)) // wait hint
goto cleanup; sListener = socket( AF_INET, SOCK_STREAM, 0 );
if ( sListener == INVALID_SOCKET ) {
//WSACleanup();
return;
} //
// Bind the socket to the port.
// sin.sin_family = AF_INET;
sin.sin_port = htons( REPL_PORT );
sin.sin_addr.s_addr = INADDR_ANY; err = bind( sListener, (LPSOCKADDR)&sin, sizeof(sin) );
if ( err == SOCKET_ERROR )
goto cleanup; //
// Listen for incoming connections on the socket.
//
err = listen( sListener, 5 );
if ( err == SOCKET_ERROR )
goto cleanup; //
// End of initialization
//
//////////////////////////////////////////////////////// ////////////////////////////////////////////////////////
//
// Service is now running, perform work until shutdown
//
dwThreadNum=0;
while (1)
{
sout_size=sizeof(sout);
s = accept( sListener, (LPSOCKADDR)&sout, &sout_size);
if ( s == INVALID_SOCKET ) {
if (bServiceTerminating )
break;
else
{
ErrorSockCount++;
if(ErrorSockCount>10)
break;
else
continue;
}
}
ErrorSockCount=0;
//
// If the service if terminating, exit this thread.
// if (bServiceTerminating )
{
closesocket(s);
break;
//continue;
}
//sprintf(cNum,"The thread num is %d",dwThreadNum);
//WriteMsgToLogFile(cNum);
if(dwMaxThreadNum!=0){
if(dwThreadNum>=dwMaxThreadNum)
{
closesocket(s);
continue;
}
}
err = setsockopt( s, SOL_SOCKET, SO_RCVBUF, (char *)&dwRCVBUF, sizeof(dwRCVBUF) );
if ( err == SOCKET_ERROR ) {
closesocket( s );
continue;
}
err=setsockopt(s,SOL_SOCKET,SO_SNDBUF,(char *)&dwSNDBUF,sizeof(dwSNDBUF));
//err=getsockopt(s,SOL_SOCKET,SO_SNDBUF,(char *)&dwSNDBUF,&buflen);
//err=setsockopt(s,SOL_SOCKET,SO_RCVBUF,(char *)&dwRCVBUF,sizeof(dwRCVBUF));
if ( err == SOCKET_ERROR ) {
closesocket( s );
continue;
} remoteIp=inet_ntoa(sout.sin_addr);
remoteport=sout.sin_port;
//memset(LogMsg,'\0',64);
//sprintf(LogMsg,"%s:%d connected, begin login.",remoteIp,remoteport);
//WriteMsgToLogFile(LogMsg); LoginUser=NULL;
LoginUser=(struct LOGINUSER *)malloc(sizeof(struct LOGINUSER));
if(LoginUser==NULL)
{
closesocket(s);
continue;
}
LoginUser->s=s;
sprintf(LoginUser->remoteIp,"%s",remoteIp);
LoginUser->remotePort=remoteport;
//free(LoginUser); //printf("send buffer length is %d,length is %d\n",dwSNDBUF,buflen);
hThreadHandle = CreateThread(
NULL,
0,
WorkerThread,
(LPVOID)LoginUser,
0,
&dwThreadId
);
if ( hThreadHandle == NULL ) {
closesocket( s );
continue;
}
else
dwThreadNum=dwThreadNum+1; //sprintf(cNum,"The last thread num is %d",dwThreadNum); } cleanup: closesocket(sListener);
WSACleanup();
}
[email protected]
VOID ServiceStart (DWORD dwArgc, LPTSTR *lpszArgv)
{
SOCKET s;
SOCKADDR_IN sin;
SOCKADDR_IN sout;
int sout_size;
char *remoteIp;
unsigned short remoteport;
// char LogMsg[64];
struct LOGINUSER *LoginUser;
int dwSNDBUF=1024;
// int buflen;
int dwRCVBUF=1024;
int err;
DWORD dwThreadId;
HANDLE hThreadHandle;
int ErrorSockCount;
//char cNum[35];
//
// Create a listening socket that we'll use to accept incoming
// conections.
//
// report the status to the service control manager.
//
if (!ReportStatusToSCMgr(
SERVICE_START_PENDING, // service state
NO_ERROR, // exit code
3000)) // wait hint
return; if(!ReadParameters())
{
//printf("read parameter error\n");
return;
} if (!ReportStatusToSCMgr(
SERVICE_START_PENDING, // service state
NO_ERROR, // exit code
3000)) // wait hint
return; if(!CAPIInitKey(szPrvKeyFile))
{
//printf("init key failed.\n");
return;
} if (!ReportStatusToSCMgr(
SERVICE_START_PENDING, // service state
NO_ERROR, // exit code
3000)) // wait hint
return; err = WSAStartup( 0x0101, &WsaData );
if ( err == SOCKET_ERROR ) {
//printf( "WSAStartup failed.\n" );
return;
}
if (!ReportStatusToSCMgr(
SERVICE_RUNNING, // service state
NO_ERROR, // exit code
0)) // wait hint
goto cleanup; sListener = socket( AF_INET, SOCK_STREAM, 0 );
if ( sListener == INVALID_SOCKET ) {
//WSACleanup();
return;
} //
// Bind the socket to the port.
// sin.sin_family = AF_INET;
sin.sin_port = htons( REPL_PORT );
sin.sin_addr.s_addr = INADDR_ANY; err = bind( sListener, (LPSOCKADDR)&sin, sizeof(sin) );
if ( err == SOCKET_ERROR )
goto cleanup; //
// Listen for incoming connections on the socket.
//
err = listen( sListener, 5 );
if ( err == SOCKET_ERROR )
goto cleanup; //
// End of initialization
//
//////////////////////////////////////////////////////// ////////////////////////////////////////////////////////
//
// Service is now running, perform work until shutdown
//
dwThreadNum=0;
while (1)
{
sout_size=sizeof(sout);
s = accept( sListener, (LPSOCKADDR)&sout, &sout_size);
if ( s == INVALID_SOCKET ) {
if (bServiceTerminating )
break;
else
{
ErrorSockCount++;
if(ErrorSockCount>10)
break;
else
continue;
}
}
ErrorSockCount=0;
//
// If the service if terminating, exit this thread.
// if (bServiceTerminating )
{
closesocket(s);
break;
//continue;
}
//sprintf(cNum,"The thread num is %d",dwThreadNum);
//WriteMsgToLogFile(cNum);
if(dwMaxThreadNum!=0){
if(dwThreadNum>=dwMaxThreadNum)
{
closesocket(s);
continue;
}
}
err = setsockopt( s, SOL_SOCKET, SO_RCVBUF, (char *)&dwRCVBUF, sizeof(dwRCVBUF) );
if ( err == SOCKET_ERROR ) {
closesocket( s );
continue;
}
err=setsockopt(s,SOL_SOCKET,SO_SNDBUF,(char *)&dwSNDBUF,sizeof(dwSNDBUF));
//err=getsockopt(s,SOL_SOCKET,SO_SNDBUF,(char *)&dwSNDBUF,&buflen);
//err=setsockopt(s,SOL_SOCKET,SO_RCVBUF,(char *)&dwRCVBUF,sizeof(dwRCVBUF));
if ( err == SOCKET_ERROR ) {
closesocket( s );
continue;
} remoteIp=inet_ntoa(sout.sin_addr);
remoteport=sout.sin_port;
//memset(LogMsg,'\0',64);
//sprintf(LogMsg,"%s:%d connected, begin login.",remoteIp,remoteport);
//WriteMsgToLogFile(LogMsg); LoginUser=NULL;
LoginUser=(struct LOGINUSER *)malloc(sizeof(struct LOGINUSER));
if(LoginUser==NULL)
{
closesocket(s);
continue;
}
LoginUser->s=s;
sprintf(LoginUser->remoteIp,"%s",remoteIp);
LoginUser->remotePort=remoteport;
//free(LoginUser); //printf("send buffer length is %d,length is %d\n",dwSNDBUF,buflen);
hThreadHandle = CreateThread(
NULL,
0,
WorkerThread,
(LPVOID)LoginUser,
0,
&dwThreadId
);
if ( hThreadHandle == NULL ) {
closesocket( s );
continue;
}
else
dwThreadNum=dwThreadNum+1; //sprintf(cNum,"The last thread num is %d",dwThreadNum); } cleanup: closesocket(sListener);
WSACleanup();
}
如果在调试的话就设置表示调试状态的变量 然后执行CmdDebugService
CmdDebugService传递的参数其实是main函数传进来的参数 我的服务程序是纯C下的
我在main里调用是
else if ( _stricmp( "debug", argv[1]+1 ) == 0 )
{
bDebug = TRUE;
CmdDebugService(argc, argv);
}
从任务管理器中结束本任务,就可以设置断点
刚刚开发的pops service 就是这样调试的。
如果在调试的话就设置表示调试状态的变量 然后执行CmdDebugService
CmdDebugService传递的参数其实是main函数传进来的参数 我的服务程序是纯C下的
我在main里调用是
else if ( _stricmp( "debug", argv[1]+1 ) == 0 )
{
bDebug = TRUE;
CmdDebugService(argc, argv);
}
HOWTO: Debugging a service
ID: Q98890 )我觉得比较好用的是在程序的开头添加一个DebugBreak()的调用,服务运行后就在这里出现一个软中断框,然后进行调试,就可以向普通应用程序一样调试了。(还需要设置该服务可以和桌面交互操作)
然后注册运行,在task manager中找到需要调试的Service的线程,
用鼠标选中后点击右键,在菜单中选择调试,然后再弹出的VC环境中
加断点调试即可。
我们设置一个CmdDebugService(argc, argv);就是,如果是debug模式,就由他来进入ServiceStart 。而程序不在调试状态时,SERVICE_TABLE_ENTRY dispatchTable[] 进入ServiceStart
void _CRTAPI1 main(int argc, char **argv)
{
// Single Process Service
SERVICE_TABLE_ENTRY dispatchTable[] = {
{ TEXT(SZSERVICENAME), (LPSERVICE_MAIN_FUNCTION)importsrv_main },
{ NULL, NULL }
}; // -install -> install the service
// -setup -> Setup system parameters
// -remove -> remove the service from Service Control
// -service -> Start the service in console
//printf("Entering main\n");
if ( (argc > 1) && ((*argv[1] == '-') || (*argv[1] == '/')) ) {
if ( _stricmp( "install", argv[1]+1 ) == 0 ) {
//printf("Install service\n");
CmdInstallService();
}
else if ( _stricmp( "setup", argv[1]+1 ) == 0 ) {
CmdSetupPara();
}
else if ( _stricmp( "remove", argv[1]+1 ) == 0 ) {
CmdRemoveService();
}
else if ( _stricmp( "service", argv[1]+1 ) == 0 ) {
goto dispatch;
}
else {
gbDebug = TRUE;
CmdDebugService(argc, argv);
}
exit(0);
}
dispatch:
// this is just to be friendly
_tprintf( "%s -install install the importsrv service\n", SZAPPNAME );
_tprintf( "%s -setup setup consrv registry entries\n", SZAPPNAME );
_tprintf( "%s -remove remove the importsrv service\n", SZAPPNAME );
_tprintf( "%s -service to run as a service\n", SZAPPNAME );
_tprintf( "\nStartServiceCtrlDispatcher being called.\n" );
_tprintf( "This may take several seconds. Please wait.\n" ); if (!StartServiceCtrlDispatcher(dispatchTable)) {
_tprintf("Service start r failed.");
WriteLog(MSGPRI_ERR, "service start CtrlDispatcher failed.");
}
}下面是主程序不在调试状态下的进入主程序,也就是SERVICE_TABLE_ENTRY dispatchTable[] = {
{ TEXT(SZSERVICENAME), (LPSERVICE_MAIN_FUNCTION)importsrv_main },{ NULL, NULL } };
而来的
void WINAPI importsrv_main(DWORD dwArgc, LPTSTR *lpszArgv)
{
DWORD dwErr; // register our service control handler:
//
gsshStatusHandle =
RegisterServiceCtrlHandler( TEXT(SZSERVICENAME),
service_ctrl); if (!gsshStatusHandle)
goto cleanup; // SERVICE_STATUS members that don't change in example
//
gssStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
gssStatus.dwServiceSpecificExitCode = 0; // report the status to the service control manager.
//
if (!ReportStatusToSCMgr( SERVICE_START_PENDING, // service state
NO_ERROR, // exit code
3000)) // wait hint
goto cleanup; ServiceStart( dwArgc, lpszArgv );<-----------------主程序cleanup: // try to report the stopped status to the service control manager.
//
dwErr = NO_ERROR ;
if (gsshStatusHandle)
(VOID)ReportStatusToSCMgr( SERVICE_STOPPED,
dwErr,
0); return;
}
由调试状态进入的主程序:void CmdDebugService(int argc, char ** argv)
{
DWORD dwArgc;
LPTSTR *lpszArgv;#ifdef UNICODE
lpszArgv = CommandLineToArgvW(GetCommandLineW(), &(dwArgc) );
#else
dwArgc = (DWORD) argc;
lpszArgv = argv;
#endif _tprintf(TEXT("Debugging %s.\n"), TEXT(SZSERVICEDISPLAYNAME)); SetConsoleCtrlHandler( ControlHandler, TRUE ); ServiceStart( dwArgc, lpszArgv );<------------------主程序
}
如果是正常模式,程序就
SERVICE_TABLE_ENTRY dispatchTable[] = {
{ TEXT(SZSERVICENAME), (LPSERVICE_MAIN_FUNCTION)uploadsrv_main },
{ NULL, NULL }
};
来进入uploadsrv_main()来进入主程序ServiceStart (DWORD dwArgc, LPTSTR *lpszArgv)
这是主要的几步:
1。void _CRTAPI1 main(int argc, char **argv)
{
// Single Process Service
SERVICE_TABLE_ENTRY dispatchTable[] = {
{ TEXT(SZSERVICENAME), (LPSERVICE_MAIN_FUNCTION)uploadsrv_main },
{ NULL, NULL }
};
//printf("Entering main\n");
if ( (argc > 1) && ((*argv[1] == '-') || (*argv[1] == '/')) ) {
if ( _stricmp( "install", argv[1]+1 ) == 0 ) {
//printf("Install service\n");
CmdInstallService();
}
else if ( _stricmp( "setup", argv[1]+1 ) == 0 ) {
CmdSetupPara();
}
else if ( _stricmp( "remove", argv[1]+1 ) == 0 ) {
CmdRemoveService();
}
else if ( _stricmp( "service", argv[1]+1 ) == 0 ) {
goto dispatch;
}
else {
gbDebug = TRUE;
CmdDebugService(argc, argv);
}
exit(0);
} // if it doesn't match any of the above parameters
// the service control manager may be starting the service
// so we must call StartServiceCtrlDispatcher
dispatch:
// this is just to be friendly
_tprintf( "%s -install install the uploadsrv service\n", SZAPPNAME );
_tprintf( "%s -setup setup consrv registry entries\n", SZAPPNAME );
_tprintf( "%s -remove remove the uploadsrv service\n", SZAPPNAME );
_tprintf( "%s -service to run as a service\n", SZAPPNAME );
_tprintf( "\nStartServiceCtrlDispatcher being called.\n" );
_tprintf( "This may take several seconds. Please wait.\n" ); if (!StartServiceCtrlDispatcher(dispatchTable)) {
_tprintf("Service start CtrlDispatcher failed.");
WriteLog(MSGPRI_ERR, "Service start CtrlDispatcher failed.");
}
}
2.
// FUNCTION: uploadsrv_main
//
// PURPOSE: To perform actual initialization of the service
//
// PARAMETERS:
// dwArgc - number of command line arguments
// lpszArgv - array of command line arguments
//
// RETURN VALUE:
// none
//
// COMMENTS:
// This routine performs the service initialization and then calls
// the user defined ServiceStart() routine to perform majority
// of the work.
//
void WINAPI uploadsrv_main(DWORD dwArgc, LPTSTR *lpszArgv)
{
DWORD dwErr; // register our service control handler:
//
gsshStatusHandle =
RegisterServiceCtrlHandler( TEXT(SZSERVICENAME),
uploadsrv_ctrl); if (!gsshStatusHandle)
goto cleanup; // SERVICE_STATUS members that don't change in example
//
gssStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
gssStatus.dwServiceSpecificExitCode = 0; // report the status to the service control manager.
//
if (!ReportStatusToSCMgr( SERVICE_START_PENDING, // service state
NO_ERROR, // exit code
3000)) // wait hint
goto cleanup; ServiceStart( dwArgc, lpszArgv );cleanup: // try to report the stopped status to the service control manager.
//
dwErr = NO_ERROR ;
if (gsshStatusHandle)
(VOID)ReportStatusToSCMgr( SERVICE_STOPPED,
dwErr,
0); return;
}3.debug模式进入点:
void CmdDebugService(int argc, char ** argv)
{
DWORD dwArgc;
LPTSTR *lpszArgv;#ifdef UNICODE
lpszArgv = CommandLineToArgvW(GetCommandLineW(), &(dwArgc) );
#else
dwArgc = (DWORD) argc;
lpszArgv = argv;
#endif _tprintf(TEXT("Debugging %s.\n"), TEXT(SZSERVICEDISPLAYNAME)); SetConsoleCtrlHandler( ControlHandler, TRUE ); ServiceStart( dwArgc, lpszArgv );
}
主程序:
VOID ServiceStart (DWORD dwArgc, LPTSTR *lpszArgv)
{
}
其实MSDN中有说的,你看看这个中文版的吧:)第七节 调试一个服务(Debugging a Service)
您可以用下面的方式调试您的服务。
•使用您自己的调试工具在服务运行时调试服务。首先,获得服务进程的进程标示符(PID)。可以从PView应用程序中获得这些信息。获得PID后,附加到运行的程序上。要获得语法信息,参看您自己调试器的文档。
•调用DebugBreak函数请求调试器进行及时调试。
•当启动程序时,指定所用的调试器。要这样做,可以在如下的注册表位置创建一个叫做映像文件执行选项的值:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion
创建一个与您的服务名称一样的子键值(例如:MYSERV.EXE)。在此子键下,添加REG_SZ类型,名称为Debugger。串值使用调试器的完整路径。在服务控制面板小程序中,选择你的服务,单击Startup并选中Allow Service to Interact with Desktop。
注释 要调试自动启动服务的初始化代码,你得暂时以请求-启动的方式安装和运行服务。