需要完成的功能
通过命令行实现windows日志的清除
具体哪些日志类型,不清楚的朋友请参考 文章
《来无影 去无踪--windows日志清除 、日志解读、入侵取证》
先贴图看下效果
命令操作
E:\>clog ======================clear log(clog)====================== author:anubis forum:cnanubis.cn Q:93665673 example: clog \\ip -l Application clog \\ip -l DNS clog \\ip -l Security clog \\ip -l System clog \\ip -l All clog \\ip -l LogName argument description -l Application|Security|System|DNS|All or Other Log Name -h|zh help
此文章主要讨论如果使用C++程序开发一个简单的日志清除工具, 日志的更信息的 请参考上面链接文章.
开发环境: VS2010
新建 Win Console App.
设置项目。
1.设置编码类型 Unicode General -> C/C++ ->Charcter Set -> Use Unicode
2.加入 CLR支持(公共语言运行库), 以为需要使用到托管的链接库 System.dll Unicode General -> C/C++ ->Common Language Runtime Support
3. 去掉代码运行时检查: General -> C/C++ -> Code Generation -> Basic Runtime Checks 设置 Default
4. 运行库设置: General -> C/C++ -> Code Generation ->RuntimeLibrary
Debug模式设置 /MDd Release模式设置 /MD
下面正式进入代码开发阶段
1. 加入头文件
#include "stdafx.h" #include <Windows.h> #include <atlconv.h> #include <locale.h> #include <tchar.h> #include <stdio.h> #include <shellapi.h> #using <System.dll> using namespace System; using namespace System::Diagnostics; using namespace System::Threading; #pragma comment(lib,"shell32.lib");
函数声明
#define MID_LOADSTRING 50 #define MAX_LOADSTRING 100 /************************************************************************/ /* clog \\ip -l Application clog \\ip -l DNS clog \\ip -l Security clog \\ip -l System clog \\ip -l All */ /************************************************************************/ /************************************************************************/ /* 1. eng 2. chinese */ /************************************************************************/ void ShowBanner(UINT lang=1); /************************************************************************/ /* 参数解析到变量 */ /************************************************************************/ BOOL ParserParams(int argc,_TCHAR* argv[]); //清除日志 BOOL ClearSysLog(LPTSTR lpszMachine,LPTSTR lpszType); //执行操作 BOOL DOEXEC(); void FormatErrMsg(); //错误输出
DOEXEC();方法好像是多余的哈哈。 但是这个日志我值做了一部分,包括ClearSysLog , 可能还有其他的 文件需要清除,所以就加了这个方法
我们用到的参数主要有2个。 一个是 目标机器的IP 另一个就是什么样的日志 ,所以定义全局变量
//主机 \\127.0.0.1 默认的参数是本机 本机使用 .表示 TCHAR szHost[MID_LOADSTRING]=TEXT("."); TCHAR szLogType[MID_LOADSTRING]={0};
int _tmain(int argc, _TCHAR* argv[]) { setlocale(LC_CTYPE, "chs");//设置语言,一般我们控制台都是ANSI的, 项目用的是UNICODE的 要不然输出乱码。 //参数解析 BOOL bRet=FALSE; //__try try { bRet=ParserParams(argc,argv); if(!bRet) return 0; DOEXEC(); } //__except(1){ catch(...){ if(!bRet){ return 0; } } return 0; }
1. 参数解析 到相应的变量
2. 执行清除
下面进行参数解析
BOOL ParserParams(int argc,_TCHAR* argv[]) { BOOL bRet=FALSE; USES_CONVERSION; if(argc==1) { ShowBanner(); return 0; } for (int idx=1;idx<argc;idx++) { //取出参数 wchar_t **wc=(wchar_t **)(argv+idx); char *pos = strtok(W2A(*wc),"\\\\"); if(pos !=NULL && strcmp(pos,W2A(*wc))!=0) { ZeroMemory(szHost,sizeof(szHost)); int len =strlen(pos); char *pTempBuf; pTempBuf = _strdup(pos); _strlwr_s(pTempBuf, len+1); if(strcmp(pTempBuf,("localhost"))==0 || strcmp(pTempBuf,("127.0.0.1"))==0) { wsprintf(szHost,TEXT("%s"),TEXT(".")); } else wsprintf(szHost,TEXT("%s"),A2W(pos)); continue; } else if(_tcscmp(*wc,TEXT("-l"))==0) { ZeroMemory(szLogType,sizeof(szLogType)); wsprintf(szLogType,TEXT("%s"),(*(wchar_t **)(argv+idx+1))); idx++; continue; } else if(_tcscmp(*wc,TEXT("-h"))==0 ||_tcscmp(*wc,TEXT("/?"))==0 ||_tcscmp(*wc,TEXT("/h"))==0||_tcscmp(*wc,TEXT("/help"))==0) { ShowBanner(); return 0; } else if(_tcscmp(*wc,TEXT("-zh"))==0) { ShowBanner(2); return 0; } else if(idx>0) {//因为第一个参数是当前的文件 //之后如果有都不符合上面的参数的,那么就肯定是错误的参数 printf("invalid operation, plz check u command.if need , type clog -h\n"); //ShowBanner(); return 0; } } bRet=TRUE; return bRet; }
大家可以参考下参数解析, 以前一直找不到什么好的参数解析办法, 自己琢磨出来一个,感觉还可以。。
参数解析完成就可以进行日志清除了
BOOL DOEXEC() { BOOL bRet=FALSE; if(_tcscmp(szLogType,TEXT("All"))==0) { //获取所有的日志 ClearSysLog(szHost,TEXT("Application")); ClearSysLog(szHost,TEXT("Security")); ClearSysLog(szHost,TEXT("System")); ClearSysLog(szHost,TEXT("DNS")); } else{ //其他任何类型的日志 ClearSysLog(szHost,szLogType); } return bRet; } BOOL ClearSysLog(LPTSTR lpszMachine,LPTSTR lpszType) { BOOL bRet =FALSE; //char* str2 = (char*)(void*)Marshal::StringToHGlobalAnsi(System::String); System::String^ strMachine = gcnew String(lpszMachine); System::String^ strType = gcnew String(lpszType); try { //EventLog::Delete("Application",strMachine); EventLog::Delete(strType,strMachine); bRet=TRUE; _tprintf(TEXT("%s clear success"),lpszType); } catch(...) { _tprintf(TEXT("%s"),lpszType); FormatErrMsg(); bRet=FALSE; } return TRUE; }
估计很多人 对于非托管的代码调用托管代码还不太了解, 反正不会的网上搜搜。 虽然这个好像网上不太多, 一般都是托管的可能会调用非托管的代码多点。
比如全局的快捷键设置, 就需要使用调用非托管的来处理
EventLog类是 dot net framework下的类, 如果学过 dotnet的 应该可以知道
EventLog.Delete(); 这个方法就是用来删除windows日志的
下面两个方法就简单了
void ShowBanner(UINT lang){ switch (lang) { case 1: printf("======================clear log(clog)======================\n"); printf("author:anubis forum:cnanubis.cn Q:93665673\n \n"); printf("example:\n"); printf("\ clog \\\\ip -l Application\n\ clog \\\\ip -l DNS\n\ clog \\\\ip -l Security\n\ clog \\\\ip -l System\n\ clog \\\\ip -l All\n\ clog \\\\ip -l LogName\n"); printf("\n"); printf(" argument description \n"); printf(" -l Application|Security|System|DNS|All or Other Log Name \n"); printf(" -h|zh help \n"); printf("\n"); printf("=========================================================="); break; case 2: printf("======================日志清楚(clog)======================\n"); printf("作者:anubis 社区:cnanubis.cn Q:93665673\n \n"); printf(" 参数 描述 \n"); printf(" -l Application|Security|System|DNS|All \n"); printf(" -h|zh 帮助 \n"); printf("=========================================================="); break; } } void FormatErrMsg(){ //MAKEWORD(LANG_NEUTRAL,SUBLANG_DEFAULT) LPTSTR msgBuf; FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER| FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS, NULL,GetLastError(), MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT), (LPTSTR)&msgBuf,0,NULL); _tprintf(TEXT("%s"),msgBuf); }
呵呵 。 帮助里面打了个广告。。 汗。。 域名备案出问题了,导致社区还没有开通。。。。55.。
好 了 各位亲。 基本就这样了。。
源码我上传下
下载地址 CLOG源码 只要 1分 没有分的留言 留下邮箱 我发你就好