Board logo

标题: 第三方离线包管理工具pkg.exe [打印本页]

作者: happy886rr    时间: 2017-5-5 11:14     标题: 第三方离线包管理工具pkg.exe

本帖最后由 happy886rr 于 2017-5-5 17:19 编辑
PKG.EXE 1.0 (BCN OFFLINE PACKAGE TOOL BY HAPPY)
城通网盘下载(有效期60天):https://page37.ctfile.com/fs/14274637-201889860

摘要:
========================================================
PKG.EXE第三方离线包管理工具,无需联网,共收录BCN第三方1500个。独创PKG-SN序号,
每个第三方拥有唯一本地序号PKG-SN,针对RAR类型的包,会自动解压安装到PKG.INI配
置的BinDir目录。自带第三方列表,查询信息无需联网,完全脱机运行。
========================================================
图片均为外链随时失效。


用法:
下载完pkg.7z,直接解压即可,里边的bin目录就是第三方的安装目录,可以将其加入环境变量PATH中,my.ini是pkg的配置文件,用于设置pkg的工作目录、包目录,以及package包的索引、编号、解压方式、描述等信息。
  1. pkg [option] [package name]...
  2.   -i Install the package
  3.   -u Uninstall the package
  4.   -l List the package, type only "-l" for installed infomation
  5.   -s Search the package\
  6.   -h Show help information
  7.   -v Version 1.0
复制代码
示例:
  1. pkg -i sed 4.3
  2. pkg -u *sed
  3. pkg -l *ti
  4. pkg -s "计算"
复制代码
  1. 离线功能无与伦比,比如我要下载msys版sed
  2. pkg -i sed msys
  3. 批量下载所有sed开头的包
  4. pkg -i sed*
  5. 删除一个已经安装的sed包
  6. pkg -u sed
  7. 批量删除所有sed开头的包
  8. pkg -u sed*
  9. 列举当前安装的第三方
  10. pkg -l
  11. 查看一个包的信息,Cracker这是一个很有名的压缩文件密码破解器。
  12. pkg -l Cracker
  13. 搜索关于计算的包
  14. pkg -s "计算"
复制代码
关于my.in的配置方法
  1. [dir]
  2. ;这里是安装目录,支持环境变量扩展,比如 BinDir = %SystemRoot%\system32\
  3. BinDir = .\bin\
  4. ;这里是安装包目录
  5. PackageDir = .\package\
