hanzsim 发表于 2018-11-25 21:02:23

发个另类的东西吧

#include"stdafx.h"
#include<windows.h>
#include<stdio.h>
#include<ShlObj.h>
#include<Shlwapi.h>
#include<regex>

#pragma comment(lib, "Shlwapi.lib")
#pragma comment(lib, "Shell32.lib")
#pragma comment(lib, "Ole32.lib")

int getCurrentPath(TCHAR *);
BOOL isFilenameValid(LPCTSTR);
BOOL createLink(LPCTSTR, LPCTSTR, LPCTSTR);
BOOL pin(int, LPCTSTR);
BOOL unpin(int, LPCTSTR);
int getTarget(LPCTSTR);
BOOL getExe(LPCTSTR, TCHAR *, TCHAR *);
BOOL getLink(LPCTSTR, TCHAR *);
BOOL getUnloadLink(int, LPCTSTR, TCHAR *);
int getOperation(LPCTSTR);
void processError();

int myError=-1;

int _tmain(int argc, _TCHAR* argv[])
{
        int target;
        BOOL isPin=TRUE;
        TCHAR exePath, arguments, linkPath;
        switch(argc){
        case 3:
                target=getTarget(argv);
                if(1==target || 2==target){
                        if(getExe(argv, exePath, arguments))
                                if(getLink(PathFindFileName(exePath), linkPath))myError=0;
                }
                break;
        case 4:
                target=getTarget(argv);
                if(1==target || 2==target){
                        if(getExe(argv, exePath, arguments))
                                if(getLink(argv, linkPath))myError=0;
                }
                else{
                        target=getTarget(argv);
                        if(1==target || 2==target){
                                int operation=getOperation(argv);
                                if(0==operation)break;
                                if(-1==operation){
                                        isPin=FALSE;
                                        if(getUnloadLink(target, argv, linkPath))myError=0;
                                }
                                else{
                                        if(getExe(argv, exePath, arguments))
                                                if(getLink(PathFindFileName(exePath), linkPath))myError=0;
                                }
                        }
                }
                break;
        case 5:
                target=getTarget(argv);
                if(1!=target && 2!=target)break;
                if(1!=getOperation(argv))break;
                if(!getExe(argv, exePath, arguments))break;
                if(getLink(argv, linkPath))myError=0;
        }
        if(!myError)
                if(isPin){
                        createLink(exePath, arguments, linkPath);
                        pin(target, linkPath);
                        if(!DeleteFile(linkPath))myError=-4;
                }
                else unpin(target, linkPath);
        processError();
}

int getCurrentPath(TCHAR *buffer)
{
        GetModuleFileName(NULL, buffer, MAX_PATH);
        TCHAR *temp=buffer;
        while('\0'!=*temp++);
        while('\\'!=*--temp);
        *++temp='\0';
        return temp-buffer;
}

BOOL isFilenameValid(LPCTSTR filename){
        int cbMultiByte = WideCharToMultiByte(CP_ACP, 0, filename, -1, NULL, 0, NULL, NULL);
        char *pszText=new char;
        WideCharToMultiByte(CP_ACP, 0, filename, -1, pszText, cbMultiByte, NULL, NULL);
        int retVal=std::regex_match(pszText, std::regex("^[^ \\\\/|<>:\"?*]+[^\\\\/|<>:\"?*]*$"));
        delete pszText;
        return retVal;
}

BOOL createLink(LPCTSTR exePath, LPCTSTR arguments, LPCTSTR linkPath)
{
        CoInitialize(NULL);
    HRESULT hr;
    IShellLink   *pLink;
    IPersistFile   *ppf;
    hr = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (void**)&pLink);
    if (FAILED(hr))return FALSE;
    hr = pLink->QueryInterface(IID_IPersistFile, (void**)&ppf);
    if (FAILED(hr))
    {
      pLink->Release();
      return FALSE;
    }
    pLink->SetPath(exePath);
        pLink->SetArguments(arguments);
        TCHAR buffer;
        _tcscpy(buffer, exePath);
        PathRemoveFileSpec(buffer);
        pLink->SetWorkingDirectory(buffer);
    pLink->SetShowCmd(SW_SHOWNORMAL);
    hr = ppf->Save(linkPath, TRUE);
    ppf->Release();
    pLink->Release();
        SHChangeNotify(SHCNE_UPDATEDIR|SHCNE_INTERRUPT, SHCNF_FLUSH | SHCNF_PATH, buffer, 0);
        CoUninitialize();
        return SUCCEEDED(hr);
}

