Here's why Links Fail on Windows 2000
-
I have looked at every sample of source code i could find on creating Links on the Desktop and EVERY piece of sample code FAILS to create links on Windows 2000--except for those samples that include a separate UNICODE version of the code. Now it is VERY inconvenient to have to include 2 versions of a program, one in ASCII and another in UNICODE. So what's the answer? I will offer 2 solutions to this problem that I originally proposed in the "Lounge" where I was told was the wrong place to post anything important or serious! The first solution is to create 2 versions of your code, and include BOTH versions as a resource in your application and launch the correction version from your program based on the Windows Platform. This works but is not elegant at all--it is the solution that i believe is used by BOTH InstallShield and WYSE Installers! No wonder their exe files are so big! The other solution I offer below. I believe it will work if compiled on Windows 2000. And it would be nice if someone with Windows 2000 could let me know if it works? I develop on Windows 98 using Visual Studio 6... #include "direct.h" /* This is needed for _mkdir */ #include "objbase.h" #include "shlguid.h" #include "wchar.h" #define INITGUID #include "initguid.h" //#define INC_OLE2 //#pragma comment( lib , "OLE2") //#include "ole2.h" //#include "comcat.h" //#include "olectl.h" Where UINT uLinkLoc = CSIDL_DESKTOP; Is there a way to write a SINGLE class that can create a link on the Desktop in both Windows 98 and Windows 2000 without compiling 2 separate versions(one UNICODE and one ASCII)??? bool CInstall::CreateShortCut( LPCSTR lpszSourceFile, LPCSTR lpszSourceDir, UINT uLinkLoc, LPCSTR lpszDesc, bool IsFolder ) { HRESULT hResult = NULL; IShellLink* pShellLink = NULL; bool rc = false; LPCSTR lpszDestination = NULL; ITEMIDLIST *id = NULL; TCHAR szLinkLoc[MAX_PATH] = ""; TCHAR szShellPath[MAX_PATH] = ""; CString sLinkLoc; sLinkLoc.Empty(); CString sLink; sLink.Empty(); // Initialize IShellLink interface hResult = CoInitialize(NULL); // Get pointer to IShellLink Interface hResult = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (void**) &pShellLink); if (SUCCEEDED(hResult)) { //Cache, Fonts, History, NetHood, Personal, Printhood, Programs, // Recent, SendTo, Start Menu, Startup, Templates, ShellNew if (uLinkLoc == CSIDL_APPDATA) { sLinkLoc = "AppData"; } else if (uLinkLoc == CSIDL_COOKIES) { sLinkLoc = "Cookies"; } else if (uLinkLo
-
I have looked at every sample of source code i could find on creating Links on the Desktop and EVERY piece of sample code FAILS to create links on Windows 2000--except for those samples that include a separate UNICODE version of the code. Now it is VERY inconvenient to have to include 2 versions of a program, one in ASCII and another in UNICODE. So what's the answer? I will offer 2 solutions to this problem that I originally proposed in the "Lounge" where I was told was the wrong place to post anything important or serious! The first solution is to create 2 versions of your code, and include BOTH versions as a resource in your application and launch the correction version from your program based on the Windows Platform. This works but is not elegant at all--it is the solution that i believe is used by BOTH InstallShield and WYSE Installers! No wonder their exe files are so big! The other solution I offer below. I believe it will work if compiled on Windows 2000. And it would be nice if someone with Windows 2000 could let me know if it works? I develop on Windows 98 using Visual Studio 6... #include "direct.h" /* This is needed for _mkdir */ #include "objbase.h" #include "shlguid.h" #include "wchar.h" #define INITGUID #include "initguid.h" //#define INC_OLE2 //#pragma comment( lib , "OLE2") //#include "ole2.h" //#include "comcat.h" //#include "olectl.h" Where UINT uLinkLoc = CSIDL_DESKTOP; Is there a way to write a SINGLE class that can create a link on the Desktop in both Windows 98 and Windows 2000 without compiling 2 separate versions(one UNICODE and one ASCII)??? bool CInstall::CreateShortCut( LPCSTR lpszSourceFile, LPCSTR lpszSourceDir, UINT uLinkLoc, LPCSTR lpszDesc, bool IsFolder ) { HRESULT hResult = NULL; IShellLink* pShellLink = NULL; bool rc = false; LPCSTR lpszDestination = NULL; ITEMIDLIST *id = NULL; TCHAR szLinkLoc[MAX_PATH] = ""; TCHAR szShellPath[MAX_PATH] = ""; CString sLinkLoc; sLinkLoc.Empty(); CString sLink; sLink.Empty(); // Initialize IShellLink interface hResult = CoInitialize(NULL); // Get pointer to IShellLink Interface hResult = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (void**) &pShellLink); if (SUCCEEDED(hResult)) { //Cache, Fonts, History, NetHood, Personal, Printhood, Programs, // Recent, SendTo, Start Menu, Startup, Templates, ShellNew if (uLinkLoc == CSIDL_APPDATA) { sLinkLoc = "AppData"; } else if (uLinkLoc == CSIDL_COOKIES) { sLinkLoc = "Cookies"; } else if (uLinkLo
I forgot to include one of the functions that I call in the code sample above and I am including it below. bool CInstall::GetShellFolderPath(LPCSTR lpShellFolder, LPSTR lpShellPath) { //lpShellFolder can be one of the following //AppData, Cache, Cookies, Desktop, Favorites, Fonts, History, NetHood, //Personal, Printhood, Programs, Recent, SendTo, Start Menu, Startup, //Templates, ShellNew DWORD rc; DWORD length = MAX_PATH; DWORD type = REG_SZ; HKEY hkey; rc = RegOpenKeyEx(HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders", 0, KEY_READ, &hkey); if (rc == ERROR_SUCCESS) { rc = RegQueryValueEx(hkey, lpShellFolder, NULL, &type, (BYTE *) lpShellPath, &length); RegCloseKey(hkey); } if (rc == ERROR_SUCCESS) return true; else return false; } Bill SerGio, The Infomercial King
-
I have looked at every sample of source code i could find on creating Links on the Desktop and EVERY piece of sample code FAILS to create links on Windows 2000--except for those samples that include a separate UNICODE version of the code. Now it is VERY inconvenient to have to include 2 versions of a program, one in ASCII and another in UNICODE. So what's the answer? I will offer 2 solutions to this problem that I originally proposed in the "Lounge" where I was told was the wrong place to post anything important or serious! The first solution is to create 2 versions of your code, and include BOTH versions as a resource in your application and launch the correction version from your program based on the Windows Platform. This works but is not elegant at all--it is the solution that i believe is used by BOTH InstallShield and WYSE Installers! No wonder their exe files are so big! The other solution I offer below. I believe it will work if compiled on Windows 2000. And it would be nice if someone with Windows 2000 could let me know if it works? I develop on Windows 98 using Visual Studio 6... #include "direct.h" /* This is needed for _mkdir */ #include "objbase.h" #include "shlguid.h" #include "wchar.h" #define INITGUID #include "initguid.h" //#define INC_OLE2 //#pragma comment( lib , "OLE2") //#include "ole2.h" //#include "comcat.h" //#include "olectl.h" Where UINT uLinkLoc = CSIDL_DESKTOP; Is there a way to write a SINGLE class that can create a link on the Desktop in both Windows 98 and Windows 2000 without compiling 2 separate versions(one UNICODE and one ASCII)??? bool CInstall::CreateShortCut( LPCSTR lpszSourceFile, LPCSTR lpszSourceDir, UINT uLinkLoc, LPCSTR lpszDesc, bool IsFolder ) { HRESULT hResult = NULL; IShellLink* pShellLink = NULL; bool rc = false; LPCSTR lpszDestination = NULL; ITEMIDLIST *id = NULL; TCHAR szLinkLoc[MAX_PATH] = ""; TCHAR szShellPath[MAX_PATH] = ""; CString sLinkLoc; sLinkLoc.Empty(); CString sLink; sLink.Empty(); // Initialize IShellLink interface hResult = CoInitialize(NULL); // Get pointer to IShellLink Interface hResult = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (void**) &pShellLink); if (SUCCEEDED(hResult)) { //Cache, Fonts, History, NetHood, Personal, Printhood, Programs, // Recent, SendTo, Start Menu, Startup, Templates, ShellNew if (uLinkLoc == CSIDL_APPDATA) { sLinkLoc = "AppData"; } else if (uLinkLoc == CSIDL_COOKIES) { sLinkLoc = "Cookies"; } else if (uLinkLo
-
Have not tested, but if you say a UNICODE build will work it is maybe because there are 2 IShellLink interfaces, one IShellLinkA and one IShellLinkW, and if that happens to be the case you could build an ANSI app and use IShellLinkW and get it to work
So if this is the case, then: if (b2000 || bNT) { // Call "IShellLinkW" } else { // Call "IShellLinkA" } Is this what you had in mind to build 2 versions in one class? What I don't understand is why hasn't anyone posted a sample of this code before? Bill SerGio, The Infomercial King
-
So if this is the case, then: if (b2000 || bNT) { // Call "IShellLinkW" } else { // Call "IShellLinkA" } Is this what you had in mind to build 2 versions in one class? What I don't understand is why hasn't anyone posted a sample of this code before? Bill SerGio, The Infomercial King