admin 发布的文章

删除历史日志的一个API

bool DeleteOldFiles(const char* strFolder, const char* strPrefix, boolis_recursion, UINT32 ulMinDateTime, UINT32 ulMaxDateTime)
{
HANDLE hFind
=NULL;
WIN32_FIND_DATAA findFileData;
std::
string strFindFolder =strFolder;//转换成大写的进行比较 std::string strUpperPrefix = str_toupper(std::string(strPrefix));
std::
string strUpperFileName(MAX_PATH, '\0');
std::
string strTempName(MAX_PATH, '\0');if (strFindFolder[strFindFolder.length() - 1] == '\\') {
strFindFolder.append(
"*.*");
}
else{
strFindFolder.append(
"\\*.*");
}

hFind
= FindFirstFileA(strFindFolder.c_str(), &findFileData);if (hFind ==INVALID_HANDLE_VALUE)
{
return false;
}
do{if ((findFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ==FILE_ATTRIBUTE_DIRECTORY) {if(is_recursion){if ((0 == strcmp(".", findFileData.cFileName)) || (0 == strcmp("..", findFileData.cFileName)))
{
continue;
}

sprintf_s(
&strTempName[0], MAX_PATH - 1, "%s\\%s", strFolder, findFileData.cFileName);

DeleteOldFiles(strTempName.c_str(), strPrefix, is_recursion, ulMinDateTime, ulMaxDateTime);
}
}
else{//判断文件名是否相同的前缀 strUpperFileName = str_toupper(std::string(findFileData.cFileName));//有相同的前缀 if (strcmp(strUpperFileName.c_str(), strUpperPrefix.c_str()) >=0) {//取当前指定位置的数值,转换成整数 UINT32 ulCurrDateTime = atoi(&strUpperFileName[strUpperPrefix.length()]);if ((ulCurrDateTime >= ulMinDateTime) && (ulCurrDateTime <=ulMaxDateTime)) {//组合文件名 sprintf_s(&strTempName[0], MAX_PATH - 1, "%s\\%s", strFolder, findFileData.cFileName);//删除文件 DeleteFileA(strTempName.c_str());
}
}
}
}
while (FindNextFileA(hFind, &findFileData));
::FindClose(hFind);
hFind
=NULL;return true;
}

 

/******************************************************** 
* @file : Mutex.h
* @desc : 同步对象
* @author :
* @date : 2019-7-30
* @version : 1.0.0
********************************************************
*/#ifndef UTILITY_MUTEX_H_#define UTILITY_MUTEX_H_#include"UtilityDef.h"#ifdef WIN32
typedef CRITICAL_SECTION thread_mutex;
#elsetypedef pthread_mutex_t thread_mutex;#endif classUTILITY_API CThreadMutex final {public:
CThreadMutex() {
#ifdef WIN32
InitializeCriticalSection(
&mutex_);#elsepthread_mutex_init(&mutex_, nullptr);#endif}~CThreadMutex(){
#ifdef WIN32
DeleteCriticalSection(
&mutex_);#elsepthread_mutex_destroy(&mutex_);#endif}void lock() {
is_lock_
= true;
#ifdef WIN32
EnterCriticalSection(
&mutex_);#elsepthread_mutex_lock(&mutex);#endif}voidunlock(){
is_lock_
= false;
#ifdef WIN32
LeaveCriticalSection(
&mutex_);#elsepthread_mutex_unlock(&mutex_);#endif}bool islock()const{returnis_lock_;
}

thread_mutex
* get(){return &mutex_;
}
private:
thread_mutex mutex_;
volatile boolis_lock_;
};
classUTILITY_API CAutoThreadMutex final {public:explicit CAutoThreadMutex(CThreadMutex*mutex_ptr): mutex_(mutex_ptr) {lock();
}
~CAutoThreadMutex() {
unlock();
}
void lock() {if(mutex_){
mutex_
->lock();
}
}
voidunlock() {if(mutex_ && mutex_->islock()) {
mutex_
->unlock();
}
}

thread_mutex
* get() {return mutex_->get();
}
protected:
CAutoThreadMutex(
const CAutoThreadMutex&rhs) {
mutex_
=rhs.mutex_;lock();
}

CAutoThreadMutex
& operator=(const CAutoThreadMutex&rhs){if(this == &rhs){return *this;
}

mutex_
=rhs.mutex_;return *this;
}
private:
CThreadMutex
*mutex_;
};
#endif

 

CSharedCriticalSection 实现临界区的访问:加锁、去锁
CSharedMutex 实现临时窃取临界区对象,然后加锁,对象销毁时又会去锁,然后归还对象