复制代码
源码:
  1. /*
  2. THE BCN OFFLINE PACKAGE TOOL, COPYRIGHT@2017~2019 BY HAPPY, VERSION 1.0
  3. PKG.EXE
  4. LINK SHLWAPI.LIB
  5. */
  6. #include      <io.h>
  7. #include   <stdio.h>
  8. #include <windows.h>
  9. #include <shlwapi.h>
  10. #if defined _MSC_VER
  11. #pragma comment(lib, "shlwapi.lib")
  12. #endif
  13. /*************宏量定义*************/
  14. #define SAFE_SIZE  512
  15. #define FILE_EXIST 0
  16. #define FILE_EREAD 4
  17. //定义帮助说明
  18. #define HELP_INFORMATION "\
  19. pkg version 1.0 - Offline pacakage tool - Copyright (C) 2017-2019 Happy Bathome\n\
  20. Usage: pkg [options] [package name] ...\n\
  21. \n\
  22. General options:\n\
  23.   -i   Install the package\n\
  24.   -u   Uninstall the package\n\
  25.   -l   List the package, type only \"-l\" for installed infomation\n\
  26.   -s   Search the package\n\
  27.   -h   Show help information\n\
  28.   -v   Version 1.0\n\
  29. \n\
  30. Official website:\n\
  31.        http://www.bathome.net/thread-44020-1-1.html\n"
  32. #define SEARCH_HEAD "\
  33. =================================================================\n\
  34. NAME                 VERSION                  PKG-SN        SIZE\n\
  35. ================================================================="
  36. /*************全局变量*************/
  37. //分配读取配置容器
  38. static char inifDIR[SAFE_SIZE];
  39. static char binDIR[SAFE_SIZE];
  40. static char packageDIR[SAFE_SIZE];
  41. static char rootENV[SAFE_SIZE];
  42. static char exeFullPath[SAFE_SIZE];
  43. //列举正则容器
  44. static char resLIST[SAFE_SIZE];
  45. //第三方下载地址容器
  46. static char pkgPATH[SAFE_SIZE];
  47. //第三方下载目录容器
  48. static char binPATH[SAFE_SIZE];
  49. //搜索关键词
  50. static char keywords[SAFE_SIZE];
  51. //分配缓存区、行容器
  52. static char LCache[SAFE_SIZE*2];
  53. //分配表格容器
  54. static char tmpp[6][SAFE_SIZE];
  55. //解压工具UNRAR容器
  56. int unrarSN=0;
  57. static char unrar7zPATH[SAFE_SIZE];
  58. static char unrar7zPKGH[SAFE_SIZE];
  59. static char unrar7zCMD[SAFE_SIZE];
  60. /*************函数声明*************/
  61. // 对VC6.0、VS2010、GCC作兼容性编译
  62. #if defined (__GNUC__) || (_MSC_VER == 1200)
  63. HWND WINAPI GetConsoleWindow();
  64. #endif
  65. /*************功能函数*************/
  66. //判断纯数字
  67. BOOL isPureNumber(const char* nstr)
  68. {
  69. char* p=(char*)nstr;
  70. while('0'<=*p && *p<='9')
  71. {
  72. p++;
  73. }
  74. return (*p=='\0')?TRUE:FALSE;
  75. }
  76. //子串查找忽略大小写
  77. const char* stristr(const char* str, const char* subStr)
  78. {
  79. int len = strlen(subStr);
  80. if(len == 0)
  81. {
  82. return NULL;
  83. }
  84. while(*str)
  85. {
  86. if(_strnicmp(str, subStr, len) == 0)
  87. {
  88. return str;
  89. }
  90. str++;
  91. }
  92. return NULL;
  93. }
  94. //删除目录树
  95. BOOL RemoveDirectoryTreeA(const char* lpszPath)
  96. {
  97. SHFILEOPSTRUCT FileOp;
  98. FileOp.fFlags = FOF_SILENT | FOF_NOCONFIRMATION;
  99. FileOp.hNameMappings = NULL;
  100. FileOp.hwnd = NULL;
  101. FileOp.lpszProgressTitle = NULL;
  102. FileOp.pFrom = lpszPath;
  103. FileOp.pTo = NULL;
  104. FileOp.wFunc = FO_DELETE;
  105. return (SHFileOperationA(&FileOp)==0)?TRUE:FALSE;
  106. }
  107. //遍历目录
  108. void ListInstalledPackage(const char* inpath)
  109. {
  110. struct _finddata_t data;
  111. long hnd=_findfirst(inpath, &data);
  112. if(hnd<0)
  113. {
  114. fprintf(stdout, "Not install any packages");
  115. return;
  116. }
  117. int nRet=(hnd<0)?-1:1;
  118. while(nRet>=0)
  119. {
  120. if(data.attrib==_A_SUBDIR && strcmp(data.name, ".")!=0 && strcmp(data.name, "..")!=0)
  121. {
  122. fprintf(stdout, "Installed package \"%s\"\n", data.name);
  123. }
  124. else
  125. {
  126. char* ep=strrchr(data.name, '.');
  127. if(ep!=NULL && stricmp(ep, ".exe")==0)
  128. {
  129. *ep='\0';
  130. fprintf(stdout, "Installed package \"%s\"\n", data.name);
  131. }
  132. }
  133. nRet=_findnext(hnd, &data);
  134. }
  135. _findclose(hnd);
  136. }
  137. //搜索函数
  138. int SearchStr(int iargc, char** iargv, char* inifile, int optionSN)
  139. {
  140. FILE* fp=fopen(inifile, "r");
  141. if(fp==NULL)
  142. {
  143. fprintf(stdout, "Can not read my.ini file .");
  144. exit(1);
  145. }
  146. BOOL kMARK=FALSE, sMARK=FALSE;
  147. int i=0, j=0, mode=0, inputSN=0, kLEN=strlen(iargv[2]);
  148. if(iargv[2][0]=='*')
  149. {
  150. //匹配任意位置
  151. mode=1;
  152. strcpy(keywords, iargv[2]+1);
  153. }
  154. else if(iargv[2][kLEN-1]=='*')
  155. {
  156. //匹配首部位置
  157. mode=2;
  158. strcpy(keywords, iargv[2]);
  159. keywords[kLEN-1]='\0';
  160. }
  161. else if(isPureNumber(iargv[2]))
  162. {
  163. //匹配PKG-SN
  164. mode=3;
  165. inputSN=atoi(iargv[2]);
  166. }
  167. else
  168. {
  169. //匹配全字
  170. mode=0;
  171. strcpy(keywords, iargv[2]);
  172. }
  173. if(optionSN==2)
  174. {
  175. fprintf(stdout, "%s\n", SEARCH_HEAD);
  176. }
  177. while(!feof(fp))
  178. {
  179. //读入标准行
  180. fgets(LCache, SAFE_SIZE*2, fp);
  181. //辅助指针
  182. char* Line=LCache;
  183. while(*Line!='\n' && *Line!='\0')
  184. {
  185. Line++;
  186. }
  187. *Line='\0';
  188. //指针回首
  189. Line=LCache;
  190. //过滤行TAB缩进或前空格
  191. while(*Line=='\t'|| *Line==' ')
  192. {
  193. Line++;
  194. }
  195. if(!kMARK)
  196. {
  197. if(stristr(Line, "[table]")==Line)
  198. {
  199. kMARK=TRUE;
  200. continue;
  201. }
  202. }
  203. if(!kMARK || *Line==';' || *Line=='\0')
  204. {
  205. continue;
  206. }
  207. //行计数器
  208. i++;
  209. //开启search开关
  210. if(optionSN==4 && stristr(Line, keywords))
  211. {
  212. sMARK=TRUE;
  213. }
  214. char* textstrp=NULL;
  215. if(textstrp=strtok(Line, " "))
  216. {
  217. strcpy(tmpp[0], textstrp);
  218. }
  219. for(j=1; j<=5; j++)
  220. {
  221. if(textstrp=strtok(NULL, " "))
  222. {
  223. strcpy(tmpp[j], textstrp);
  224. }
  225. else
  226. {
  227. tmpp[j][0]=0;
  228. }
  229. }
  230. int pkgSN=atoi(tmpp[1]+1);
  231. if(
  232.     (optionSN==4 && sMARK==TRUE)                    ||
  233.     (mode==0 && stricmp(tmpp[0], keywords)==0)      ||
  234.     (mode==1 && stristr(tmpp[0], keywords))         ||
  235.     (mode==2 && stristr(tmpp[0], keywords)==tmpp[0])||
  236.     (mode==3 && pkgSN==inputSN)
  237. )
  238. {
  239. if(iargc>3 && stristr(tmpp[2], iargv[3])==NULL)
  240. {
  241. continue;
  242. }
  243. //开启list开关
  244. if(optionSN==2)
  245. {
  246. //打印搜索结果
  247. fprintf(stdout, "%-20.20s %-24.24s %s     %7s\n", tmpp[0], tmpp[2], tmpp[1], tmpp[4]);
  248. continue;
  249. }
  250. //开启info开关
  251. if(optionSN==4)
  252. {
  253. //打印搜索结果
  254. fprintf(stdout, "\nNAME       :%s\nPKGSN      :%s\nVERSION    :%s\nCOMPRESS   :%s\nSIZE       :%s\nDETAILE    :%s\n\n", tmpp[0], tmpp[1], tmpp[2], tmpp[3], tmpp[4], tmpp[5]);
  255. sMARK=FALSE;
  256. continue;
  257. }
  258. //删除包命令
  259. if(optionSN==5)
  260. {
  261. fprintf(stdout, "Remove package \"%s\" ...\n", tmpp[0]);
  262. BOOL isREMOVE=TRUE;
  263. sprintf(binPATH, "%s%s", binDIR, tmpp[0]);
  264. //删除包目录树
  265. if(PathIsDirectoryA(binPATH))
  266. {
  267. if(!RemoveDirectoryTreeA(binPATH))
  268. {
  269. isREMOVE=FALSE;
  270. }
  271. }
  272. strcat(binPATH, ".exe");
  273. if(_access(binPATH, FILE_EXIST)==0)
  274. {
  275. if(remove(binPATH)!=0)
  276. {
  277. isREMOVE=FALSE;
  278. }
  279. }
  280. if(isREMOVE)
  281. {
  282. fprintf(stdout, "The package \"%s\" has been removed .\n", tmpp[0]);
  283. }
  284. else
  285. {
  286. fprintf(stdout, "The package \"%s\" remove failed .\n", tmpp[0]);
  287. }
  288. if(mode==0)
  289. {
  290. return 0;
  291. }
  292. else
  293. {
  294. fprintf(stdout, "\n");
  295. }
  296. continue;
  297. }
  298. if (optionSN==1)
  299. {
  300. //判断文件压缩类型
  301. int pressTYPE=atoi(tmpp[3]+1);
  302. sprintf(pkgPATH, "%s%04d", packageDIR, pkgSN);
  303. sprintf(binPATH, "%s%s", binDIR, tmpp[0]);
  304. if(pressTYPE==0)
  305. {
  306. strcat(binPATH, ".exe");
  307. //显示下载信息
  308. fprintf(stdout, "Install package \"%s\" ...\n", tmpp[0]);
  309. //复制文件
  310. if(CopyFileA(pkgPATH, binPATH, FALSE))
  311. {
  312. fprintf(stdout, "Install completed .\n");
  313. }
  314. else
  315. {
  316. fprintf(stdout, "Install error .\n");
  317. continue;
  318. }
  319. }
  320. else
  321. {
  322. if(unrar7zPATH[0]=='\0')
  323. {
  324. sprintf(unrar7zPATH, "%s%s", binDIR, "7z.exe");
  325. }
  326. if(_access(unrar7zPATH, FILE_EXIST)!=0)
  327. {
  328. sprintf(unrar7zPKGH, "%s%04d", packageDIR, unrarSN);
  329. //复制文件
  330. if(!CopyFileA(unrar7zPKGH, unrar7zPATH, FALSE))
  331. {
  332. fprintf(stdout, "Missing unrar tool, can't extract the package \"%s\".\n", tmpp[0]);
  333. exit(1);
  334. }
  335. }
  336. sprintf(unrar7zCMD, "-y x %s -o%s", pkgPATH, binDIR);
  337. fprintf(stdout, "Installation package \"%s\" ...\n", tmpp[0]);
  338. ShellExecuteA(GetConsoleWindow(), "runas", unrar7zPATH, unrar7zCMD, "", SW_HIDE);
  339. fprintf(stdout, "Install completed .\n");
  340. }
  341. //优化显示
  342. if(mode==0)
  343. {
  344. return 0;
  345. }
  346. else
  347. {
  348. fprintf(stdout, "\n");
  349. }
  350. }
  351. }
  352. }
  353. fclose(fp);
  354. return 0;
  355. }
  356. /*************MAIN函数*************/
  357. int main(int argc, char** argv)
  358. {
  359. //设置开关模式变量
  360. int optionSN=0;
  361. if(argc<3)
  362. {
  363. if(argc==2 && stricmp(argv[1], "-l")==0)
  364. {
  365. optionSN=7;
  366. }
  367. else
  368. {
  369. fprintf(stdout, HELP_INFORMATION);
  370. return 0;
  371. }
  372. }
  373. if (stricmp(argv[1], "-h")==0 || stricmp(argv[1], "-v")==0)
  374. {
  375. fprintf(stdout, HELP_INFORMATION);
  376. return 0;
  377. }
  378. if(stricmp(argv[1], "-i")==0)
  379. {
  380. optionSN=1;
  381. }
  382. else if(argc!=2 && stricmp(argv[1], "-l")==0)
  383. {
  384. optionSN=2;
  385. }
  386. else if(stricmp(argv[1], "-s")==0)
  387. {
  388. optionSN=4;
  389. }
  390. else if(stricmp(argv[1], "-u")==0)
  391. {
  392. optionSN=5;
  393. }
  394. else if(optionSN !=7)
  395. {
  396. fprintf(stdout, "Type \"-h\" for help information .\n");
  397. return 1;
  398. }
  399. //获取可执行文件所在目录
  400. GetModuleFileNameA(NULL, exeFullPath, SAFE_SIZE);
  401. char *p=strrchr(exeFullPath, '\\');
  402. *(++p)='\0';
  403. //获取配置文件pkg.ini路径
  404. sprintf(inifDIR, "%s..\\my.ini", exeFullPath);
  405. if(_access(inifDIR, FILE_EREAD)!=0)
  406. {
  407. fprintf(stdout, "Can not read my.ini file .\n");
  408. return 1;
  409. }
  410. //获取配置键值bindir
  411. GetPrivateProfileStringA("dir", "bindir", "non", binDIR, SAFE_SIZE, inifDIR);
  412. if(strcmp(binDIR, "non")==0)
  413. {
  414. sprintf(binDIR, "%s..\\", exeFullPath);
  415. }
  416. else
  417. {
  418. ExpandEnvironmentStringsA(binDIR, rootENV,SAFE_SIZE);
  419. if(strchr(rootENV, ':')==NULL)
  420. {
  421. sprintf(binDIR, "%s..\\%s", exeFullPath, rootENV);
  422. }
  423. else
  424. {
  425. sprintf(binDIR, "..\\%s", rootENV);
  426. }
  427. //判断根目录是否存在
  428. if(!PathIsDirectory(binDIR))
  429. {
  430. fprintf(stdout, "The bin directory \"%s\" does not exist .\n", binDIR);
  431. return 1;
  432. }
  433. strcat(binDIR, ".\\");
  434. }
  435. //获取配置键值packagedir
  436. GetPrivateProfileStringA("dir", "packagedir", "non", packageDIR, SAFE_SIZE, inifDIR);
  437. if(strcmp(binDIR, "non")==0)
  438. {
  439. sprintf(packageDIR, "%s..\\", exeFullPath);
  440. }
  441. else
  442. {
  443. ExpandEnvironmentStringsA(packageDIR, rootENV, SAFE_SIZE);
  444. if(strchr(rootENV, ':')==NULL)
  445. {
  446. sprintf(packageDIR, "%s..\\%s", exeFullPath, rootENV);
  447. }
  448. else
  449. {
  450. sprintf(packageDIR, "..\\%s", rootENV);
  451. }
  452. //判断包目录是否存在
  453. if(!PathIsDirectory(packageDIR))
  454. {
  455. fprintf(stdout, "The package directory \"%s\" does not exist .\n", binDIR);
  456. return 1;
  457. }
  458. strcat(packageDIR, ".\\");
  459. }
  460. if(optionSN==7)
  461. {
  462. sprintf(resLIST, "%s*", binDIR);
  463. ListInstalledPackage(resLIST);
  464. return 0;
  465. }
  466. //调用核心函数
  467. SearchStr(argc, argv, inifDIR, optionSN);
  468. return 0;
  469. }
复制代码

作者: shootman2    时间: 2018-6-15 14:25

管理员大神,pkg的下载链接失效了,能否提供一个新的地址。
第三方下载页面只能下载pkg.exe没有附带的my.ini
作者: CrLf    时间: 2020-2-29 20:55

楼主大佬,我把my.ini保存到pkg.exe目录下,还是报错了:
  1. Can not read my.ini file .
复制代码
另外,因为七牛云的域名调整,所用的第三方工具清单文件已改到 http://www.bathome.net/s/tool/ 路径下了,应该会影响原有功能




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