6

I've searching a long time, but i couldn't find answer. Is there any way to determine framework and service pack .NET installed on PC, without access to registry in C#? I can use registry keys, but i have to do this without access to registry. I read something about directories in C:\Windows\Microsoft .NET, but there, I only found framework version, nothing about SP. But I need framework and Service Pack. Can somebody help me?

Regards, Greg

ogrod87
  • 61
  • 2
  • 1
    Why can't you use the registry? – SLaks Aug 01 '11 at 14:16
  • 1
    Because I'm doing this for user, who hasn't permission to access to registry. – ogrod87 Aug 01 '11 at 14:18
  • 1
    You _always_ have permission to access the registry. You may not have write access, but you will have read access. (Unless you're running untrusted code, in which case you can't access the filesystem either) – SLaks Aug 01 '11 at 14:20
  • Yes, but I have to do without registry. It's my boss wish – ogrod87 Aug 01 '11 at 14:21
  • 5
    Can you explain to your boss that his wish makes no sense? – SLaks Aug 01 '11 at 14:23
  • 2
    @ogrod87 sometimes it's important to tell your boss they're making asinine requirements. – Chris Marisic Aug 01 '11 at 14:24
  • 6
    Let's just fulfill the user's requirements. Sometimes you can't control what your boss wants - we've all been there. –  Aug 01 '11 at 14:25
  • Why do you even need to know this information? If you target a specfic framework say 3.5 SP1 then it will work if .NET Framework 4.0 is installed or if .NET Framework 3.5 SP1 is installed. It doesn't matter because the program will work in either case. – Security Hound Aug 01 '11 at 15:18

6 Answers6

4
string clrVersion = System.Environment.Version.ToString();
string dotNetVersion = Assembly
                      .GetExecutingAssembly()
                      .GetReferencedAssemblies()
                      .Where(x => x.Name == "mscorlib").First().Version.ToString();
sll
  • 61,540
  • 22
  • 104
  • 156
2

you could use WMI to get a list of all the installed software filtering the result to achieve your goal

 public static class MyClass
    {
        public static void Main()
        {
            ManagementObjectSearcher mos = new ManagementObjectSearcher("SELECT * FROM Win32_Product");
            foreach (ManagementObject mo in mos.Get())
            {
                Console.WriteLine(mo["Name"]);
            }


        }
    }
Massimiliano Peluso
  • 26,379
  • 6
  • 61
  • 70
0

I think it's possible to ask the WMI.

Query for all Win32_Product elements and look for the Name Property contains "Microsoft .NET Framework"

ServicePack information is also provided by WMI.. But I don't know exactly where.

Thorsten Hans
  • 2,675
  • 19
  • 21
0

You can do this:

System.Environment.Version.ToString()

(CLR Version only)

or this

from MSDN blog on Updated sample .NET Framework detection code that does more in-depth checking

or this

No registry access. Borrowed from this blog.

using System;
using System.IO;
using System.Security;
using System.Text.RegularExpressions;

namespace YourNameSpace
{
    public class SystemInfo
    {
        private const string FRAMEWORK_PATH = "\\Microsoft.NET\\Framework";
        private const string WINDIR1 = "windir";
        private const string WINDIR2 = "SystemRoot";

        public static string FrameworkVersion
        {
            get
            {
                try
                {
                    return getHighestVersion(NetFrameworkInstallationPath);
                }
                catch (SecurityException)
                {
                    return "Unknown";
                }
            }
        }

        private static string getHighestVersion(string installationPath)
        {
            string[] versions = Directory.GetDirectories(installationPath, "v*");
            string version = "Unknown";

            for (int i = versions.Length - 1; i >= 0; i--)
            {
                version = extractVersion(versions[i]);
                if (isNumber(version))
                    return version;
            }

            return version;
        }

        private static string extractVersion(string directory)
        {
            int startIndex = directory.LastIndexOf("\\") + 2;
            return directory.Substring(startIndex, directory.Length - startIndex);
        }

        private static bool isNumber(string str)
        {
            return new Regex(@"^[0-9]+\.?[0-9]*$").IsMatch(str);
        }