BOOL pin(int target, LPCTSTR link){
        LPCTSTR strTarget=1==target?TEXT("startpin"):TEXT("taskbarpin");
        return (int)ShellExecute(NULL, strTarget, link, NULL, NULL, 0);
}

BOOL unpin(int target, LPCTSTR exe){
        LPCTSTR strTarget=1==target?TEXT("startunpin"):TEXT("taskbarunpin");
        return (int)ShellExecute(NULL, strTarget, exe, NULL, NULL, 0);
}

int getTarget(LPCTSTR argv){
        return _tstoi(argv);
}

int getOperation(LPCTSTR argv){
        if(0==_tcsicmp(argv, TEXT("/i")))return 1;
        if(0==_tcsicmp(argv, TEXT("/u")))return -1;
        return 0;
}

BOOL getExe(LPCTSTR argv, TCHAR *exePath, TCHAR *arguments){
        TCHAR *pArguments, buffer;
        _tcscpy(buffer, argv);
        pArguments=PathGetArgs(buffer);
        _tcscpy(arguments, pArguments);
        _tcscpy(exePath, argv);
        PathRemoveArgs(exePath);
        if(PathIsRelative(exePath)){
                getCurrentPath(buffer);
                _tcscat(buffer, exePath);
        }
        else _tcscpy(buffer, exePath);
        PathCanonicalize(exePath, buffer);
        if(!PathFileExists(exePath) || PathIsDirectory(exePath) || !PathMatchSpec(exePath, TEXT("*.exe"))){
                myError=-2;
                return FALSE;
        }
        return TRUE;
}

BOOL getLink(LPCTSTR argv, TCHAR *link){
    if(!isFilenameValid(argv)){myError=-3; return FALSE;}
        int retVal=GetTempPath(MAX_PATH, link);
        if(retVal>MAX_PATH || 0==retVal){myError=-4; return FALSE;}
        _tcscat(link, argv);
        PathRenameExtension(link, TEXT(".lnk"));
        return TRUE;
}

BOOL getUnloadLink(int target, LPCTSTR argv, TCHAR *linkPath){
        if(!isFilenameValid(argv)){myError=-3; return FALSE;}
        SHGetSpecialFolderPath(NULL, linkPath, CSIDL_APPDATA, FALSE);
        _tcscat(linkPath, TEXT("\\Microsoft\\Internet Explorer\\Quick Launch\\User Pinned\\"));
        _tcscat(_tcscat(_tcscat(linkPath, 1==target?TEXT("StartMenu\\"):TEXT("TaskBar")), argv), TEXT(".lnk"));
    if(!PathFileExists(linkPath)){myError=-3; return FALSE;}
        return TRUE;
}

void processError(){
        LPCTSTR badUsage=TEXT("用法:\nPINT <1/2> exePath "),
                badLink=TEXT("无效的快捷方式名称!"), badExe=TEXT("指定的文件不是可执行程序!"), badTemp=TEXT("临时文件夹错误!");

        switch(myError){
        case -1:_tprintf(badUsage);break;
        case -2:_tprintf(badExe);break;
        case -3:_tprintf(badLink);break;
        case -4:_tprintf(badTemp);break;
        }
        exit(myError);
}

hanzsim 发表于 2018-11-25 21:04:28

花了我一个星期时间搞出来了。结果在台机上运行很好,PE上不能运行。一琢磨,台机是Win7x64,PE是8x64,基础库都不一样。。。懒的弄了,源码上来,谁想弄谁弄吧。

zhangze 发表于 2018-11-25 21:09:21

干毛用的!!!???

hanzsim 发表于 2018-11-25 21:12:43

