[.NET]Com interop Exception

Pagina: 1
Acties:

  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
Topicstarter
We zijn hier bezig met een ASP.NET applicatie waar gebruik wordt gemaakt van een FOX Com dll. Om hier gebruik van te maken is er een stub gegenereerd door VS.NET ( Gewoon door een reference toe te voegen naar de COM dll ). Als deze dll gebruikt wordt op de test server of op de ontwikkel machines werkt dit allemaal goed. maar zo gauw als het op een andere server gezet wordt werkt het opeens niet meer en komen er exception. Een van de exceptions is bijvoorbeeld

code:
1
2
3
4
5
6
7
8
9
Exception of type: System.InvalidCastException

HelpLink: 
Message: ?
Source: Interop.bbbusiness
TargeSite: ADODB.Recordset moGetUserProp( ... )
StackTrace:
   at bbbusiness.cMemPlusClass.moGetUserProp( ... )
   at ... GetFriends(Int32 mUserId) in ... SaldoMasterDataAccess.cs


De com dll is gebouwd met Visual Foxpro 8. Het lijkt erop dat het fout gaat bij het Casten naar een ADODB.Recordset, als namelijk de zelfde methode aangeroepen wordt die alleen een int terug geeft ( het eerste field uit de recordset ) dan gaat het wel goed. De recordset bevat dus ook gegevens, het gaat dus niet verkeerd omdat de recordset bijvoorbeeld NULL is.

Om te testen waar het probleem zit hebben we een simpele ASP.NET pagina gemaakt die de volgende code uitvoerd
ASP.NET:
1
2
bbbusiness.cMemPlusClass memTest = new bbbusiness.cMemPlusClass();
Response.Write( memTest.moGetUserProp( "string","string", "string" ) );

Als deze code uitgevoerd wordt komt er dus in de moGetUserProp ( die deel uitmaakt van de stub die door VS.NET gegenereerd is ) de bovengenoemde Exception.

Ik vindt de Message van de Exception ook heel vreemd ( "?" ). Het is geen exception die door ons zelf gethrowed wordt. Ook zoeken op Google met die message heeft niet zoveel nut aangezien Google ( en andere zoekmachines ) het vraagteken gewoon negeren.

Heeft er iemand mischien nog een idee waarom het op de ene machine wel werkt en op de andere niet?

Ik weet zeker dat er op de machines dezelfde dll draait want we hebben deze meerdere malen weg gegooid en opnieuw geregistreerd. De com dll werkt ook gewoon goed als je hem bijvoorbeeld vanuit een simpele ASP Clasic pagina aanroept.

[ Voor 6% gewijzigd door Woy op 31-08-2004 10:56 . Reden: Even de layout verbeterd ]

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


  • EfBe
  • Registratie: Januari 2000
  • Niet online
Met welke ADO versie is de FOX dll gecompileerd? Het kan zijn dat deze niet op de server te vinden is? (lijkt me niet waarschijnlijk, maar het zou kunnen).

Creator of: LLBLGen Pro | Camera mods for games
Photography portfolio: https://fransbouma.com


  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
Topicstarter
Ik zal morgen even kijken met welke versie van ado er gecompileerd is. Maar de ADO dll ( .net dll ) staat ieder geval in de bin dir van de web applicatie.

Dan zou toch de dll uit de bin dir van de web applicatie geladen moeten worden ookal is er een andere dll aanwezig op de server?.

Ik zal morgen ieder geval even kijken wat voor installatie er op de verschillende machines staan. Het zou inderdaad best mogelijk dat er op de computer waar het niet op werkt een oudere versie staat aangezien die minder makkelijk geupdate wordt, aangezien die ook via internet te benaderen is.

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


  • EfBe
  • Registratie: Januari 2000
  • Niet online
rwb schreef op 01 september 2004 @ 00:49:
Ik zal morgen even kijken met welke versie van ado er gecompileerd is. Maar de ADO dll ( .net dll ) staat ieder geval in de bin dir van de web applicatie.

Dan zou toch de dll uit de bin dir van de web applicatie geladen moeten worden ookal is er een andere dll aanwezig op de server?.
De COM dll moet natuurlijk wel geregged zijn in windows, dus met regsvr32 zijn toegevoegd aan de registry. Hoe weet windows anders waar deze de com components kan vinden. :) Als er elders een ADO 2.5 dll is geregistreerd en jij plaatst de ADO 2.8 dll in je bin dir dan heb je daar weinig aan denk ik.

Creator of: LLBLGen Pro | Camera mods for games
Photography portfolio: https://fransbouma.com


  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
Topicstarter
EfBe schreef op 01 september 2004 @ 09:23:
[...]

De COM dll moet natuurlijk wel geregged zijn in windows, dus met regsvr32 zijn toegevoegd aan de registry. Hoe weet windows anders waar deze de com components kan vinden. :) Als er elders een ADO 2.5 dll is geregistreerd en jij plaatst de ADO 2.8 dll in je bin dir dan heb je daar weinig aan denk ik.
Ja daar heb je gelijk in. Op zich werkt de FOX dll ook goed in andere applicaties ( Niet .NET ). Maar je hebt wel een punt dat .NET problemen kan hebben met de verschillende types als er verschillende ADO's geinstalleerd zijn.

Maar de server beheerder gaat vandaag even kijken welke versie er geinstalleerd staat.

