1.首先判断是否安装winrar,读注册表
#include <iostream.h>
#include <windows.h>
//有的主机上的注册表键值不全,必须进行对多个键的分析
char* value1="InstallLocation";
char* value2="UninstallString";
char* value3="DisplayIcon";
//保存winrar的安装路径
char winrarInstallPath[260]={0};
//检测是否安装winrar
bool isInstallWinrar()
{
HKEY hSubKey=NULL;
long result=RegOpenKeyEx(HKEY_LOCAL_MACHINE,"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\WinRAR archiver",0,KEY_READ,&hSubKey);
if(result!=ERROR_SUCCESS)
return false;
DWORD size=sizeof(winrarInstallPath);
DWORD type=REG_SZ;
//读取第一个优先的属性值
result=RegQueryValueEx(hSubKey,value1,NULL,&type,(unsigned char*)winrarInstallPath,&size);
//第一个属性读取不到
if(result!=ERROR_SUCCESS)
{
//读取第二个属性
result=RegQueryValueEx(hSubKey,value2,NULL,&type,(unsigned char*)winrarInstallPath,&size);
if(result!=ERROR_SUCCESS)
{
//第二个属性也读取不到,开始读取第三个属性
result=RegQueryValueEx(hSubKey,value3,NULL,&type,(unsigned char*)winrarInstallPath,&size);
}
//通过第二或第三属性读取到
if(result==ERROR_SUCCESS)
{
int len=strlen(winrarInstallPath);
while (winrarInstallPath[--len]!='\\')
{
winrarInstallPath[len]=0;
}
}//还是没有读取到
else
{
RegCloseKey(hSubKey);
return false;
}
}
RegCloseKey(hSubKey);
strcat(winrarInstallPath,"WinRAR.exe");
return true;
}
void main()
{
if(isInstallWinrar())
cout<<winrarInstallPath<<endl;
else
cout<<"没有安装winrar"<<endl;
}
//传递需要解压的源文件路径,绝对路径
//解压,本函数为阻塞状态,直到解压进程完成,函数才会返回,所以调用的地方将是阻塞调用
//返回值:winrar退出代码
//srcFloder和destFloder要么都加'\',要么都不加
int deCompress(const char*srcFilePath,const char*srcFloder,const char*destFloder)
{
//去除后缀,vs2010.iso解压后必定存在于vs2010文件夹内,
//尤其需要注意的是解压的目的文件夹必须加'\'
string dest=srcFilePath;
int pos=dest.find_last_of('.');
dest.replace(pos,dest.length()-pos,"");
dest+="\\";
dest.replace(0,strlen(srcFloder),destFloder);
//x解压 -ibck后台执行 -o+如存在,则覆盖 -inul不弹出错误提示
string strCmd=string(winrarInstallPath)+" x -ibck -o+ -inul "+srcFilePath+" "+dest;
STARTUPINFO si={sizeof(si)};
//本来想通过下面两句使winrar后台,即隐藏界面,但实践发现,只对命令行解压工具rar.exe有效,
//但是rar.exe又只能解压rar格式的,所以才使用 -ibck,但也没有真正隐藏,只是缩小到了系统托盘区域
// si.dwFlags!=STARTF_USESHOWWINDOW;
// si.wShowWindow=SW_HIDE;
PROCESS_INFORMATION pi;
BOOL bRet=CreateProcess(NULL,(char*)strCmd.c_str(),NULL,NULL,FALSE,0,NULL,NULL,&si,&pi);
DWORD dwExit=-1;
if(bRet)
{
//这个地方将导致该函数为阻塞状态
WaitForSingleObject(pi.hProcess,INFINITE);
::GetExitCodeProcess(pi.hProcess,&dwExit);
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
}
return dwExit;
}