这个程序是锁定程序到任务栏和开始菜单的,为避免麻烦,当前源码只支持.exe。Windows API是不是支持其它我没试。
现在这程序做到了能分别向开始菜单和任务栏锁定和解锁,锁定名称自定义。命令行操作。
参数:<1|2> exePath
功能:添加锁定
参数:</u|-u> <1|2> <friendlyName>
i为锁定,U为解锁,不分大小写。
1为开始菜单,2为任务栏
exepath可带参数,我只试了不太复杂的参数情况,成功的。用Explorer.exe/e,::{20D0...那个试的。带参数的程序锁定时,一定要在命令两端加引号。友好名称如果包含空格,也要带引号。
有兴趣的自己建个工程编译吧。

hanzsim 发表于 2018-11-26 06:12:44

今天解决了。不是库的问题,是我VS2010默认的生成方式32位的,台机完整系统跑32位也行,PE跑不了。重新生成了64位版的,在很小的PE上测试通过。

hanzsim 发表于 2018-11-26 06:14:46

zhangze 发表于 2018-11-25 21:09
干毛用的!!!???

5楼

hanzsim 发表于 2018-11-26 10:34:25

更新:省略了/i参数和友好名称后,将使用系统默认的文件描述作为锁定名称;有/i参数省略了友好名称,将使用exe文件名作为锁定名称。
源代码:
#include"stdafx.h"
#include<windows.h>
#include<stdio.h>
#include<ShlObj.h>
#include<Shlwapi.h>
#include<regex>
#include<strsafe.h>

#pragma comment(lib, "Shlwapi.lib")
#pragma comment(lib, "Shell32.lib")
#pragma comment(lib, "Version.lib")
#pragma comment(lib, "Ole32.lib")

int getCurrentPath(LPTSTR);
BOOL isFilenameValid(LPCTSTR);
BOOL createLink(LPCTSTR, LPCTSTR, LPCTSTR);
BOOL pin(int, LPCTSTR);
BOOL unpin(int, LPCTSTR);
int getTarget(LPCTSTR);
BOOL getExe(LPCTSTR, LPTSTR, LPTSTR, LPTSTR);
BOOL getLink(LPCTSTR, LPTSTR);
BOOL getUnloadLink(int, LPCTSTR, LPTSTR);
int getOperation(LPCTSTR);
void processError();
BOOL getDescription(LPCTSTR, LPTSTR);

int myError=-1;

int _tmain(int argc, _TCHAR* argv[])
{
        int target;
        BOOL isPin=TRUE;
        TCHAR exePath, arguments, linkPath, description;
        switch(argc){
        case 3:
                target=getTarget(argv);
                if(1==target || 2==target){
                        if(getExe(argv, exePath, arguments, description))
                                if(getDescription(exePath, description)){
                                        if(getLink(description, linkPath))myError=0;
                                }
                                else{
                                        if(getLink(PathFindFileName(exePath), linkPath))myError=0;
                                }
                }
                break;
        case 4:
                target=getTarget(argv);
                if(1==target || 2==target){
                        if(getExe(argv, exePath, arguments, description))
                                if(getLink(argv, linkPath))myError=0;
                }
                else{
                        target=getTarget(argv);
                        if(1==target || 2==target){
                                int operation=getOperation(argv);
                                if(0==operation)break;
                                if(-1==operation){
                                        isPin=FALSE;
                                        if(getUnloadLink(target, argv, linkPath))myError=0;
                                }
                                else{
                                        if(getExe(argv, exePath, arguments, description))
                                                if(getLink(PathFindFileName(exePath), linkPath))myError=0;
                                }
                        }
                }
                break;
        case 5:
                target=getTarget(argv);
                if(1!=target && 2!=target)break;
                if(1!=getOperation(argv))break;
                if(!getExe(argv, exePath, arguments, description))break;
                if(getLink(argv, linkPath))myError=0;
        }
        if(!myError)
                if(isPin){
                        createLink(exePath, arguments, linkPath);
                        pin(target, linkPath);
                        if(!DeleteFile(linkPath))myError=-4;
                }
                else unpin(target, linkPath);
        processError();
}

int getCurrentPath(LPTSTR buffer)
{
        GetModuleFileName(NULL, buffer, MAX_PATH);
        LPTSTR temp=buffer;
        while('\0'!=*temp++);
        while('\\'!=*--temp);
        *++temp='\0';
        return temp-buffer;
}

BOOL isFilenameValid(LPCTSTR filename){
        int cbMultiByte = WideCharToMultiByte(CP_ACP, 0, filename, -1, NULL, 0, NULL, NULL);
        char *pszText=new char;
        WideCharToMultiByte(CP_ACP, 0, filename, -1, pszText, cbMultiByte, NULL, NULL);
        int retVal=std::regex_match(pszText, std::regex("^[^ \\\\/|<>:\"?*]+[^\\\\/|<>:\"?*]*$"));
        delete pszText;
        return retVal;
}

BOOL createLink(LPCTSTR exePath, LPCTSTR arguments, LPCTSTR linkPath)
{
        CoInitialize(NULL);
    HRESULT hr;
    IShellLink   *pLink;
    IPersistFile   *ppf;
    hr = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (void**)&pLink);
    if (FAILED(hr))return FALSE;
    hr = pLink->QueryInterface(IID_IPersistFile, (void**)&ppf);
    if (FAILED(hr))
    {
      pLink->Release();
      return FALSE;
    }
    pLink->SetPath(exePath);
        pLink->SetArguments(arguments);
        TCHAR buffer;
        _tcscpy(buffer, exePath);
        PathRemoveFileSpec(buffer);
        pLink->SetWorkingDirectory(buffer);
    pLink->SetShowCmd(SW_SHOWNORMAL);
    hr = ppf->Save(linkPath, TRUE);
    ppf->Release();
    pLink->Release();
        SHChangeNotify(SHCNE_UPDATEDIR|SHCNE_INTERRUPT, SHCNF_FLUSH | SHCNF_PATH, buffer, 0);
        CoUninitialize();
        return SUCCEEDED(hr);
}

