Showing posts with label 32 vs. 64 bit. Show all posts
Showing posts with label 32 vs. 64 bit. Show all posts

Saturday, May 25, 2013

Language neutral Pin shortcut to Start Menu using C#

Problem: I needed a program that would automatically pin an existing shortcut on the desktop to the start menu, regardless what localization the Windows user was using. I was using Windows Server 2008 R2 with a couple of alternate languages to English installed for testing. The program was written in C#. I hit the wall a copule of times while trying to make c# code from an earlier implementation written in VB.NET - this is a summary of what I got to work in the end:
Type shellAppType = Type.GetTypeFromProgID("Shell.Application");
Object oShell = Activator.CreateInstance(shellAppType);
Shell32.Folder oFolder = (Shell32.Folder)shellAppType.InvokeMember("NameSpace", System.Reflection.BindingFlags.InvokeMethod, null, oShell, new object[] { 0 }); //25 = common desktop, 0 is local desktop
 


if (System.IO.File.Exists(ShortcutTarget) & (oFolder != null))
{
   Shell32.FolderItem oFolderItem = oFolder.ParseName("somefile.lnk");
   Shell32.ShellLinkObject oShellLink = (Shell32.ShellLinkObject)oFolderItem.GetLink;
   if (oShellLink != null)
   {
      // Find localized shell32 verb used to pin shortcut to the start menu (so that it works in any language)
      StringBuilder szPinToStartLocalized = new StringBuilder(MAX_PATH);
      IntPtr hShell32 = LoadLibrary("SHELL32");
      LoadString(hShell32, 5381, szPinToStartLocalized, MAX_PATH); // 5381 is the DLL index for "Pin to start menu", ref. http://www.win7dll.info/shell32_dll.html
      string localizedVerb = szPinToStartLocalized.ToString();

      foreach (Shell32.FolderItemVerb verb in oFolderItem.Verbs())
      {
         if (verb.Name == localizedVerb)
         {
            verb.DoIt();
            break;
         }
      }
   }
}


You need to reference Shell32 - i.e. Microsoft Shell Controls and Automation on the COM tab of your "Add reference" dialog in VS2010. Also make sure you copy the shell32.interop.dll along with your application when you move the application out of your bin folder.

The following problems were encountered and solved on the way:

BadImageFormatException when entering the method containing this code. The code worked well on a Windows Vista computer, but crashed when running on Server 2008 R2. I assume this happened because of the fact that Server 2008 R2 is a 64 bit OS, and this did not work well with using the unmanaged Shell32.
Solution: Change the target CPU of your application to x86. If you use VS2010 Express, this tip on StackOverflow may be helpful to you - Make sure to read all the answers if you are stuck.

InvokeVerb did not work. Before ending up using the line verb.DoIt(), I tried using oFolderItem.InvokeVerb(verb.Name), which used to work in an earlier VB.NET implementation of the same code. I have no explanation to why this did not work, but it did not. A conspiracy theory is that Nike paid them off to just do it...

By the way, this earlier post mentions a problem I encountered trying to do the same in VB.NET some time ago. It probably applies here too, which is why the top three lines of the code looks like they do.

Monday, September 5, 2011

ODBC 32 vs. 64 bit

Scenario: I needed to connect 32 bit software running on a 64 bit Windows 7 OS to an SQL server via ODBC. Using a User DSN, everything was fine - setting up a System DSN instead, the application could no longer find it or and connect to the database. I preferred setting up a System DSN, so that any user logged on to the computer would be able to run the software without further hassle in setting up the needed ODBC connection.
Cause: An ODBC System DSN in 32 and 64 bit versions are two separate matters, hence a 32-bit application will not see a 64 bit ODBC System DSN and vice versa. User DSNs are however visible on both sides. Confusing.
Gotcha: Both the 64 and 32 bit version of the ODBC tool's is named odbcad32.exe. Hence, the Win7 standard method of writing this in the search field at the bottom of the start menu would always give you the 64 bit version. You have to run %windir%\syswow64\odbcad32.exe (for instance via the run dialog, keyboard shortcut winkey-r) to start the 32 bit ODBC application.
Reference: Microsoft's Knowledge Base article 942976