Board logo

标题: [文件操作] 无窗命令行ezip.exe [打印本页]

作者: happy886rr    时间: 2017-5-4 00:13     标题: 无窗命令行ezip.exe

本帖最后由 happy886rr 于 2017-5-4 20:21 编辑

[易压2.0版] 增加 批量解压、批量压缩、单文件压缩、过滤空目录等新功能。一键易压,无声无息。
下载地址: https://pan.baidu.com/s/1geWEDZt
借助开源zlib写了一个zip高速压缩解压软件,实现右键一键压缩解压。程序会自动判断是否为压缩文件,智能的自动选择压缩或是解压。由于是无窗命令行,在控制台下亦可直接被批处理调用。

GUI下调用说明,直接双击ezip.exe就完成了易压的安装,右键查看zip包会有E-Zip的右键菜单和图标。所有压缩解压都是一键的,非常易捷。

命令行下调用说明:
  1. Usage: ezip [argv] ...
  2.     ezip [待解压zip文件]
  3.     ezip [待压缩目录]
复制代码
经测试易压的zip压缩解压速度均高于winRAR,对于zip类型的文件有非常大的压缩优势,且不会弹出任何窗口消耗系统资源。

源码,请配合zlib库、MFC、ATL库编译。
  1. #include "stdafx.h"
  2. #include "unzip.h"
  3. #include "zip.h"
  4. using namespace std;
  5. // 定义控制台启动方式
  6. #pragma comment(linker, "/subsystem:\"windows\" /entry:\"wmainCRTStartup\"")
  7. //判断注册表键值是否存在
  8. BOOL RegValueExist(HKEY hMainKey, LPCTSTR pSubKey, LPCTSTR pValName)
  9. {
  10. BOOL ret =FALSE;
  11. DWORD dwType = REG_SZ;
  12. HKEY hKey;
  13. LSTATUS nRes = RegOpenKeyEx(hMainKey, pSubKey, 0, KEY_READ,  &hKey);
  14. if (nRes != ERROR_SUCCESS)
  15. {
  16. return FALSE;
  17. }
  18. nRes = RegQueryValueEx(hKey, pValName, NULL, &dwType, NULL, NULL);
  19. RegCloseKey(hKey);
  20. if (nRes == ERROR_SUCCESS || nRes ==ERROR_MORE_DATA)
  21. {
  22. ret = TRUE;
  23. }
  24. return ret;
  25. }
  26. // 注册右键快捷键值
  27. int REGRightKeyValue()
  28. {
  29. // 获取可执行文件全路径
  30. TCHAR szFilePath[MAX_PATH + 1];
  31. GetModuleFileName(NULL, szFilePath, MAX_PATH);
  32. CString csPathBuf=_T("\"") + (CString)szFilePath + _T("\"");
  33. CString csCommandBuf=_T("\"") + (CString)szFilePath + _T("\"") + _T(" ") + _T("\"%1\"");
  34. // 创建注册表键值
  35. HKEY hKey;
  36. DWORD dwDisposition;
  37. RegCreateKeyEx(HKEY_CLASSES_ROOT, _T("*\\shell\\E-Zip"), 0, REG_NONE, REG_OPTION_NON_VOLATILE, KEY_WRITE|KEY_READ, NULL, &hKey, &dwDisposition);
  38. RegSetValueEx(hKey, _T("icon"), 0, REG_SZ, (BYTE*)(LPCTSTR)csPathBuf, csPathBuf.GetLength()*sizeof(TCHAR));
  39. RegCreateKeyEx(HKEY_CLASSES_ROOT, _T("*\\shell\\E-Zip\\command"), 0, REG_NONE, REG_OPTION_NON_VOLATILE, KEY_WRITE|KEY_READ, NULL, &hKey, &dwDisposition);
  40. RegSetValueEx(hKey, NULL, 0, REG_SZ, (BYTE*)(LPCTSTR)csCommandBuf, csCommandBuf.GetLength()*sizeof(TCHAR));
  41. RegCreateKeyEx(HKEY_CLASSES_ROOT, _T("Folder\\shell\\E-Zip"), 0, REG_NONE, REG_OPTION_NON_VOLATILE, KEY_WRITE|KEY_READ, NULL, &hKey, &dwDisposition);
  42. RegSetValueEx(hKey, _T("icon"), 0, REG_SZ, (BYTE*)(LPCTSTR)csPathBuf, csPathBuf.GetLength()*sizeof(TCHAR));
  43. RegCreateKeyEx(HKEY_CLASSES_ROOT, _T("Folder\\shell\\E-Zip\\command"), 0, REG_NONE, REG_OPTION_NON_VOLATILE, KEY_WRITE|KEY_READ, NULL, &hKey, &dwDisposition);
  44. RegSetValueEx(hKey, NULL, 0, REG_SZ, (BYTE*)(LPCTSTR)csCommandBuf, csCommandBuf.GetLength()*sizeof(TCHAR));
  45. RegCloseKey(hKey);
  46. return 0;
  47. }
  48. // 从压缩包解压文件
  49. ZRESULT ExtractZipToDir(LPCTSTR lpszZipFullName, CStringArray& szFilePathArr, LPCTSTR lpszUnZipPath)
  50. {
  51. TCHAR buffer[MAX_PATH] = {0};
  52. CString strUnZipPath = lpszUnZipPath;
  53. DWORD zResult = ZR_OK;
  54. if (!strUnZipPath.IsEmpty())
  55. {
  56. SHCreateDirectoryEx(NULL, lpszUnZipPath, NULL);
  57. }
  58. else
  59. {
  60. GetCurrentDirectory(MAX_PATH, (LPTSTR)&buffer);
  61. strUnZipPath = buffer;
  62. SHCreateDirectoryEx(NULL, strUnZipPath, NULL);
  63. }
  64. HZIP hz = OpenZip(lpszZipFullName, 0);
  65. ZIPENTRY ze;
  66. GetZipItem(hz, -1, &ze);
  67. int numitems = ze.index;
  68. for (int zi = 0; zi < numitems; zi++)
  69. {
  70. ZIPENTRY ze;
  71. GetZipItem(hz,zi,&ze);
  72. zResult = UnzipItem(hz, zi, (CString)strUnZipPath+_T("\\")+ze.name);
  73. szFilePathArr.Add(ze.name);
  74. if (zResult != ZR_OK)
  75. {
  76. #ifndef _UNICODE
  77. if (_access(szFilePathArr[zi], 0))
  78. {
  79. return zResult;
  80. }
  81. #else
  82. if (_access((char *)(LPTSTR)(LPCTSTR)szFilePathArr[zi], 0))
  83. {
  84. return zResult;
  85. }
  86. #endif
  87. }
  88. }
  89. CloseZip(hz);
  90. return zResult;
  91. }
  92. // 递归子目录到zip文件
  93. ZRESULT RecursiveSubdirToZip(HZIP zf, const CString& strPath, const CString& parentDir)
  94. {
  95. CString strRelativePath;
  96. CFileFind finder;
  97. BOOL bWorking = finder.FindFile(strPath + _T("\\*.*"));
  98. while(bWorking)
  99. {
  100. bWorking = finder.FindNextFile();
  101. if(finder.IsDots())
  102. {
  103. continue;
  104. }
  105. if (parentDir == _T(""))
  106. {
  107. strRelativePath = finder.GetFileName();
  108. }
  109. else
  110. {
  111. //生成在zip文件中的相对路径
  112. strRelativePath = parentDir + _T("\\") + finder.GetFileName();
  113. }
  114. if(finder.IsDirectory())
  115. {
  116. //在zip文件中生成目录结构
  117. ZipAdd(zf, strRelativePath, NULL);
  118. //递归收集子目录文件
  119. RecursiveSubdirToZip(zf, finder.GetFilePath(), strRelativePath);
  120. continue;
  121. }
  122. //将文件添加到zip文件中
  123. ZipAdd(zf, strRelativePath, finder.GetFilePath());
  124. }
  125. return ZR_OK;
  126. }
  127. // 从目录创建zip压缩文件
  128. ZRESULT CompressPathToZip(const CString& dirName, const CString& zipFileName)
  129. {
  130. //创建zip文件
  131. HZIP  newZipFile = CreateZip(zipFileName, 0);
  132. if (newZipFile == NULL)
  133. {
  134. _tprintf(_T("Can not create zip file !\n"));
  135. return ZR_FAILED;
  136. }
  137. RecursiveSubdirToZip(newZipFile, dirName, _T(""));
  138. //关闭zip文件
  139. CloseZip(newZipFile);
  140. return ZR_OK;
  141. }
  142. // 从文件创建zip压缩文件
  143. ZRESULT CompressFileToZip(LPCTSTR lpszSrcFile, LPCTSTR lpszZipName)
  144. {
  145. CString m_s=lpszSrcFile;
  146. HZIP hz = CreateZip(lpszZipName, 0);
  147. int ind=m_s.ReverseFind(_T('\\'));
  148. if(ind==-1)
  149. {
  150. m_s=lpszSrcFile;
  151. }
  152. else
  153. {
  154. m_s = m_s.Right(m_s.GetLength()-1-ind);
  155. }
  156. DWORD zResult = ZipAdd(hz, m_s, (CString)lpszSrcFile);
  157. if(zResult == ZR_OK)
  158. {
  159. CloseZip(hz);
  160. }
  161. return zResult;
  162. }
  163. // 唯一的应用程序对象
  164. CWinApp theApp;
  165. int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
  166. {
  167. int ezipMODE=0;
  168. CString m_InFullName;
  169. if(argc==1)
  170. {
  171. REGRightKeyValue();
  172. }
  173. if(argc==2)
  174. {
  175. m_InFullName=argv[1];
  176. TCHAR* tpstr=_tcsrchr(argv[1], _T('.'));
  177. if(tpstr && _tcsicmp(tpstr, _T(".zip"))==0)
  178. {
  179. ezipMODE=1;
  180. }
  181. else if(PathIsDirectory(m_InFullName))
  182. {
  183. ezipMODE=2;
  184. }
  185. else
  186. {
  187. ezipMODE=3;
  188. }
  189. }
  190. else
  191. {
  192. //_tprintf(_T("\nUsage: ezip [option] [parameter] [parameter]\n  -x [source file] [extract path]\n  -z [source path] [compression name]\n\n"));
  193. return 1;
  194. }
  195. int nRetCode = 0;
  196. HMODULE hModule = GetModuleHandle(NULL);
  197. if (hModule != NULL)
  198. {
  199. // 初始化 MFC 并在失败时显示错误
  200. if (!AfxWinInit(hModule, NULL, GetCommandLine(), 0))
  201. {
  202. // TODO: 更改错误代码以符合您的需要
  203. //_tprintf(_T("Error: MFC failed to initialize .\n"));
  204. nRetCode = 1;
  205. }
  206. else
  207. {
  208. //根据ezipMODE值执行相应函数
  209. if(ezipMODE==1)
  210. {
  211. CStringArray tmpNAME;
  212. ExtractZipToDir(m_InFullName, tmpNAME, m_InFullName.Left(m_InFullName.GetLength()-4));
  213. }
  214. else if(ezipMODE==2)
  215. {
  216. CompressPathToZip(m_InFullName, m_InFullName + _T(".zip"));
  217. }
  218. else if(ezipMODE==3)
  219. {
  220. CompressFileToZip(m_InFullName, m_InFullName + _T(".zip"));
  221. }
  222. }
  223. }
  224. else
  225. {
  226. // TODO: 更改错误代码以符合您的需要
  227. //_tprintf(_T("Error: get module handle failed .\n"));
  228. nRetCode = 1;
  229. }
  230. return nRetCode;
  231. }
