Home > OS >  Create Internet shortcut using C
Create Internet shortcut using C

Time:07-08

I need to be able to create an Internet shortcut to a specific URL and always open it with Microsoft Edge. The only info that is out there seems to be [this page][1].

I'm not sure how to use this site, or look for an example on how to create an Internet shortcut with target path and URL.

Any ideas?

I did manage to find this code and was able to get it to work with either browser type or URL but not both. Tried escaping quotation marks but still nothing.

{
    CoInitialize(NULL);

    WCHAR sp[MAX_PATH] = { 0 };
    WCHAR p[MAX_PATH] = { 0 };

    WCHAR deskPath[MAX_PATH] = { 0 };
    SHGetFolderPathW(NULL, CSIDL_DESKTOP, NULL, 0, deskPath);
    swprintf_s(sp, _countof(sp), L"%s\\ShortcutTest", deskPath);

    WCHAR path[MAX_PATH] = { 0 };
    std::wstring path1 = L"C:/Program Files (x86)/Microsoft/Edge/Application/msedge.exe" "http://www.bing.com";
    SHGetFolderPathW(NULL, CSIDL_PROGRAM_FILESX86, NULL, 0, path);
    swprintf_s(p, _countof(p), path1.c_str(), path);

    CreateLink(p, sp, L"", L"");

    CoUninitialize();

    return 0;

CodePudding user response:

MSDN provides example code for creating shortcuts with IShellLink. This is also referenced in answers on Stack Overflow, most notably this one: How to programmatically create a shortcut using Win32

For your requirement specifically, note that the IShellLink object provides a method SetArguments. You can use this to specify the URL that will be passed on the command line when running MS Edge.

So let's expand the example CreateLink function, rearrange it a little and add a parameter that lets you provide arguments:

#include <windows.h>
#include <shlobj.h>

HRESULT CreateLink(LPCWSTR lpszShortcut,
                   LPCWSTR lpszPath,
                   LPCWSTR lpszArgs,
                   LPCWSTR lpszDesc)
{
    HRESULT hres;
    IShellLinkW* psl;

    hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLinkW, (LPVOID*)&psl);
    if (SUCCEEDED(hres))
    {
        IPersistFile* ppf;

        psl->SetPath(lpszPath);
        psl->SetArguments(lpszArgs);
        psl->SetDescription(lpszDesc);

        // Save link
        hres = psl->QueryInterface(IID_IPersistFile, (LPVOID*)&ppf);
        if (SUCCEEDED(hres))
        {
            hres = ppf->Save(lpszShortcut, TRUE);
            ppf->Release();
        }

        psl->Release();
    }

    return hres;
}

Now all you need is to invoke it correctly. Taking your example as a starting point:

#include <string>

int main()
{
    HRESULT hres = CoInitialize(NULL);
    if (SUCCEEDED(hres))
    {
        PWSTR deskPath, programsPath;
        SHGetKnownFolderPath(FOLDERID_Desktop, 0, NULL, &deskPath);
        SHGetKnownFolderPath(FOLDERID_ProgramFilesX86, 0, NULL, &programsPath);

        std::wstring linkFile = std::wstring(deskPath)   L"\\ShortcutTest.lnk";
        std::wstring linkPath = std::wstring(programsPath)   L"\\Microsoft\\Edge\\Application\\msedge.exe";
        LPCWSTR linkArgs = L"https://www.stackoverflow.com";
        LPCWSTR linkDesc = L"Launch Stack Overflow";

        CreateLink(linkFile.c_str(), linkPath.c_str(), linkArgs, linkDesc);

        CoTaskMemFree(deskPath);
        CoTaskMemFree(programsPath);
    }

    CoUninitialize();
    return 0;
}

Note that I also used the correct extension for the shortcut file, which is .lnk. This is required for Windows to recognize the file as a shortcut.

I also changed the method of acquiring standard folders, as per recommendation in MSDN documentation. You should generally avoid anything that uses MAX_PATH. For clarity I am not testing whether these calls succeed, but you should do so in a complete program.

  • Related