AutoHotkey Homepage AutoHotkey Community
Let's help each other out
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

.NET Framework Interop
Goto page 1, 2, 3  Next
 
Post new topic   Reply to topic    AutoHotkey Community Forum Index -> Scripts & Functions
View previous topic :: View next topic  
Author Message
Lexikos



Joined: 17 Oct 2006
Posts: 2486
Location: Australia, Qld

PostPosted: Mon Dec 03, 2007 10:21 am    Post subject: .NET Framework Interop Reply with quote

Microsoft Common Language Runtime / .NET Framework Interop

CLR.ahk

Requires: COM Standard Library

Current Features:
  • Load the Common Language Runtime into the current process.
  • Load .NET assemblies (dll files) by full name, partial name, or path.
  • Create and unload AppDomains. (Assemblies can't be unloaded individually, nor can the default AppDomain.)
  • Create objects.
  • Compile C# or VB code on the fly, and interact with it. (EXE and DLL files can also be generated.)
Calling instance (non-static) methods of .NET objects can be done using COM_Invoke() or COM_Invoke_().

Functions

CLR_Start()
    Loads the Common Language Runtime.
CLR_StartDomain( ByRef pAppDomain [, BaseDirectory ] )
    Creates/starts an AppDomain and returns (via ByRef) a pointer that should be passed to CLR_LoadLibrary() to load an assembly into the domain. BaseDirectory defines the base search path used when loading assemblies into the AppDomain.
CLR_StopDomain( pAppDomain )
    Stops the specified AppDomain and attempts to unload any assemblies that were loaded into it. (May not actually unload some system assemblies.)
CLR_Stop()
    Stops the Common Language Runtime. Once stopped, it cannot be reinitialized into the same process.
CLR_LoadLibrary( sLibrary [, pAppDomain ] )
    Loads an assembly, given a full name, partial name or path. If specified, pAppDomain is a pointer to the AppDomain to load the assembly into. Returns a pointer to the Assembly, to be used with CLR_CreateObject.
CLR_CreateObject( pAssembly, sType [, Type1, Arg1, Type2, Arg2 ... ] )
    Creates an object of the specified type from the specified assembly. Optionally accepts a list of arguments and their types to pass to the object's constructor. TypeN is a value from the VARENUM enumeration - i.e. a COM VT_* value. (The actual values can be found in Ks.h of the Windows SDK.)
CLR_CompileC#( Code, References [, pAppDomain, FileName, CompilerOptions ] )
CLR_CompileVB( Code, References [, pAppDomain, FileName, CompilerOptions ] )
    Compile the specified C# or VB code. If FileName is omitted, the assembly is compiled "in-memory" and automatically loaded. DLL and EXE files may be generated. Specify for 'References' a pipe (|) delimited list of assemblies that the code requires. If FileName is omitted, returns a pointer to the compiled Assembly, to be used with CLR_CreateObject; otherwise FileName is returned on success or 0 on failure.
    Additional command-line arguments can be passed to the compiler via CompilerOptions. (For instance, if FileName specifies an .exe file, a console app is generated unless CompilerOptions includes "/target:winexe".)
    Note that once loaded, an Assembly cannot be unloaded other than by stopping/unloading the AppDomain that contains it.

Additional Functions
Not included in CLR.ahk since they generally aren't of use.

CLR_GetVersion( ByRef sVer )
    If the Common Language Runtime is loaded, gets the version in use. Otherwise, gets the latest installed version.
CLR_GetAssemblies( [ pAppDomain ] )
    Gets a `n-delimited list of assemblies loaded into the specified AppDomain (or the default AppDomain if not specified.)
Code:
; Gets either the CLR version in use, or the latest installed version.
CLR_GetVersion(ByRef sVer)
{
    VarSetCapacity(wsVer,40)
    hr:=DllCall("MSCorEE\GetCORVersion","uint",&wsVer,"uint",20,"uint*",0)
    sVer := COM_Ansi4Unicode(&wsVer)
    return hr
}

; Lists the assemblies loaded into an AppDomain.
CLR_GetAssemblies(pAppDomain=0)
{
    pApp := pAppDomain ? pAppDomain : CLR_GetDefaultDomain()
    if !pApp
        return
    if p_App := COM_QueryInterface(pApp,"{05F696DC-2B29-3663-AD8B-C4389CF2A713}")
    {
        DllCall(NumGet(NumGet(p_App+0)+228),"uint",p_App,"uint*",pa_Asm)
        DllCall("oleaut32\SafeArrayGetUBound","uint",pa_Asm,"uint",1,"int*",ubound)
        Loop, % ubound+1
        {
            DllCall("oleaut32\SafeArrayGetElement","uint",pa_Asm,"int*",A_Index-1,"uint*",p_Asm)
            DllCall(NumGet(NumGet(p_Asm+0)+112),"uint",p_Asm,"uint*",psAsm)
            list .= COM_Ansi4Unicode(psAsm) "`n"
            COM_Release(p_Asm), COM_SysFreeString(psAsm)
        }
        DllCall("oleaut32\SafeArrayDestroy","uint",pa_Asm)
    }
    if (pAppDomain != pApp)
        COM_Release(pApp)
    return SubStr(list,1,-1)
}


