查杀进程

来源:互联网 发布:园林景观软件 编辑:程序博客网 时间:2024/05/01 09:51

******CNTServices.h******

 

/*有错误*/

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

class CNTServices
{
public:
 SERVICE_STATUS m_ServiceStatus;
 SERVICE_STATUS_HANDLE m_ServiceStatusHandle;

 /***************************************************************
 *static function
 */
 // Control Handler
 static void WINAPI ControlHandler(DWORD request);

 //Service main program
 static void WINAPI ServiceMain(int argc, char** argv);

 /*
 static member
 */
 static CNTServices* m_pThis; // nasty hack to get object ptr

public:
 char m_szServicename[MAX_PATH];
 char m_szFilePath[MAX_PATH];

 CNTServices(char* szServiceName);

 virtual ~CNTServices()
 {
  m_ServiceStatus.dwCurrentState = SERVICE_STOPPED;
  m_ServiceStatus.dwWin32ExitCode = -1;
  SetServiceStatus(m_ServiceStatusHandle, &m_ServiceStatus);
 }

 //获取当前程序路径,不包含程序名
 void GetAppPath()
 {
  char szExePath[MAX_PATH] = { 0 };
  GetModuleFileName(NULL, szExePath, MAX_PATH);
  strncpy(m_szFilePath, szExePath, strlen(szExePath)-strlen("KillProcess.exe"));
 }

 //写日志
 int WriteToLog(char* str)
 {
  FILE* log;
  char szLogPath[MAX_PATH] = { 0 };
  sprintf(szLogPath, "%slog.txt", m_szFilePath);
  log = fopen(szLogPath, "a+");
  if (log == NULL)
  {
   OutputDebugString("Log file open failed.");
   return -1;
  }

  //write str in logfile
  SYSTEMTIME systemTime;
/*  ::GetSystemTime(&systemTime); //返回值中小时总是比系统时间少八个小时
      //这是世界标准时间。和我国的时间不一样
      //getlocaltime 返回的才是本地时间
*/
  ::GetLocalTime(&systemTime);
  char sztime[MAX_PATH] = {0};
  sprintf(sztime, "%d-%d-%d %d:%d:%d", systemTime.wYear, systemTime.wMonth, systemTime.wDay,
     systemTime.wHour, systemTime.wMinute, systemTime.wSecond);

  char szlog[MAX_PATH] = {0};
  sprintf(szlog, "%s /t%s", sztime, str);
  fprintf(log, "%s/n", szlog);
  fclose(log);
  return 0;
 }

 int InitService()
 {
  OutputDebugString("Monitoring started.");
  int result;
  result = WriteToLog("Monitoring started.");
  return(result);
 }

 virtual void DoTask() = 0;

 
};

 

 

 

********CNTServices.cpp***********

 

#include "CNTServices.h"

// static variables
CNTServices* CNTServices::m_pThis = NULL;

CNTServices::CNTServices(char* szServiceName)
{
 memset(m_szServicename, 0, MAX_PATH);
 memset(m_szFilePath, 0, MAX_PATH);

 strcpy(m_szServicename, szServiceName);

 GetAppPath();

 m_pThis = this;
}

void CNTServices::ControlHandler(DWORD request)
{
 switch(request)
 {
 case SERVICE_CONTROL_STOP:
  OutputDebugString("Monitoring stopped.");
  m_pThis->WriteToLog("Monitoring stopped.");

  m_pThis->m_ServiceStatus.dwWin32ExitCode = 0;
  m_pThis->m_ServiceStatus.dwCurrentState = SERVICE_STOPPED;
  SetServiceStatus (m_pThis->m_ServiceStatusHandle, &m_pThis->m_ServiceStatus);
  return;

 case SERVICE_CONTROL_SHUTDOWN:
  OutputDebugString("Monitoring stopped.");
  m_pThis->WriteToLog("Monitoring stopped.");

  m_pThis->m_ServiceStatus.dwWin32ExitCode = 0;
  m_pThis->m_ServiceStatus.dwCurrentState = SERVICE_STOPPED;
  SetServiceStatus (m_pThis->m_ServiceStatusHandle, &m_pThis->m_ServiceStatus);
  return;

 default:
  break;
 }

 // Report current status
 SetServiceStatus (m_pThis->m_ServiceStatusHandle, &m_pThis->m_ServiceStatus);

 return;
}

