Way to determine framework version without Registry
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
string clrVersion = System.Environment.Version.ToString();
string dotNetVersion = Assembly
.GetExecutingAssembly()
.GetReferencedAssemblies()
.Where(x => x.Name == "mscorlib").First().Version.ToString();
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"]);
}
}
}
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.
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.
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);
}
}
}
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.
精彩评论