BOOL pin(int target, LPCTSTR link){
        LPCTSTR strTarget=1==target?TEXT("startpin"):TEXT("taskbarpin");
        return (int)ShellExecute(NULL, strTarget, link, NULL, NULL, 0);
}

BOOL unpin(int target, LPCTSTR exe){
        LPCTSTR strTarget=1==target?TEXT("startunpin"):TEXT("taskbarunpin");
        return (int)ShellExecute(NULL, strTarget, exe, NULL, NULL, 0);
}

int getTarget(LPCTSTR argv){
        return _tstoi(argv);
}

int getOperation(LPCTSTR argv){
        if(0==_tcsicmp(argv, TEXT("/i")))return 1;
        if(0==_tcsicmp(argv, TEXT("/u")))return -1;
        return 0;
}

BOOL getExe(LPCTSTR argv, LPTSTR exePath, LPTSTR arguments, LPTSTR description){
        LPTSTR pArguments;
        TCHAR buffer;
        _tcscpy(buffer, argv);
        pArguments=PathGetArgs(buffer);
        _tcscpy(arguments, pArguments);
        _tcscpy(exePath, argv);
        PathRemoveArgs(exePath);
        if(PathIsRelative(exePath)){
                getCurrentPath(buffer);
                _tcscat(buffer, exePath);
        }
        else _tcscpy(buffer, exePath);
        PathCanonicalize(exePath, buffer);
        if(!PathFileExists(exePath) || PathIsDirectory(exePath) || !PathMatchSpec(exePath, TEXT("*.exe"))){
                myError=-2;
                return FALSE;
        }
        getDescription(exePath, description);
        return TRUE;
}

BOOL getLink(LPCTSTR argv, LPTSTR linkPath){
    if(!isFilenameValid(argv)){myError=-3; return FALSE;}
        int retVal=GetTempPath(MAX_PATH, linkPath);
        if(retVal>MAX_PATH || 0==retVal){myError=-4; return FALSE;}
        _tcscat(linkPath, argv);
        PathRenameExtension(linkPath, TEXT(".lnk"));
        return TRUE;
}

BOOL getUnloadLink(int target, LPCTSTR argv, LPTSTR linkPath){
        if(!isFilenameValid(argv)){myError=-3; return FALSE;}
        SHGetSpecialFolderPath(NULL, linkPath, CSIDL_APPDATA, FALSE);
        _tcscat(linkPath, TEXT("\\Microsoft\\Internet Explorer\\Quick Launch\\User Pinned\\"));
        _tcscat(_tcscat(_tcscat(linkPath, 1==target?TEXT("StartMenu\\"):TEXT("TaskBar")), argv), TEXT(".lnk"));
    if(!PathFileExists(linkPath)){myError=-3; return FALSE;}
        return TRUE;
}