void CNTServices::ServiceMain(int argc, char** argv)
{
 int error;

 m_pThis->m_ServiceStatus.dwServiceType = SERVICE_WIN32;
 m_pThis->m_ServiceStatus.dwCurrentState = SERVICE_START_PENDING;
 m_pThis->m_ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN;
 m_pThis->m_ServiceStatus.dwWin32ExitCode = 0;
 m_pThis->m_ServiceStatus.dwServiceSpecificExitCode = 0;
 m_pThis->m_ServiceStatus.dwCheckPoint = 0;
 m_pThis->m_ServiceStatus.dwWaitHint = 0;

 m_pThis->m_ServiceStatusHandle = RegisterServiceCtrlHandler(
  m_pThis->m_szServicename/*"MemoryStatus"*/,
  ControlHandler/*(LPHANDLER_FUNCTION)ControlHandler*/);
 //error reason:ControlHandler属于这个类,而LPHANDLER_FUNCTION不属于这个类
 //so: ControlHandler应该改为静态函数
 if (m_pThis->m_ServiceStatusHandle == (SERVICE_STATUS_HANDLE)0)
 {
  // Registering Control Handler failed
  return;
 } 

 // Initialize Service ,InitService()是自己的代码
 error = m_pThis->InitService();
 if (error)
 {
  // Initialization failed
  m_pThis->m_ServiceStatus.dwCurrentState = SERVICE_STOPPED;
  m_pThis->m_ServiceStatus.dwWin32ExitCode = -1;
  SetServiceStatus(m_pThis->m_ServiceStatusHandle, &m_pThis->m_ServiceStatus);
  return;
 }

 // We report the running status to SCM.
 m_pThis->m_ServiceStatus.dwCurrentState = SERVICE_RUNNING;
 SetServiceStatus (m_pThis->m_ServiceStatusHandle, &m_pThis->m_ServiceStatus);

 // The worker loop of a service
 while (m_pThis->m_ServiceStatus.dwCurrentState == SERVICE_RUNNING)
 {
  m_pThis->DoTask();
 }
 return;
}

 

 

 

*********KillProcess.h***********

 

#include "CNTServices.h"

class CKillProcess : public CNTServices
{
 struct PROCINFO
 {
  char szName[26];
  int nLivingTime;  //被杀进程允许存活时间
  int nLeaveTime;

  HANDLE hProcess;
  DWORD dwProcessId[2]; //检测到的被杀进程ID
  int i;
 };
 PROCINFO* m_pProc;

 char m_szTimeUnit[7];  //3个值:"minute", "hour", "second"
 int m_nCheckTime;   //程序检测时间
 int m_nProcessNum;
 bool m_bIfIniRight;

public:
 CKillProcess(char* szName) : CNTServices(szName)
 {
//  m_nProcessNum = 1;
//  m_nCheckTime = 1;
  m_pProc = 0;
  m_bIfIniRight = true;
  memset(m_szTimeUnit, 0, 7);
  strcpy(m_szTimeUnit, "second");
  ReadIniFile();
 }

 ~CKillProcess()
 {
  if(m_pProc != NULL)
  {
   delete [] m_pProc;
   m_pProc = NULL;
  }
 }

 int TransTime(const char* szTimeUnit, int nTranTime)
 {
  //因为Sleep参数是毫秒,*1000=秒
  if(strcmp(szTimeUnit, "minute") == 0)
  {
//   m_nCheckTime = atoi(szChecktime)*1000*60;//单位是分钟
//   m_nLivingTime = atoi(szLivingtime)*1000*60;
   WriteToLog("time_unit is minute!");
   return nTranTime*1000*60;
  }
  else if(strcmp(szTimeUnit, "hour") == 0)
  {
//   m_nCheckTime = atoi(szChecktime)*1000*60*60;//单位是小时
//   m_nLivingTime = atoi(szLivingtime)*1000*60*60;
   WriteToLog("time_unit is hour!");
   return (nTranTime*1000*60*60);
  }
  else if(strcmp(szTimeUnit, "second") == 0)
  {
   WriteToLog("time_unit is second!");
   return nTranTime*1000;
  }
  else
  {
   WriteToLog("time_unit setting error!");
   return -1;
  }
 }

