一个清理VS工程的小工具

VS工程编译完之后会产生大量的临时文件,这个小程序就是清理VS工程残留文件的,能迅速清理VS的工程,如果有子文件夹递归进行清理,程序使用多线程效率很高。

/*
 *	filename:   main.cpp
 *	author:	    lougd
 *	created:    2014-12-26 10:25
 *	version:    1.0.0.1
 *	desc:       clear vs project
 *      version:
 *      history:
*/
#include <Windows.h>
#include <stdio.h>
#include <set>
#include <list>
#include <string>
#include <Shlwapi.h>

#pragma  comment(lib, "shlwapi.lib")
using namespace std;

size_t g_busy_count = 0;
set<string> g_exts;
set<string> g_dirs;
list<string> g_dir_list;
HANDLE g_dir_lock = CreateMutexA(NULL, FALSE, NULL);
HANDLE g_work = CreateEventA(NULL, FALSE, FALSE, NULL);
HANDLE g_exit = CreateEventA(NULL, TRUE, FALSE, NULL);

VOID WINAPI Lock()
{
	WaitForSingleObject(g_dir_lock, INFINITE);
}

VOID WINAPI UnLock()
{
	ReleaseMutex(g_dir_lock);
}

VOID WINAPI DeleteDirWithFile(const char *dir)
{
	list<string> files;
	list<string> dirs;
	WIN32_FIND_DATAA data;
	char tmp[512] = {0x00};
	char path[512] = {0x00};
	int mark = lstrlenA(dir);
	lstrcatA(tmp, dir);
	lstrcatA(path, dir);
	PathAppendA(path, "*");

	HANDLE h = FindFirstFileA(path, &data);
	if (!h || INVALID_HANDLE_VALUE == h)
	{
		return;
	}
	do
	{
		if (0 == lstrcmpA(".", data.cFileName) || 0 == lstrcmpA("..", data.cFileName) || 0 == lstrlenA(data.cFileName))
		{
			if (!FindNextFileA(h, &data))
			{
				break;
			}
			continue;
		}

		PathAppendA(tmp, data.cFileName);
		if (PathIsDirectoryA(tmp))
		{
			dirs.push_back(tmp);
		}
		else
		{
			files.push_back(tmp);
		}
		tmp[mark] = 0x00;
	} while (FindNextFileA(h, &data));

	if (h && INVALID_HANDLE_VALUE != h)
	{
		FindClose(h);
	}

	list<string>::iterator itm;
	for (itm = dirs.begin() ; itm != dirs.end() ; itm++)
	{
		DeleteDirWithFile(itm->c_str());
	}

	for (itm = files.begin() ; itm != files.end() ; itm++)
	{
		DeleteFileA(itm->c_str());
	}
	RemoveDirectoryA(dir);
}

VOID WINAPI RecursionClearDir(const char *dir)
{
	list<string> files;
	list<string> dirs;
	WIN32_FIND_DATAA data;
	char tmp[512] = {0x00};
	char path[512] = {0x00};
	int mark = lstrlenA(dir);
	lstrcatA(tmp, dir);
	lstrcatA(path, dir);
	PathAppendA(path, "*");

	HANDLE h = FindFirstFileA(path, &data);
	if (!h || INVALID_HANDLE_VALUE == h)
	{
			return;
	}
	do
	{
		if (0 == lstrcmpA(".", data.cFileName) || 0 == lstrcmpA("..", data.cFileName) || 0 == lstrlenA(data.cFileName))
		{
			if (!FindNextFileA(h, &data))
			{
				break;
			}
			continue;
		}

		PathAppendA(tmp, data.cFileName);
		if (PathIsDirectoryA(tmp))
		{
			if (g_dirs.end() != g_dirs.find(data.cFileName))
			{
				dirs.push_back(tmp);
			}
			Lock();
			g_dir_list.push_back(string(tmp));
			UnLock();
			SetEvent(g_work);
		}
		else
		{
			if (g_exts.end() != g_exts.find(PathFindExtensionA(tmp)))
			{
				files.push_back(tmp);
			}
		}
		tmp[mark] = 0x00;
	} while (FindNextFileA(h, &data));

	list<string>::iterator itm;
	for (itm = dirs.begin() ; itm != dirs.end() ; itm++)
	{
		DeleteDirWithFile(itm->c_str());
	}

	for (itm = files.begin() ; itm != files.end() ; itm++)
	{
		DeleteFileA(itm->c_str());
	}

	if (h && INVALID_HANDLE_VALUE != h)
	{
		FindClose(h);
	}
}

