本帖最后由 happy886rr 于 2017-4-30 23:11 编辑
windows下的yum诞生了。完全借鉴linux yum的操作体验,大部分用法都进行了兼容移植。强大的缓存机制,一般查询都不需要任何网络。正真将包管理引入windows下,一个包的安装、移除、更新,各种管理机制都做了最大限度的实现。鉴于目前BCN的云目录结构,一些特殊功能,暂时无法对接,不过它已经把yum的体验带到了win下。
YUM.EXE 1.0 (YUM TOOL BY HAPPY)
下载:
图片存为a.zip解压即是。

摘要:
======================================================
YUM.EXE 第三方包管理工具,完全移植LINUX的包管理模式,包括开关、用户体验都做了
极为精细的移植。独创YUM云序列号,每个第三方拥有唯一的云序列YUM-SN, 针对RAR类
型的包,会自动解压安装到YUM.INI配置的本地目录。总之,你把它当做WINDOWS下的YUM
用就对了。
强大的缓存体系,将访问BCN服务器的次数控制到非常苛刻的地步。自带第三方列表,查
询信息都不需要任何网络,后期将推出单机版完全脱网工作。
备注:几乎实现了LINUX下YUM 70%的功能,但是鉴于BCN的目录架构,很多更奇异的功能
暂时不会开放。
======================================================
用法:
-----------------------------------------------------------------------------
yum [option] [package name]...
-----------------------------------------------------------------------------
-i, install
Install the package
-u, update
Update the package
-c, clean
Clean the package cache
-f, info
Show the package info
-s, search
Search the package
-l, list
List the package, type "installed" for installed infomation
-r, remove
Remove the package
-h, help
Show help information
-----------------------------------------------------------------------------
示例:
-----------------------------------------------------------------------------
yum install sed
yum install sed 4.3
yum install sed*
yum list im*
yum list *ti
yum install 0001
yum remove sed
yum update sed
yum clean sed
yum info s*
yum serach "计算"
...
-----------------------------------------------------------------------------
同时配备了缩写开关
yum -i sed 4.3 ==> yum install sed 4.3
yum -r sed 4.3 ==> yum remove sed 4.3
...
-----------------------------------------------------------------------------
功能强大到无与伦比,比如我要下载msys版sed
yum install sed msys
下载happy版本的choice高仿版
yum install choice happy
移除一个已经安装的sed包
yum remove sed
清除sed包缓存
yum clean sed
列举当前安装的第三方
yum list installed
查看一个包的信息,Cracker这是一个很有名的压缩文件密码破解器。
yum info Cracker
更新astyle包,astyle非常智能的代码格式化工具。
yum update astyle
-----------------------------------------------------------------------------
配置:
-----------------------------------------------------------------------------
关于yum.ini的配置方法
[url ]
;这里是yum的下载源地址,可以是任意的服务器地址,只要搭建了yum源,均可支持yum
yumsurl = http://batch-cn.qiniudn.com/tool/
[dir]
;这里是安装目录,支持环境变量扩展,比如 rootdir = %SystemRoot%\system32\
rootdir = .\
;这里是包缓存目录
cachedir = .\
[setting]
;安装完后是否保留安装包
keepcache = 1
-----------------------------------------------------------------------------
原创代码 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #include <stdio.h> | | #include <stdlib.h> | | #include <string.h> | | #include <windows.h> | | #include <wininet.h> | | #include <shlwapi.h> | | #include<shellapi.h> | | #include <direct.h> | | #include <conio.h> | | #include <time.h> | | #include <math.h> | | #include <io.h> | | #pragma comment(lib, "wininet.lib") | | #pragma comment(lib, "shlwapi.lib") | | | | | | #define SAFE_SIZE 512 | | #define FILE_EXIST 0 | | #define FILE_EREAD 4 | | | | | | #define HELP_INFORMATION "\ | | Usage: yum [option] [package name]...\n\ | | \n\ | | -i, install\n\ | | Install the package\n\ | | -u, update\n\ | | Update the package\n\ | | -c, clean\n\ | | Clean the package cache\n\ | | -f, info\n\ | | Show the package info\n\ | | -s, search\n\ | | Search the package\n\ | | -l, list\n\ | | List the package, type \"installed\" for installed infomation\n\ | | -r, remove\n\ | | Remove the package\n\ | | -h, help\n\ | | Show help information\n\ | | \n\ | | Version 1.0 2017-04-30 20:32 UTC\n\ | | Officil: www.bathome.net/thread-43961-1-1.html\n" | | | | #define SEARCH_HEAD "\ | | =================================================================\n\ | | NAME VERSION YUM-SN SIZE\n\ | | =================================================================" | | | | #define SEARCH_LOGO "\ | | -----------------------------------------------------------------\n\ | | \n\ | | _ _ _ _ | The Batch Online Yum Tool,\n\ | | \\ | | | \\ / | | Copyright@2017~2019 By Happy, yum.exe\n\ | | \\ \\| |_ _| |\\ /| | | Type \"help\" for help informaiton .\n\ | | \\_| | | | | | \\/ | | |\n\ | | | | |_| | |\\ /| | | Version 1.0 (2017-04-30 20:32 UTC)\n\ | | _/ |\\__'_|_| VV |_| | Officil http://www.bathome.net/thread-\n\ | | |__/ | 43961-1-1.html\n\ | | \n\ | | -----------------------------------------------------------------\n\n" | | | | | | | | static char yumsURL[SAFE_SIZE]; | | static char inifDIR[SAFE_SIZE]; | | static char rootDIR[SAFE_SIZE]; | | static char rootENV[SAFE_SIZE]; | | static char exeFullPath[SAFE_SIZE]; | | static char keepCACHE[SAFE_SIZE]; | | | | | | static char resLIST[SAFE_SIZE]; | | | | static char yumURL[SAFE_SIZE]; | | | | static char binPATH[SAFE_SIZE]; | | | | static char unrarPATH[SAFE_SIZE]; | | static char unrarDURL[SAFE_SIZE]; | | | | | | static char keywords[SAFE_SIZE]; | | | | | | static char LCache[SAFE_SIZE*2]; | | | | | | static char tmpp[6][SAFE_SIZE]; | | | | | | static char unrarCMD[SAFE_SIZE]; | | | | | | static char proGRESS[64]= {0}; | | clock_t preTime; | | ULONG preProgress; | | | | | | typedef HRESULT (WINAPI *PGETA)(LPUNKNOWN,LPCSTR,LPCSTR,DWORD,LPBINDSTATUSCALLBACK); | | PGETA PgetUrlToFileA; | | | | | | | | 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, "Already installed package \"%s\"\n\n", data.name); | | } | | else | | { | | char* ep=strrchr(data.name, '.'); | | if(ep!=NULL && stricmp(ep, ".exe")==0) | | { | | *ep='\0'; | | fprintf(stdout, "Already installed package \"%s\"\n\n", data.name); | | } | | } | | nRet=_findnext(hnd, &data); | | } | | _findclose(hnd); | | } | | | | class DownloadProgress :public IBindStatusCallback | | { | | public: | | HRESULT __stdcall QueryInterface(const IID &, void **) | | { | | return E_NOINTERFACE; | | } | | ULONG STDMETHODCALLTYPE AddRef(void) | | { | | return 1; | | } | | ULONG STDMETHODCALLTYPE Release(void) | | { | | return 1; | | } | | HRESULT STDMETHODCALLTYPE OnStartBinding(DWORD dwReserved, IBinding *pib) | | { | | return E_NOTIMPL; | | } | | virtual HRESULT STDMETHODCALLTYPE GetPriority(LONG *pnPriority) | | { | | return E_NOTIMPL; | | } | | virtual HRESULT STDMETHODCALLTYPE OnLowResource(DWORD reserved) | | { | | return S_OK; | | } | | virtual HRESULT STDMETHODCALLTYPE OnStopBinding(HRESULT hresult, LPCWSTR szError) | | { | | return E_NOTIMPL; | | } | | virtual HRESULT STDMETHODCALLTYPE GetBindInfo(DWORD *grfBINDF, BINDINFO *pbindinfo) | | { | | return E_NOTIMPL; | | } | | virtual HRESULT STDMETHODCALLTYPE OnDataAvailable(DWORD grfBSCF, DWORD dwSize, FORMATETC *pformatetc, STGMEDIUM *pstgmed) | | { | | return E_NOTIMPL; | | } | | virtual HRESULT STDMETHODCALLTYPE OnObjectAvailable(REFIID riid, IUnknown *punk) | | { | | return E_NOTIMPL; | | } | | virtual HRESULT __stdcall OnProgress(ULONG ulProgress, ULONG ulProgressMax, ULONG ulStatusCode, LPCWSTR szStatusText) | | { | | if (ulProgressMax != 0) | | { | | | | | | int downloadSpeed, restTime; | | int i=(int)ulProgress * 100.0 / (int)ulProgressMax; | | int j=i/2, disTime=(int)(clock()-preTime); | | if(disTime > 100) | | { | | downloadSpeed=((int)ulProgress-(int)preProgress) * CLOCKS_PER_SEC / disTime / 1000; | | restTime=(downloadSpeed!=0) ?((int)ulProgressMax-(int)ulProgress) / downloadSpeed :99999; | | preProgress=ulProgress, preTime+=disTime; | | } | | else if(i <100) | | { | | return S_OK; | | } | | | | if(i==100) | | { | | downloadSpeed=restTime=0; | | } | | | | for(int n=1; n<=j; n++) | | { | | proGRESS[n]='='; | | } | | | | | | fprintf(stdout, "\r%s%3d%%, %3dKB/s ", proGRESS, i, downloadSpeed); | | fflush(stdout); | | } | | return S_OK; | | } | | }; | | | | int SearchStr(int iargc, char** iargv, char* inifile, int optionSN) | | { | | FILE* fp=fopen(inifile, "r"); | | if(fp==NULL) | | { | | fprintf(stdout, "Can not read yum settings."); | | exit(1); | | } | | | | BOOL kMARK=FALSE, sMARK=FALSE; | | int mode=0, yumSN=0, kLEN=strlen(iargv[2]), kpmode=atoi(keepCACHE); | | | | 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])) | | { | | | | mode=3; | | yumSN=atoi(iargv[2]); | | } | | else | | { | | | | mode=0; | | strcpy(keywords, iargv[2]); | | } | | | | if(optionSN==2) | | { | | fprintf(stdout, "%s\n", SEARCH_HEAD); | | } | | | | int i=0; | | while(!feof(fp)) | | { | | | | fgets(LCache, SAFE_SIZE*2, fp); | | | | | | char* Line=LCache; | | | | while(*Line!='\n' && *Line!='\0') | | { | | Line++; | | } | | *Line='\0'; | | | | | | Line=LCache; | | | | | | while(*Line=='\t'|| *Line==' ') | | { | | Line++; | | } | | | | if(!kMARK) | | { | | if(stristr(Line, "[table]")==Line) | | { | | kMARK=TRUE; | | continue; | | } | | } | | | | if(!kMARK || *Line==';' || *Line=='\0') | | { | | continue; | | } | | | | | | i++; | | | | | | if(optionSN==4 && stristr(Line, keywords)) | | { | | sMARK=TRUE; | | } | | | | char* textstrp=NULL; | | | | if(textstrp=strtok(Line, " ")) | | { | | strcpy(tmpp[0], textstrp); | | } | | | | for(int j=1; j<=5; j++) | | { | | if(textstrp=strtok(NULL, " ")) | | { | | strcpy(tmpp[j], textstrp); | | } | | else | | { | | tmpp[j][0]=0; | | } | | } | | | | 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 && atoi(tmpp[1]+1)==yumSN) | | ) | | { | | if(iargc>3 && stristr(tmpp[2], iargv[3])==NULL) | | { | | continue; | | } | | | | | | if(optionSN==2) | | { | | | | fprintf(stdout, "%-20.20s %-24.24s %s %7s\n", tmpp[0], tmpp[2], tmpp[1], tmpp[4]); | | continue; | | } | | | | | | if(optionSN==5||optionSN==4) | | { | | | | fprintf(stdout, "\nNAME :%s\nYUMSN :%s\nVERSION :%s\nCOMPRESS :%s\nSIZE :%s\nDESCRIPTION:%s\n\n", tmpp[0], tmpp[1], tmpp[2], tmpp[3], tmpp[4], tmpp[5]); | | sMARK=FALSE; | | continue; | | } | | | | if (optionSN==1) | | { | | | | DownloadProgress progress; | | IBindStatusCallback* callback=(IBindStatusCallback*)&progress; | | | | | | memset(proGRESS, ' ', 51); | | proGRESS[0]='[', proGRESS[51]=']'; | | | | preTime=clock(); | | preProgress=(ULONG)0; | | | | | | int pressTYPE=atoi(tmpp[3]+1); | | | | strcpy(yumURL, yumsURL); | | strcat(yumURL, tmpp[2]); | | strcat(yumURL, "/"); | | strcat(yumURL, tmpp[0]); | | if(pressTYPE==0) | | { | | strcat(yumURL, ".exe"); | | } | | else | | { | | strcat(yumURL, ".rar"); | | } | | | | strcpy(binPATH, rootDIR); | | strcat(binPATH, tmpp[0]); | | | | | | if(pressTYPE==0) | | { | | strcat(binPATH, ".exe"); | | } | | else | | { | | strcat(binPATH, ".rar"); | | } | | | | | | fprintf(stdout, "Download package \"%s\" ...\n", tmpp[0]); | | | | | | if (PgetUrlToFileA(NULL, yumURL, binPATH, 0, static_cast<IBindStatusCallback*>(&progress)) != S_OK) | | { | | | | memset(proGRESS, ' ', 51); | | proGRESS[0]='[', proGRESS[51]=']'; | | | | preTime=clock(); | | preProgress=(ULONG)0; | | | | strcpy(yumURL, yumsURL); | | strcat(yumURL, tmpp[0]); | | if(pressTYPE==0) | | { | | strcat(yumURL, ".exe"); | | } | | else | | { | | strcat(yumURL, ".rar"); | | } | | | | if (PgetUrlToFileA(NULL, yumURL, binPATH, 0, static_cast<IBindStatusCallback*>(&progress)) != S_OK) | | { | | fprintf(stdout, "Download \"%s\" error.\n\n", tmpp[0]); | | continue; | | } | | | | } | | | | fprintf(stdout, "\n"); | | | | if(pressTYPE==1) | | { | | | | if(unrarPATH[0]=='\0') | | { | | strcpy(unrarPATH, rootDIR); | | strcat(unrarPATH, "unrar.exe"); | | } | | | | if(_access(unrarPATH, FILE_EXIST)!=0) | | { | | strcpy(unrarDURL, yumsURL); | | strcat(unrarDURL, "unrar.exe"); | | if (PgetUrlToFileA(NULL, unrarDURL, unrarPATH, 0, 0) != S_OK) | | { | | fprintf(stdout, "Can not download the unrar tool, can not extract the package \"%s\".\n", tmpp[0]); | | exit(1); | | } | | } | | | | strcpy(unrarCMD, "x -o+ -y "); | | strcat(unrarCMD, binPATH); | | strcat(unrarCMD, " "); | | strcat(unrarCMD, rootDIR); | | fprintf(stdout, "Installation package \"%s\" ...\n\n", tmpp[0]); | | ShellExecuteA(GetConsoleWindow(), "runas", unrarPATH, unrarCMD, "", SW_HIDE); | | | | | | if(kpmode==0) | | { | | remove(binPATH); | | } | | } | | else | | { | | fprintf(stdout, "\n"); | | } | | | | if(mode==0) | | { | | return 0; | | } | | | | } | | } | | } | | | | fclose(fp); | | | | return 0; | | } | | | | | | int main(int argc, char** argv) | | { | | if(argc==2) | | { | | if(stricmp(argv[1], "help")==0 || stricmp(argv[1], "-h")==0) | | { | | fprintf(stdout, HELP_INFORMATION); | | return 0; | | } | | } | | | | if(argc<3) | | { | | | | fprintf(stdout, SEARCH_LOGO); | | | | fprintf(stdout, "Type \"yum help\" for help information .\n"); | | return 1; | | } | | | | | | int optionSN=0; | | | | if(stricmp(argv[1], "install")==0 || stricmp(argv[1], "update")==0 || stricmp(argv[1], "-i")==0 || stricmp(argv[1], "-u")==0) | | { | | optionSN=1; | | } | | else if(stricmp(argv[1], "list")==0 || stricmp(argv[1], "-l")==0) | | { | | optionSN=2; | | if(stricmp(argv[2], "installed")==0) | | { | | optionSN=7; | | } | | } | | else if(stricmp(argv[1], "remove")==0 || stricmp(argv[1], "-r")==0) | | { | | optionSN=3; | | } | | else if(stricmp(argv[1], "search")==0 || stricmp(argv[1], "-s")==0) | | { | | optionSN=4; | | } | | else if(stricmp(argv[1], "info" )==0 || stricmp(argv[1], "-f")==0) | | { | | optionSN=5; | | } | | else if(stricmp(argv[1], "clean" )==0 || stricmp(argv[1], "-c")==0) | | { | | optionSN=6; | | } | | else | | { | | | | fprintf(stdout, SEARCH_LOGO); | | fprintf(stdout, "Type \"yum help\" for help information .\n"); | | return 1; | | } | | | | | | HMODULE hLib=LoadLibraryW(L"URLMON"); | | if(hLib==NULL) | | { | | fprintf(stdout, "Load urlmon library error"); | | return 1; | | } | | | | | | PgetUrlToFileA=(PGETA)GetProcAddress(hLib, "URLDownloadToFileA"); | | | | | | GetModuleFileNameA(NULL, exeFullPath, SAFE_SIZE); | | char *p=strrchr(exeFullPath, '\\'); | | *(++p)='\0'; | | | | | | strcpy(inifDIR, exeFullPath); | | strcat(inifDIR, ".\\yum.ini"); | | | | if(_access(inifDIR, FILE_EREAD)!=0) | | { | | fprintf(stdout, "Can not read yum ini.\n"); | | return 1; | | } | | | | | | GetPrivateProfileStringA("url", "yumsurl", "non", yumsURL, SAFE_SIZE, inifDIR); | | if(strcmp(yumsURL, "non")==0) | | { | | fprintf(stdout, "Needs yum url.\n"); | | return 1; | | } | | else | | { | | if(strrchr(yumsURL, '/')+1 != '\0') | | { | | strcat(yumsURL, "/"); | | } | | } | | | | | | GetPrivateProfileStringA("dir", "rootdir", "non", rootDIR, SAFE_SIZE, inifDIR); | | if(strcmp(rootDIR, "non")==0) | | { | | strcpy(rootDIR, exeFullPath); | | } | | else | | { | | ExpandEnvironmentStringsA(rootDIR, rootENV,SAFE_SIZE); | | if(strchr(rootENV, ':')==NULL) | | { | | strcpy(rootDIR, exeFullPath); | | strcat(rootDIR, rootENV); | | } | | else | | { | | strcpy(rootDIR, rootENV); | | } | | | | | | if(!PathIsDirectory(rootDIR)) | | { | | fprintf(stdout, "The root directory \"%s\" does not exist.\n", rootDIR); | | return 1; | | } | | | | strcat(rootDIR, ".\\"); | | } | | | | | | GetPrivateProfileStringA("setting", "keepcache", "non", keepCACHE, SAFE_SIZE, inifDIR); | | if(strcmp(keepCACHE, "non")==0) | | { | | strcpy(keepCACHE, "0"); | | } | | | | | | if(optionSN!=2) | | { | | fprintf(stdout, SEARCH_LOGO); | | } | | | | | | if(optionSN==3) | | { | | fprintf(stdout, "Remove package \"%s\" ...\n", argv[2]); | | | | BOOL isREMOVE=TRUE; | | char tmpT[SAFE_SIZE]= {0}; | | | | strcpy(tmpT, rootDIR); | | strcat(tmpT, argv[2]); | | | | | | if(PathIsDirectory(tmpT)) | | { | | if(!RemoveDirectoryTreeA(tmpT)) | | { | | isREMOVE=FALSE; | | } | | } | | | | strcat(tmpT, ".exe"); | | if(_access(tmpT, FILE_EXIST)==0) | | { | | if(remove(tmpT)!=0) | | { | | isREMOVE=FALSE; | | } | | } | | | | char* tp=strrchr(tmpT, '.'); | | | | if(isREMOVE) | | { | | fprintf(stdout, "The package \"%s\" has been removed.\n", argv[2]); | | } | | else | | { | | fprintf(stdout, "The package \"%s\" remove failed.\n", argv[2]); | | } | | | | return 0; | | } | | | | if(optionSN==6) | | { | | fprintf(stdout, "Clean package \"%s\"'s cache ...\n", argv[2]); | | | | char tmpT[SAFE_SIZE]= {0}; | | strcpy(tmpT, rootDIR); | | strcat(tmpT, argv[2]); | | strcat(tmpT, ".rar"); | | remove(tmpT); | | return 0; | | } | | | | if(optionSN==7) | | { | | strcpy(resLIST, rootDIR); | | strcat(resLIST, ".\\*"); | | ListInstalledPackage(resLIST); | | return 0; | | } | | | | | | SearchStr(argc, argv, inifDIR, optionSN); | | | | return 0; | | }COPY |
|