Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

.NET Framework Interop


  • Please log in to reply
155 replies to this topic
IsNull
  • Moderators
  • 990 posts
  • Last active: May 15 2014 11:56 AM
  • Joined: 10 May 2007

IronAhk_L

haha, you want a mod of a Tool, which is not even released. funny people here :D

infogulch
  • Moderators
  • 717 posts
  • Last active: Jul 31 2014 08:27 PM
  • Joined: 27 Mar 2008

haha, you want a mod of a Tool, which is not even released. funny people here :D

no that would be a mod of a rewrite of a tool.

xD

wtg
  • Members
  • 251 posts
  • Last active: Dec 19 2012 03:54 PM
  • Joined: 04 Oct 2006
I'm trying to use CLR for the first time, converting a PowerShell script I have to AHK, but I can't quite figure out how to load the Oracle assembly.

In PowerShell, I use the following
[Reflection.Assembly]::LoadWithPartialName("Oracle.DataAccess") 
$db = New-Object Oracle.DataAccess.Client.OracleConnection( "Data Source=DB;User Id=TEST;Password=TEST" ) 
$db.Open()  
...

I assumed the equivalent using CLR would be this:
OraLib := CLR_LoadLibrary( "Oracle.DataAccess" )
DB := CLR_CreateObject( OraLib, "Oracle.DataAccess.Client.OracleConnection", 8, "Data Source=DB;User Id=TEST;Password=TEST") 
DB.Open()
...

Unfortunately, CLR_LoadLibrary() appears to fail as OraLib ends up empty and I receive a "No COM dispatch object" error. I'm obviously missing something. Any thoughts?

Edit: I'm using AHK_L/COM_L/CLR_L

Lexikos
  • Administrators
  • 9844 posts
  • AutoHotkey Foundation
  • Last active:
  • Joined: 17 Oct 2006

Unfortunately, CLR_LoadLibrary() appears to fail as OraLib ends up empty

How did you determine it is empty?
x := Object()
MsgBox % x  ; Objects *appear* empty.
MsgBox % x ? "true" : "false"
MsgBox % IsObject(x) ? "object" : "no object"

and I receive a "No COM dispatch object" error.

Try removing the '8' parameter, which shouldn't be there. If you need to specify the type of the parameter, use COM_Parameter() to wrap the type and value.

wtg
  • Members
  • 251 posts
  • Last active: Dec 19 2012 03:54 PM
  • Joined: 04 Oct 2006

Unfortunately, CLR_LoadLibrary() appears to fail as OraLib ends up empty

How did you determine it is empty?

Very poorly apparently. :) I had noticed when I inspected the contents via MsgBox % Lib in some of the sample code in the thread that an integer was displayed, so when the same showed nothing in my code, I assumed it was empty. However, MsgBox % IsObject(OraLib) ? "object" : "no object" indeed indicates that I have an object. In fact, MsgBox % OraLib.ToString() actually displays the version and other info.

Try removing the '8' parameter, which shouldn't be there. If you need to specify the type of the parameter, use COM_Parameter() to wrap the type and value.

Wow, I guess I'm completely misunderstanding something since I thought the docs in the OP indicate I need to pass the VT_ value of the passed arg. When I remove the 8 and simply execute:
DB := CLR_CreateObject( OraLib, "Oracle.DataAccess.Client.OracleConnection", "Data Source=DB;User Id=TEST;Password=TEST")
... I receive the following error.

COM Error Notification
Function Name: "CreateInstance_3"
ERROR: (0x80131509)
ERROR2: Member not found.
(0x80020003)

When I pass the 8, I get:
COM Error Notification
Function Name: "CreateInstance_3"
ERROR: (0x80131513)
PROG: mscorlib
DESC: Constructor on type 'Oracle.DataAccess.Client.OracleConnection' not found.
HELP: ,0
ERROR2: Member not found.
(0x80020003)

Any other suggestions?

sinkfaze
  • Moderators
  • 6367 posts
  • Last active: Nov 30 2018 08:50 PM
  • Joined: 18 Mar 2008

