3

I'm trying to create an .lnk file programatically. I would prefer to use C, but C++ is fine (and is what all the MSDN stuff is in).

The relevant code sample is:

#include <windows.h>
#include <shobjidl.h>
#include <shlguid.h>

HRESULT CreateLink(LPCSTR lpszPathObj, LPCSTR lpszPathLink, LPCSTR lpszDesc) {
  HRESULT hres;
  IShellLink* psl;

  /* Get a pointer to the IShellLink interface. */
  hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER,
                          IID_IShellLink, (LPVOID*)&psl);
  return hres;
}

I'm trying to comple with wineg++ using:

wineg++ -mno-cygwin -o t t2.cpp

And I'm getting the following errors:

t2-Tw9YPp.o: In function `CreateLink(char const*, char const*, char const*)':
t2.cpp:(.text+0x34): undefined reference to `IID_IShellLinkA'
/usr/bin/ld: t2-Tw9YPp.o: relocation R_386_GOTOFF against undefined hidden symbol `IID_IShellLinkA' can not be used when making a shared object
/usr/bin/ld: final link failed: Bad value
collect2: ld returned 1 exit status
winegcc: i486-linux-gnu-g++ failed

Any ideas?

singpolyma
  • 10,999
  • 5
  • 47
  • 71
  • You say your question is how to create a shortcut file, but the problem you illustrate is a linker error. Do you know how to create the shortcut, and you're just having trouble building the program, or will fixing the linker problem still have you stuck wondering what to do next? – Rob Kennedy Mar 03 '09 at 23:34
  • I *think* I have some example code from MSDN that will form the basis for what I need if I can get it to link. I should probably change the question title, it *is* misleading – singpolyma Mar 03 '09 at 23:53
  • If you are willing to give up C/C++, you can create a .lnk link in Wine using a simple `.bat` dos shell script as [in this answer](https://superuser.com/questions/392061/how-to-make-a-shortcut-from-cmd#392082) — it works nice. – loved.by.Jesus Jan 23 '21 at 17:22

2 Answers2

4

The solution seems to be to change the includes section to:

#define INITGUID
#include <windows.h>
#include <shobjidl.h>
#include <shlguid.h>
#include <initguid.h>

ie, add #define INITGUID before everything and include #include <initguid.h>

I have no idea why this works.

I also had to add -lole32 to fix an error that came up after the cited one was resolved.

The code compiles... now to see if I can make it do what I need.

singpolyma
  • 10,999
  • 5
  • 47
  • 71
1

The linker is complaining that it doesn't know where IID_IShellLinkA is defined. You have the declaration in a header, but you're probably missing a library. I think it's defined in libuuid, so include that in your linking command with -luuid. The linker is probably configured to include a certain set of libraries automatically, including kernel32 and user32, but uuid just might not be on that list.

Rob Kennedy
  • 161,384
  • 21
  • 275
  • 467
  • Adding -luuid doesn't change the error messages. It doesn't error about not finding the library, just the error is not changed. – singpolyma Mar 03 '09 at 23:52
  • I don't have Wine, so I can't say for certain what library it IS defined in. You can see what a Unix library file contains with elfdump. Maybe that works for Wine libs, too, so you could search your lib folder for the file you need. – Rob Kennedy Mar 03 '09 at 23:57
  • 1
    I downloaded Wine. I find the string "IID_IShellLinkA" in shell32.dll.so. – Rob Kennedy Mar 04 '09 at 03:52