|
| Problem with InterOp of the MSI.DLL with VB.NET |
|
|
|
|
| Messages |
|
Related Types |
This message was discovered on microsoft.public.dotnet.framework.interop.
Responses highlighted in red are from those people who are likely to be able to contribute good, authoratitive information to this discussion. They include Microsoft employees, MVP's and others who IMHO contribute well to these kinds of discussions.
| Scott Williams |
I'm not a hardcore .NET InterOp guy, basically I add in the reference, and away I go.
Let me explain the problem first, some of this is MSI specific but my problem comes in the InterOp of the MSI automation objects. I am converting a VB6 program I have that is a custom MSI build tool. One of the things that I do in this program is read an entry from a configuration file that tells me what tables to add that are not part of my "base" .msi file. This is done by opening a schema.msi file and obtaining the required information about the table and then creating it in my target database. One of the properties I need to reference is the PrimaryKeys property that is part of the Database Object and it returns a Record object. I believe this may be where the issue is cropping up as in several searches it seems to imply that InterOp has an issue with Properties and prefers methods, and I think more specifically because the return type isn't easily converted to a native type. I have also found that the MSI.DLL seems to be a bit quirky as it is really only contains interfaces. In fact when I first went create an instance of WindowsInstaller.Installer, I received an error, I eventually had to just declare a general Object reference and then use CreateObject("WindowsInstaller.Installer), but all other objects that get generated from that object work being strongly typed.
When I try to retrieve the PrimaryKeys property into a Record object I get a "Method not Found" error. Here are the IL DASM entries for the property: ..property class WindowsInstaller.Record PrimaryKeys(string) { .custom instance void [mscorlib]System.Runtime.InteropServices.DispIdAttribute::.ctor(int32) = ( 01 00 05 00 00 00 00 00 ) .get instance class WindowsInstaller.Record WindowsInstaller.Database::get_PrimaryKeys(string) } // end of property Database::PrimaryKeys
..method public hidebysig newslot specialname abstract virtual instance class WindowsInstaller.Record marshal( interface) get_PrimaryKeys([in] string marshal( bstr) Table) runtime managed preservesig internalcall { .custom instance void [mscorlib]System.Runtime.InteropServices.DispIdAttribute::.ctor(int32) = ( 01 00 05 00 00 00 00 00 ) } // end of method Database::get_PrimaryKeys
All of which is pretty Greek to me.
I have seen some references to C# code that wraps up the MSI.DLL with the API function calls, but I have a lot of code I don't really want to change around (at least at this time) and for this particular problem I believe I could have an easier work around than that anyhow, that and I'm only converting it to .NET at this point to take advantage of Reflection to better process Assemblies into my .MSI files and to take advantage of the RegEx capabilities to parse COM server registry information.
I have seen several posts/articles that talk about different functions in the Marshal namespace, but I'm just not anywhere near that level of understanding yet. Is there some simple solution to this, or can someone suggest some better search terms for me to research? Can I just not get there from here? It seems like most other aspects of the InterOp assembly work just fine.
Thanks for any assistance that you can provide.
|
|
|
| |
|
| |
| |
| Phil Wilson |
Have you tried calling with the actual signature of get_PrimaryKeys? -- Phil Wilson [MVP Windows Installer] ---- "Scott Williams" <Click here to reveal e-mail address> wrote in message news:Click here to reveal e-mail address... [Original message clipped]
|
|
|
| |
|
| |
| |
| Scott Williams |
Yes I have. No go there.
"Phil Wilson" <Click here to reveal e-mail address> wrote in message news:Opt%Click here to reveal e-mail address... [Original message clipped]
|
|
|
| |
|
|
| |
| |
| Scott Williams |
Just as an update, I have a hack around the problem by creating a VB6 COM DLL where I just pass the parameter I need in the property and then the Database Object itself, then make the call and return the Record Object. Since this is a utility that only I run, I can live with that, at least for now. It is ugly, but I feel the advantages for this particular program outweight the ugliness. I would still like to know if anyone has a better solution to this, well except for the API wrappers. :)
"Scott Williams" <Click here to reveal e-mail address> wrote in message news:Click here to reveal e-mail address... [Original message clipped]
|
|
|
| |
|
| |
| |
| Phil Wilson |
Maybe someone from MS could jump in with an official answer - but this is just my take on the general situation based on the documented interfaces. There are two ways to call the MSI functions: 1. The Win32 APIs, which obviously need wrapping with P/Invoke code to call from ..NET managed code. 2. The automation interface, which is a late-binding COM automation interface. This is intended to be used with CreateObject() and its equivalents in the .NET world (Activator.CreateInstance, GetTypeFromProgID, and Type.InvokeMember etc).
You're not really using either of these. You're trying to do a early-binding COM (via interop), and I don't think it's an official way to do it. -- Phil Wilson [MVP Windows Installer] ---- "Scott Williams" <Click here to reveal e-mail address> wrote in message news:Click here to reveal e-mail address... [Original message clipped]
|
|
|
| |
|
| |
| |
| Scott Williams |
"Phil Wilson" <Click here to reveal e-mail address> wrote in message news:Click here to reveal e-mail address... > Maybe someone from MS could jump in with an official answer - but this is just [Original message clipped]
Ahh, OK. I really don't know anything about that second point, I'll shift my research to that and see what I come up with. Thank you for that direction.
|
|
|
| |
|
|
| |
| |
| Ying-Shen Yu[MSFT] (VIP) |
Hi Scott and Phil,
From your discussion, I think the key problem is app throw "Member not found" when calling Database.get_PrimaryKey method. We are now investigating this issue, I am able to reproduce this problem on my system, and it seems this problem also exists when using MSI using a MFC program. I'll go on researching this issue and update this issue later. Thanks!
Best regards,
Ying-Shen Yu [MSFT] Microsoft Online Partner Support Get Secure! - www.microsoft.com/security
This posting is provided "AS IS" with no warranties and confers no rights. This mail should not be replied directly, "online" should be removed before sending.
|
|
|
| |
|
|
| |
| |
| Ying-Shen Yu[MSFT] (VIP) |
Hi all,
This is an update to let you know, we are still investigating on this issue, I'll continue investigating this issue and ask some senior engineer to involve this issue. Thanks!
Best regards,
Ying-Shen Yu [MSFT] Microsoft Online Partner Support Get Secure! - www.microsoft.com/security
This posting is provided "AS IS" with no warranties and confers no rights. This mail should not be replied directly, "online" should be removed before sending.
|
|
|
| |
|
|
| |
| |
| Alden Raymundo [MSFT] (VIP) |
Hi all,
I'm looking into this as well and will update the thread as I find information.
Please stay tuned.
Alden Raymundo Developer Support - Windows Installer
This posting is provided “AS IS” with no warranties, and confers no rights.
|
|
|
| |
|
|
| |
|
|
|
|
|
| |
| Erik Kupferer [MSFT] (VIP) |
Hi Scott,
Ok this took me a little while to track this issue down. If you make the following changes the CDatabase0.h header it will resolve the issue.
from
InvokeHelper(0x5, DISPATCH_PROPERTYGET, VT_DISPATCH, (void*)&result, parms, Table);
to
InvokeHelper(0x5, DISPATCH_PROPERTYGET | DISPATCH_METHOD, VT_DISPATCH, (void*)&result, parms, Table);
It was an issue in the MSI automation. I will inform the development team of what I found. If you have any questions please let me know.
I hope that helps.
Cheers,
- Erik
-------------------- | From: "Scott Williams" <Click here to reveal e-mail address> | References: <Click here to reveal e-mail address> <Opt#Click here to reveal e-mail address> <Click here to reveal e-mail address> | Subject: Re: Problem with InterOp of the MSI.DLL with VB.NET | Date: Wed, 4 Feb 2004 12:25:44 -0500 | Lines: 22 | X-Priority: 3 | X-MSMail-Priority: Normal | X-Newsreader: Microsoft Outlook Express 6.00.3790.0 | X-MIMEOLE: Produced By Microsoft MimeOLE V6.00.3790.0 | Message-ID: <Click here to reveal e-mail address> | Newsgroups: microsoft.public.dotnet.framework.interop,microsoft.public.platformsdk.msi | NNTP-Posting-Host: 12.17.95.135 | Path: cpmsftngxa07.phx.gbl!cpmsftngxa06.phx.gbl!TK2MSFTNGP08.phx.gbl!TK2MSFTNGP10. phx.gbl | Xref: cpmsftngxa07.phx.gbl microsoft.public.platformsdk.msi:18774 microsoft.public.dotnet.framework.interop:21801 | X-Tomcat-NG: microsoft.public.dotnet.framework.interop | | Just as an update, I have a hack around the problem by creating a VB6 COM | DLL where I just pass the parameter I need in the property and then the | Database Object itself, then make the call and return the Record Object. | Since this is a utility that only I run, I can live with that, at least for | now. It is ugly, but I feel the advantages for this particular program | outweight the ugliness. I would still like to know if anyone has a better | solution to this, well except for the API wrappers. :) | | | "Scott Williams" <Click here to reveal e-mail address> wrote in message | news:Click here to reveal e-mail address... | > Yes I have. No go there. | > | > "Phil Wilson" <Click here to reveal e-mail address> wrote in message | > news:Opt%Click here to reveal e-mail address... | > > Have you tried calling with the actual signature of get_PrimaryKeys? | > > -- | > > Phil Wilson [MVP Windows Installer] | > | > | | |
This posting is provided "AS IS" with no warranties, and confers no rights.
|
|
|
| |
|
|
| |
|
|
|
|
|
|
|
|
|
|
|
BootFX
Reliable and powerful .NET application framework. |
|
|
|
|
|
|