1
votes

I have a problem with SHGetFolderPathA in Visual Studio 2010 (Windows Forms). I included to project ShlObj.h and added for button this code:

char SciezkaCookies[MAX_PATH];
HRESULT hr = ::SHGetFolderPathA(0, CSIDL_APPDATA, 0, SHGFP_TYPE_DEFAULT, SciezkaCookies);

But when i try compile my project, Visual return errors:

error LNK2028: unresolved token (0A000012) "extern "C" long stdcall SHGetFolderPathA(struct HWND *,int,void *,unsigned long,char *)" (?SHGetFolderPathA@@$$J220YGJPAUHWND__@@HPAXKPAD@Z) referenced in function "private: void __clrcall VoxPopuli::Form1::start_Click(class System::Object ^,class System::EventArgs ^)" (?start_Click@Form1@VoxPopuli@@$$FA$AAMXP$AAVObject@System@@P$AAVEventArgs@4@@Z)

and

1>VoxPopuli.obj : error LNK2019: unresolved external symbol "extern "C" long stdcall SHGetFolderPathA(struct HWND *,int,void *,unsigned long,char *)" (?SHGetFolderPathA@@$$J220YGJPAUHWND__@@HPAXKPAD@Z) referenced in function "private: void __clrcall VoxPopuli::Form1::start_Click(class System::Object ^,class System::EventArgs ^)" (?start_Click@Form1@VoxPopuli@@$$FA$AAMXP$AAVObject@System@@P$AAVEventArgs@4@@Z)

I'm looking for solutions in google, but all examples is not working ;/

Thanks for help!

3

3 Answers

2
votes

Calling native winapi functions like SHGetFolderPath() is fine from C++/CLI, that's what the language is good at, but you do have to keep the linker happy yourself. Use the MSDN Library article for the function (not today, site has been down all week). At the bottom of the article it lists "Header", that's how you found out that you needed to tell the compiler about shlobj.h. It also lists "Import library", that's what you need to tell the linker. The import library tells the linker what DLL needs to be loaded at runtime to call the function.

Project + Properties, Linker, Input, Additional Dependencies. Add "shell32.lib"

Or you do it in your source code with a #pragma, a way to pass link instructions to the linker:

#include <shlobj.h>
#pragma comment(lib, "shell32.lib")

It should be said, this is definitely one api function that you really want somebody else to have to deal with. Note how the MSDN Library article also says that the function is deprecated. There's been a lot of flux in standard folder paths across Windows versions. You have the "someone else" readily available in a .NET app, Environment::GetFolderPath() does this for you. Also saves you from the hassle of having to deal with different string types.

0
votes

You must have declared it yourself to avoid including the Windows headers- not that I blame you for doing that- but you have mangled the name, so the linker cannot resolve it from the native library.

Oh, you're in C++/CLI? Maybe the compiler flat out won't like the native call into managed code, then.

0
votes

I'd avoided using native functions if .NET solution is possible. Try to use

 Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData));

Both native and .NET approaches are discussed here: http://bytes.com/topic/c-sharp/answers/269259-my-documents-path-c