        public static string NetFrameworkInstallationPath
        {
            get { return WindowsPath + FRAMEWORK_PATH; }
        }

        public static string WindowsPath
        {
            get
            {
                string winDir = Environment.GetEnvironmentVariable(WINDIR1);
                if (String.IsNullOrEmpty(winDir))
                    winDir = Environment.GetEnvironmentVariable(WINDIR2);

                return winDir;
            }
        }
    }
}

Here is an improved example that includes service packs,

string path = System.Environment.SystemDirectory;
path = path.Substring( 0, path.LastIndexOf('\\') );
path = Path.Combine( path, "Microsoft.NET" );
// C:\WINDOWS\Microsoft.NET\

string[] versions = new string[]{
    "Framework\\v1.0.3705",
    "Framework64\\v1.0.3705",
    "Framework\\v1.1.4322",
    "Framework64\\v1.1.4322",
    "Framework\\v2.0.50727",
    "Framework64\\v2.0.50727",
    "Framework\\v3.0",
    "Framework64\\v3.0",
    "Framework\\v3.5",
    "Framework64\\v3.5",
    "Framework\\v3.5\\Microsoft .NET Framework 3.5 SP1",
    "Framework64\\v3.5\\Microsoft .NET Framework 3.5 SP1",
    "Framework\\v4.0",
    "Framework64\\v4.0"
};

foreach( string version in versions )
{
    string versionPath = Path.Combine( path, version );

    DirectoryInfo dir = new DirectoryInfo( versionPath );
    if( dir.Exists )
    {
        Response.Output.Write( "{0}<br/>", version );
    }
}

The problem is that you will have to keep up with the versions as they come out.

Community
  • 1
  • 1
0

You can use the MSI API functions to get a list of all installed products and then check whether the required .NET Framework version is installed.

Just don't tell you boss that these functions will read from the Registry.

Here's the code:

using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text;

class Program
{
    [DllImport("msi.dll", SetLastError = true)]
    static extern int MsiEnumProducts(int iProductIndex, StringBuilder lpProductBuf);

    [DllImport("msi.dll", CharSet = CharSet.Unicode)]
    static extern Int32 MsiGetProductInfo(string product, string property, [Out] StringBuilder valueBuf, ref Int32 len);

    public const int ERROR_SUCCESS = 0;
    public const int ERROR_MORE_DATA = 234;
    public const int ERROR_NO_MORE_ITEMS = 259;

    static void Main(string[] args)
    {
        int index = 0;
        StringBuilder sb = new StringBuilder(39);
        while (MsiEnumProducts(index++, sb) == 0)
        {
            var productCode = sb.ToString();
            var product = new Product(productCode);
            Console.WriteLine(product);
        }
    }

    class Product
    {
        public string ProductCode { get; set; }
        public string ProductName { get; set; }
        public string ProductVersion { get; set; }

        public Product(string productCode)
        {
            this.ProductCode = productCode;
            this.ProductName = GetProperty(productCode, "InstalledProductName");
            this.ProductVersion = GetProperty(productCode, "VersionString");
        }

        public override string ToString()
        {
            return this.ProductCode + " - Name: " + this.ProductName + ", Version: " + this.ProductVersion;
        }

        static string GetProperty(string productCode, string name)
        {
            int size = 0;
            int ret = MsiGetProductInfo(productCode, name, null, ref size); if (ret == ERROR_SUCCESS || ret == ERROR_MORE_DATA)
            {
                StringBuilder buffer = new StringBuilder(++size);
                ret = MsiGetProductInfo(productCode, name, buffer, ref size);
                if (ret == ERROR_SUCCESS)
                    return buffer.ToString();
            }

            throw new System.ComponentModel.Win32Exception(ret);
        }
    }
}
Dirk Vollmar
  • 172,527
  • 53
  • 255
  • 316
-1

This page may be of use: http://blogs.msdn.com/b/astebner/archive/2009/06/16/9763379.aspx

Although the registry bit is irrelevant to you, the checking using mscoree.dll may be of help - its just that I cant access skydrive from work hence cant look through the code.

Ill see if i find something else.

Chada
  • 36
  • 1
  • 5