classCSharedCriticalSection {public:
CSharedCriticalSection() {
InitializeCriticalSection(
&critical_section_);
}
~CSharedCriticalSection() {
DeleteCriticalSection(
&critical_section_);
}
void lock() {
EnterCriticalSection(
&critical_section_);
}
voidunlock() {
LeaveCriticalSection(
&critical_section_);
}
private:
CRITICAL_SECTION critical_section_;
};
classCSharedMutex {public:explicit CSharedMutex(CSharedCriticalSection&critical_section)
: is_lock_(
false)
, critical_section_(critical_section)
{
if(is_lock_ == false) {
is_lock_
= true;
critical_section_.
lock();
}
}
~CSharedMutex(){if(is_lock_) {
is_lock_
= false;
critical_section_.unlock();
}
}
void lock() {if(is_lock_ == false) {
is_lock_
= true;
critical_section_.
lock();
}
}
voidunlock() {if(is_lock_) {
is_lock_
= false;
critical_section_.unlock();
}
}
protected:
CSharedMutex(
const CSharedMutex&rhs)
: critical_section_(rhs.critical_section_)
{

}

CSharedMutex
& operator=(const CSharedMutex&rhs) {return *this;
}
private:volatile boolis_lock_;
CSharedCriticalSection
&critical_section_;
};

 

beyond compare 4.2.9桌面右键集成的问题修复

安装后,发现在WIN64时,注册表中注册的DLL库有问题

出错处:

[HKEY_CLASSES_ROOT\CLSID\{57FA2D12-D22D-490A-805A-5CB48E84F12A}\InProcServer32]
@="D:\\05.Tools\\BeyondCompare4.2.9\\BCShellEx.dll"
"ThreadingModel"="Apartment"

修改为:

[HKEY_CLASSES_ROOT\CLSID\{57FA2D12-D22D-490A-805A-5CB48E84F12A}\InProcServer32]
@="D:\\05.Tools\\BeyondCompare4.2.9\\BCShellEx64.dll"
"ThreadingModel"="Apartment"

如果还不行,注意去这儿删除相应的{57FA2D12-D22D-490A-805A-5CB48E84F12A}信息

[HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Shell Extensions\Cached]

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Shell Extensions\Cached]

修复右键的完整的注册表项见下,注意修改为你电脑上BC4的安装位置(目录需要双斜杠)

