我有个问题是是否能够在NTService中使用多线程和时钟。
如:由时钟控制到了一定的时间就产生一个新的线程
每隔一定的时间去判断线程是否结束?

解决方案 »

  1.   


    #include <windows.h> typedef struct tagSOCKETSTRU{ 
    WORD dwVersion; 
    DWORD dwFlag; 
    int addrlen,ret; 
    WSADATA wsaData; 
    SOCKET CreateSock,NewSock; 
    SOCKADDR_IN Sock_in; 
    fd_set FdRead; 
    }SOCKETSTRU,*LPSOCKETSTRU; 
    LPSOCKETSTRU lpSockStru; SERVICE_STATUS_HANDLE ssh; 
    SERVICE_STATUS ss; LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM); 
    void WINAPI StartupService(); void WINAPI WriteLogFile(LPCTSTR szBuff) 

    HANDLE hFile; 
    DWORD dwWrite; 
    TCHAR szTemp[MAX_PATH]; 
    SYSTEMTIME systime; hFile=CreateFile( "C:\\IP_Log.log", 
    GENERIC_READ|GENERIC_WRITE, 
    FILE_SHARE_WRITE, 
    NULL, 
    OPEN_ALWAYS, 
    FILE_ATTRIBUTE_HIDDEN, 
    NULL 
    ); GetSystemTime(&systime); wsprintf(szTemp,"<<%ld.%ld.%ld.%ld.%ld.%ld--ip: %s>>,", 
    systime.wYear, 
    systime.wMonth, 
    systime.wDay, 
    systime.wHour+8, 
    systime.wMinute, 
    systime.wSecond, 
    szBuff 
    ); SetFilePointer(hFile,0,NULL,FILE_END); 
    WriteFile(hFile,szTemp,lstrlen(szTemp),&dwWrite,0); 
    CloseHandle(hFile); 
    } DWORD WINAPI IPThread(LPVOID lParam) 
    { TCHAR szBuf[MAX_PATH]; 
    LPSOCKETSTRU lpSock=(LPSOCKETSTRU)lParam; while(TRUE) 

    FD_ZERO(&lpSock->FdRead); 
    FD_SET(lpSock->CreateSock,&lpSock->FdRead); lpSock->ret=select(0,&lpSock->FdRead,NULL,NULL,NULL); 
    if(lpSock->ret==SOCKET_ERROR) 

    closesocket(lpSock->CreateSock); 
    return FALSE; 
    } if(FD_ISSET(lpSock->CreateSock,&lpSock->FdRead)) 

    lpSock->addrlen=sizeof(SOCKADDR_IN); 
    lpSock->NewSock=accept(lpSock->CreateSock,(LPSOCKADDR)&lpSock->Sock_in,&lpSock->addrlen); 
    if(lpSock->NewSock==INVALID_SOCKET) 

    closesocket(lpSock->NewSock); 

    getpeername(lpSock->CreateSock,(LPSOCKADDR)&lpSock->Sock_in,&lpSock->addrlen); 
    wsprintf(szBuf,"Your IP Address is %s",inet_ntoa(lpSock->Sock_in.sin_addr)); 
    send(lpSock->NewSock,szBuf,lstrlen(szBuf),0); 
    WriteLogFile(inet_ntoa(lpSock->Sock_in.sin_addr)); 

    } return TRUE; 
    } void WINAPI LogIP(LPSOCKETSTRU lpSock,int Port) 
    { HANDLE hThread; 
    DWORD dwTid; lpSock->dwVersion=MAKEWORD(1,1); 
    lpSock->dwFlag=TRUE; if((WSAStartup(lpSock->dwVersion,&lpSock->wsaData))!=0) 

    MessageBox(NULL,"INIT SOCKET ERROR",NULL,MB_OK); 
    } lpSock->CreateSock=socket(AF_INET,SOCK_STREAM,0); 
    if(lpSock->CreateSock==SOCKET_ERROR) 

    closesocket(lpSock->CreateSock); 
    MessageBox(NULL,"SOCKET ERROR",NULL,MB_OK); 
    } lpSock->Sock_in.sin_family=AF_INET; 
    lpSock->Sock_in.sin_port=htons(Port); 
    lpSock->Sock_in.sin_addr.S_un.S_addr=htonl(INADDR_ANY); setsockopt(lpSock->CreateSock,SOL_SOCKET,SO_REUSEADDR,(LPSTR)&lpSock->dwFlag,sizeof(lpSock->dwFlag));
    if(bind(lpSock->CreateSock,(LPSOCKADDR)&lpSock->Sock_in,sizeof(lpSock->Sock_in))==SOCKET_ERROR) 

    closesocket(lpSock->CreateSock); 
    MessageBox(NULL,"BIND ERROR",NULL,MB_OK); 
    } else if(listen(lpSock->CreateSock,1)==SOCKET_ERROR) 

    closesocket(lpSock->CreateSock); 
    MessageBox(NULL,"LISTEN ERROR",NULL,MB_OK); 
    } hThread=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)IPThread,(LPVOID)lpSock,0,&dwTid); 
    CloseHandle(hThread); } 
    void WINAPI Handler(DWORD Opcode) 

    switch(Opcode) 

    case SERVICE_CONTROL_STOP: 
    closesocket(lpSockStru->CreateSock); 
    closesocket(lpSockStru->NewSock); 
    ss.dwWin32ExitCode=0; 
    ss.dwCurrentState=SERVICE_STOPPED; 
    ss.dwCheckPoint=0; 
    ss.dwWaitHint=0; 
    SetServiceStatus(ssh,&ss); 
    if(lpSockStru!=NULL) 
    HeapFree(GetProcessHeap(),HEAP_NO_SERIALIZE,lpSockStru); 
    break; case SERVICE_CONTROL_INTERROGATE: 
    SetServiceStatus (ssh,&ss); break; 


    void WINAPI ServiceMain(DWORD dwArgc,LPTSTR *lpszArgv) 

    ssh=RegisterServiceCtrlHandler("JIA.JIA.SERVICE",Handler); 
    ss.dwServiceType=SERVICE_WIN32_OWN_PROCESS|SERVICE_INTERACTIVE_PROCESS; 
    ss.dwCurrentState=SERVICE_START_PENDING; 
    ss.dwControlsAccepted=SERVICE_ACCEPT_STOP; 
    ss.dwWin32ExitCode=NO_ERROR; 
    ss.dwCheckPoint=0; 
    ss.dwWaitHint=0; 
    SetServiceStatus(ssh, &ss); ss.dwServiceType=SERVICE_WIN32_OWN_PROCESS|SERVICE_INTERACTIVE_PROCESS; 
    ss.dwCurrentState=SERVICE_RUNNING; 
    ss.dwControlsAccepted=SERVICE_ACCEPT_STOP; 
    ss.dwWin32ExitCode=NO_ERROR; 
    ss.dwCheckPoint=0; 
    ss.dwWaitHint=0; 
    SetServiceStatus(ssh,&ss); 
    lpSockStru=(LPSOCKETSTRU)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(SOCKETSTRU)); 
    if(lpSockStru!=NULL) LogIP(lpSockStru,102); } 
    void WINAPI InstallService() 

    SC_HANDLE scm; 
    SC_HANDLE svc; 
    TCHAR szFile[MAX_PATH]; GetModuleFileName(NULL,szFile,MAX_PATH); 
    scm=OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS); 
    svc=CreateService( scm, 
    "JIA.JIA.SERVICE", 
    "JIA.JIA.SERVICE",//Service名字 
    SERVICE_ALL_ACCESS, 
    SERVICE_WIN32_OWN_PROCESS|SERVICE_INTERACTIVE_PROCESS, 
    SERVICE_AUTO_START, //以自动方式开始 
    SERVICE_ERROR_NORMAL, 
    szFile, //Service本体程序路径, 必须与具体位置相符 
    NULL, 
    NULL, 
    NULL, 
    NULL, 
    NULL 
    ); 
    if(svc!=NULL) 

    CloseServiceHandle(svc); 
    CloseServiceHandle(scm); 
    StartupService(); } 

    void WINAPI DeleteService() 

    SC_HANDLE scm; 
    SC_HANDLE svc; 
    SERVICE_STATUS ServiceStatus; scm=OpenSCManager(NULL,NULL,SC_MANAGER_CONNECT); 
    if(scm!=NULL) 

    svc=OpenService(scm,"JIA.JIA.SERVICE",SERVICE_ALL_ACCESS); 
    if (svc!=NULL) 

    QueryServiceStatus(svc,&ServiceStatus); 
    if (ServiceStatus.dwCurrentState==SERVICE_RUNNING) 
    ControlService(svc,SERVICE_CONTROL_STOP,&ServiceStatus); 
    DeleteService(svc); 
    CloseServiceHandle(svc); 
    MessageBox(NULL,"IPLog 服务已删除","删除",MB_OK); 

    CloseServiceHandle(scm); 

    else MessageBox(NULL,"IPLog 删除失败",NULL,MB_OK); } void WINAPI StartupService() 

    SC_HANDLE scm; 
    SC_HANDLE svc; scm=OpenSCManager(NULL,NULL,SC_MANAGER_CONNECT); 
    if(scm!=NULL) 

    svc=OpenService(scm,"JIA.JIA.SERVICE",SERVICE_START); 
    if(svc!=NULL) 

    StartService(svc,0,NULL); 
    CloseServiceHandle(svc); 
    MessageBox(NULL,"服务已启动","启动",MB_OK); 

    CloseServiceHandle(scm); 

    else MessageBox(NULL,"启动服务失败",NULL,MB_OK); } void WINAPI InitService() 

    SERVICE_TABLE_ENTRY ste[2]; ste[0].lpServiceName="JIA.JIA.SERVICE"; 
    ste[0].lpServiceProc=ServiceMain; 
    ste[1].lpServiceName=NULL; 
    ste[1].lpServiceProc=NULL; 
    StartServiceCtrlDispatcher(ste); 
    InstallService(); 
    } int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE,PSTR ,int iCmdShow) 

    static char szAppName[]="LogIP_Service" ; 
    HWND hWnd ; 
    MSG msg ; 
    WNDCLASSEX wndclass ; wndclass.cbSize =sizeof (wndclass) ; 
    wndclass.style =CS_HREDRAW | CS_VREDRAW ; 
    wndclass.lpfnWndProc =WndProc ; 
    wndclass.cbClsExtra =0 ; 
    wndclass.cbWndExtra =0 ; 
    wndclass.hInstance =hInstance ; 
    wndclass.hIcon =LoadIcon (NULL, IDI_APPLICATION) ; 
    wndclass.hCursor =LoadCursor (NULL, IDC_ARROW) ; 
    wndclass.hbrBackground =(HBRUSH) GetStockObject (WHITE_BRUSH) ; 
    wndclass.lpszMenuName =NULL ; 
    wndclass.lpszClassName =szAppName ; 
    wndclass.hIconSm =LoadIcon (NULL, IDI_APPLICATION) ; RegisterClassEx (&wndclass) ; hWnd=CreateWindow(szAppName,"IP_Service", 
    WS_OVERLAPPEDWINDOW, 
    CW_USEDEFAULT, CW_USEDEFAULT, 
    CW_USEDEFAULT, CW_USEDEFAULT, 
    NULL, NULL, hInstance, NULL) ; ShowWindow(hWnd,SW_HIDE); 
    UpdateWindow(hWnd); while(GetMessage(&msg,NULL,0,0)) 

    TranslateMessage (&msg) ; 
    DispatchMessage (&msg) ; 

    return msg.wParam ; 

    LRESULT CALLBACK WndProc (HWND hWnd, UINT iMsg, WPARAM wParam, LPARAM lParam) 
    ]{ 
    switch (iMsg) 

    case WM_CREATE : 
    InitService(); 
    //DeleteService(); 
    return 0 ; case WM_DESTROY : 
    DeleteService(); 
    PostQuitMessage(0); 
    return 0; 

    return DefWindowProc(hWnd,iMsg,wParam,lParam) ; 
    }  
      

  2.   

    在标准的NT SERVIE程序中,你不得不使用多线程。可以用用户界面的线程,在那里面搞一个窗口,窗口是HIDDEN的,然后在窗口里搞一个TIMER
      

  3.   

    当然可以  你可以使用楼上人的意见 使用一个用户界面的TIMER
      

  4.   

    可以使用WaitableTimer吧:
    HANDLE CreateWaitableTimer(
      LPSECURITY_ATTRIBUTES lpTimerAttributes, // SD
      BOOL bManualReset,                       // reset type
      LPCTSTR lpTimerName                      // object name
    );然后在做一个工作线程Wait该Timer,wait到了就创建新线程,然后再Wait这个Timer..