Solved

Create a Desktop Shortcut for an program in C

Posted on 2002-06-27
13
360 Views
Last Modified: 2010-04-15
Hello All. Is it possible to write a C program to create a desktop shortcut for a specific static executable? I am trying to package some software for end users and want to have a program automatically create a shortcut on the desktop for the program that just installed in the package.

Thanks a lot.
0
Comment
Question by:wauger
13 Comments
 
LVL 86

Expert Comment

by:jkr
ID: 7114194
0
 
LVL 86

Expert Comment

by:jkr
ID: 7114217
BTW, there's more sample code available - check http://www.microsoft.com/msj/defaulttop.asp?page=/msj/archive/s2bd.htm ("Fusing Your Applications to the System Through the Windows95 Shell")
0
 

Author Comment

by:wauger
ID: 7114567
Thanks. But I really dont want to use the Windows Shell environment if possible. Is there another way? Cant I just write a plan C program and compile a small executable to create a desktop shortcut? Thanks agian.
0
 
LVL 86

Expert Comment

by:jkr
ID: 7114579
>>Cant I just write a plan C program and compile a small executable to create a desktop shortcut?

That is what I am suggesting. However, this C program will have to use the shell's API do achieve that.
0
 
LVL 86

Accepted Solution

by:
jkr earned 100 total points
ID: 7114593
BTW, here's a complete program that does it for you:

#include <windows.h>
#include <windowsx.h>
#include <objbase.h>
#include <shlobj.h>
#include <stdio.h>
#include <initguid.h>
#include <string.h>