DWORD WINAPI ProcessThread(LPVOID param)
{
	HANDLE arry[] = {g_work, g_exit};
	while(TRUE)
	{
		DWORD ret = WaitForMultipleObjects(sizeof(arry) / sizeof(HANDLE), arry, FALSE, INFINITE);
		if (WAIT_OBJECT_0 == ret)
		{
			string path;
			Lock();
			g_busy_count++;
			UnLock();

			while(TRUE)
			{
				Lock();
				count = g_dir_list.size();
				if (count <= 0)
				{
					UnLock();
					break;
				}
				path = g_dir_list.front();
				g_dir_list.pop_front();
				UnLock();
				RecursionClearDir(path.c_str());
			}

			Lock();
			g_busy_count--;
			if (0 == g_busy_count && 0 == g_dir_list.size())
			{
				SetEvent(g_exit);
			}
			UnLock();
		}

		if ((WAIT_OBJECT_0 + 1) == ret)
		{
			break;
		}
	}
	return 0;
}

VOID WINAPI GetFileType()
{
	g_exts.insert(".ncb");
	g_exts.insert(".suo");
	g_exts.insert(".exp");
	g_exts.insert(".pdb");
	g_exts.insert(".ilk");
	g_exts.insert(".user");
	g_exts.insert(".aps");
	g_exts.insert(".obj");
	g_exts.insert(".idb");
	g_exts.insert(".dep");
	g_exts.insert(".sbr");
	g_exts.insert(".tmp");
	g_exts.insert(".tlh");
	g_exts.insert(".tli");
	g_exts.insert(".tlog");
	g_exts.insert(".log");
	g_exts.insert(".htm");
	g_exts.insert(".clw");
	g_exts.insert(".dsp");
	g_exts.insert(".opt");
	g_exts.insert(".sdf");
	g_exts.insert(".filters");
	g_exts.insert(".plg");
	g_exts.insert(".positions");
	g_exts.insert(".svn-base");

	g_dirs.insert(".svn");
	g_dirs.insert("Debug");
}

int main(int argc, char *argv[])
{
	if (argc < 2)
	{
		printf("param error\n");
	}

	if (0 == lstrcmpiA(argv[1], "/c"))
	{
		string path = argv[2];
		SYSTEM_INFO system = {0};
		GetSystemInfo(&system);
		int cpu = system.dwNumberOfProcessors;
		g_dir_list.push_back(path.c_str());
		SetEvent(g_work);
		GetFileType();

		int itm;
		HANDLE *ws = new HANDLE[cpu + 2];
		for (itm = 0 ; itm < (cpu + 2) ; itm++)
		{
			ws[itm] = CreateThread(NULL, 0, ProcessThread, 0, 0, NULL);
		}
		WaitForMultipleObjects(cpu + 2, ws, TRUE, INFINITE);
		delete []ws;
	}
	return 0;
}
时间: 2024-10-05 04:44:50

一个清理VS工程的小工具的相关文章

用php写一个管理外借设备的小工具--技术提高生产力

我学网站编程属于半途出家的类型,本是搞运维的,进了现在的公司后意识到学习一门编程语言的重要性,便从平时的工作时间里抽出部分来做学习和练习. 公司做技术的都是属于编程出身的,从网站设计到手机程式设计,好像大多数的人都在走这样的一条道路. 公司的部分业务是做手机游戏开发的,测试设备也越来越多,管理权归我们运维两个人所有,一直以来都是用个小笔记本做外借的登记,每天都有不同的测试人员过来借设备,ipad,iphone,android机,借了又还,还了另外一个人过来借,不用多久,那笔记本已经累积到厚厚的一

python的实战:一个目录一键启动管理小工具

