0

My application needs to know if a program is installed on the machine in order to work, and I want the option to know if Program Files folder exist in only the (32 Bit machine) or also has the Program Files (x86) folder (64 Bit machine).

What is the best way to do it via my code?

my application that i need on the machine is Wireshark that can install on both 32 and 64 bit (in the appropriate Program Files folder) and i am not sure what to do because i am making installer file with Wireshark inside and try to find the best option to know what to install.

Dana Yeger
  • 617
  • 3
  • 9
  • 26
  • You shouldn't be hardcoding "Program Files" in the first place. On older German systems, for example, it would be "C:\Programme". –  Oct 04 '12 at 13:11
  • possible duplicate of [C# - How to get Program Files (x86) on Windows Vista 64 bit](http://stackoverflow.com/questions/194157/c-sharp-how-to-get-program-files-x86-on-windows-vista-64-bit) – Paolo Moretti Oct 04 '12 at 13:15

5 Answers5

3

To dynamically get the correct Program Files (x86) path, use

Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86)

On 32-bit systems, this will return the regular Program Files directory. On 64-bit systems, this will return the Program Files (x86) directory.

In your specific case, as I understand it, you want to install the 64-bit Wireshark on a 64-bit system, so you want to launch the 64-bit installer, unless it's already available. If that's the case, you can ignore the Program Files (x86) entirely, and only check Program Files. If, however, you want to use an existing 32-bit Wireshark if available, you'd need to check each location Wireshark could be installed in: check in ProgramFiles, if not found, check in ProgramFilesX86, if not found, launch installer. The installer to use can be determined based on Environment.Is64BitOperatingSystem (from Furqan's answer).

  • @DanaYeger I've updated my answer based on your updated question, does this help? –  Oct 04 '12 at 13:26
  • my problem is that on 64Bit machine Wireshark 32Bit can install so in that case i can find 64Bit machine that Wireshark install on Program Files (x86) so maybe the best option is to split the exe file to 32 and 64 bit machines ? – Dana Yeger Oct 04 '12 at 13:30
  • @DanaYeger I thought I addressed that: only launch the installer if you can't find Wireshark in Program Files and you also can't find it in Program Files (x86) (both paths determined using `GetFolderPath`). If it's found in either, don't install anything, but use what you've already got. Did I misunderstand? –  Oct 04 '12 at 13:39
0

This way you can get the path to the Program Files:

string programFilePath = Environment.Is64BitOperatingSystem

   // If 64 bit locate the 32 bit folder
   ? @"C:\Program Files (x86)\"

   // Else 32 bit
   : @"C:\Program Files\";

Using System.Environment:

bool is64Bit = System.Environment.Is64BitOperatingSystem;

OR

Using Environment Variable:

System.Environment.GetEnvironmentVariable("PROCESSOR_ARCHITECTURE")

OR

Using P/Invoke:

public static ProcessorArchitecture GetProcessorArchitecture()
{
    SYSTEM_INFO si = new SYSTEM_INFO();
    GetNativeSystemInfo(ref si);
    switch (si.wProcessorArchitecture)
    {
        case PROCESSOR_ARCHITECTURE_AMD64:
            return ProcessorArchitecture.Amd64;

        case PROCESSOR_ARCHITECTURE_IA64:
            return ProcessorArchitecture.IA64;

        case PROCESSOR_ARCHITECTURE_INTEL:
            return ProcessorArchitecture.X86;

        default:
            return ProcessorArchitecture.None; // that's weird :-)
    }
}

with

[DllImport("kernel32.dll")]
private static extern void GetNativeSystemInfo(ref SYSTEM_INFO lpSystemInfo);

private const int PROCESSOR_ARCHITECTURE_AMD64 = 9;
private const int PROCESSOR_ARCHITECTURE_IA64 = 6;
private const int PROCESSOR_ARCHITECTURE_INTEL = 0;

[StructLayout(LayoutKind.Sequential)]
private struct SYSTEM_INFO
{
    public short wProcessorArchitecture;
    public short wReserved;
    public int dwPageSize;
    public IntPtr lpMinimumApplicationAddress;
    public IntPtr lpMaximumApplicationAddress;
    public IntPtr dwActiveProcessorMask;
    public int dwNumberOfProcessors;
    public int dwProcessorType;
    public int dwAllocationGranularity;
    public short wProcessorLevel;
    public short wProcessorRevision;
}
Furqan Safdar
  • 16,260
  • 13
  • 59
  • 93
  • 1
    That would help determine the OS version, not determine whether the program OP is looking for is installed or not. – zmbq Oct 04 '12 at 13:11
  • I have edited the code to include the path information as well. – Furqan Safdar Oct 04 '12 at 13:17
  • You could check the `IntPtr.Size` property but this doesent help with detail of the original question. – Jodrell Oct 04 '12 at 13:19
  • You use `Enviorment.Is64BitOperatingSystem`, but you don't use `Environment.SpecialFolder.ProgramFiles` or `Environment.SpecialFolder.ProgramFilesX86`. What do you do if a user does not have program files in the normal location? – Scott Chamberlain Oct 04 '12 at 13:28
0

You should look in both folders, because it's quite legal to install a 32-bit application on a 64-bit machine, even though a 64-bit version exists.

Also, don't check the hard coded folder names, use Environment.GetSpecialFolder instead.

If the program you're looking for leaves a mark on the registry, you could check for that instead. It'll be the best solution, as users can install programs just about everywhere.

The Wireshark installed writes an uninstall registry entry you can look for. See here. Check that instead of everything else.

zmbq
  • 38,013
  • 14
  • 101
  • 171
0

In answer to the OP's specific question...

if (!Directory.Exists(Environment.SpecialFolder.ProgramFilesX86.ToString())) {
    if (Directory.Exists(Environment.SpecialFolder.ProgramFiles.ToString())) {
        \\ Program Files folder exists, but Program Files (x86) does not
    } else {
        \\ Neither folder exists
    }
} else {
    if (Directory.Exists(Environment.SpecialFolder.ProgramFiles.ToString())) {
        \\ Both folders exist
    } else {
        \\ Program Files (x86) exists but Program Files does not
    }
}
Kevin
  • 704
  • 3
  • 4
0

You could use WMI

using System.Management;

WqlObjectQuery wqlQuery =new WqlObjectQuery("select * from Win32_Processor where         DeviceID='CPU0' AND AddressWidth='64' ");
ManagementObjectSearcher searcher =new ManagementObjectSearcher(wqlQuery);

if (searcher.Get().Count > 0)
   Console.Write("64 Bit");

Once you know what type of system it is,You can check on the specific directories

Prabhu Murthy
  • 9,031
  • 5
  • 29
  • 36