@ -7,16 +7,17 @@
using System ;
using System ;
using System.Collections.Generic ;
using System.Collections.Generic ;
using System.IO ;
using System.Runtime.InteropServices ;
using System.Runtime.InteropServices.ComTypes ;
using Microsoft.Win32 ;
using Microsoft.Win32 ;
namespace ICSharpCode.SharpDevelop.Project
namespace ICSharpCode.SharpDevelop.Project
{
{
/// <summary>
/// Description of TypeLibrary.
/// </summary>
public class TypeLibrary
public class TypeLibrary
{
{
string name ;
string name ;
string description ;
string path ;
string path ;
string guid ;
string guid ;
string version ;
string version ;
@ -43,10 +44,19 @@ namespace ICSharpCode.SharpDevelop.Project
public string Name {
public string Name {
get {
get {
if ( name = = null ) {
name = GetTypeLibName ( ) ;
}
return name ;
return name ;
}
}
}
}
public string Description {
get {
return description ;
}
}
public string Path {
public string Path {
get {
get {
return path ;
return path ;
@ -90,40 +100,40 @@ namespace ICSharpCode.SharpDevelop.Project
public static IEnumerable < TypeLibrary > Libraries {
public static IEnumerable < TypeLibrary > Libraries {
get {
get {
RegistryKey typel ibsKey = Registry . ClassesRoot . OpenSubKey ( "TypeLib" ) ;
RegistryKey typeL ibsKey = Registry . ClassesRoot . OpenSubKey ( "TypeLib" ) ;
foreach ( string typelibKeyName in typel ibsKey . GetSubKeyNames ( ) ) {
foreach ( string typeLibKeyName in typeL ibsKey . GetSubKeyNames ( ) ) {
RegistryKey typelibKey = typel ibsKey . OpenSubKey ( typel ibKeyName ) ;
RegistryKey typeLibKey = typeL ibsKey . OpenSubKey ( typeL ibKeyName ) ;
if ( typel ibKey = = null ) {
if ( typeL ibKey = = null ) {
continue ;
continue ;
}
}
TypeLibrary lib = Create ( typel ibKey ) ;
TypeLibrary lib = Create ( typeL ibKey ) ;
if ( lib ! = null & & lib . Name ! = null & & lib . Path ! = null & & lib . Name . Length > 0 & & lib . Path . Length > 0 ) {
if ( lib ! = null & & lib . Description ! = null & & lib . Path ! = null & & lib . Description . Length > 0 & & lib . Path . Length > 0 ) {
yield return lib ;
yield return lib ;
}
}
}
}
}
}
}
}
static TypeLibrary Create ( RegistryKey typel ibKey )
static TypeLibrary Create ( RegistryKey typeL ibKey )
{
{
string [ ] versions = typel ibKey . GetSubKeyNames ( ) ;
string [ ] versions = typeL ibKey . GetSubKeyNames ( ) ;
if ( versions . Length > 0 ) {
if ( versions . Length > 0 ) {
TypeLibrary lib = new TypeLibrary ( ) ;
TypeLibrary lib = new TypeLibrary ( ) ;
// Use the last version
// Use the last version
lib . version = versions [ versions . Length - 1 ] ;
lib . version = versions [ versions . Length - 1 ] ;
RegistryKey versionKey = typel ibKey . OpenSubKey ( lib . version ) ;
RegistryKey versionKey = typeL ibKey . OpenSubKey ( lib . version ) ;
lib . name = ( string ) versionKey . GetValue ( null ) ;
lib . descriptio n = ( string ) versionKey . GetValue ( null ) ;
lib . path = GetTypel ibPath ( versionKey , ref lib . lcid ) ;
lib . path = GetTypeL ibPath ( versionKey , ref lib . lcid ) ;
lib . guid = System . IO . Path . GetFileName ( typel ibKey . Name ) ;
lib . guid = System . IO . Path . GetFileName ( typeL ibKey . Name ) ;
return lib ;
return lib ;
}
}
return null ;
return null ;
}
}
static string GetTypel ibPath ( RegistryKey versionKey , ref string lcid )
static string GetTypeL ibPath ( RegistryKey versionKey , ref string lcid )
{
{
// Get the default value of the (typically) 0\win32 subkey:
// Get the default value of the (typically) 0\win32 subkey:
string [ ] subkeys = versionKey . GetSubKeyNames ( ) ;
string [ ] subkeys = versionKey . GetSubKeyNames ( ) ;
@ -132,17 +142,15 @@ namespace ICSharpCode.SharpDevelop.Project
return null ;
return null ;
}
}
for ( int i = 0 ; i < subkeys . Length ; i + + ) {
for ( int i = 0 ; i < subkeys . Length ; i + + ) {
try {
int result ;
int . Parse ( subkeys [ i ] ) ; // The right key is a number
if ( I nt32 . Try Parse( subkeys [ i ] , out result ) ) {
lcid = subkeys [ i ] ;
lcid = subkeys [ i ] ;
RegistryKey NullKey = versionKey . OpenSubKey ( subkeys [ i ] ) ;
RegistryKey NullKey = versionKey . OpenSubKey ( subkeys [ i ] ) ;
string [ ] subsubkeys = NullKey . GetSubKeyNames ( ) ;
string [ ] subsubkeys = NullKey . GetSubKeyNames ( ) ;
RegistryKey win32Key = NullKey . OpenSubKey ( "win32" ) ;
RegistryKey win32Key = NullKey . OpenSubKey ( "win32" ) ;
return win32Key = = null | | win32Key . GetValue ( null ) = = null ? null : win32Key . GetValue ( null ) . ToString ( ) ;
return win32Key = = null | | win32Key . GetValue ( null ) = = null ? null : GetTypeLibPath ( win32Key . GetValue ( null ) . ToString ( ) ) ;
} catch ( FormatException ) {
}
// Wrong keys don't parse til int
}
}
}
return null ;
return null ;
}
}
@ -155,5 +163,89 @@ namespace ICSharpCode.SharpDevelop.Project
}
}
return - 1 ;
return - 1 ;
}
}
string GetTypeLibName ( )
{
string name = null ;
int typeLibLcid ;
if ( guid ! = null & & lcid ! = null & & Int32 . TryParse ( lcid , out typeLibLcid ) ) {
Guid typeLibGuid = new Guid ( this . guid ) ;
name = GetTypeLibNameFromGuid ( ref typeLibGuid , ( short ) VersionMajor , ( short ) VersionMinor , typeLibLcid ) ;
}
if ( name = = null ) {
name = GetTypeLibNameFromFile ( path ) ;
}
if ( name ! = null ) {
return name ;
}
return description ;
}
/// <summary>
/// Removes the trailing part of the type library filename if it
/// starts with a number.
/// </summary>
static string GetTypeLibPath ( string fileName )
{
if ( fileName ! = null ) {
int index = fileName . LastIndexOf ( '\\' ) ;
if ( index > 0 & & index + 1 < fileName . Length ) {
if ( Char . IsDigit ( fileName [ index + 1 ] ) ) {
return fileName . Substring ( 0 , index ) ;
}
}
}
return fileName ;
}
static string GetTypeLibNameFromFile ( string fileName )
{
if ( fileName ! = null & & fileName . Length > 0 & & File . Exists ( fileName ) ) {
ITypeLib typeLib ;
if ( LoadTypeLibEx ( fileName , RegKind . None , out typeLib ) = = 0 ) {
try {
return Marshal . GetTypeLibName ( typeLib ) ;
} finally {
Marshal . ReleaseComObject ( typeLib ) ;
}
}
}
return null ;
}
static string GetTypeLibNameFromGuid ( ref Guid guid , short versionMajor , short versionMinor , int lcid )
{
ITypeLib typeLib ;
if ( LoadRegTypeLib ( ref guid , versionMajor , versionMinor , lcid , out typeLib ) = = 0 ) {
try {
return Marshal . GetTypeLibName ( typeLib ) ;
} finally {
Marshal . ReleaseComObject ( typeLib ) ;
}
}
return null ;
}
enum RegKind {
Default ,
Register ,
None
}
[DllImport("oleaut32.dll")]
static extern int LoadTypeLibEx ( [ MarshalAs ( UnmanagedType . BStr ) ] string szFile ,
RegKind regkind ,
out ITypeLib pptlib ) ;
[DllImport("oleaut32.dll")]
static extern int LoadRegTypeLib (
ref Guid rguid ,
short wVerMajor ,
short wVerMinor ,
int lcid ,
out ITypeLib pptlib ) ;
}
}
}
}