复制代码

作者: codegay    时间: 2017-5-4 00:21

本帖最后由 codegay 于 2017-5-4 00:24 编辑

可以弄一个快捷键。
winrar 默认按右键后,再按X可以解。我很喜欢这种操作方式。


类似这个例子:我平常用记事本打开文字文件是按3:
  1. Windows Registry Editor Version 5.00
  2. [HKEY_LOCAL_MACHINE\SOFTWARE\Classes\*\shell]
  3. [HKEY_LOCAL_MACHINE\SOFTWARE\Classes\*\shell\用记事本打开.reg]
  4. @="用记事本戳开Y(&3) ^_^"                        
  5. [HKEY_LOCAL_MACHINE\SOFTWARE\Classes\*\shell\用记事本打开.reg\command]
  6. @="notepad.exe %1"
复制代码

作者: CrLf    时间: 2017-5-4 10:28

和 zip.exe 相比呢?
作者: happy886rr    时间: 2017-5-4 10:37

本帖最后由 happy886rr 于 2017-5-4 10:40 编辑

回复 3# CrLf
有点bug,我打算改用7z的成熟算法。EasyIFS已改成命令行版,原来的是窗口不支持命令行。单机版BCN马上完成,还在修复个别第三方中。
作者: ShowCode    时间: 2017-5-4 10:47