Wow, I guess I'm completely misunderstanding something since I thought the docs in the OP indicate I need to pass the VT_ value of the passed arg.


I don't know this library from Adam but I don't think you're misunderstanding the instructions so much as the method. In vanilla AHK/COM you pass the VT_* value directly as a function parameter paired with its argument, but with AHK_L/COM_L you wrap the value with its accompanying argument using COM_Parameter() and pass it in a single parameter (untested):

DB := CLR_CreateObject( OraLib, "Oracle.DataAccess.Client.OracleConnection", [color=red]COM_Parameter(8,"Data Source=DB;User Id=TEST;Password=TEST")[/color])


wtg
  • Members
  • 251 posts
  • Last active: Dec 19 2012 03:54 PM
  • Joined: 04 Oct 2006
Thanks sinkfaze.

Just for giggles I tried tested using COM_Parameter() and as you'd expect, I get the same error that I get by simply passing the connect string.

I'm hoping there's just something silly I'm overlooking, especially since I know there are other people that would find using Oracle's .NET drivers in AHK useful.

Lexikos
  • Administrators
  • 9844 posts
  • AutoHotkey Foundation
  • Last active:
  • Joined: 17 Oct 2006

COM Error Notification
Function Name: "CreateInstance_3"
ERROR: (0x80131509)

0x80131509 is InvalidOperationException. CreateInstance is not documented to throw that Exception, so maybe it's thrown by the OracleConnection constructor? I don't know why that would be if your original code works.

When I pass the 8, I get:
COM Error Notification
Function Name: "CreateInstance_3"
ERROR: (0x80131513)
PROG: mscorlib
DESC: Constructor on type 'Oracle.DataAccess.Client.OracleConnection' not found.

I presume this is because no constructor exists with that combination of parameter types.

ERROR2: Member not found.
(0x80020003)

I think this is the result of COM_Invoke's second attempt, using different flags. I don't think it's relevant.


Can you use the default parameterless constructor and then set the ConnectionString?

wtg
  • Members
  • 251 posts
  • Last active: Dec 19 2012 03:54 PM
  • Joined: 04 Oct 2006
I've tried the parameterless constructor too, with virtually the same error.

On this line:
DB := CLR_CreateObject( OraLib, "Oracle.DataAccess.Client.OracleConnection" ) 
...I get this error:
COM Error Notification
Function Name: "CreateInstance"
ERROR: (0x80131509)
ERROR2: Member not found.
(0x80020003

The PowerShell program I'm trying to translate is just a small program that tests the Oracle connectivity, which works fine as do some much more significant and involved PS scripts that use the Oracle drivers. In it's entirety the PowerShell program is:
# Load Oracle dll required for connecting to the DB.
[Reflection.Assembly]::LoadWithPartialName("Oracle.DataAccess") 

$Connect = "Data Source=DB;User Id=TEST;Password=TEST"
$db = New-Object Oracle.DataAccess.Client.OracleConnection( $Connect ) 
$db.Open()  
   
$query = "select sysdate from dual" 
$c = New-Object Oracle.DataAccess.Client.OracleCommand( $query, $db )
$r = $c.ExecuteReader()    #  returns Oracle.DataAccess.Client.OracleDataReader

$dt = New-Object System.Data.DataTable
if ($r) {
   # We have results, so load them.
   $dt.load( $r )
   $r.Dispose()
   $c.Dispose()
}

if ( $dt.Rows.Count -eq 0  ) {
   write-host "Can't retrieve time"
} else {
   $cur_time = $dt.Rows[0][0]
   write-host "Current time: $cur_time"
} 

$dt.Dispose()
$db.Close()
$db.Dispose()
My goal is to convert an existing AHK app to use the Oracle .NET drivers instead of using the Oracle command line utilities. I imagine there are a lot of other people that would appreciate being able to connect to an Oracle DB directly too. I figured I was just making some kind of bonehead error not being able to get it to work, especially since my COM and .NET experience is very limited. I'm really bummed if you can't figure it out though. :)

