返回列表 发帖

第三方离线包管理工具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包的索引、编号、解压方式、描述等信息。
pkg [option] [package name]...
  -i Install the package
  -u Uninstall the package
  -l List the package, type only "-l" for installed infomation
  -s Search the package\
  -h Show help information
  -v Version 1.0COPY
示例:
pkg -i sed 4.3
pkg -u *sed
pkg -l *ti
pkg -s "计算"COPY
离线功能无与伦比,比如我要下载msys版sed
pkg -i sed msys
批量下载所有sed开头的包
pkg -i sed*
删除一个已经安装的sed包
pkg -u sed
批量删除所有sed开头的包
pkg -u sed*
列举当前安装的第三方
pkg -l
查看一个包的信息,Cracker这是一个很有名的压缩文件密码破解器。
pkg -l Cracker
搜索关于计算的包
pkg -s "计算"COPY
关于my.in的配置方法
[dir]
;这里是安装目录,支持环境变量扩展,比如 BinDir = %SystemRoot%\system32\
BinDir = .\bin\
;这里是安装包目录
PackageDir = .\package\COPY
源码:
/*
THE BCN OFFLINE PACKAGE TOOL, COPYRIGHT@2017~2019 BY HAPPY, VERSION 1.0
PKG.EXE
LINK SHLWAPI.LIB
*/
#include      <io.h>
#include   <stdio.h>
#include <windows.h>
#include <shlwapi.h>
#if defined _MSC_VER
#pragma comment(lib, "shlwapi.lib")
#endif
/*************宏量定义*************/
#define SAFE_SIZE  512
#define FILE_EXIST 0
#define FILE_EREAD 4
//定义帮助说明
#define HELP_INFORMATION "\
pkg version 1.0 - Offline pacakage tool - Copyright (C) 2017-2019 Happy Bathome\n\
Usage: pkg [options] [package name] ...\n\
\n\
General options:\n\
  -i   Install the package\n\
  -u   Uninstall the package\n\
  -l   List the package, type only \"-l\" for installed infomation\n\
  -s   Search the package\n\
  -h   Show help information\n\
  -v   Version 1.0\n\
\n\
Official website:\n\
       http://www.bathome.net/thread-44020-1-1.html\n"