回复 4# happy886rr


    无窗命令行7z.exe有哪些痛点需要解决呢?
作者: happy886rr    时间: 2017-5-4 20:24

回复 5# ShowCode
已修复,请下载最新2.0版,这才是最实用的。
作者: happy886rr    时间: 2017-5-4 20:26

回复 2# codegay
我把注册表弄进C语言里了,请下载2.0最新版,修复bug3处,新增一些功能。
作者: ShowCode    时间: 2017-5-4 21:34

回复 6# happy886rr


    不需要了,我就用7-Zip挺好,没什么理由抛弃它。
作者: happy886rr    时间: 2017-5-4 21:56

本帖最后由 happy886rr 于 2017-5-4 22:01 编辑

回复 8# ShowCode
现在1T的硬盘也不贵,硬盘空间已经足够大了,7z不会节省太多容量。E-zip无论是zip解压速度还是zip压缩速度都完爆7z,还不费电。当7z压缩时你会看到cpu暴涨到90%,所以目前标准zip压缩方式更有前提,会成为新的趋势。这两个可以共存。
作者: ShowCode    时间: 2017-5-5 10:40

回复 9# happy886rr


建议放一些数据对比在顶楼,让大家有更加直观的震撼。比如:
大量小文件的压缩、解压
少量大文件的压缩、解压
等等

这样才能更好的体现ezip对比市面上其它软件的优势所在




欢迎光临 批处理之家 (http://bbs.bathome.net/) Powered by Discuz! 7.2