Sean
  • Members
  • 2462 posts
  • Last active: Feb 07 2012 04:00 AM
  • Joined: 12 Feb 2007
You have to know first what the error code 0x80131509 means in your application to proceed further. I believe it's your job to figure it out as it's you who has all the resources needed for that. BTW, my mere guess is that your app seems to prevent being called/created via COM. Maybe it also exposes direct COM access through, e.g., ADO etc.

wtg
  • Members
  • 251 posts
  • Last active: Dec 19 2012 03:54 PM
  • Joined: 04 Oct 2006

You have to know first what the error code 0x80131509 means in your application to proceed further.

If by "my application" you mean Oracle's .NET drivers, I can't find any documentation for that particular error code. Perhaps the drivers just aren't usable within AHK and I wrongly assumed that it would be via the CLR functions. You guys know way more than I do about both .NET and COM, I'm sure, as my experience with both is quite limited. I thought this CLR library was essentially giving AHK the same ability to use .NET drivers as PowerShell has, being able to load assemblies and create .NET objects.

I believe it's your job to figure it out as it's you who has all the resources needed for that.

I'd like to think that wasn't meant as rudely as it comes across. I've tried to figure it out on my own and have so far been unable to, and as it's such a few lines of code, I figured I was making either a simple error or misunderstanding of something basic.

BTW, my mere guess is that your app seems to prevent being called/created via COM. Maybe it also exposes direct COM access through, e.g., ADO etc.

Again, I'm not sure what you mean by "my app". I was trying to translate a simply PS script into AHK to establish using the Oracle drivers was possible, and it's essentially two lines of code that I can't get working
oralib := CLR_LoadLibrary( "Oracle.DataAccess" )
DB := CLR_CreateObject( oralib, "Oracle.DataAccess.Client.OracleConnection" ) 
It's so incredibly basic perhaps I should have realized immediately that I was wrong about what the CLR lib makes possible vs posting here and asking for help. But as useful as the Oracle drivers would be to others, I thought it was worth asking.

Sean
  • Members
  • 2462 posts
  • Last active: Feb 07 2012 04:00 AM
  • Joined: 12 Feb 2007
It appears to me that creating .NET object was fine (no error of 0x80131513: COR_E_MISSINGMETHOD), however, some procedure was prohibited (0x80131509: COR_E_INVALIDOPERATION) during wrapping the .NET object into COM object. In this situation I can give you only generic suggestions. You may look for native COM (or other) way to access your DB, or, write C# code and run it through CLR_CompileC#().

hoppfrosch
  • Members
  • 399 posts
  • Last active: Feb 26 2016 05:31 AM
  • Joined: 25 Jan 2006
@Lexikos:

There are some incompatibilities in the versions of COM_L and CLR_L you linked to in your first post:

Current CLR_L calls COM_EnWrap()
Current COM_L does not contain COM_EnWrap() ...

Therefore your given examples do not work with this combination of linked zips ...
Haven't used COM until now - so I don't have an idea how to replace the COM_EnWrap() call ...

Lexikos
  • Administrators
  • 9844 posts
  • AutoHotkey Foundation
  • Last active:
  • Joined: 17 Oct 2006
Firstly, I never linked to COM_L.zip. I linked only to the COM thread, which contains a link to COM_L.zip. I control neither the link nor the file it points to.

Secondly, I just downloaded the current COM_L.zip, and both ANSI\COM.ahk and UNICODE\COM.ahk most definitely contain COM_Enwrap().

hoppfrosch
  • Members
  • 399 posts
  • Last active: Feb 26 2016 05:31 AM
  • Joined: 25 Jan 2006
Sorry for the wrong alarm - it's a bit hot here in Germany (too hot for my taste ...)

It's true that latest COM_L-Unicode COM.ahk contains COM_Enwrap() ...

But there's still an error on my machine running your "FIRST EXAMPLE":

Error in include file ...\lib\CLR.ahk: Call to nonexistent function

Specifically: COM_Enwrap(pAsm):""

...
--> 0049: Return, pAsm ? COM_Enwrap(pAsm):""
...

I have to investigate further - sorry again ...