Windows Registry Editor Version 5.00[HKEY_CLASSES_ROOT\*\shellex\ContextMenuHandlers\CirrusShellEx]
@
="{57FA2D12-D22D-490A-805A-5CB48E84F12A}"[HKEY_CLASSES_ROOT\CLSID\{57FA2D12-D22D-490A-805A-5CB48E84F12A}]
@
="CirrusShellEx"[HKEY_CLASSES_ROOT\CLSID\{57FA2D12-D22D-490A-805A-5CB48E84F12A}\InProcServer32]
@
="D:\\05.Tools\\BeyondCompare4.2.9\\BCShellEx64.dll" "ThreadingModel"="Apartment"[HKEY_CLASSES_ROOT\Directory\shellex\ContextMenuHandlers\CirrusShellEx]
@
="{57FA2D12-D22D-490A-805A-5CB48E84F12A}"[HKEY_CLASSES_ROOT\Folder\shellex\ContextMenuHandlers\CirrusShellEx]
@
="{57FA2D12-D22D-490A-805A-5CB48E84F12A}"[HKEY_CLASSES_ROOT\lnkfile\shellex\ContextMenuHandlers\CirrusShellEx]
@
="{57FA2D12-D22D-490A-805A-5CB48E84F12A}"[HKEY_CLASSES_ROOT\WOW6432Node\CLSID\{57FA2D12-D22D-490A-805A-5CB48E84F12A}]
@
="CirrusShellEx"[HKEY_CLASSES_ROOT\WOW6432Node\CLSID\{57FA2D12-D22D-490A-805A-5CB48E84F12A}\InProcServer32]
@
="D:\\05.Tools\\BeyondCompare4.2.9\\BCShellEx.dll" "ThreadingModel"="Apartment"[HKEY_CURRENT_USER\Software\Classes\*\shellex\ContextMenuHandlers\CirrusShellEx]
@
="{57FA2D12-D22D-490A-805A-5CB48E84F12A}"[HKEY_CURRENT_USER\Software\Classes\CLSID\{57FA2D12-D22D-490A-805A-5CB48E84F12A}]
@
="CirrusShellEx"[HKEY_CURRENT_USER\Software\Classes\CLSID\{57FA2D12-D22D-490A-805A-5CB48E84F12A}\InProcServer32]
@
="D:\\05.Tools\\BeyondCompare4.2.9\\BCShellEx64.dll" "ThreadingModel"="Apartment"[HKEY_CURRENT_USER\Software\Classes\Directory\shellex\ContextMenuHandlers\CirrusShellEx]
@
="{57FA2D12-D22D-490A-805A-5CB48E84F12A}"[HKEY_CURRENT_USER\Software\Classes\Folder\shellex\ContextMenuHandlers\CirrusShellEx]
@
="{57FA2D12-D22D-490A-805A-5CB48E84F12A}"[HKEY_CURRENT_USER\Software\Classes\lnkfile\shellex\ContextMenuHandlers\CirrusShellEx]
@
="{57FA2D12-D22D-490A-805A-5CB48E84F12A}"[HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Shell Extensions\Approved]"{57FA2D12-D22D-490A-805A-5CB48E84F12A}"="Beyond Compare 4 Shell Extension"[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\*\shellex\ContextMenuHandlers\CirrusShellEx]
@
="{57FA2D12-D22D-490A-805A-5CB48E84F12A}"[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID\{57FA2D12-D22D-490A-805A-5CB48E84F12A}]
@
="CirrusShellEx"[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID\{57FA2D12-D22D-490A-805A-5CB48E84F12A}\InProcServer32]
@
="D:\\05.Tools\\BeyondCompare4.2.9\\BCShellEx64.dll" "ThreadingModel"="Apartment"[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Directory\shellex\ContextMenuHandlers\CirrusShellEx]
@
="{57FA2D12-D22D-490A-805A-5CB48E84F12A}"[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Folder\shellex\ContextMenuHandlers\CirrusShellEx]
@
="{57FA2D12-D22D-490A-805A-5CB48E84F12A}"[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\lnkfile\shellex\ContextMenuHandlers\CirrusShellEx]
@
="{57FA2D12-D22D-490A-805A-5CB48E84F12A}"[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\WOW6432Node\CLSID\{57FA2D12-D22D-490A-805A-5CB48E84F12A}]
@
="CirrusShellEx"[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\WOW6432Node\CLSID\{57FA2D12-D22D-490A-805A-5CB48E84F12A}\InProcServer32]
@
="D:\\05.Tools\\BeyondCompare4.2.9\\BCShellEx.dll" "ThreadingModel"="Apartment"[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Shell Extensions\Approved]"{57FA2D12-D22D-490A-805A-5CB48E84F12A}"="Beyond Compare 4 Shell Extension"[HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Classes\CLSID\{57FA2D12-D22D-490A-805A-5CB48E84F12A}]
@
="CirrusShellEx"[HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Classes\CLSID\{57FA2D12-D22D-490A-805A-5CB48E84F12A}\InProcServer32]
@
="D:\\05.Tools\\BeyondCompare4.2.9\\BCShellEx.dll" "ThreadingModel"="Apartment"[HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Shell Extensions\Approved]"{57FA2D12-D22D-490A-805A-5CB48E84F12A}"="Beyond Compare 4 Shell Extension"

 

递归创建目录1:

需要#include <shlwapi.h>,并且配置好shlwapi.ib

BOOL CreateDirTree( LPCTSTR lpPath )
{
if( NULL == lpPath || _tcslen(lpPath)==0)
{
returnFALSE;
}
if( ::PathFileExists( lpPath) ||::PathIsRoot(lpPath) )returnTRUE;

TCHAR szParentpath[MAX_PATH]
= _T("");
::lstrcpy( szParentpath, lpPath );

::PathRemoveBackslash( szParentpath );
//去除路径最后的反斜杠 ::PathRemoveFileSpec( szParentpath );//将路径末尾的文件名或文件夹和反斜杠去掉 if(0 ==_tcscmp(lpPath, szParentpath))returnFALSE;

assert(
0 !=_tcscmp(lpPath, szParentpath));if( CreateDirTree( szParentpath) )//递归创建直到上一层存在或是根目录 {return::CreateDirectory(lpPath, NULL);
}
else{returnFALSE;
}
returnTRUE;
}

递归创建目录2:

