Google 网上论坛不再支持新的 Usenet 帖子或订阅项。历史内容仍可供查看。

Build when #importing MDAC2.7 fails when run on system with MDAC2.5 when only us

已查看 29 次
跳至第一个未读帖子

Lito Lelina

未读,
2002年4月25日 04:46:462002/4/25
收件人
Hi Mark,

Use the Type Library instead of the DLL, this should work. This is
documented somewhere in MSDN

#import "c:\Program Files\Common Files\system\ado\msado25.tlb" rename("EOF",
"EndOfFile")

"Mark Dunmill" <mdun...@runge.com.au> wrote in message
news:182b01c1eb51$ae0bc5d0$9ae62ecf@tkmsftngxa02...
> THE PROBLEM
> -----------------------
>
> Had the following problem:
>
> Have a Visual Studio C++ (Version 6.0) ADO app that
> #import's from "msado15.dll".
>
> Initially compiled this app on a Windows 2000 machine
> with MDAC 2.5 SP1 installed (I believe MDAC 2.2 SP1 is
> the default version of MDAC installed as part of the
> Windows 2000 installation).
>
> This application ran fine on any system with MDAC 2.5 or
> better installed.
>
> We then upgraded our development machines to run Windows
> XP. As a result and without us realising the full
> implications Windows XP includes MDAC 2.7 as part of the
> default installation.
>
> The next time we compiled our app and produced an exe,
> without changing any of the source code, the app would
> work fine on Windows XP machines (or any machine with
> MDAC 2.7 installed) but would fail on our Windows 2000
> systems (with MDAC 2.5 installed).
>
> *** The important thing to note is that none of the
> source code had been changed ***
>
> We eventually tracked down the problem to the way the
> _Command interface is defined in the "msado15.dll"
> typelib. It seems that Microsoft have 'bent' the rules
> when it comes to COM interfaces. What's happened is that
> Microsoft have renamed the old '_Command' interface that
> was in MDAC 2.5 to be 'Command25' and then have created a
> new '_Command' interface which inherits from this old
> one. i.e. and this is the important bit, _Command is
> associated with a new GUID different than it had with
> MDAC 2.5 - and this GUID/interface doesn't exist in MDAC
> 2.5.
>
> Here's a fragment taken from the msado15.tlh file
> generated with MDAC 2.5 which defines the _Command
> interface.
>
> struct __declspec(uuid("0000054e-0000-0010-8000-
> 00aa006d2ea4"))
> _Command : Command15
> {
> //
> // Property data
> //
>
> __declspec(property(get=GetState))
> long State;
>
> //
> // Wrapper methods for error-handling
> //
>
> long GetState ( );
> HRESULT Cancel ( );
>
> //
> // Raw methods provided by interface
> //
>
> virtual HRESULT __stdcall get_State (
> long * plObjState ) = 0;
> virtual HRESULT __stdcall raw_Cancel ( ) = 0;
> };
>
> Here's a fragment taken from the msado15.tlh file
> generated with MDAC 2.7 which shows how _Command has been
> redefined.
>
> struct __declspec(uuid("0000054e-0000-0010-8000-
> 00aa006d2ea4"))
> Command25 : Command15
> {
> //
> // Property data
> //
>
> __declspec(property(get=GetState))
> long State;
>
> //
> // Wrapper methods for error-handling
> //
>
> long GetState ( );
> HRESULT Cancel ( );
>
> //
> // Raw methods provided by interface
> //
>
> virtual HRESULT __stdcall get_State (
> long * plObjState ) = 0;
> virtual HRESULT __stdcall raw_Cancel ( ) = 0;
> };
>
> struct __declspec(uuid("b08400bd-f9d1-4d02-b856-
> 71d5dba123e9"))
> _Command : Command25
> {
> //
> // Property data
> //
>
> __declspec(property(get=GetDialect,put=PutDialect))
> _bstr_t Dialect;
> __declspec(property
> (get=GetNamedParameters,put=PutNamedParameters))
> VARIANT_BOOL NamedParameters;
>
> //
> // Wrapper methods for error-handling
> //
>
> void PutRefCommandStream (
> IUnknown * pvStream );
> _variant_t GetCommandStream ( );
> void PutDialect (
> _bstr_t pbstrDialect );
> _bstr_t GetDialect ( );
> void PutNamedParameters (
> VARIANT_BOOL pfNamedParameters );
> VARIANT_BOOL GetNamedParameters ( );
>
> //
> // Raw methods provided by interface
> //
>
> virtual HRESULT __stdcall putref_CommandStream (
> IUnknown * pvStream ) = 0;
> virtual HRESULT __stdcall get_CommandStream (
> VARIANT * pvStream ) = 0;
> virtual HRESULT __stdcall put_Dialect (
> BSTR pbstrDialect ) = 0;
> virtual HRESULT __stdcall get_Dialect (
> BSTR * pbstrDialect ) = 0;
> virtual HRESULT __stdcall put_NamedParameters (
> VARIANT_BOOL pfNamedParameters ) = 0;
> virtual HRESULT __stdcall get_NamedParameters (
> VARIANT_BOOL * pfNamedParameters ) = 0;
> };
>
> Now here's a code fragment that illustrates the problem,
> (It's assumed that the #import "msado15.dll" is included
> etc.). The format of this code is the same as that which
> appears in Microsoft's own C++ ADO Samples.
>
> // Note: ADODB::_CommandPtr is a smart ptr which
> is defined like this
> // _COM_SMARTPTR_TYPEDEF(_Command,
> __uuidof(_Command))
> // i.e. it is a Smart interface pointer
> associated with the GUID for _Command
> ADODB::_CommandPtr pCmdChange = NULL;
> HRESULT hResult = pCmdChange.CreateInstance
> (__uuidof(ADODB::Command));
>
> The call to CreateInstance will fail when the code is
> compiled with a MDAC 2.7 version of msado.dll but run on
> a system with MDAC 2.5 installed. It returns a HRESULT of
> 0x80004002 (E_NOINTERFACE) - "The QueryInterface method
> did not recognize the requested interface. The interface
> is not supported.". i.e. the code tried to find the new
> _Command interface NOT the old _Command interface as
> defined in MDAC 2.5.
> The code works fine when compiled with MDAC 2.5 and run
> on a system with MDAC 2.5 or greater. (Will also work
> fine when compiled with MDAC 2.7 and run on MDAC 2.7).
>
> SOLUTIONS
> ------------------
>
> 1) Compile only on MDAC 2.5 and then can target MDAC 2.5
> or greater (Not really an option with Windows XP (.NET
> etc.))
>
> 2) Compile with MDAC 2.7 and force all clients to upgrade
> to MDAC 2.7 (Not an ideal solution as already have enough
> problems when forcing clients to install MDAC 2.5 -
> breaking existing apps - or simply not installing
> properly as part of the install process)
>
> 3) The solution we have come up with is to develop on
> systems with MDAC 2.7 installed but not to use
> the "_Command" interface. Instead we use the "Command25"
> interface (i.e. this is the renamed "_Command" interface
> from MDAC 2.5). This means all our developers are forced
> to develop on MDAC 2.7 but we can continue to target MDAC
> 2.5 or better). i.e. the above code becomes
>
> ADODB::Command25Ptr pCmdChange = NULL;
> HRESULT hResult = pCmdChange.CreateInstance
> (__uuidof(ADODB::Command));
>
> 4) An alternative to 3) would be put 'old' MDAC 2.5 dlls
> in a separate directory on our developers machines and
> #import them explicitly from this location. Then we could
> compile on any platform and target MDAC 2.5 or better.
>
> SAMPLE PROJECT ATTACHED
> -----------------------------------------------
>
> I have attached a simple console app which includes the
> above code fragment so that if anyone wants they can
> experiment with this problem. Please let me know if you
> come up with any better solutions to this problem.
>
> (MY TWO BITS WORTH - If only Microsoft hadn't bent the
> COM rules by renaming an interface then none of this
> would be happening - I mean we had the code working -
> install a new operating system and it breaks when running
> on our client's machines - makes source code control and
> versioning much more difficult).
>
> Hope this helps other people avoid the same pitfalls.
>
> Regards,
> Mark Dunmill
> [Software Engineer]
>
> e-mail: mdun...@runge.com.au
> web: www.runge.com
> phone: +61 7 3221 1883
> fax: +61 7 3229 3756
>
> address:Runge Pty Ltd
> Level 17 Central Plaza One
> 345 Queen Street
> Brisbane Qld 4000
> AUSTRALIA
>
> GPO Box 2774
> Brisbane Qld 4001
> AUSTRALIA
>


