Creating Shortcuts with C++

I've been trying to learn how to create a windows shortcut. I think I can do it using a Windows Script File, but I want to see if I can do it in C++. Here is where I got most of my information:

http://www.flexhex.com/docs/articles/hard-links.phtml#softlinks

and here is the code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <windows.h>
#include <shlobj.h>

int main()
{
    IShellLink* pShellLink;
    CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_ALL,
                   IID_IShellLink, (void**)&pShellLink);
    pShellLink->SetPath("C:\\Python27\\python.exe");  // Path to the object we are referring to
    pShellLink->SetDescription("The Python shell");
    pShellLink->SetIconLocation("C:\\Python27\\python.exe", 0);
	
    IPersistFile *pPersistFile;
    pShellLink->QueryInterface(IID_IPersistFile, (void**)&pPersistFile);
    pPersistFile->Save(L"C:\\test", TRUE);
	
    pPersistFile->Release();
    pShellLink->Release();
	
    return 0;
}


I link to the ole32 and uuid libraries and it compiles fine. But the program crashes with a:
test.exe has encountered a problem and needs to close.  We are sorry for the inconvenience.


Am I on the right path?
You don't check pShellLink for NULL before use and you don't check CoCreateInstance for success.

If you haven't called CoInitialize (as is the case), the CoCreateInstance will fail.
Thank you, it doesn't crash anymore. But I am still having trouble getting it to do what I want, CoCreateInstance() fails:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#include <windows.h>
#include <shlobj.h>
#include <iostream>
using namespace std;

int main()
{
    IShellLink* pShellLink = NULL;
    HRESULT hres;
    hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_ALL,
                   IID_IShellLink, (void**)&pShellLink);
    
    if (SUCCEEDED(hres))
    {
        pShellLink->SetPath("C:\\Python27\\python.exe");  // Path to the object we are referring to
        pShellLink->SetDescription("The Python shell");
        pShellLink->SetIconLocation("C:\\Python27\\python.exe", 0);
    
        IPersistFile *pPersistFile;
        hres = pShellLink->QueryInterface(IID_IPersistFile, (void**)&pPersistFile);
        
        if (SUCCEEDED(hres))
        {
            hres = pPersistFile->Save(L"C:\\test", TRUE);
        
            pPersistFile->Release();
        }
        else
        {
            cout << "Error 2" << endl;
            return 2;
        }
        pShellLink->Release();
    }
    else
    {
        cout << "Error 1" << endl;
        return 1;
    }
    
    return 0;
}


hres returns -2147221008 (shouldnt this be a hex value?). I'm looking up the codes on msdn.

Edit: I've checked all of the return codes for CoCreateInstance and none of them are returned: http://msdn.microsoft.com/en-us/library/ms686615%28v=VS.85%29.aspx

1
2
3
4
5
6
7
8
9
    IShellLink* pShellLink = NULL;
    HRESULT hres;
    hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_ALL, IID_IShellLink, (void**)&pShellLink);

    if (hres == S_OK) cout << "OK" << endl;
    if (hres == REGDB_E_CLASSNOTREG) cout << "Class not registered" << endl;
    if (hres == CLASS_E_NOAGGREGATION) cout << "No Aggregation" << endl;
    if (hres == E_NOINTERFACE) cout << "No interface" << endl;
    if (hres == E_POINTER) cout << "Pointer" << endl;


Edit: Okay, I figured out the error code:

cout << hex << hres << endl;

This shows the return code to be 0x800401f0 (CO_E_NOTINITIALIZED), which according to the HRESULT return codes means "CoInitialize has not been called.": http://msdn.microsoft.com/en-gb/library/cc704587.aspx

PROBLEM SOLVED: I needed to call CoInitialize(NULL):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#include <windows.h>
#include <shlobj.h>
#include <iostream>
using namespace std;

int main()
{
    CoInitialize(NULL);
    IShellLink* pShellLink = NULL;
    HRESULT hres;
    hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_ALL,
                   IID_IShellLink, (void**)&pShellLink);
    cout << hex << hres << endl;
    if (SUCCEEDED(hres))
    {
        pShellLink->SetPath("C:\\Python27\\python.exe");  // Path to the object we are referring to
        pShellLink->SetDescription("The Python shell");
        pShellLink->SetIconLocation("C:\\Python27\\python.exe", 0);
    
        IPersistFile *pPersistFile;
        hres = pShellLink->QueryInterface(IID_IPersistFile, (void**)&pPersistFile);
        
        if (SUCCEEDED(hres))
        {
            hres = pPersistFile->Save(L"C:\\test.lnk", TRUE);
        
            pPersistFile->Release();
        }
        else
        {
            cout << "Error 2" << endl;
            return 2;
        }
        pShellLink->Release();
    }
    else
    {
        cout << "Error 1" << endl;
        return 1;
    }
    
    return 0;
}
Last edited on
kbw:
If you haven't called CoInitialize (as is the case), the CoCreateInstance will fail.


Sorry, had I paid better attention I would have figured that out sooner :).
Last edited on
Topic archived. No new replies allowed.