main(int ac, char *av[])
    {
    IShellLink *psl;
    HRESULT hres;
    WIN32_FIND_DATA wfd;
    char szGotPath[MAX_PATH];
    IPersistFile *ppf;

    if (ac != 2)
        {
        printf("Syntax: ln <pathname>\n");
        return 0;
        }

    hres = CoInitialize(NULL);
    if (!SUCCEEDED(hres))
        printf("Could not open the COM library\n");

    hres = CoCreateInstance(&CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER,
                                &IID_IShellLink, (LPVOID *)&psl);
    if (SUCCEEDED(hres))
        {
        hres = psl->lpVtbl->QueryInterface(psl, &IID_IPersistFile, &ppf);

        if (SUCCEEDED(hres))
            {
            WORD wsz[MAX_PATH];

            MultiByteToWideChar(CP_ACP, 0, av[1], -1, wsz, MAX_PATH);

            hres = ppf->lpVtbl->Load(ppf, wsz, STGM_READ);
            if (SUCCEEDED(hres))
                {
                hres = psl->lpVtbl->Resolve(psl, 0, SLR_ANY_MATCH);

                if (SUCCEEDED(hres))
                   {
                   strcpy(szGotPath, av[1]);

                   hres = psl->lpVtbl->GetPath(psl, szGotPath, MAX_PATH,
                               (WIN32_FIND_DATA *)&wfd, SLGP_SHORTPATH );
                   if (!SUCCEEDED(hres))
                       printf("GetPath failed!\n");

                   printf("This points to %s\n", wfd.cFileName);
                   if (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
                       printf("This is a directory\n");
                   }
               }
           else
               printf("IPersistFile Load Error\n");
           ppf->lpVtbl->Release(ppf);
           }
       else
           printf("QueryInterface Error\n");
       psl->lpVtbl->Release(psl);
       }
   else
       printf("CoCreateInstance Error - hres = %08x\n", hres);
   return 0;
   }


==================================
C++ version
==================================

#include <windowsx.h>
#include <objbase.h>
#include <shlobj.h>
#include <stdio.h>
#include <initguid.h>
#include <stdlib.h>
#include <io.h>
#include <string.h>


// This program should print out whether the file is a link and where it
// points to and whether it is a directory or not.
//

main(int ac, char *av[])
    {
    if (ac != 2)
        {
        printf("Syntax: ln <pathname>\n");
        return 0;
        }

    IShellLink *psl;                            // pointer to IShellLink i/f
    HRESULT hres;
    WIN32_FIND_DATA wfd;
    char szGotPath[MAX_PATH];

    // Get pointer to the IShellLink interface.

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

    if (SUCCEEDED(hres))
        {
        // Get pointer to the IPersistFile interface.

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

        if (SUCCEEDED(hres))
            {
            WORD wsz[MAX_PATH];

            // Ensure string is Unicode.
            MultiByteToWideChar(CP_ACP, 0, av[1], -1, wsz, MAX_PATH);

            // Load the shell link
            hres = ppf->Load(wsz, STGM_READ);
            if (SUCCEEDED(hres))
                {
                // Resolve the link.

                hres = psl->Resolve(0, SLR_ANY_MATCH);
                //                  ^
                // Using 0 instead -| of hWnd, as hWnd is only used if
                // interface needs to prompt for more information. Should use
                // hWnd from current console in the long run.

                if (SUCCEEDED(hres))
                    {
                    strcpy(szGotPath, av[1]);

                    hres = psl->GetPath(szGotPath, MAX_PATH,
                                (WIN32_FIND_DATA *)&wfd, SLGP_SHORTPATH );
                    if (!SUCCEEDED(hres))
                        printf("GetPath failed!\n");

                    printf("This points to %s\n", wfd.cFileName);
                    if (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
                        printf("This is a directory\n");
                    }
                }
            else
                printf("IPersistFile Load Error\n");
            ppf->Release();
            }
        else
            printf("QueryInterface Error\n");
        psl->Release();
        }
    else
        printf("CoCreateInstance Error - hres = %08x\n", hres);
    return 0;
    }

You can find the original archive at http://www.wotsit.org/download.asp?f=lnk


0
 

Author Comment

by:wauger
ID: 7114629
That is perfect. Thanks a lot. But I tried compiling the C code and got multiple errors. Any ideas? Thanks
0
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 
LVL 86

Expert Comment

by:jkr
ID: 7114664
>>Any ideas?

Yes. Post the errors - I forgot to clean my crystal ball :o)
0
 

Author Comment

by:wauger
ID: 7114696
Oh, yea. That would help. Here you go....

shortcut.c: In function `main':
shortcut.c:23: parse error before `*'
shortcut.c:30: `hres' undeclared (first use in this function)
shortcut.c:30: (Each undeclared identifier is reported only once
shortcut.c:30: for each function it appears in.)
shortcut.c:31: `psl' undeclared (first use in this function)
shortcut.c:31: incompatible type for argument 1 of `CoCreateInstance'
shortcut.c:31: incompatible type for argument 4 of `CoCreateInstance'
shortcut.c:48: structure has no member named `Load'
shortcut.c:61: `szGotPath' undeclared (first use in this function)
shortcut.c:64: `wfd' undeclared (first use in this function)
shortcut.c:75: structure has no member named `Release'
0
 
LVL 86

Expert Comment

by:jkr
ID: 7114788
That is weird - did you use the code from the link or copy the code from my above comment?
0
 

Author Comment

by:wauger
ID: 7114796
oh, i just copied it from your comment. I should try the link first.
0
 
LVL 2

Expert Comment

by:jonnin
ID: 7116133
er, could you not just make a shortuct to it to distribute, then open that with your program and change where it points to??  Its a binary file but the path part is in text, it should be an easy, quick way to do this.

not a great way to do things, but that way you don't need os specific headers or anything, if its still giving you trouble and you need a fix now it may help...





0
 
LVL 7

Expert Comment

by:peterchen092700
ID: 7928107
No comment has been added lately.
To cleanup this TA, I will recommend to moderators that this question is:

*** Answered by: jkr ***

Please leave any comments here within the next seven days, or finalize the question if you own it
 
PLEASE DO NOT ACCEPT THIS COMMENT AS AN ANSWER!
 
peterchen
EE Cleanup Volunteer
0
 
LVL 45

Expert Comment

by:Kdo
ID: 9480396
No comment has been added lately, so it's time to clean up this TA.

I will leave a recommendation in the Cleanup topic area that this question is:
Accept jkr's comment as answer

Please leave any comments here within the next seven days.

PLEASE DO NOT ACCEPT THIS COMMENT AS AN ANSWER!

Kent (Kdo)
EE Cleanup Volunteer
0

Featured Post

6 Surprising Benefits of Threat Intelligence

All sorts of threat intelligence is available on the web. Intelligence you can learn from, and use to anticipate and prepare for future attacks.

Join & Write a Comment

An Outlet in Cocoa is a persistent reference to a GUI control; it connects a property (a variable) to a control.  For example, it is common to create an Outlet for the text field GUI control and change the text that appears in this field via that Ou…
This tutorial is posted by Aaron Wojnowski, administrator at SDKExpert.net.  To view more iPhone tutorials, visit www.sdkexpert.net. This is a very simple tutorial on finding the user's current location easily. In this tutorial, you will learn ho…
Video by: Grant
The goal of this video is to provide viewers with basic examples to understand and use for-loops in the C programming language.
The goal of this video is to provide viewers with basic examples to understand how to create, access, and change arrays in the C programming language.

760 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

17 Experts available now in Live!

Get 1:1 Help Now