[ Voor 9% gewijzigd door Woy op 01-09-2004 09:33 ]

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
Topicstarter
Het progid ADODB.Recordset maakt op beide machines gebruik van msado15.dll versie 2.70.7713.0. Aan die kan het dus niet liggen. Bij beiden is ook ADODB.Recordset.2.7 de laatste versie. Misschien is er nog een supporting dll die een andere versie kan hebben.

Hoe kun je precies zien welke versie van ADO je hebt. Ik heb het volgende programma bij microsoft vandaan gehaald: Component Checker, maar die zegt op mijn computer ( XP met SP2 )
The following product releases were matched:

UNKNOWN

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


  • EfBe
  • Registratie: Januari 2000
  • Niet online
Aan com ligt het dus niet, je weet zeker dat die rowset bestaat en niet null is die je teruggeeft, dat de verbinding gemaakt kan worden e.d. ? Wellicht nuttig die FOX dll van wat trace messages te voorzien zodat je kunt zien tot hoever die komt...

Creator of: LLBLGen Pro | Camera mods for games
Photography portfolio: https://fransbouma.com


  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
Topicstarter
EfBe schreef op 01 september 2004 @ 11:10:
Aan com ligt het dus niet, je weet zeker dat die rowset bestaat en niet null is die je teruggeeft, dat de verbinding gemaakt kan worden e.d. ? Wellicht nuttig die FOX dll van wat trace messages te voorzien zodat je kunt zien tot hoever die komt...
Het is inderdaad zeker dat die rowset bestaat. Exact dezelde code in asp levert een RecordSet met 1 Row terug. De parameters worden in de fox dll direct gebruikt om een select uit te voeren.

Het lijkt er dus ook op dat de FOX dll wel goed uitgevoerd wordt. Als er een methode aangeroepen wordt die intern dezelfde methode aanroep en dan alleen het eerste field terug geeft dan krijg ik in mijn .NET applicatie ook netjes die waarde te zien.

Ik zal even vragen of ze een andere FOX dll kunnen maken om te testen of het altijd mis gaat met een RecordSet.

Ik krijg de fout namelijk ook al als ik nog niks met die recordset doe. Het lijkt er op dat het type wat ik terug krijg niet overeen komt met wat de stub verwacht.

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
Topicstarter
Ik ben nog eens aan het testen gegaan met een testdll en ik krijg nou een Exception die ikzelf ieder geval niet kan verklaren.
Ik heb hier een dll die in FOX8 gecompileerd is de er als volgt uitziet.

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
DEFINE CLASS testADODB as Session Olepublic
    PROCEDURE moGetRecordSet as ADODB.RecordSet
        loDB = CREATEOBJECT("test.testADODB_DB")
        RETURN loDB.moGetRecordSet
    ENDPROC
ENDDEFINE

DEFINE CLASS testADODB_DB as Session Olepublic
    PROCEDURE moGetRecordSet
        loRS = CREATEOBJECT("ADODB.RecordSet")
        RETURN loRS
    ENDPROC
ENDDEFINE


Het zijn 2 classes om zo het voorbeeldje een beetje meer op de werkelijke situatie te laten lijken. Als ik dit comobject als referentie aan mijn .net project toevoeg gaat het allemaal goed. Ik kan er een instantie van aanmaken en de Intellisense ziet ook netjes de moGetRecordSet methode en ook dat hij een ADODB.RecordSet als returnvalue heeft.

Als ik deze nou met de volgende code aanroep gaat het mis en krijg ik een NullReferenceException
C#:
1
2
3
4
5
6
7
8
9
10
11
12
test.testADODBClass testClass = new test.testADODBClass();
ADODB.Recordset recset = (ADODB.Recordset)testClass.moGetRecordSet();
if( recset == null )
    return;
if( recset.State > 0 )
{
    lblResult.Text = "RecCount: " + recset.RecordCount;
}
else
{
    lblResult.Text = recset.GetType().ToString();
}

De NullReferenceException komt op de regel waar ik recset.State opvraag. In mijn debugger kan ik zien dat recset een ADODB.Recordset is en als ik de properties daar lees zie ik ook dat State 0 is zoals verwacht aangezien de recordset nooit geopend is.

Het vreemde is dat dit allemaal wel goed gaat als in de FOX dll bij de functie defenitie "as ADODB.RecordSet" ( regel 2 ) weg gelaten wordt.

Als deze definitie er wel is dan hoef ik op regel 2 van mijn C# code eigenlijk niet te casten naar een ADODB.RecordSet omdat deze al in de definitie zit. Als ik dit dan ook niet doe krijg ik geen NullReferenceException maar een ExecutionEngineException. Ik deze Exception dus opzoeken in de documentatie en daar staat heel leuk bij Remarks "Execution engine errors are fatal errors that should never occur.".

Daar werdt ik dus ook niet echt wijzer van. Ik dacht dat het mischien een fout in de FOX compiler is. Dus ik heb deze functionaliteit ook even na laten maken in een VB6 Com dll. Hierbij is het resultaat precies hetzelfde.

Heeft er mischien nog iemand een idee hoe het komt dat dit fout gaat een hoe het op te lossen is? ( Dan bedoel ik dus zonder die "as ADODB.RecordSet" weg te halen. )

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
Topicstarter
Kick....

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
Topicstarter
Echt niemand die een idee heeft, of mischien iets waar ik verder mee kan zoeken. Ik kom er nu echt niet meer verder mee.

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”

Pagina: 1