Mark Dunmill

未读,
2002年4月25日 20:30:032002/4/25
收件人
Thanks!

I tried importing the typelib "msado25.tlb" rather than the DLL and it works
just fine.

I didn't realise that there was a separate Typelib for each version of MDAC.
i.e. when MDAC 2.6 is installed then the "c:\Program Files\Common
Files\system\ado\" folder contains the following MSADO typelibs.

msado20.tlb
msado21.tlb
msado25.tlb
msado26.tlb

These obviously correspond to version 2, 2.1, 2.5 and 2.6 of MDAC.

As to being documented in MSDN, I just tried looking for references to
msado25.tlb and only found one relevant article. Here's an extract from the
article (as you can see it is very heavy on the VB) :-

----------------------------------------

Referencing the ADO Libraries
As with any library that provides a type library, you must set a reference
to the ADO library you want to use in your Visual Basic project. The type
library for the current version of ADO is contained within the ADO DLL,
msado15.dll. (To meet the needs of certain applications written with older
versions, older versions of the type library can be referenced as well
through the provided msado20.tlb, msado21.tlb, and msado25.tlb files.)

To reference the ADO library in your Visual Basic project, open the Project
menu and click References. Scroll down and select Microsoft ActiveX Data
Objects 2.7 Library. If an application compiled on a system with ADO 2.7
must run on a computer with a previous version of ADO installed, it needs to
use one of the backwards compatibility type libraries. Add a reference to
the appropriate .tlb file instead of to msado15.dll.

---------------------------------------

The last line is the important one, so here it is again :-

If an application compiled on a system with ADO 2.7 must run on a computer
with a previous version of ADO installed, it needs to use one of the
backwards compatibility type libraries. Add a reference to the appropriate
.tlb file instead of to msado15.dll

Hope this helps others.

Regards,
Mark Dunmill


"Lito Lelina" <ecle...@stag.com.ph> wrote in message
news:uwaoAXD7BHA.1864@tkmsftngp04...

0 个新帖子