Microsoft small business knowledge base

Article ID: 241733 - Last Review: March 1, 2007 - Revision: 3.4

This article was previously published under Q241733


During an upgrade from Windows 95 or Windows 98 to Windows 2000 Professional, a migration DLL may want to access special folders, such as the Start menu folder or the Desktop folder. A migration DLL cannot assume that these folders exist in default locations. Instead, it should use SHGetSpecialFolderPath or SHGetFolderPath.


SHGetSpecialFolderPath will only work on Windows 95 if Internet Explorer 4.0 is installed with the desktop update. On Windows 2000, SHGetSpecialFolderPath will always work. However, in both cases, it is best to use the new SHGetFolderPath API, which is a superset of SHGetSpecialFolderPath. To use SHGetFolderPath on Windows 95 or Windows 98, you must redistribute the SHFolder.dll file along with the migration DLL.

You can get SHFolder.dll from the latest Platform SDK. To download the Platform SDK, see the following Web site: (
When installing the Platform SDK, make sure to install the redistributable components and the build environment. Also, choose to integrate the Platform SDK with Microsoft Visual C++ when prompted. This is necessary because of the SHFolder.h file that is needed. Once the Platform SDK is installed, search the installation folder for the redistributable executable SHFolder.exe. This file installs SHFolder.dll and all other updates that are needed for it to run on Windows 95 or Windows 98. This executable file should be run on the user's computer when the user places the migration DLL on the computer. It can also be installed during your application setup.

The following code demonstrates how to obtain a pointer to SHGetFolderPath API:
#include <windows.h>
#include <shfolder.h>

   static HMODULE hMod = NULL;

   // Load SHFolder.dll only once
   if (!hMod)
      hMod = LoadLibrary("SHFolder.dll");

   if (hMod)
      // Obtain a pointer to the SHGetFolderPathA function
      pSHGetFolderPath = (PFNSHGETFOLDERPATHA)GetProcAddress(hMod, 

   return pSHGetFolderPath;

The following sample code demonstrates one possible use of this function. During an upgrade to Windows 2000, an application may contain a Windows 2000-specific program or utility that requires a shortcut in the application's Start menu Programs folder. After copying the new program to the computer, the migration DLL can add a shortcut to the user's Start menu. For a per-user setting, the MigrateUserNT function is the best place to perform this task.

The following function takes three parameters. The first parameter is the path to the target executable. The second parameter is a description. The final parameter is a subfolder that will be created in the Start menu programs folder. This is where the shortcut will be created.
#include <windows.h>
#include <objbase.h>
#include <shlobj.h>
#include <shfolder.h>

HRESULT CreateUserStartMenuShortcut(LPSTR pszShortcutFile,
            LPSTR pszDescription, LPTSTR pszRelativeFolder)
   HRESULT hr;
   TCHAR pszLink[MAX_PATH];
   BOOL bFound = FALSE;

   pSHGetFolderPath = GetFuncPtr_SHGetFolderPathA();

   // Find the current user's Start Menu Programs folder
   if (pSHGetFolderPath)
      bFound = SUCCEEDED(pSHGetFolderPath(NULL, CSIDL_PROGRAMS, 
                           NULL, SHGFP_TYPE_CURRENT, pszLink));

   if (bFound)
      // Proceed to create the shortcut
      IShellLink *pIShellLink = NULL;
      IPersistFile *ppf = NULL;
      WCHAR pLinkUnicode[MAX_PATH];


      // Get a pointer to the IShellLink interface.
      hr = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER,
                            IID_IShellLink, (void **)&pIShellLink);

      if (SUCCEEDED(hr))
         // Get a pointer to IPersistFile interface for saving shortcut
         hr = pIShellLink->QueryInterface(IID_IPersistFile, (void **)&ppf);

         if (SUCCEEDED(hr))
            hr = pIShellLink->SetPath(pszShortcutFile);
            hr = pIShellLink->SetDescription(pszDescription);

            if (SUCCEEDED(hr))
               // Add the target folder to the Start Menu Programs path
               lstrcat(pszLink, "\\");
               lstrcat(pszLink, pszRelativeFolder);
               lstrcat(pszLink, "\\");

               // Create the directory if it does not exist

               // Add the file name for the shortcut
               lstrcat(pszLink, pszDescription);
               lstrcat(pszLink, ".lnk");

               // Convert string to Unicode, and call IPersistFile::Save()
               MultiByteToWideChar(CP_ACP, 0, pszLink, -1, pLinkUnicode, MAX_PATH);
               hr = ppf->Save(pLinkUnicode, TRUE);

   return hr;
Refer to the documentation for SHGetSpecialFolderPath and SHGetFolderPath to determine the other types of special folders that these functions can obtain. Note in the example that CoInitialize and CoUnitialize are called within this function. If COM is used in other functions, these calls should be moved to the migration DLL's DllMain function. Call CoInitialize for the DLL_PROCESS_ATTACH notification and CoUninitialize for the DLL_PROCESS_DETACH notification.


For more information on Migration DLLs, see the topic following in the MSDN Library:
Platform SDK; Management Services; Setup; Migration-Extension Interface

  • Microsoft Windows 2000 Server
  • Microsoft Windows 2000 Advanced Server
  • Microsoft Windows 2000 Professional Edition
  • Microsoft Windows 98 Standard Edition
  • Microsoft Windows 95
kbfaq kbhowto kbmigrate kbsetup KB241733
Additional support options
Ask The Microsoft Small Business Support Community
Contact Microsoft Small Business Support
Find Microsoft Small Business Support Certified Partner
Find a Microsoft Store For In-Person Small Business Support