void __fastcall RecursiveDirectory(CString cstrDir) //递归创建目录
{if (cstrDir.GetLength() <= 3)//是根目录,无需创建目录
{return;
}
if (cstrDir[cstrDir.GetLength()-1] == '\\') //将路径改为目录 {
cstrDir.Delete(cstrDir.GetLength()
-1, 1);
}
//修改文件属性 WIN32_FIND_DATA wfd;
HANDLE hFind
= FindFirstFile(cstrDir, &wfd); //查找 if (hFind !=INVALID_HANDLE_VALUE)
{
FindClose(hFind);
if (wfd.dwFileAttributes &FILE_ATTRIBUTE_DIRECTORY)return;
}
//创建当前目录的地目录失败 if (CreateDirectory(cstrDir,NULL) == false)
{
//退到上一级目录 CString wstrNewDir =cstrDir;int n = wstrNewDir.ReverseFind('\\');
wstrNewDir
=cstrDir.Left(n);//递归进入 RecursiveDirectory(wstrNewDir); //递归本函数,再创建目录//递归退出后创建之前失败的目录 CreateDirectory(cstrDir,NULL); //递归返回,在存在的目录上再建目录 }//多级目录创建成功 }

递归创建目录3:

BOOL RecursiveDirectory(wstring wstrDir)
{
if (wstrDir.length() <= 3)
{
returnFALSE;
}
if (wstrDir[wstrDir.length() - 1] == '\\')
{
wstrDir.erase(wstrDir.end()
- 1);
}
if(PathFileExists(wstrDir.c_str()))returnTRUE;if (CreateDirectory(wstrDir.c_str(), NULL) == false)
{
wstring wstrNewDir
=wstrDir;while (wstrNewDir[wstrNewDir.length() - 1] != '\\')
{
wstrNewDir.erase(wstrNewDir.length()
- 1);
}
//delete '\\' wstrNewDir.erase(wstrNewDir.length() - 1);

RecursiveDirectory(wstrNewDir);
CreateDirectory(wstrDir.c_str(), NULL);
}
if (!PathFileExists(wstrDir.c_str()))returnFALSE;returnTRUE;
}

 递归创建目录4:

bool createDirectory(const char*pathName)
{
charpath[MAX_PATH];
memset(path,
0x00, MAX_PATH);const char* pos =pathName;while ((pos = strchr(pos, '\\')) !=NULL)
{
memcpy(path, pathName, pos
- pathName + 1);
pos
++;if (_access(path, 0) == 0)
{
continue;
}
else{int ret =_mkdir(path);if (ret == -1)
{
return false;
}
}
}
return true;
}

 

 

递归删除目录1:

system("rmdir /s /q dirname");  //dirname是要删除的目录名称,这种方式,在使用MFC程序的时候出闪过一个CMD的窗口
/s是级联删除  /q 是不提示(在命令行下操作的话,如果不加这个开关,会有提示确认是否删除目录,而在程序中不允许停下)

递归删除目录2:

SHFILEOPSTRUCT FileOp;
FileOp.fFlags
=FOF_NOCONFIRMATION;
FileOp.hNameMappings
=NULL;
FileOp.hwnd
=NULL;
FileOp.lpszProgressTitle
=NULL;
FileOp.pFrom
= ".\\tempDir";
FileOp.pTo
=NULL;
FileOp.wFunc
=FO_DELETE;
SHFileOperation(
&FileOp);

此处有一个地方要留心一下,就是FileOp.pFrom这个参数,它使用的字符串一定是要'\0'结尾的,这个地方使用".\\tempDir",这个字符串默认的结束字符就是'\0',所以如果存在这个目录或者文件的话,一定可以将其删除,如果像下面这样写的话就会出错:

std::string delPath = ".\\tempDir";

FileOp.pFrom = delPath.c_str();  // 此时字符串没有以'\0'结尾,所以删除的时候会出错

递归删除目录3:

bool deleteDirectory( char*pathName)
{
struct_finddata_t fData;
memset(
&fData, 0, sizeof(fData));if (_chdir(pathName) != 0) //_chdir函数设置当前目录 {
printf(
"chdir failed: %s\n",pathName);return false;
}

intptr_t hFile
= _findfirst("*",&fData); //参数1:char *类型,"*"表示通配符,可以查找文件、文件夹 if(hFile == -1)
{
printf(
"_findfirst error!\n");return false;
}
do{if(fData.name[0] == '.')continue;if(fData.attrib == _A_SUBDIR) //子文件夹 {chardirPath[MAX_PATH];
memset(dirPath,
0,sizeof(pathName));
strcpy_s(dirPath,pathName);
strcat_s(dirPath,
"\\");
strcat_s(dirPath,fData.name);

deleteDirectory(dirPath);
//recursion subdir printf("remove dir: %s\n",dirPath);
_chdir(
"..");
_rmdir(dirPath);
}
else{charfilePath[MAX_PATH];
memset(filePath,
0,sizeof(filePath));
strcpy_s(filePath,pathName);
strcat_s(filePath,
"\\");
strcat_s(filePath,fData.name);

remove(filePath);
printf(
"remove file: %s\n",filePath);
}
}
while(_findnext(hFile,&fData) == 0);

_findclose(hFile);
//close return true;
}