#include <iostream>
#include <fstream>
#include <windows.h>
#include <shellapi.h>
#include <shlobj.h>
#include <assert.h>
#include <tchar.h>
using namespace std;
bool RegisterExtensionLink(
const std::wstring& reg_type, // 注册表类型
const std::wstring& reg_name, // 注册表名称
const std::wstring& name, // 显示名称
const std::wstring& command, // 进程路径
const std::wstring& icon); // 显示图标
bool CreateLink(
const std::wstring& application, // 快捷方式对应的程序
const std::wstring& argvs, // 传进程序的参数
const std::wstring& link, // 快捷方式的路径
const std::wstring& icon); // 快捷方式的图标
inline void help()
{
const std::wstring _help=L"mklink-win [ -a -p -l -i ]\n"
"\t version:1.00\n"
"\t -a: application path!\n"
"\t -p: application parameter!\n"
"\t -l: path of shortcut!\n"
"\t -i: shortcut icon path!\n"
"\t -h: help!\n"
"\t -v: version!\n"
"\t demo:----------------\n"
"\t mklink-win [file-path] output file-path.lnk\n"
"\t mklink-win -a [file-path] output file-path.lnk\n"
"\t mklink-win -a [file-path] -i [icon-path] output file-path.lnk\n"
"\t mklink-win -a [file-path] -l [shortcut-path] output shortcut-path.lnk\n"
"\t ---------------------\n"
;
std::wcout<<_help<<std::endl;
}
//将string转换成wstring
inline std::wstring string2wstring(std::string str)
{
std::wstring result;
//获取缓冲区大小,并申请空间,缓冲区大小按字符计算
int len = MultiByteToWideChar(CP_ACP, 0, str.c_str(), str.size(), NULL, 0);
TCHAR* buffer = new TCHAR[len + 1];
//多字节编码转换成宽字节编码
MultiByteToWideChar(CP_ACP, 0, str.c_str(), str.size(), buffer, len);
buffer[len] = '\0'; //添加字符串结尾
//删除缓冲区并返回值
result.append(buffer);
delete[] buffer;
return result;
}
inline wchar_t* char2wchar(const char* str)
{
return string2wstring(str).data();
}
//将wstring转换成string
inline std::string wstring2string(std::wstring wstr)
{
std::string result;
//获取缓冲区大小,并申请空间,缓冲区大小事按字节计算的
int len = WideCharToMultiByte(CP_ACP, 0, wstr.c_str(), wstr.size(), NULL, 0, NULL, NULL);
char* buffer = new char[len + 1];
//宽字节编码转换成多字节编码
WideCharToMultiByte(CP_ACP, 0, wstr.c_str(), wstr.size(), buffer, len, NULL, NULL);
buffer[len] = '\0';
//删除缓冲区并返回值
result.append(buffer);
delete[] buffer;
return result;
}
inline char* wchar2char(const wchar_t* str)
{
return wstring2string(str).data();
}
int main( int argc, char* _argv[] )
{
int i=1;
int j=0;
// 转化为字符串
std::wstring _param,_app,_icon,_link;
// if( argc<5 )
// {
// std::wcout<<"create link fail!"<<std::endl;
// help();
// return -1;
// }
i=0;
do
{
j=0;
if( _argv[i][j++] =='-' )
{
while( _argv[i][j] =='-' )j++;
switch( _argv[i][j] )
{
case 'a':{
_app = string2wstring( _argv[++i] );
}
break;
case 'p':{
_param = string2wstring( _argv[++i] );
}
break;
case 'l':{
_link = string2wstring( _argv[++i] );
}
break;
case 'i':{
_icon = string2wstring( _argv[++i] );
}
break;
case 'v':
case 'h':{
help();
return 0;
}
break;
default:{
help();
return -1;
}
break;
}
}
else
i++;
}
while ( i<argc );
if( _app.empty() )
{
if( 2 == argc )
{
fstream f;
f.open( _argv[1], iostream::in | iostream::binary );
if( f.is_open() )
_app = string2wstring( _argv[1] );
f.close();
}
else
{
std::wcout<<"create link fail!"<<std::endl;
help();
return -1;
}
}
if ( _icon.empty() )
{
_icon=_app;
}
if ( _link.empty() )
{
_link=_app+L".lnk";
}
// 定位桌面路径
LPITEMIDLIST lp{ 0 };
HRESULT result = SHGetSpecialFolderLocation(0, CSIDL_DESKTOPDIRECTORY, &lp);
if ( SUCCEEDED(result) )
{
if ( CreateLink(
_app.c_str(),
_param.c_str(),
_link.c_str(),
_icon.c_str()) )
{
std::wcout<<"create link success: "<<_link<<std::endl;
return 0;
}
}
std::wcout<<"create link fail: "<<_link<<std::endl;
return -1;
}
bool CreateLink (
const std::wstring& application, // 快捷方式对应的程序
const std::wstring& argvs, // 传进程序的参数
const std::wstring& link, // 快捷方式的路径
const std::wstring& icon ) // 快捷方式的图标
{
bool result = false;
HRESULT hr = CoInitialize(NULL);
if ( !SUCCEEDED(hr) )
return result;
IShellLink* _ShellLink = NULL;
hr = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER,
IID_IShellLinkW, (void**)&_ShellLink);
if (SUCCEEDED(hr))
{
// 设置程序路径
hr = _ShellLink->SetPath( application.c_str() );
wchar_t t[0x1000]{ 0 };
wcscpy_s( t, application.c_str() );
wchar_t* p = wcsrchr(t, L'\\');
p[1] = 0;
// 设置工作目录
hr = _ShellLink->SetWorkingDirectory(t);
// 设置参数
if( !argvs.empty() )
hr = _ShellLink->SetArguments(argvs.c_str());
// 设置图标
hr = _ShellLink->SetIconLocation(icon.c_str(), 0);
IPersistFile* _PersistFile = NULL;
hr = _ShellLink->QueryInterface(IID_IPersistFile, (void**)&_PersistFile);
if (SUCCEEDED(hr))
{
// 创建快捷方式
hr = _PersistFile->Save((link.c_str()), FALSE);
if ( SUCCEEDED(hr) )
result = true;
_PersistFile->Release();
}
_ShellLink->Release();
}
CoUninitialize();
return result;
}
bool RegisterExtensionLink(
const std::wstring& reg_type, // 注册表类型
const std::wstring& reg_name, // 注册表名称
const std::wstring& name, // 显示名称
const std::wstring& command, // 进程路径
const std::wstring& icon) // 显示图标
{
HKEY key;
//wchar_t path[0x1000]{ 0 };
std::wstring __path;
//wsprintfW( path, L"%ws\\shell\\%ws", reg_type.c_str(), reg_name.c_str());
__path = reg_type + L"\\shell\\" + reg_name;
if (RegCreateKeyW(HKEY_CLASSES_ROOT, __path.c_str(), &key) == ERROR_SUCCESS)
{
// 显示的字符串
RegSetValueExW(key, 0, 0, REG_EXPAND_SZ, (LPBYTE)name.c_str(), (name.size() + 1) * sizeof(wchar_t));
// 显示的图标
RegSetValueExW(key, L"Icon", 0, REG_EXPAND_SZ, (LPBYTE)icon.c_str(), (icon.size() + 1) * sizeof(wchar_t));
RegCloseKey(key);
}
//wsprintfW( path, L"%ws\\shell\\%ws\\Command", reg_type.c_str(), reg_name.c_str());
__path += L"\\Command";
if (RegCreateKeyW(HKEY_CLASSES_ROOT, __path.c_str(), &key) == ERROR_SUCCESS)
{
// 程序路径
RegSetValueExW(key, 0, 0, REG_EXPAND_SZ, (LPBYTE)command.c_str(), (command.size() + 1) * sizeof(wchar_t));
RegCloseKey(key);
}
return true;
}
mklink-win.pro
TEMPLATE = app
CONFIG += console c++17
CONFIG -= app_bundle
CONFIG -= qt
SOURCES += \
main.cpp
LIBS += -lshell32 -lole32
DEFINES += INITGUID