void processError(){
        LPCTSTR badUsage=TEXT("用法:\nPINT <1/2> exePath "),
                badLink=TEXT("无效的快捷方式名称!"), badExe=TEXT("指定的文件不是可执行程序!"), badTemp=TEXT("临时文件夹错误!");

        switch(myError){
        case -1:_tprintf(badUsage);break;
        case -2:_tprintf(badExe);break;
        case -3:_tprintf(badLink);break;
        case -4:_tprintf(badTemp);break;
        }
        exit(myError);
}

BOOL getDescription(LPCTSTR exePath, LPTSTR description){
        DWORD arg=0;
        LPTSTR result;
        int size=GetFileVersionInfoSize(exePath, &arg);
        arg=FALSE;
        if(size){
                byte *buffer=new byte;
                GetFileVersionInfo(exePath, 0, size, buffer);
                HRESULT hr;
                struct LANGANDCODEPAGE {
                        WORD wLanguage;
                        WORD wCodePage;
                } *lpTranslate;
                UINT cbTranslate, dwBytes;
                VerQueryValue(buffer, TEXT("\\VarFileInfo\\Translation"), (LPVOID*)&lpTranslate, &cbTranslate);
                TCHAR item;
                arg=FALSE;
                for(int i = (cbTranslate/sizeof(struct LANGANDCODEPAGE))-1; i>=0 ; i-- ){
                        hr = StringCchPrintf(item, 50, TEXT("\\StringFileInfo\\%04x%04x\\FileDescription"),
                                        lpTranslate.wLanguage,
                                        lpTranslate.wCodePage);
                        if (FAILED(hr)){delete buffer; return FALSE;}
                        VerQueryValue(buffer, item, (LPVOID *)&result, &dwBytes);
                        _tcscpy(description, result);
                        arg=TRUE;
                }
                delete buffer;
        }
        return arg;
}

hanzsim 发表于 2018-11-26 10:40:56

提取码:lha1只有100K+,有兴趣的帮我测试一下其它系统是否能用。我测试的PE8x64可能用。用法说明见5楼和7楼

hanzsim 发表于 2018-11-26 11:06:31

链接:提取码:mmau

hanzsim 发表于 2018-11-26 13:30:18

回头准备再加入清除所有锁定的功能

whyme22 发表于 2018-11-26 14:29:41

hanzsim 发表于 2018-11-26 11:06
链接:提取码:mmau

啊哦,你来晚了,分享的文件已经被取消了,下次要早点哟。

hanzsim 发表于 2018-11-26 18:00:21

hanzsim 发表于 2018-11-26 11:06
链接:提取码:mmau

提取码:whhy

hanzsim 发表于 2018-11-27 04:34:59

whyme22 发表于 2018-11-26 14:29
啊哦,你来晚了,分享的文件已经被取消了,下次要早点哟。

提取码:yhhy

eastmz 发表于 2018-11-27 10:13:32

hanzsim 发表于 2018-11-25 21:12
这个程序是锁定程序到任务栏和开始菜单的,为避免麻烦,当前源码只支持.exe。Windows API是不是支持其它我 ...

原来如此,一楼看的我一头雾水……感谢分享,我最近在用Win7!

hanzsim 发表于 2018-11-28 14:03:52

调整:
命令参数次序调整为
PINT目标[锁定或解锁] [程序和/或友好名称/快捷方式]
更新:
1.支持startmenu和taskbar作为目标,1/2保持不变。
2.支持如下的全部解除锁定命令:
PINT 1 /u
3.支持desktop.ini本地化后的锁定名称的解锁。解锁名称参数带有.lnk扩展名时,强制认定以快捷方式文件名方式解锁;解锁名称没有.lnk扩展名时,本地化名称与参数一致、快捷方式名称与参数一致的,都将被解锁。
提取码: 7jnq
页: [1]
查看完整版本: 发个另类的东西吧