 void InitProcInfo(int nProcessNum, char* szIniFile)
 {
  ///  PROCINFO proc[nProcessNum];
  m_pProc = new PROCINFO[nProcessNum];
  int j;
  for(j = 0; j < nProcessNum; j++)
  {
   char szProcName[26] = {0};
   int nLivingtime = 0;
   char szArea[26] = {0};
   sprintf(szArea, "process_%d", j);
   
   int value2;
   value2 = ::GetPrivateProfileString(szArea, "PROCESS_NAME", NULL, szProcName, 26, szIniFile);
   nLivingtime = GetPrivateProfileInt(szArea, "LIVING_TIME", -1, szIniFile);

   if(value2 == 0 || nLivingtime == 0)
   {
    char strtmp[80] = {0};
    sprintf(strtmp, "can't find right set: process_%d or process_name or living_time", j);
    WriteToLog(strtmp);
    m_bIfIniRight = false;
    return ;
   }
   if(strcmp(szProcName,"") == 0)
   {
    WriteToLog("error: process_name set null!");
    m_bIfIniRight = false;
    return ;
   }
//   m_pProc[j].szName = szProcName;//error
   memset(m_pProc[j].szName, 0, 26);
   strcpy(m_pProc[j].szName, szProcName);

   int time = TransTime(m_szTimeUnit, nLivingtime);
   if(time == -1)
   {
    WriteToLog("error: living_time setting!");
    m_bIfIniRight = false;
    return ;
   }

   m_pProc[j].nLivingTime = m_pProc[j].nLeaveTime = time;
   m_pProc[j].dwProcessId[0] = m_pProc[j].dwProcessId[1] = 0;
   m_pProc[j].hProcess = 0;
   m_pProc[j].i = 0;
  }
 }

 void CreateIniFile(char* szIniFile)
 {
  //怎样在配置文件中写入空行??????
  WritePrivateProfileString("SETTING", "TIME_UNIT", "second", szIniFile);
  WritePrivateProfileString("SETTING", "CHECK_TIME", "1", szIniFile);
  WritePrivateProfileString("SETTING", "PROCESS_NUM", "1", szIniFile);

//  WritePrivateProfileString("", "", "", szIniFile);

  WritePrivateProfileString("PROCESS_0", "PROCESS_NAME", "***", szIniFile);
  WritePrivateProfileString("PROCESS_0", "LIVING_TIME", "1", szIniFile);
 }

 void ReadIniFile()
 {
  //get base setting param
  char szIniFile[MAX_PATH] = {0};
  sprintf(szIniFile, "%sKillProcess.ini", CNTServices::m_szFilePath);
  FILE* pFini = fopen(szIniFile, "r");//判断是否有配置文件
  if(pFini == NULL)
  {
   CreateIniFile(szIniFile);
   m_nProcessNum = 1;
  }
  else
  {
   fclose(pFini);
   pFini = NULL;
   int value1;

   char szProcessNum[3] = {0};
///   char szCheckUnit[7] = {0};
   int nChecktime = 0;
   value1 = ::GetPrivateProfileString("setting", "TIME_UNIT ", NULL, m_szTimeUnit, 7, szIniFile);
//   value2 = ::GetPrivateProfileInt("SETTING", "PROCESS_NUM", m_nProcessNum, szIniFile);//用法错误
   m_nProcessNum = ::GetPrivateProfileInt("SETTING", "PROCESS_NUM", -1, szIniFile);
//   m_nProcessNum = atoi(szProcessNum);
   if(m_nProcessNum  == -1)
   {
//    m_nProcessNum = 1;
    WriteToLog("error:process_num setting");
    m_bIfIniRight = false;
    return ;
   }

   nChecktime = GetPrivateProfileInt("setting", "check_time", nChecktime, szIniFile);
/*   *
   *测试代码
   *
   char strtmp[4] = {0};
   sprintf(strtmp, "%d", value);
   WriteToLog(strtmp);*/

   //GetPrivateProfileString没有找到正确的setting或check_time
   if(0 == value1 || 0 == m_nProcessNum || 0 == nChecktime)
   {
    WriteToLog("can't find right set: setting or time_unit or check_time or process_num");
    m_bIfIniRight = false;
    return ;
   }
   else
   {
    m_nCheckTime = TransTime(m_szTimeUnit, nChecktime);
    if(m_nCheckTime == -1)
    {
     WriteToLog("error:check_time or time_unit setting");
     m_bIfIniRight = false;
     return ;
    }
   }
  }

  InitProcInfo(m_nProcessNum, szIniFile);
 }

 bool FindProcessByName();
 void KillProcess(int nProcNo);
 void DoTask();

};

 

 

********KillProcess.cpp**********

 