#define SEARCH_HEAD "\
=================================================================\n\
NAME                 VERSION                  PKG-SN        SIZE\n\
================================================================="
/*************全局变量*************/
//分配读取配置容器
static char inifDIR[SAFE_SIZE];
static char binDIR[SAFE_SIZE];
static char packageDIR[SAFE_SIZE];
static char rootENV[SAFE_SIZE];
static char exeFullPath[SAFE_SIZE];
//列举正则容器
static char resLIST[SAFE_SIZE];
//第三方下载地址容器
static char pkgPATH[SAFE_SIZE];
//第三方下载目录容器
static char binPATH[SAFE_SIZE];
//搜索关键词
static char keywords[SAFE_SIZE];
//分配缓存区、行容器
static char LCache[SAFE_SIZE*2];
//分配表格容器
static char tmpp[6][SAFE_SIZE];
//解压工具UNRAR容器
int unrarSN=0;
static char unrar7zPATH[SAFE_SIZE];
static char unrar7zPKGH[SAFE_SIZE];
static char unrar7zCMD[SAFE_SIZE];
/*************函数声明*************/
// 对VC6.0、VS2010、GCC作兼容性编译
#if defined (__GNUC__) || (_MSC_VER == 1200)
HWND WINAPI GetConsoleWindow();
#endif
/*************功能函数*************/
//判断纯数字
BOOL isPureNumber(const char* nstr)
{
char* p=(char*)nstr;
while('0'<=*p && *p<='9')
{
p++;
}
return (*p=='\0')?TRUE:FALSE;
}
//子串查找忽略大小写
const char* stristr(const char* str, const char* subStr)
{
int len = strlen(subStr);
if(len == 0)
{
return NULL;
}
while(*str)
{
if(_strnicmp(str, subStr, len) == 0)
{
return str;
}
str++;
}
return NULL;
}
//删除目录树
BOOL RemoveDirectoryTreeA(const char* lpszPath)
{
SHFILEOPSTRUCT FileOp;
FileOp.fFlags = FOF_SILENT | FOF_NOCONFIRMATION;
FileOp.hNameMappings = NULL;
FileOp.hwnd = NULL;
FileOp.lpszProgressTitle = NULL;
FileOp.pFrom = lpszPath;
FileOp.pTo = NULL;
FileOp.wFunc = FO_DELETE;
return (SHFileOperationA(&FileOp)==0)?TRUE:FALSE;
}
//遍历目录
void ListInstalledPackage(const char* inpath)
{
struct _finddata_t data;
long hnd=_findfirst(inpath, &data);
if(hnd<0)
{
fprintf(stdout, "Not install any packages");
return;
}
int nRet=(hnd<0)?-1:1;
while(nRet>=0)
{
if(data.attrib==_A_SUBDIR && strcmp(data.name, ".")!=0 && strcmp(data.name, "..")!=0)
{
fprintf(stdout, "Installed package \"%s\"\n", data.name);
}
else
{
char* ep=strrchr(data.name, '.');
if(ep!=NULL && stricmp(ep, ".exe")==0)
{
*ep='\0';
fprintf(stdout, "Installed package \"%s\"\n", data.name);
}
}
nRet=_findnext(hnd, &data);
}
_findclose(hnd);
}
//搜索函数
int SearchStr(int iargc, char** iargv, char* inifile, int optionSN)
{
FILE* fp=fopen(inifile, "r");
if(fp==NULL)
{
fprintf(stdout, "Can not read my.ini file .");
exit(1);
}
BOOL kMARK=FALSE, sMARK=FALSE;
int i=0, j=0, mode=0, inputSN=0, kLEN=strlen(iargv[2]);
if(iargv[2][0]=='*')
{
//匹配任意位置
mode=1;
strcpy(keywords, iargv[2]+1);
}
else if(iargv[2][kLEN-1]=='*')
{
//匹配首部位置
mode=2;
strcpy(keywords, iargv[2]);
keywords[kLEN-1]='\0';
}
else if(isPureNumber(iargv[2]))
{
//匹配PKG-SN
mode=3;
inputSN=atoi(iargv[2]);
}
else
{
//匹配全字
mode=0;
strcpy(keywords, iargv[2]);
}
if(optionSN==2)
{
fprintf(stdout, "%s\n", SEARCH_HEAD);
}
while(!feof(fp))
{
//读入标准行
fgets(LCache, SAFE_SIZE*2, fp);
//辅助指针
char* Line=LCache;
while(*Line!='\n' && *Line!='\0')
{
Line++;
}
*Line='\0';
//指针回首
Line=LCache;
//过滤行TAB缩进或前空格
while(*Line=='\t'|| *Line==' ')
{
Line++;
}
if(!kMARK)
{
if(stristr(Line, "[table]")==Line)
{
kMARK=TRUE;
continue;
}
}
if(!kMARK || *Line==';' || *Line=='\0')
{
continue;
}
//行计数器
i++;
//开启search开关
if(optionSN==4 && stristr(Line, keywords))
{
sMARK=TRUE;
}
char* textstrp=NULL;
if(textstrp=strtok(Line, " "))
{
strcpy(tmpp[0], textstrp);
}
for(j=1; j<=5; j++)
{
if(textstrp=strtok(NULL, " "))
{
strcpy(tmpp[j], textstrp);
}
else
{
tmpp[j][0]=0;
}
}
int pkgSN=atoi(tmpp[1]+1);
if(
    (optionSN==4 && sMARK==TRUE)                    ||
    (mode==0 && stricmp(tmpp[0], keywords)==0)      ||
    (mode==1 && stristr(tmpp[0], keywords))         ||
    (mode==2 && stristr(tmpp[0], keywords)==tmpp[0])||
    (mode==3 && pkgSN==inputSN)
)
{
if(iargc>3 && stristr(tmpp[2], iargv[3])==NULL)
{
continue;
}
//开启list开关
if(optionSN==2)
{
//打印搜索结果
fprintf(stdout, "%-20.20s %-24.24s %s     %7s\n", tmpp[0], tmpp[2], tmpp[1], tmpp[4]);
continue;
}
//开启info开关
if(optionSN==4)
{
//打印搜索结果
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]);
sMARK=FALSE;
continue;
}
//删除包命令
if(optionSN==5)
{
fprintf(stdout, "Remove package \"%s\" ...\n", tmpp[0]);
BOOL isREMOVE=TRUE;
sprintf(binPATH, "%s%s", binDIR, tmpp[0]);
//删除包目录树
if(PathIsDirectoryA(binPATH))
{
if(!RemoveDirectoryTreeA(binPATH))
{
isREMOVE=FALSE;
}
}
strcat(binPATH, ".exe");
if(_access(binPATH, FILE_EXIST)==0)
{
if(remove(binPATH)!=0)
{
isREMOVE=FALSE;
}
}
if(isREMOVE)
{
fprintf(stdout, "The package \"%s\" has been removed .\n", tmpp[0]);
}
else
{
fprintf(stdout, "The package \"%s\" remove failed .\n", tmpp[0]);
}
if(mode==0)
{
return 0;
}
else
{
fprintf(stdout, "\n");
}
continue;
}
if (optionSN==1)
{
//判断文件压缩类型
int pressTYPE=atoi(tmpp[3]+1);
sprintf(pkgPATH, "%s%04d", packageDIR, pkgSN);
sprintf(binPATH, "%s%s", binDIR, tmpp[0]);
if(pressTYPE==0)
{
strcat(binPATH, ".exe");
//显示下载信息
fprintf(stdout, "Install package \"%s\" ...\n", tmpp[0]);
//复制文件
if(CopyFileA(pkgPATH, binPATH, FALSE))
{
fprintf(stdout, "Install completed .\n");
}
else
{
fprintf(stdout, "Install error .\n");
continue;
}
}
else
{
if(unrar7zPATH[0]=='\0')
{
sprintf(unrar7zPATH, "%s%s", binDIR, "7z.exe");
}
if(_access(unrar7zPATH, FILE_EXIST)!=0)
{
sprintf(unrar7zPKGH, "%s%04d", packageDIR, unrarSN);
//复制文件
if(!CopyFileA(unrar7zPKGH, unrar7zPATH, FALSE))
{
fprintf(stdout, "Missing unrar tool, can't extract the package \"%s\".\n", tmpp[0]);
exit(1);
}
}
sprintf(unrar7zCMD, "-y x %s -o%s", pkgPATH, binDIR);
fprintf(stdout, "Installation package \"%s\" ...\n", tmpp[0]);
ShellExecuteA(GetConsoleWindow(), "runas", unrar7zPATH, unrar7zCMD, "", SW_HIDE);
fprintf(stdout, "Install completed .\n");
}
//优化显示
if(mode==0)
{
return 0;
}
else
{
fprintf(stdout, "\n");
}
}
}
}
fclose(fp);
return 0;
}
/*************MAIN函数*************/
int main(int argc, char** argv)
{
//设置开关模式变量
int optionSN=0;
if(argc<3)
{
if(argc==2 && stricmp(argv[1], "-l")==0)
{
optionSN=7;
}
else
{
fprintf(stdout, HELP_INFORMATION);
return 0;
}
}
if (stricmp(argv[1], "-h")==0 || stricmp(argv[1], "-v")==0)
{
fprintf(stdout, HELP_INFORMATION);
return 0;
}
if(stricmp(argv[1], "-i")==0)
{
optionSN=1;
}
else if(argc!=2 && stricmp(argv[1], "-l")==0)
{
optionSN=2;
}
else if(stricmp(argv[1], "-s")==0)
{
optionSN=4;
}
else if(stricmp(argv[1], "-u")==0)
{
optionSN=5;
}
else if(optionSN !=7)
{
fprintf(stdout, "Type \"-h\" for help information .\n");
return 1;
}
//获取可执行文件所在目录
GetModuleFileNameA(NULL, exeFullPath, SAFE_SIZE);
char *p=strrchr(exeFullPath, '\\');
*(++p)='\0';
//获取配置文件pkg.ini路径
sprintf(inifDIR, "%s..\\my.ini", exeFullPath);
if(_access(inifDIR, FILE_EREAD)!=0)
{
fprintf(stdout, "Can not read my.ini file .\n");
return 1;
}
//获取配置键值bindir
GetPrivateProfileStringA("dir", "bindir", "non", binDIR, SAFE_SIZE, inifDIR);
if(strcmp(binDIR, "non")==0)
{
sprintf(binDIR, "%s..\\", exeFullPath);
}
else
{
ExpandEnvironmentStringsA(binDIR, rootENV,SAFE_SIZE);
if(strchr(rootENV, ':')==NULL)
{
sprintf(binDIR, "%s..\\%s", exeFullPath, rootENV);
}
else
{
sprintf(binDIR, "..\\%s", rootENV);
}
//判断根目录是否存在
if(!PathIsDirectory(binDIR))
{
fprintf(stdout, "The bin directory \"%s\" does not exist .\n", binDIR);
return 1;
}
strcat(binDIR, ".\\");
}
//获取配置键值packagedir
GetPrivateProfileStringA("dir", "packagedir", "non", packageDIR, SAFE_SIZE, inifDIR);
if(strcmp(binDIR, "non")==0)
{
sprintf(packageDIR, "%s..\\", exeFullPath);
}
else
{
ExpandEnvironmentStringsA(packageDIR, rootENV, SAFE_SIZE);
if(strchr(rootENV, ':')==NULL)
{
sprintf(packageDIR, "%s..\\%s", exeFullPath, rootENV);
}
else
{
sprintf(packageDIR, "..\\%s", rootENV);
}
//判断包目录是否存在
if(!PathIsDirectory(packageDIR))
{
fprintf(stdout, "The package directory \"%s\" does not exist .\n", binDIR);
return 1;
}
strcat(packageDIR, ".\\");
}
if(optionSN==7)
{
sprintf(resLIST, "%s*", binDIR);
ListInstalledPackage(resLIST);
return 0;
}
//调用核心函数
SearchStr(argc, argv, inifDIR, optionSN);
return 0;
}COPY

管理员大神,pkg的下载链接失效了,能否提供一个新的地址。
第三方下载页面只能下载pkg.exe没有附带的my.ini

TOP

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

TOP

返回列表