C ++:在Windows中创建快捷方式 - 使用MinGW / g ++的实际工作示例

时间:2014-03-25 22:29:01

标签: c++

经过一些研究,我找到了解决方案如何使用C ++ / MinGW / g ++在Windows中创建快捷方式:

#include <stdio.h>
#include <windows.h>
#include <Shlobj.h>
#include <objidl.h>
#include <iostream>

using namespace std;

HRESULT CreateLink(
        LPCWSTR FilePath,
        LPCWSTR LnkPath,
        LPCWSTR LnkDesc,
        LPCWSTR WorkDir) {


    CoInitialize(NULL);
    IShellLinkW* psl;

    HRESULT hres = CoCreateInstance(
            CLSID_ShellLink,
            NULL,
            CLSCTX_INPROC_SERVER,
            IID_IShellLink,
            (LPVOID *) & psl);

    if (SUCCEEDED(hres)) {
        IPersistFile* ppf;

        wstring file(L"C:\\jarlauncher.exe");
        psl->SetPath((LPWSTR)file.c_str());//Not working - only first letter is visible in created shortcut properties

        psl->SetWorkingDirectory(WorkDir);
        psl->SetDescription(LnkDesc);

        hres = psl->QueryInterface(IID_IPersistFile, (LPVOID*) & ppf);

        if (SUCCEEDED(hres)) {
            hres = ppf->Save(LnkPath, TRUE);
            ppf->Release();
        }

        psl->Release();
    }

    CoUninitialize();
    return hres;
}

仍在测试中。问题是psl->SetDescription(LnkDesc); - 在创建的快捷方式中只能看到一个符号。与其他领域相同。这可能是什么问题?

但我可以使用Unicode名称创建快捷方式(添加一些日文字符):

...
   hres = psl->QueryInterface(IID_IPersistFile, (LPVOID*) &ppf);

        wstring shortCutName(L"C:\\猫が好き?.lnk");

        if (SUCCEEDED(hres)) {
            hres = ppf->Save((LPWSTR)shortCutName.c_str(), TRUE);
            ppf->Release();
        }
...

修改

现在的工作示例:

#include <Shlobj.h>
#include <tchar.h>

using namespace std;

HRESULT CreateLink(
        LPCWSTR filePath,
        LPCWSTR workDir,
        LPCWSTR desc,
        LPCWSTR iconPath,
        LPCWSTR linkPath) {

    CoInitialize(NULL);
    IShellLinkW* psl;

    HRESULT hres = CoCreateInstance(
            CLSID_ShellLink,
            NULL,
            CLSCTX_INPROC_SERVER,
            IID_IShellLinkW,
            (LPVOID*) &psl);

    if (SUCCEEDED(hres)) {

        IPersistFile* ppf;

        psl->SetPath(filePath);
        psl->SetWorkingDirectory(workDir);
        psl->SetDescription(desc);
        psl->SetIconLocation(iconPath, 0);

        hres = psl->QueryInterface(IID_IPersistFile, (LPVOID*) &ppf);

        if (SUCCEEDED(hres)) {
            hres = ppf->Save(linkPath, TRUE);
            ppf->Release();
        }

        psl->Release();
    }

    CoUninitialize();
    return hres;
}

int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) {

    CreateLink(
            L"C:\\Program Files\\Appl\\Appl.exe",
            L"C:\\Program Files\\Appl",
            L"Location: C:\\Program Files\\Appl",
            L"C:\\Program Files\\Appl\\someIcon.ico",
            L"C:\\Appl.lnk");//Shortcut will be created at C:/

    return 0;
}

您还需要在项目属性中添加Ole32.libUuid.lib库文件。如果您不需要终端窗口 - 只需将-mwindows添加到C ++编译器选项。这就是全部 - 不再是“秘密”信息。

此文件在带有C / C ++插件的Windows + NetBeans IDE 8.0上进行了测试,并在C:\上安装了MinGW和msys,并在NetBeans IDE当前项目属性中进行了正确配置。

1 个答案:

答案 0 :(得分:2)

听起来你没有明确地定义UNICODE,如果你已经定义它应该调用条件代码:

#ifdef UNICODE
#define IID_IShellLink IID_IShellLinkW
#else
#define IID_IShellLink IID_IShellLinkA
#endif

当您要求IShellLink的通用版本时,它为您提供了IShellLink接口的宽版本。在您的情况下,您必须使用IID_IShellLink显式替换IID_IShellLinkW,并在调用CoCreateInstance时实例化宽版本,从而获得所有广泛的例程。

  

官方MS SDK与mingw转换之间的标题看起来有些不同(我认为在这些标题中使用__MINGW_NAME_AW()宏完成了它。