简单的学习了几天的python,总觉得最好根据自身的需求来做点小工具实战一下. 上班的时候由于有很多目录需要打开.每次都要一个个的找那些目录.我觉得,我需要一个小工具.然后登记下,所有需要打开的目录.然后可以很方便的一键打开所有的目录或者是有哪些文件.然后登记一下.可以一次性打开所有登记的目标每次打开工具时,需要读取xml的数据.每增加一条数据要写入到xml中.这样我们即使部使用辅助工具去添加记录.直接修改xml文件的数据来增加记录也是可以的.具体实现如下 import os import xm

一个我自己用的小工具

最近一段时间,事越来越多,要做的事情越来越多,需要的工具越来越多, 好多工具都要自己写,所以我又把我以前写的一个脚本工具弄出来了, 一个小的脚本工具,能做几乎所有事情,(就是有些简单有些麻烦而以), 打开之后,界面是这样的 这个脚本工具是基于lua 脚本的,因为我感觉lua更简单,小巧,便捷, 虽然也有一些不足,但是比那些个什么什么奇葩的强迫症脚本,比如python友善一些. 内部支持一些内建的命令,来做一些相关的辅助操作 输入一个"?"会列出全部内建命令,有些说明可能不正确,有些命令

初学Python-搞了一个linux用户登录监测小工具

这几天突发奇想,想学习一下Python.看了点基础,觉得有点枯燥,所以想搞点什么.想了想,就随便弄个检测Linux用户登录的小工具吧~ 首先,明确一下功能: 1.能够捕获 linux 用户登录的信息.(这个很容易,方法比较多) 2.能够将捕捉的信息记录下来.(不然要这信息干嘛……) 3.最好能够一发现有人登陆,就给管理员发个邮件.(这个功能比较实用~) 4.没想好.(功能可以不断完善嘛) 嗯,那现在就要着手解决技术难点了(对我来说可能是难点吧,毕竟才看了几天书……). 1.捕获linux登录信息

发布一个关于SharePoint的管理小工具

源码地址:  https://github.com/GavinHacker/SiteCollectionManager 这是一个C#可执行程序,用于添加,删除,备份,还原SharePoint站点,可以查看一些SharePoint数据属性,比如SharePoint ContentTypes ,Columns等等,层级到List级别. 这个Tool是开始接触SharePoint不久写的,最初由于有很多用于开发的站点占用很多的资源,直接删掉还担心之后会用到,借助STSADMIN写了这个有备份功能的工具

JDBCUtils,一个操作关系型数据库的小工具

先贴代码 1 public class SqlC3p0Utils { 2 private static ComboPooledDataSource dataSource; 3 static{ 4 ResourceBundle bundle=ResourceBundle.getBundle("db");//获得配置文件对象 5 dataSource = new ComboPooledDataSource();//获得连接池对象 6 //根据配置文件队连接池进行配置 7 try { 8 d

用C#写一个Excel转Txt的小工具

using System; using System.Collections.Generic; using System.Data; using System.Data.OleDb; using System.Linq; using System.Text; using System.Threading.Tasks; using System.IO; using Microsoft.Office.Core; using Excel = Microsoft.Office.Interop.Excel

Java正则表达式——测试正则表达式的一个小工具

正则表达式是一种强大而灵活的文本处理工具.使用它我们能以编程的方式,构造复杂的文本模式,并对输入的字符串进行搜索.一旦找到了匹配这些模式的部分,你就能够随心所欲地对它们进行处理. 关于正则表达式的语法,网上对此有介绍的文章实在是多不胜数,实在找不到,还可以查看Java的API文档,就不多介绍了.这里主要介绍一个可以测试正则表达式的小工具.直接上代码: 1 package com.test.stringregex; 2 //{Args: abcabcabcdefabc "abc+" &q

Python学习之旅:用Python制作一个打字训练小工具

一.写在前面 说道程序员,你会想到什么呢?有人认为程序员象征着高薪,有人认为程序员都是死肥宅,还有人想到的则是996和 ICU. 别人眼中的程序员:飞快的敲击键盘.酷炫的切换屏幕.各种看不懂的字符代码. 然而现实中的程序员呢?对于很多程序员来说,没有百度和 Google 解决不了的问题,也没有 ctrl + c 和 ctrl + v 实现不了的功能. 那么身为一个程序员,要怎么让自己看起来更加“专业”呢?答案就是加快自己的打字速度了,敲的代码可能是错的,但这个13却是必须装的! 然而还是有不少人