Last edited by Lexikos on Wed Dec 05, 2007 11:53 am; edited 2 times in total
Back to top
View user's profile Send private message
Lexikos



Joined: 17 Oct 2006
Posts: 2486
Location: Australia, Qld

PostPosted: Mon Dec 03, 2007 10:29 am    Post subject: Reply with quote

First Example
The following is a translation of some sample code accompanying XPTable. The sample code (and XPTable itself) can be found at:
XPTable - .NET ListView meets Java's JTable (@ The Code Project)
Code:
#NoEnv
SetWorkingDir, %A_ScriptDir%

CLR_Start()
pasm := CLR_LoadLibrary("XPTable.dll")

; Type names must be fully qualified.
table       := CLR_CreateObject(pasm,"XPTable.Models.Table")
columnModel := CLR_CreateObject(pasm,"XPTable.Models.ColumnModel")
tableModel  := CLR_CreateObject(pasm,"XPTable.Models.TableModel")

; Prefix "+" to pass objects (IDispatch),
COM_Invoke(table,"ColumnModel=","+" columnModel)
; or use COM_Invoke_ and pass the type explicitly. Generally IUnknown (13)
; and IDispatch (9) are interchangeable, but maybe not for interfaces with
; this attribute: [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
COM_Invoke_(table,"TableModel=",13,tableModel)

Columns := COM_Invoke(columnModel,"Columns")
COM_Invoke_(Columns,"Add", 13,col1:=CLR_CreateObject(pasm,"XPTable.Models.TextColumn",8,"Text"))
COM_Invoke_(Columns,"Add", 13,col2:=CLR_CreateObject(pasm,"XPTable.Models.CheckBoxColumn",8,"CheckBox"))
COM_Invoke_(Columns,"Add", 13,col3:=CLR_CreateObject(pasm,"XPTable.Models.ButtonColumn",8,"Button"))

; Object references must be released explicitly.
COM_Release(col1), COM_Release(col2), COM_Release(col3)
COM_Release(Columns)

Rows := COM_Invoke(tableModel,"Rows")

; The C# code:
;   tableModel.Rows[0]
; is roughly equivalent to:
;   Rows := COM_Invoke(tableModel,"Rows")
;   Rows0 := COM_Invoke(Rows,"Item",0)
;   COM_Release(Rows)
; Since we are creating the Row object, we don't need to use the above.

COM_Invoke_(Rows,"Add"
    , 13,row:=CLR_CreateObject(pasm,"XPTable.Models.Row"))
Cells := COM_Invoke(row,"Cells")
COM_Release(row)
COM_Invoke_(Cells,"Add"
    , 13,cel1:=CLR_CreateObject(pasm,"XPTable.Models.Cell",8,"Text 1"))
COM_Invoke_(Cells,"Add"
    , 13,cel2:=CLR_CreateObject(pasm,"XPTable.Models.Cell",8,"CheckBox 1",11,true))
COM_Invoke_(Cells,"Add"
    , 13,cel3:=CLR_CreateObject(pasm,"XPTable.Models.Cell",8,"Button 1"))
COM_Release(cel1), COM_Release(cel2), COM_Release(cel3)
COM_Release(Cells)

COM_Invoke_(Rows,"Add", 13,row:=CLR_CreateObject(pasm,"XPTable.Models.Row"))
Cells := COM_Invoke(row,"Cells")
COM_Release(row)
COM_Invoke_(Cells,"Add"
    , 13,cel1:=CLR_CreateObject(pasm,"XPTable.Models.Cell",8,"Text 2"))
COM_Invoke_(Cells,"Add"
    , 13,cel2:=CLR_CreateObject(pasm,"XPTable.Models.Cell",8,"CheckBox 2",11,false))
COM_Invoke_(Cells,"Add"
    , 13,cel3:=CLR_CreateObject(pasm,"XPTable.Models.Cell",8,"Button 2"))
COM_Release(cel1), COM_Release(cel2), COM_Release(cel3)
COM_Release(Cells)

COM_Release(Rows)

COM_Release(tableModel), COM_Release(columnModel)

; END CODE BASED ON CODEPROJECT SAMPLE

COM_Invoke(table,"Left=",10)
COM_Invoke(table,"Top=",10)
COM_Invoke(table,"Width=",300)
COM_Invoke(table,"Height=",200)

hwnd := COM_Invoke(table,"Handle")

Gui, +LastFound
DllCall("SetParent","uint",hwnd,"uint",WinExist())
Gui, Show, W320 H220, XPTable

return

GuiClose:
ExitApp

I haven't yet been able to hook events of .NET objects...
Back to top
View user's profile Send private message
majkinetor



Joined: 24 May 2006
Posts: 3615
Location: Belgrade

PostPosted: Mon Dec 03, 2007 11:56 am    Post subject: Reply with quote

Thx m8, this is really kewl. Will check it out in a second.

Didn't know about XPTable, but its sure valuable thing to have.

Talking about .Net, I developed IPC module for C# (with exactly same API and usage as AHK version) so if ppl are interested I can upload it. With it, u can talk C# <-> AHK and C# <-> C#
_________________
Back to top
View user's profile Send private message MSN Messenger
Lexikos



Joined: 17 Oct 2006
Posts: 2486
Location: Australia, Qld

PostPosted: Mon Dec 03, 2007 12:30 pm    Post subject: Reply with quote

Heh, you thought that was cool. Now I've added on-the-fly compiling of C# and VB code. Cool

Second Example
Code:
c# =
(
    using System.Windows.Forms;
    class Foo {
        public void Test() {
            MessageBox.Show("Hello, world, from C#!");
        }
    }
)
vb =
(
    Imports System.Windows.Forms
    Class Foo
        Public Sub Test()
            MessageBox.Show("Hello, world, from VB!")
        End Sub
    End Class
)

CLR_Start()

asm := CLR_CompileC#(c#, "System.dll | System.Windows.Forms.dll")
obj := CLR_CreateObject(asm, "Foo")
COM_Invoke(obj, "Test")
COM_Release(obj)
; Note: This doesn't unload the Assembly itself, just frees the Assembly object.
COM_Release(asm)

asm := CLR_CompileVB(vb, "System.dll | System.Windows.Forms.dll")
obj := CLR_CreateObject(asm, "Foo")
COM_Invoke(obj, "Test")
COM_Release(obj), COM_Release(asm)
Back to top
View user's profile Send private message
majkinetor



Joined: 24 May 2006
Posts: 3615
Location: Belgrade

PostPosted: Mon Dec 03, 2007 2:13 pm    Post subject: Reply with quote

OMG!

Currently it issues this message.

---------------------------
1.ahk
---------------------------
Error at line 1 in #include file "c:\Utils\AutoHotkey\Lib\CLR.ahk".

Line Text: CLR_Start()
Error: Duplicate function definition.

The program will exit.
---------------------------
OK
---------------------------
_________________
Back to top
View user's profile Send private message MSN Messenger
Lexikos



Joined: 17 Oct 2006
Posts: 2486
Location: Australia, Qld

PostPosted: Mon Dec 03, 2007 3:58 pm    Post subject: Reply with quote

Laughing You didn't update CLR.ahk, did you? I added CLR_CompileC#(), CLR_CompileVB() and CLR_CompileAssembly() after you posted.

(CompileAssembly() potentially supports other languages, like JScript and managed C++.)
Back to top
View user's profile Send private message
Andreone



Joined: 20 Jul 2007
Posts: 257
Location: Paris, France

PostPosted: Mon Dec 03, 2007 6:47 pm    Post subject: Reply with quote

Some more informations about XPtable: it is now an open-source project hosted on sourceforge.net XPTable - advanced data grid (lastest version is 1.1.7 - 08/03/07).

For those who have interest with XPtable, I recently found out another great c# control hosted on sourceforge: ZedGraph:
Quote:
ZedGraph is a class library, user control, and web control for .net, written in C#, for drawing 2D Line, Bar, and Pie Charts. It features full, detailed customization capabilities, but most options have defaults for ease of use.
A stand-alone demo is available and it deserves to be checked out. Smile

And last but not least, thank you lexikos for sharing your work. Very Happy
Back to top
View user's profile Send private message
majkinetor



Joined: 24 May 2006
Posts: 3615
Location: Belgrade

PostPosted: Tue Dec 04, 2007 12:15 am    Post subject: Reply with quote

Quote:
You didn't update CLR.ahk, did you?

Yes I did.... must be some cache bug with Opera. I was alrady experiencing it from time to time... I mean, I know that kind of error.

2Andreone
Thx for info
_________________
Back to top
View user's profile Send private message MSN Messenger
AHKnow*
Guest





PostPosted: Tue Dec 04, 2007 6:51 am    Post subject: Reply with quote

Hahahaha.... I knew you smart guys would be doing something like this, sooner or later. Another dream comes true C# and AHK working hand and hand.

Here is another thought.... Why can't AutoHotkey make ActiveX DLLs??? With this code or variation of it, using C#/.NET, you can. So why not advance the concept more?

Hmmmm... Maybe we could discuss thing in Chat.

Great work lexikos and company.
Back to top
majkinetor



Joined: 24 May 2006
Posts: 3615
Location: Belgrade

PostPosted: Tue Dec 04, 2007 9:25 am    Post subject: Reply with quote

Yes, sounds like idea Exclamation

The bad thing is u are connected with dotNet framework and many ppl don't like to have it in the system, but I guess that will become very rare in the future.
_________________
Back to top
View user's profile Send private message MSN Messenger
Lexikos



Joined: 17 Oct 2006
Posts: 2486
Location: Australia, Qld

PostPosted: Tue Dec 04, 2007 10:15 am    Post subject: Reply with quote

AHKnow* wrote:
Here is another thought.... Why can't AutoHotkey make ActiveX DLLs??? With this code or variation of it, using C#/.NET, you can. So why not advance the concept more?
You could generate a DLL (from C# or VB source, not .ahk) which other applications may load, but you would not be able to load the AutoHotkey script itself into another application (i.e. via the DLL). It is literally just another .NET DLL, with no relation to AutoHotkey.

However, Sean recently demonstrated that it is possible to write a local (i.e. EXE) COM Server in AutoHotkey. (Follow the link and look for "AutoHotkeyVerb.zip".)

Anyway...
Handling Events
Code:
c# =
(
    using System;
    using System.Runtime.InteropServices;
   
    class ObjectWithEvent {
        public void RaiseEvent() {
            if (OnEvent != null)
                OnEvent(this, EventArgs.Empty);
        }
        public event EventHandler OnEvent;
       
        public Delegate Delegate4FuncPtr(uint ptr, Type t) {
            return Marshal.GetDelegateForFunctionPointer((IntPtr)ptr, t);
        }
    }
)

CLR_Start()

asm := CLR_CompileC#(c#, "System.dll")
obj := CLR_CreateObject(asm, "ObjectWithEvent")

asmCor := CLR_LoadLibrary("mscorlib")
; Get typeof(System.EventHandler)
tEH := COM_Invoke(asmCor, "GetType_2", "System.EventHandler")
; Create a .NET Delegate for the EventHandler() callback.
pEH := COM_Invoke(obj, "Delegate4FuncPtr", RegisterCallback("EventHandler"), "+" tEH)
; Register the event handler. (Events export add_event() and remove_event()).
COM_Invoke_(obj, "add_OnEvent", 13,pEH)
; Call the C# method which raises the event.
COM_Invoke(obj, "RaiseEvent")

; (Cleanup code omitted.)

ListVars
Pause

EventHandler(vt, junk1, sender, junk2, eventArgs)
{
    MsgBox, 0, Event Raised, % "sender: " COM_Invoke(sender,"ToString")
        . "`neventArgs: " COM_Invoke(eventArgs,"ToString")
}

Events raised by .NET objects cannot be handled by unmanaged code "directly." Instead, the unmanaged callback must be wrapped in a .NET Delegate. Fortunately, the .NET Framework 2.0 provides GetDelegateForFunctionPointer(). (Since it is not an instance method, it is much easier to call from C# than from AutoHotkey.)

You may notice that Delegate4FuncPtr() accepts a uint, but casts it to IntPtr. It seems that IntPtr is marshalled into VT_INT (22), but since VT_INT is marshalled into System.Int32, Invoke will always fail. (It would, however, be possible to call the function directly via the exported COM interface.)

Parameters of type System.Object, unless otherwise specified by [MarshalAsAttribute], are marshalled as VARIANT. This means that for every Object parameter in .NET code, 16 bytes are pushed onto the stack, which equals 4 parameters for the AHK callback. The low-word of the first parameter (vt) defines the COM VARTYPE of the variant. For most managed types, this should be 13 (VT_UNKNOWN.) If VT_UNKNOWN, the third parameter is a pointer to the IUnknown interface of the object (which can generally be COM_Invoke'd.)

Parameters of more specific reference types (such as System.EventArgs) are marshalled as a pointer to the relevant exported COM interface - i.e. 4 bytes = 1 parameter. (Usually this is an automatically-generated interface which can be COM_Invoke'd.)
Back to top
View user's profile Send private message
majkinetor



Joined: 24 May 2006
Posts: 3615
Location: Belgrade

PostPosted: Tue Dec 04, 2007 12:01 pm    Post subject: Reply with quote

Quote:
You could generate a DLL (from C# or VB source, not .ahk) which other applications may load, but you would not be able to load the AutoHotkey script itself into another application (i.e. via the DLL). It is literally just another .NET DLL, with no relation to AutoHotkey.

Well, thats not quite true. There are workarounds.

First, you can communicate with AHK script using IPC module. I have IPC C# part which can be used in DLL for communication. Then, u can create an AHK function that creates dll, and executes adequate AHK functions and receive results via IPC or some other message mechanism. This is similar to what JDN has done in its ASM dlls.

Ofcourse, the good side is that you can tweak DLL code from AHK, using C# language and add other kind of logic, even some more communication with AHK if needed etc...

I am posting you now C# IPC part, so you can try if you want. The usage is exactly the same as with AHK.

IPC.cs
Code:
// IPC module C# side
// by majkinetor
using System;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace MM_IPC
{
   /// <summary>
   /// Implementation of process communication via WM_COPYDATA
   /// </summary>
   public class IPC : NativeWindow
   {
      /// <summary> Delegate for IPC.OnMessage event. </summary>
      ///   <param name="message">Message that was received</param>
      ///   <param name="port">Port that received the message</param>
      public delegate void MessageAction(string message, int port);
   
      /// <summary>Event fired when message arrives</summary>
      public event MessageAction OnMessage;

      #region Private fields
      IntPtr       id = new IntPtr(951753);
      const int    WM_COPYDATA = 74;
      string       strData;
                          
      [StructLayout(LayoutKind.Sequential)]
         struct COPYDATASTRUCT
      {
         public int dwData;
         public int cbData;
         public int lpData;
      }
         
      COPYDATASTRUCT CD;
      #endregion

      #region Win32 imports
      [DllImport("user32.dll", SetLastError = true)]
      private static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
      
      [DllImport("user32.dll",CharSet=CharSet.Ansi)]
      private static extern int SendMessage(IntPtr hWnd, int wMsg, IntPtr wParam, ref COPYDATASTRUCT lParam);   
      #endregion
      
      ///<summary> Creates IPC object. </summary>
      ///<param name="host">Form object that will monitor and accept communication with other process</param>
      public IPC(Form host)
      {
         this.AssignHandle(host.Handle);
      }

      
      ///<summary> Find window by title </summary>
      ///<param name="WinTitle">Window title, case insensitive</param>
      public static IntPtr WinExist( string WinTitle )
      {
         return FindWindow(null, WinTitle);
      }
      
      ///<summary>Send the message to another process (receiver) using WM_COPYDATA.</summary>
      ///<param name="hHost">Handle of the receiver</param>
      ///<param name="msg">Message to be sent</param>
      ///<param name="port">Port on which to send the message</param>
      public bool Send(IntPtr hHost, string msg, int port)
      {
         COPYDATASTRUCT cd = new COPYDATASTRUCT();
         cd.dwData = port;
         cd.cbData = msg.Length+1;
         cd.lpData = Marshal.StringToHGlobalAnsi(msg).ToInt32();
         
         //IntPtr pcd = Marshal.AllocCoTaskMem(Marshal.SizeOf(cd));   // Alocate memory
         //Marshal.StructureToPtr(cd, pcd, true);               // Converting structure to IntPtr
         int i = SendMessage(hHost, WM_COPYDATA, id, ref cd);   
         return i==1 ? true : false;
      }

      protected override void WndProc(ref Message m)
      {
         if((m.Msg==WM_COPYDATA) && (m.WParam == id))
         {
            CD = (COPYDATASTRUCT)m.GetLParam(typeof(COPYDATASTRUCT));
            strData = Marshal.PtrToStringAnsi(new IntPtr(CD.lpData), CD.cbData);
                                    
            if (OnMessage != null)
               OnMessage( strData, CD.dwData );

            return;
         }
         
         base.WndProc(ref m);
      }
   }
}


To use this in any C# app, you just add Using IPC.cs in the C# cod header. This is the simple test:

Code:
      private void btnSend_Click(object sender, System.EventArgs e)
      {
         IntPtr hHost = IPC.WinExist("Client");
         if (!ipc.Send( hHost, "message", "101")  ///send message on port 101
            MessageBox.Show("Sending failed");
      }


This is the test app:
http://www.autohotkey.net/~majkinetor/IPC/IPCTest.rar

You can try AHk <-> C# communication with samples on IPC page:
http://www.autohotkey.com/forum/topic21699.html
_________________
Back to top
View user's profile Send private message MSN Messenger
Lexikos



Joined: 17 Oct 2006
Posts: 2486
Location: Australia, Qld

PostPosted: Tue Dec 04, 2007 1:34 pm    Post subject: Reply with quote

majkinetor wrote:
Quote:
You could generate a DLL (from C# or VB source, not .ahk) which other applications may load, but you would not be able to load the AutoHotkey script itself into another application (i.e. via the DLL). It is literally just another .NET DLL, with no relation to AutoHotkey.

Well, thats not quite true. There are workarounds.
Your workarounds involve starting a separate instance of AutoHotkey. What I said is perfectly accurate, but what I really meant to say about AHKnow's post...
AHKnow* wrote:
With this code or variation of it, using C#/.NET, you can. So why not advance the concept more?
...was: what does this have to do with AutoHotkey or this script?

If your goal is to generate a .NET DLL for use in some process other than AutoHotkey, you don't even need my script. Given that the so-called "in-memory compiling" actually creates a number of temporary files in %A_Temp% (including a .cs and a .dll), it would probably be just as efficient to simply run the C# compiler (csc.exe), which I think is included with all .NET Framework installs.

Do you actually have a use for generating .NET DLLs? If so, I'd like to know what that is...

In any case, to generate a DLL I think all you need to do is remove this line:
Code:
COM_Invoke(compilerParms, "GenerateInMemory=", true)

and set the OutputAssembly property to the file name to generate. Also, you should be able to generate .exe files by setting GenerateExecutable to true.
Back to top
View user's profile Send private message
majkinetor



Joined: 24 May 2006
Posts: 3615
Location: Belgrade

PostPosted: Tue Dec 04, 2007 3:30 pm    Post subject: Reply with quote

Quote:
Your workarounds involve starting a separate instance of AutoHotkey
I don't think so, but I don't want to argue.

Quote:
Do you actually have a use for generating .NET DLLs?

Well, it can be there just for the sake of compliteness then Smile, especialy if there isn't much to be done about it, like you already noted Smile
_________________


Last edited by majkinetor on Tue Dec 04, 2007 3:31 pm; edited 1 time in total
Back to top
View user's profile Send private message MSN Messenger
AHKnow



Joined: 03 Jul 2004
Posts: 118

PostPosted: Tue Dec 04, 2007 3:30 pm    Post subject: Reply with quote

My suggestion was meant along the lines of doing something "funky" like what majkinetor was suggesting.

A .NET DLL is a .NET DLL.

I meant having a compiled AHK.exe make use of functions from another compiled AHK.exe, have an AHK script compile a .NET DLL "on the fly" and in response to a variable and then communicate with it to carry out various tasks, or have an AHK script create and make use of an AcitveX DLL or something funky that is close to it.

By the way, I'm just spewing out some stuff. Lexikos, reflect on it at your leisure. I think what you are doing here is great.
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    AutoHotkey Community Forum Index -> Scripts & Functions All times are GMT
Goto page 1, 2, 3  Next
Page 1 of 3

 
Jump to:  
You can post new topics in this forum
You can reply to topics in this forum


Powered by phpBB © 2001, 2005 phpBB Group