#include "KillProcess.h"
#include <windows.h>
#include <Tlhelp32.h>


bool CKillProcess::FindProcessByName()
{
 HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
 if(INVALID_HANDLE_VALUE == hSnapshot)
 {
  CNTServices::WriteToLog("CreateToolhelp32Snapshot fail!");
  ::CloseHandle(hSnapshot);
  return false;
 }

 PROCESSENTRY32 prosinfo;
 prosinfo.dwSize = sizeof(prosinfo);
 bool bState = Process32First(hSnapshot, &prosinfo);
 if(!bState)
 {
  CNTServices::WriteToLog("Process32First fail!");
  ::CloseHandle(hSnapshot);
  return false;
 }

 while(bState)
 {
  char* pStr = prosinfo.szExeFile;

  int j;
  for(j = 0; j < m_nProcessNum; j++)
  {
   //找到进程
   if(strcmp(pStr, m_pProc[j].szName) == 0)
   {
    m_pProc[j].dwProcessId[m_pProc[j].i] = prosinfo.th32ProcessID;
    //对于同样的进程,每次OpenProcess返回的handle都不一样
    m_pProc[j].hProcess = ::OpenProcess(PROCESS_TERMINATE, false, m_pProc[j].dwProcessId[m_pProc[j].i]);

    if(NULL == m_pProc[j].hProcess)
    {
     CNTServices::WriteToLog("OpenProcess failed!");
     ::CloseHandle(hSnapshot);
     return false;
    }

    m_pProc[j].i = (m_pProc[j].i + 1) % 2;
    ::CloseHandle(hSnapshot);
    return true;
   }
  }

  bState = Process32Next(hSnapshot, &prosinfo);
 }

 ::CloseHandle(hSnapshot);
 return false;
}

void CKillProcess::KillProcess(int nProcNo)
{
 bool bResult = ::TerminateProcess(m_pProc[nProcNo].hProcess, 0);
 if(!bResult)
 {
  CNTServices::WriteToLog("TerminateProcess failed!");
 }
 else
  CNTServices::WriteToLog("TerminateProcess success!");
}

void CKillProcess::DoTask()
{
 if(!m_bIfIniRight)
 {
  WriteToLog("monitor haven't run!/tplease set again!");
  Sleep(1000*60*10);
  return ;
 }
 int j;
 if(FindProcessByName())//find process for killed
 {
/*  //对于同样的进程,每次打开得到的句柄是不一样的,如果仅仅在KillProcess中关闭
  //一个的话,那么就会多出一句柄来,而当不在KillProcess中关闭的话,也会多出一个来
  if(m_dwProcessId[0] == m_dwProcessId[1])
  {
   m_nLeaveTime = m_nLeaveTime - m_nCheckTime;
   if(m_nLeaveTime <= m_nCheckTime)
    KillProcess();
  }

  ::CloseHandle(m_hProcess);//注意要在此处去释放句柄*/

  for(j = 0; j < m_nProcessNum; j++)
  {
   if(m_pProc[j].dwProcessId[0] == m_pProc[j].dwProcessId[1])
   {
    m_pProc[j].nLeaveTime -= m_nCheckTime;
    if(m_pProc[j].nLeaveTime <= m_nCheckTime)
    {
     KillProcess(j);
     m_pProc[j].nLeaveTime = m_pProc[j].nLivingTime;
    }
   }
   if(m_pProc[j].hProcess != 0)
    ::CloseHandle(m_pProc[j].hProcess);
  }
 }
 else
 {
  for(j = 0; j < m_nProcessNum; j++)
   m_pProc[j].dwProcessId[0] = m_pProc[j].dwProcessId[1] = 0;
 }

 Sleep(m_nCheckTime);
}

 

int main()
{
 CNTServices* pService;
 pService = new CKillProcess("MonitorDebug");

 SERVICE_TABLE_ENTRY ServiceTable[2];
 ServiceTable[0].lpServiceName = pService->m_szServicename;
 ServiceTable[0].lpServiceProc = (LPSERVICE_MAIN_FUNCTION)pService->ServiceMain;

 ServiceTable[1].lpServiceName = NULL;
 ServiceTable[1].lpServiceProc = NULL;

 // Start the control dispatcher thread for our service
 StartServiceCtrlDispatcher(ServiceTable);

 delete pService;//删除时会出错,为什么??????,因为析构函数不是虚函数,继承时出现问题

 return 0;
}

 

 

原创粉丝点击