I've been working on a script for using the .NET Framework from within AutoHotkey. I haven't yet implemented (direct) method invocation, etc., but I have managed to run an executable (written in C#) inside the AutoHotkey.exe process :lol: (see script below.)
What I'd like to know before I continue (the reason I'm posting) is:
What .NET capabilities would people be interested in?
(Specific components or general interop features.)
I started this project with no particular goal. :roll: Now I'm asking for requests of general features or simple demonstration scripts. For instance, I know there are many useful .NET components out there, especially Controls (i.e. for GUIs.) If there are any specific components/controls you want to see in AutoHotkey, let me know.
#NoEnv
; Load .NET and get ICorRuntimeHost interface.
hr:=CLR_CorBind(pCorRuntimeHost)
if (hr != 0) {
MsgBox CLR_CorBind error %hr%.
ExitApp
}
; Start the .NET common language runtime.
hr:=CLR_CorStart(pCorRuntimeHost)
if (hr != 0) {
MsgBox CLR_CorStart error %hr%.
ExitApp
}
CLR_GetVersion(sVer)
MsgBox % "Loaded .NET Framework " sVer
hr:=CLR_CorGetDefaultDomain(pCorRuntimeHost, pAppDomain)
if (hr != 0) {
MsgBox CLR_CorGetDefaultDomain error %hr%.
ExitApp
}
; Since the entry point for an application does not return until the application
; exits, neither does CLR_ExecuteAssembly() when sAssemblyFile is an application...
CLR_ExecuteAssembly(pAppDomain, "Z:\AppRunTimer.exe")
; ListVars
; Pause
; Process, Exist
; RunWait, %comspec% /k tasklist /FI "PID eq %ErrorLevel%" /M
; Load the common language runtime (CLR) into the current process.
; Returns an interface pointer of type ICorRuntimeHost.
CLR_CorBind(ByRef pCorRuntimeHost)
{
return DllCall("MSCorEE\CorBindToRuntime"
,"uint", 0 ; pwszVersion: use latest
,"uint", 0 ; pwszBuildFlavor: default (workstation)
,"uint", COM_GUID4String(clsid,"{CB2F6723-AB3A-11d2-9C40-00C04FA30A3E}") ; CLSID_CorRuntimeHost
,"uint", COM_GUID4String(iid,"{CB2F6722-AB3A-11d2-9C40-00C04FA30A3E}") ; IID_ICorRuntimeHost
,"uint*", pCorRuntimeHost)
}
CLR_GetVersion(ByRef sVer)
{
VarSetCapacity(wsVer,40)
hr:=DllCall("MSCorEE\GetCORVersion","uint",&wsVer,"uint",20,"uint*",0)
sVer := COM_Ansi4Unicode(&wsVer)
return hr
}
;
; ICorRuntimeHost Methods
;
CLR_CorStart(pCorRuntimeHost)
{ ; ICorRuntimeHost.Start()
return DllCall(NumGet(NumGet(pCorRuntimeHost+0)+40),"uint",pCorRuntimeHost)
}
; Gets an interface pointer of type _AppDomain that represents the default domain for the current process.
CLR_CorGetDefaultDomain(pCorRuntimeHost, ByRef pAppDomain)
{ ; ICorRuntimeHost.GetDefaultDomain()
hr:=DllCall(NumGet(NumGet(pCorRuntimeHost+0)+52),"uint",pCorRuntimeHost,"uint*",pUnk)
if (hr = 0) {
pAppDomain:=COM_QueryInterface(pUnk,"{05F696DC-2B29-3663-AD8B-C4389CF2A713}")
COM_Release(pUnk)
if !pAppDomain
hr := 0x80004002+0 ; E_NOINTERFACE
}
return hr
}
;
; _AppDomain Methods
;
CLR_ExecuteAssembly(pAppDomain, sAssemblyFile, ByRef Ret="")
{
pFilename:=COM_SysAllocString(sAssemblyFile)
hr:=DllCall(NumGet(NumGet(pAppDomain+0)+204),"uint",pAppDomain,"uint",pFilename,"int*",Ret)
COM_SysFreeString(pFilename)
return hr
}Requires COM.ahk. Tested on Vista (.NET v2.0.50727) and XP (.NET v1.1.4322). Obviously, for the example to work you'd need to replace "Z:\AppRunTimer.exe" with the path of a .NET executable.(advanced:)
Note that MSDN suggests that the ICorRuntimeHost interface shouldn't be used with the .NET Framework 2.0, but it seems to work fine for me (on Vista, apparently .NET v2.0.50727.) Since the alternative is to not support the .NET Framework 1.0 and 1.1, I'll continue to use ICorRuntimeHost until I encounter problems.
The hosting interfaces that are supported for the CLR in the .NET Framework versions 1.0 and 1.1 are not supported in later versions of the .NET Framework. Mixing and matching these interfaces could cause unexpected behavior.





