I'm trying to get some properties from a COM object.
I built WindowsInstaller.dll by means of tlbimp.exe above msi.dll (Windows
Installer objects), then I added a reference to it in VS.NET 2003.
I succeeded with reading some objects reference using Reflection and
InvokeMember method. I used the following interfaces: Installer, Database,
View, Record of the COM object in .NET.
At least, when I fetched Record, I succeeded with retrieving a scalar
property: FieldCount, but my code failed dealing with a 1-based vectorial
property: StringData. I catch the following Inner Exception:
System.Runtime.InteropServices.COMException (0x80020005): Type mismatch.
Anyone can help me? Does it exist another way to solve my problem?
It follows my code (the code that fails is commented).
using System;
using System.Reflection;
namespace TestAutomation
{
class Test
{
[STAThread]
static void Main(string[] args)
{
Type insttype = Type.GetTypeFromProgID("WindowsInstaller.Installer");
object instobj = Activator.CreateInstance(insttype);
object[] dbparams = new object[2];
dbparams[0] = @"C:\MySetup.msi";
dbparams[1] = 0;
object dbobj =
insttype.InvokeMember("OpenDatabase",BindingFlags.InvokeMethod,null,instobj,dbparams);
object[] viewparams = new object[1];
viewparams[0] = "SELECT `FileName`, `Version`, `FileSize` FROM
`File`";
object viewobj =
insttype.InvokeMember("OpenView",BindingFlags.InvokeMethod,null,dbobj,viewparams);
insttype.InvokeMember("Execute",BindingFlags.InvokeMethod,null,viewobj,null);
int counter = 0;
while( true )
{
object recobj =
insttype.InvokeMember("Fetch",BindingFlags.InvokeMethod,null,viewobj,null);
if ( recobj != null )
{
++counter;
Console.WriteLine( "*** Row n. {0} ***", counter );
int num = 0;
// string[] columns = new string[4];
try
{
num = (int)
recobj.GetType().InvokeMember("FieldCount",BindingFlags.GetProperty,null,recobj,null);
Console.WriteLine( "FieldCount = {0}", num );
/*
columns = (string[])
recobj.GetType().InvokeMember("StringData",BindingFlags.GetProperty,null,recobj,null);
*/
}
catch( Exception exc )
{
Console.WriteLine( "Exception: {0}", exc.Message );
Console.WriteLine( "Inner: {0}", exc.InnerException );
break;
}
}
else
{
break;
}
}
Console.WriteLine( "Read {0} file(s)", counter );
}
}
}
c# programmer - 15 Dec 2004 09:19 GMT
You're trying to read an indexed property, then use the following snippet:
for ( int index = 1; index <= 3; index++ )
{
object result =
recobj.GetType().InvokeMember("StringData",BindingFlags.GetProperty,null,recobj,new object[]{index});
Console.WriteLine ("StringData[{0}] = {1}", index, result.ToString());
}
It should work fine
> I'm trying to get some properties from a COM object.
> I built WindowsInstaller.dll by means of tlbimp.exe above msi.dll (Windows
[quoted text clipped - 69 lines]
> }
> }
Pino - 15 Dec 2004 09:23 GMT
Thanks, it's actually works fine!
> You're trying to read an indexed property, then use the following snippet:
>
[quoted text clipped - 85 lines]
>> }
>> }
Lancellotti - 15 Dec 2004 09:23 GMT
You're trying to read an indexed property. It's not an interop issue.
Use the following snippet in your code:
for ( int index = 1; index <= 3; index++ )
{
object result =
recobj.GetType().InvokeMember("StringData",BindingFlags.GetProperty,null,recobj,new object[]{index});
Console.WriteLine ("StringData[{0}] = {1}", index, result.ToString());
}
It should work fine
> I'm trying to get some properties from a COM object.
> I built WindowsInstaller.dll by means of tlbimp.exe above msi.dll (Windows
[quoted text clipped - 69 lines]
> }
> }