Dynamic API(SHGetSpecialFolderPathA)



  • Versuche die API(http://msdn.microsoft.com/en-us/library/bb762204%28VS.85%29.aspx) zuladen mit Visual Studio 2010 C++.
    Es wird ohne Warnungen und Errors compiliert. Doch GetModuleHandle() kann
    den Offset der Addresse von Shell32.dll nicht laden, die für den API-Aufruf
    benötigt wird. Habe es schon mit den Pseudos wie SHELL32, shell32.dll versucht.

    //Für CopyFileA(KERNEL32) hat es funktioniert !

    #include <Windows.h>
    #include <ShlObj.h>
    
    typedef
    BOOL SHGetSpecialFolderPath_t(
             HWND hwndOwner,
      __out  LPSTR lpszPath,
      __in   int csidl,
      __in   BOOL fCreate
      /* Shell32.dll 
         TRUE if successful; otherwise, FALSE.
      */
    );
    
    bool dynamic_SHGetSpecialFolderPath(char* cPath)
    {
        HMODULE h_Load;
        SHGetSpecialFolderPath_t* mySHGetSpecialFolderPath = 0;
        h_Load = GetModuleHandle((LPCTSTR)"Shell32.dll"); //<---
        if (h_Load == false)
    	{
    		MessageBoxA(NULL,"failed","lol",0);
    		return false;
    	}
    	*(FARPROC*)&mySHGetSpecialFolderPath = GetProcAddress(h_Load, (LPCSTR)"SHGetSpecialFolderPathA");
    	mySHGetSpecialFolderPath(NULL,(LPSTR)cPath,CSIDL_APPDATA|CSIDL_FLAG_CREATE,0);
    	return true;
    }
    

    Regards,
    IEFMC



  • //push

    Hat jemand eine Erleuchtung,
    die dem Problem weiterhelfen könnte ?!



  • versuch es mal mit GetModuleHandleA()



  • Habe die GetModuleFileName zu Ansi geändert,
    aber das hat leider nicht das Problem gelöst.
    Ich Poste nochmal alles dazu, vielleicht hilft das weiter
    zur Lösung.

    Auch damit geht es nicht 😃

    h_Load = LoadLibraryExA((LPCSTR)"Shell32.dll",NULL,0x00000008);
    h_Load = LoadLibraryA((LPCSTR)"Shell32.dll");
    

    Oder vielleicht nach MSDN,

    lpFileName specifies an absolute path,
    nun stellt sich die Frage wieso es bei KERNEL32 funktioniert hat 😃

    Hier noch mal der Ausschnitt

    bool dynamic_SHGetSpecialFolderPath(char* cPath)
    {
    	HMODULE h_Load;
        SHGetSpecialFolderPath_t* mySHGetSpecialFolderPath = 0;
    	h_Load = LoadLibraryA((LPCSTR)"Shell32.dll");
        if (h_Load == NULL)
    	{
    		return false;
    	}
    	*(FARPROC*)&mySHGetSpecialFolderPath = GetProcAddress(h_Load, (LPCSTR)"SHGetSpecialFolderPathA");
    	mySHGetSpecialFolderPath(NULL,(LPSTR)cPath,CSIDL_APPDATA|CSIDL_FLAG_CREATE,0);
    	FreeLibrary(h_Load);
    	return true;
    }
    

    Dazu noch der Aufruf

    int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
    {
    	char cPath[255] = {0};
    	if(dynamic_SHGetSpecialFolderPath(cPath) == false)
    	{
    		MessageBoxA(NULL,"Error","?",0);
    	}
    	else
    	{
    		MessageBoxA(NULL,(LPCSTR)cPath,"Dir:",0);
    	}
    	return 0;
    }
    

    Die API CopyFile funktioniert ..

    bool dynamic_CopyFile(const char* ccSource,  const char* ccTarget)
    {
    	HMODULE h_Load;
        CopyFile_t* myCopyFile = 0;
        h_Load = GetModuleHandle(TEXT("KERNEL32"));
        if (h_Load == false)
    	{
    		return false;
    	}
    	*(FARPROC*)&myCopyFile = GetProcAddress(h_Load, (LPCSTR)"CopyFileA");
    	myCopyFile((LPCSTR)(ccSource),(LPCSTR)(ccTarget),0);
        return true;
    }
    


  • Schon mal versucht den Fehlercode mit GetLastError() zu ermitteln?



  • Ich sehe 2 Probleme deiner Codeteile:

    1. du wechselst ständig zwischen Unicode und Multibyte
    2. du hast die Spezifikation von GetModuleHandle nicht gelesen, inkl. des dort vorhandenen Vorschlags, im Fehlerfall GetLastError zu befragen

    zu 1.
    entweder du entscheidest dich für Multibyte,
    dann kannst du nach

    #undef UNICODE
    #undef _UNICODE
    #include <windows.h>
    

    auf alle String-Casts und alle A/W-Funktionsunterscheidungen verzichten, oder mit Unicode dann am besten mit
    #include <tchar.h>
    und dann ebenfalls ohne A/W-Funktionen, aber mit _T()/TEXT() Casts, wobei du dann alle "char" Referenzen natürlich umbauen musst

    zu 2.
    GetModuleHandle gibt nur gültige Handles für bereits im Prozess GELADENE Module/Dlls zurück, shell32.dll ist wohl bei dir zum fraglichen Zeitpunkt nicht geladen, d.h. du musst dies erzwingen um mit GetModuleHandle arbeiten zu können:

    h_Load = LoadLibrary("shell32.dll"),GetModuleHandle("shell32.dll");
    

  • Mod

    Wie wäre es weiterhin damit, dass Du einfach mal die Doku liest:
    http://msdn.microsoft.com/en-us/library/bb762204(VS.85).aspx

    Remarks
    The Microsoft Internet Explorer 4.0 Desktop Update must be installed for this function to be available.

    With Windows 2000, this function is superseded by ShGetFolderPath. You can use this function on earlier systems by including the redistributable DLL, ShFolder.dll.


Anmelden zum Antworten