转载或依赖请标注Mono等字样
C#与AHK混合编程的可能性还是有的,至少大部分代码挂载在C#环境下运行效率会高的多。
具体用法:注意cs类的ahk_flag属性默认为true,代表下标索引从1开始,若为false,则为0。
ArrayList
创建 --- list := cs.ArrayList()
函数:
添加元素 --- list.add(obj)
添加ArrayList --- list.addRange(arrayList)
清空元素 --- list.clear()
包含元素 --- list.contains(obj)
获取范围内元素 --- list.getRange(index, length)
获取指定元素返回的第一索引 --- list.indexOf(obj)
插入元素 --- list.insert(index, obj)
插入ArrayList --- list.insertRange(index, arrayList)
删除元素 --- list.remove(obj)
删除某位置元素 -- list.removeAt(index)
删除范围内元素 --- list.removeRange(index, length)
反转 --- list.reverse()
设置从某一索引起被ArrayList覆盖 --- list.setRange(index, arrayList)
排序 --- list.sort()
转为ahk的array --- list.toArray()
数组将长度和容量对齐 --- list.trimToSize()
属性:
返回长度(只读) --- count/length
返回容量,或设置更大容量 --- capacity
支持索引直接获取、修改值 --- list[exist_index] := value
BitArray
创建 --- list := cs.BitArray(number)
函数:
进行与运算 --- list.and(bitArray)
获取从后往前数某一位的布尔值 --- list.get(index)
进行非运算 --- list.not()
进行或运算 --- list.or(bitArray)
设置从后往前数某一位的布尔值 --- list.set(index, value)
设置所有的布尔值 --- list.setAll(value)
类型转换 --- list.toArray()\toArrayList()\toInt()\toString()
进行亦或运算 --- list.xor(bitArray)
属性:
返回长度(只读) --- count
返回长度,或设置长度 --- length
支持索引直接获取、修改值 --- list[exist_index] := value
Func(自定义类)
创建 --- myfunc := cs.Func()
函数:
执行JS代码 --- myfunc.eval(script)
Hashtable
创建 --- table := cs.Hashtable()
函数:
添加键值对 --- table.add(key, value)
清空键值对 --- table.clear()
包含键 --- table.containsKey(key)
包含值 --- table.containsValue(value)
删除键值对 --- table.remove(key)
属性:
返回长度(只读) --- count/length
返回包含键的ArrayList --- keys
返回包含值的ArrayList --- values
支持键直接获取、修改值 --- table[key] := value
Queue
创建 --- queue := cs.Queue()
函数:
清空队列 --- queue.clear()
包含值 --- queue.contains(obj)
出队列 --- queue.dequeue()
入队列 --- queue.enqueue(obj)
转换类型 --- queue.toArray()\toArrayList()
属性:
返回长度(只读) --- count/length
Stack
创建 --- stack := cs.Stack()
函数:
清空栈 --- stack.clear()
包含值 --- stack.contains(obj)
获取栈顶 --- stack.peek()
出栈 --- stack.pop()
入栈 --- stack.push(obj)
转换类型 --- stack.toArray()\toArrayList()
属性:
返回长度(只读) --- count/length
StringBuilder
创建 --- builder := cs.StringBuilder(string := "")
函数:
向构造器尾部加入字符串 --- builder.append(string, looptimes := 1)
向构造器尾部加入C#格式化字符串 --- builder.appendFormat(string, looptimes := 1, format*)
获取构造器某一位置字符 --- builder.charAt(index) ; 这里返回的是Unicode值
向构造器插入字符串 --- builder.insert(index, string, looptimes := 1)
移除构造器从start开始的length长度 --- builder.remove(start, length, looptimes := 1)
替换构造器指定字符串 --- builder.replace(haystack, needle := "", looptimes := 1)
转换类型 --- builder.toString()
属性:
返回长度(只读)--- count
返回长度或设置长度 --- length
支持直接获取、修改字符 --- builder[exist_index] := value
源码
; Author: Mono Even
; Time: 2023.02.06
class cs
{
static ahk_flag := true
static code := "
(
using System;
using System.Collections;
using System.Text;
using System.Threading;
using System.Runtime.InteropServices;
using Microsoft.JScript;
using Microsoft.JScript.Vsa;
class CS_ArrayList
{
public ArrayList Init()
{
return new ArrayList();
}
public void Add(ArrayList array, params Object[] param)
{
foreach (Object i in param)
array.Add(i);
}
public void AddRange(ArrayList array, params ArrayList[] param)
{
foreach (ArrayList i in param)
array.AddRange(i);
}
public bool Contains(ArrayList array, Object item)
{
return array.Contains(item);
}
public ArrayList GetRange(ArrayList array, int index, int count)
{
return array.GetRange(index, count);
}
public int IndexOf(ArrayList array, Object item)
{
return array.IndexOf(item);
}
public void Insert(ArrayList array, int index, Object item)
{
array.Insert(index, item);
}
public void InsertRange(ArrayList array, int index, ArrayList item)
{
array.InsertRange(index, item);
}
public void Remove(ArrayList array, Object item)
{
array.Remove(item);
}
public void RemoveAt(ArrayList array, int index)
{
array.RemoveAt(index);
}
public void RemoveRange(ArrayList array, int index, int count)
{
array.RemoveRange(index, count);
}
public void SetRange(ArrayList array, int index, ArrayList item)
{
array.SetRange(index, item);
}
}
class CS_BitArray
{
public BitArray Init(int number)
{
byte[] tmp = BitConverter.GetBytes(number);
return new BitArray(tmp);
}
public BitArray And(BitArray source, BitArray target)
{
return source.And(target);
}
public bool Get(BitArray source, int index)
{
return source.Get(index);
}
public BitArray Or(BitArray source, BitArray target)
{
return source.Or(target);
}
public void Set(BitArray source, int index, bool value)
{
source.Set(index, value);
}
public void SetAll(BitArray source, bool value)
{
source.SetAll(value);
}
public ArrayList ToArrayList(BitArray source)
{
ArrayList array = new ArrayList();
array.AddRange(source);
return array;
}
public bool[] ToArray(BitArray source)
{
bool[] tmp = new bool[source.Length];
source.CopyTo(tmp, 0);
return tmp;
}
public int ToInt(BitArray source)
{
int res = 0;
for (int i = source.Count - 1; i >= 0; i--)
res = source[i] ? res + (1 << i) : res;
return res;
}
public string ToStr(BitArray source)
{
StringBuilder res = new StringBuilder();
for (int i = source.Count - 1; i >= 0; i--)
res.Append(source[i] ? 1 : 0);
return res.ToString();
}
public BitArray Xor(BitArray source, BitArray target)
{
return source.Xor(target);
}
}
class CS_Hashtable
{
public Hashtable Init()
{
return new Hashtable();
}
public void Add(Hashtable table, Object key, Object value)
{
table.Add(key, value);
}
public bool ContainsKey(Hashtable table, Object key)
{
return table.ContainsKey(key);
}
public bool ContainsValue(Hashtable table, Object value)
{
return table.ContainsValue(value);
}
public ArrayList Keys(Hashtable table)
{
ArrayList array = new ArrayList();
array.AddRange(table.Keys);
return array;
}
public ArrayList Values(Hashtable table)
{
ArrayList array = new ArrayList();
array.AddRange(table.Values);
return array;
}
public void Remove(Hashtable table, Object key)
{
table.Remove(key);
}
}
class CS_Queue
{
public Queue Init()
{
return new Queue();
}
public bool Contains(Queue queue, Object obj)
{
return queue.Contains(obj);
}
public void Enqueue(Queue queue, Object obj)
{
queue.Enqueue(obj);
}
public ArrayList ToArrayList(Queue queue)
{
ArrayList array = new ArrayList();
array.AddRange(queue);
return array;
}
}
class CS_Stack
{
public Stack Init()
{
return new Stack();
}
public bool Contains(Stack stack, Object obj)
{
return stack.Contains(obj);
}
public void Push(Stack stack, Object obj)
{
stack.Push(obj);
}
public ArrayList ToArrayList(Stack stack)
{
ArrayList array = new ArrayList();
array.AddRange(stack);
return array;
}
}
class CS_StringBuilder
{
public StringBuilder Init(string source)
{
StringBuilder builder = new StringBuilder(source);
return builder;
}
public void Append(StringBuilder builder, string source, int looptimes)
{
for (int i = 0; i < looptimes; i++)
builder.Append(source);
}
public void AppendStringBuilder(StringBuilder builder, StringBuilder source, int looptimes)
{
for (int i = 0; i < looptimes; i++)
builder.Append(source);
}
public void AppendFormat(StringBuilder builder, string source, int looptimes, params Object[] format)
{
for (int i = 0; i < looptimes; i++)
builder.AppendFormat(source, format);
}
public void AppendStringBuilderFormat(StringBuilder builder, StringBuilder source, int looptimes, params Object[] format)
{
string tmp_source = source.ToString();
for (int i = 0; i < looptimes; i++)
builder.AppendFormat(tmp_source, format);
}
public void Insert(StringBuilder builder, string source, int pos, int looptimes)
{
for (int i = 0; i < looptimes; i++)
builder.Insert(pos, source);
}
public void InsertStringBuilder(StringBuilder builder, StringBuilder source, int pos, int looptimes)
{
string tmp_source = source.ToString();
for (int i = 0; i < looptimes; i++)
builder.Insert(pos, tmp_source);
}
public void Remove(StringBuilder builder, int start, int length, int looptimes)
{
for (int i = 0; i < looptimes; i++)
builder.Remove(start, length);
}
public void Replace(StringBuilder builder, string haystack, string needle, int looptimes)
{
for (int i = 0; i < looptimes; i++)
builder.Replace(haystack, needle);
}
}
class CS_Thread
{
public Thread Start(int fn)
{
Thread childThread = new Thread((obj) => BindNoParamFuncVoid(fn));
childThread.Start(fn);
return childThread;
}
public void End(Thread thread)
{
thread.Abort();
}
delegate void CFuncDelegateVoid();
public void BindNoParamFuncVoid(int CFunc)
{
CFuncDelegateVoid func = (CFuncDelegateVoid)Marshal.GetDelegateForFunctionPointer((IntPtr)CFunc, typeof(CFuncDelegateVoid));
func();
}
}
class CS_Func
{
public Object Eval(string eval)
{
return Microsoft.JScript.Eval.JScriptEvaluate(eval, Microsoft.JScript.Vsa.VsaEngine.CreateEngine());
}
}
)"
static ref := "
(Join|
System.dll
Microsoft.JScript.dll
)"
static asm := CLR_CompileCS(cs.code, cs.ref)
static ComArrayMake(array)
{
comArray := ComObjArray(VT_VARIANT := 12, array.length)
for i in array
comArray[a_index - 1] := i
return comArray
}
class ArrayList
{
static obj := CLR_CreateObject(cs.asm, "CS_ArrayList")
capacity
{
get => this.array.Capacity
set => this.array.Capacity := value
}
count
{
get => this.array.Count
}
length
{
get => this.array.Count
}
__new(arr := "")
{
if type(arr) = "ArrayList"
this.array := arr
else if arr is cs.ArrayList
this.array := arr.array
else
this.array := cs.ArrayList.obj.Init()
}
__item[index]
{
get => this.array[index - cs.ahk_flag]
set => this.array[index - cs.ahk_flag] := value
}
add(obj*)
{
cs.ArrayList.obj.Add(this.array, obj*)
return this
}
addRange(arrayList)
{
if !(arrayList is cs.ArrayList)
arrayList := cs.ArrayList(arrayList)
cs.ArrayList.obj.AddRange(this.array, arrayList.array)
return this
}
clear()
{
this.array.Clear()
return this
}
contains(item)
{
return cs.ArrayList.obj.Contains(this.array, item)
}
getRange(index, count)
{
index -= cs.ahk_flag
return cs.ArrayList(cs.ArrayList.obj.GetRange(this.array, index, count))
}
indexOf(item)
{
return cs.ArrayList.obj.IndexOf(this.array, item) + cs.ahk_flag
}
insert(index, obj)
{
index -= cs.ahk_flag
cs.ArrayList.obj.Insert(this.array, index, obj)
return this
}
insertRange(index, arrayList)
{
index -= cs.ahk_flag
if !(arrayList is cs.ArrayList)
arrayList := cs.ArrayList(arrayList)
cs.ArrayList.obj.InsertRange(this.array, index, arrayList.array)
return this
}
remove(obj)
{
cs.ArrayList.obj.Remove(this.array, obj)
return this
}
removeAt(index)
{
index -= cs.ahk_flag
cs.ArrayList.obj.RemoveAt(this.array, index)
return this
}
removeRange(index, count)
{
index -= cs.ahk_flag
cs.ArrayList.obj.RemoveRange(this.array, index, count)
return this
}
reverse()
{
this.array.Reverse()
return this
}
setRange(index, arrayList)
{
index -= cs.ahk_flag
if !(arrayList is cs.ArrayList)
arrayList := cs.ArrayList(arrayList)
cs.ArrayList.obj.SetRange(this.array, index, arrayList.array)
return this
}
sort()
{
this.array.sort()
return this
}
toArray()
{
return [this.array*]
}
trimToSize()
{
this.array.TrimToSize()
return this
}
__delete()
{
this.clear()
this.array := ""
}
}
class BitArray
{
static obj := CLR_CreateObject(cs.asm, "CS_BitArray")
count
{
get => this.bitarray.Count
}
length
{
get => this.bitarray.Length
set => this.bitarray.Length := value
}
__new(bitarray := 0)
{
if type(bitarray) = "Bitarray"
this.bitarray := bitarray
else if bitarray is cs.Bitarray
this.bitarray := bitarray.bitarray
else
this.bitarray := cs.Bitarray.obj.Init(bitarray)
}
__item[index]
{
get => this.bitarray[index - cs.ahk_flag]
set => this.bitarray[index - cs.ahk_flag] := value
}
and(value)
{
if !(value is cs.BitArray)
value := cs.BitArray(value)
return cs.BitArray(cs.BitArray.obj.And(this.bitarray, value.bitarray))
}
get(index)
{
index -= cs.ahk_flag
return cs.BitArray.obj.Get(this.bitarray, index)
}
not()
{
return cs.BitArray(this.bitarray.Not())
}
or(value)
{
if !(value is cs.BitArray)
value := cs.BitArray(value)
return cs.BitArray(cs.BitArray.obj.Or(this.bitarray, value.bitarray))
}
set(index, value)
{
index -= cs.ahk_flag
return cs.BitArray.obj.Set(this.bitarray, index, value)
}
setAll(value)
{
return cs.BitArray.obj.SetAll(this.bitarray, value)
}
toArray()
{
return [cs.BitArray.obj.ToArray(this.bitarray)*]
}
toArrayList()
{
return cs.ArrayList(cs.BitArray.obj.ToArrayList(this.bitarray))
}
toInt()
{
return cs.BitArray.obj.ToInt(this.bitarray)
}
toString()
{
return ltrim(cs.BitArray.obj.ToStr(this.bitarray), 0)
}
xor(value)
{
if !(value is cs.BitArray)
value := cs.BitArray(value)
return cs.BitArray(cs.BitArray.obj.Xor(this.bitarray, value.bitarray))
}
__delete()
{
this.bitarray.Length := 0
this.bitarray := ""
}
}
class Func
{
static obj := CLR_CreateObject(cs.asm, "CS_Func")
eval(_string)
{
return cs.Func.obj.Eval(_string)
}
}
class Hashtable
{
static obj := CLR_CreateObject(cs.asm, "CS_Hashtable")
count
{
get => this.table.Count
}
length
{
get => this.table.Count
}
keys
{
get => cs.ArrayList(cs.Hashtable.obj.Keys(this.table))
}
values
{
get => cs.ArrayList(cs.Hashtable.obj.Values(this.table))
}
__new(table := "")
{
if type(table) = "Hashtable"
this.table := table
else if table is cs.Hashtable
this.table := table.table
else
this.table := cs.Hashtable.obj.Init()
}
__item[key]
{
get => this.table[key]
set => this.table[key] := value
}
add(key, value)
{
cs.Hashtable.obj.Add(this.table, key, value)
return this
}
clear()
{
this.table.Clear()
return this
}
containsKey(key)
{
return cs.Hashtable.obj.ContainsKey(this.table, key)
}
containsValue(value)
{
return cs.Hashtable.obj.ContainsValue(this.table, value)
}
remove(key)
{
cs.Hashtable.obj.Remove(this.table, key)
return this
}
__delete()
{
this.clear()
this.table := ""
}
}
class Queue
{
static obj := CLR_CreateObject(cs.asm, "CS_Queue")
count
{
get => this.queue.Count
}
length
{
get => this.queue.Count
}
__new(queue := "")
{
if type(queue) = "Queue"
this.queue := queue
else if queue is cs.Queue
this.queue := queue.queue
else
this.queue := cs.Queue.obj.Init()
}
clear()
{
this.queue.Clear()
return this
}
contains(obj)
{
return cs.Queue.obj.Contains(this.queue, obj)
}
dequeue()
{
return this.queue.Dequeue()
}
enqueue(obj)
{
cs.Queue.obj.Enqueue(this.queue, obj)
return this
}
toArray()
{
return [this.queue.ToArray()*]
}
toArrayList()
{
return cs.ArrayList(cs.Queue.obj.ToArrayList(this.queue))
}
__delete()
{
this.clear()
this.queue := ""
}
}
class Stack
{
static obj := CLR_CreateObject(cs.asm, "CS_Stack")
count
{
get => this.stack.Count
}
length
{
get => this.stack.Count
}
__new(stack := "")
{
if type(stack) = "Stack"
this.stack := stack
else if stack is cs.Stack
this.stack := stack.stack
else
this.stack := cs.Stack.obj.Init()
}
clear()
{
this.stack.Clear()
return this
}
contains(obj)
{
return cs.Stack.obj.Contains(this.stack, obj)
}
peek()
{
return this.stack.Peek()
}
pop()
{
return this.stack.Pop()
}
push(obj)
{
cs.Stack.obj.Push(this.stack, obj)
return this
}
toArray()
{
return [this.stack.ToArray()*]
}
toArrayList()
{
return cs.ArrayList(cs.Stack.obj.ToArrayList(this.stack))
}
__delete()
{
this.clear()
this.stack := ""
}
}
class StringBuilder
{
static obj := CLR_CreateObject(cs.asm, "CS_StringBuilder")
count
{
get => this.builder.Length
}
length
{
get => this.builder.Length
set => this.builder.Length := value
}
__new(_string := "")
{
if type(_string) = "StringBuilder"
this.builder := _string
else if _string is cs.StringBuilder
this.builder := _string.builder
else if _string is string || _string is number
this.builder := cs.StringBuilder.obj.Init(_string)
else
this.builder := cs.StringBuilder.obj.Init("")
}
__item[index]
{
get => chr(this.builder[index - cs.ahk_flag])
set => this.builder[index - cs.ahk_flag] := ord(value)
}
append(_string, looptimes := 1)
{
if _string is string || _string is number
cs.StringBuilder.obj.Append(this.builder, _string, looptimes)
else if type(_string) = "StringBuilder"
cs.StringBuilder.obj.AppendStringBuilder(this.builder, _string, looptimes)
else if _string is cs.StringBuilder
cs.StringBuilder.obj.AppendStringBuilder(this.builder, _string.builder, looptimes)
return this
}
appendFormat(_string, looptimes := 1, format*)
{
if _string is string || _string is number
cs.StringBuilder.obj.AppendFormat(this.builder, _string, looptimes, format*)
else if type(_string) = "StringBuilder"
cs.StringBuilder.obj.AppendStringBuilderFormat(this.builder, _string, looptimes, format*)
else if _string is cs.StringBuilder
cs.StringBuilder.obj.AppendStringBuilderFormat(this.builder, _string.builder, looptimes, format*)
return this
}
charAt(index)
{
return this.builder[index - cs.ahk_flag]
}
insert(pos, _string, looptimes := 1)
{
pos -= cs.ahk_flag
if _string is string || _string is number
cs.StringBuilder.obj.Insert(this.builder, _string, pos, looptimes)
else if type(_string) = "StringBuilder"
cs.StringBuilder.obj.InsertStringBuilder(this.builder, _string, pos, looptimes)
else if _string is cs.StringBuilder
cs.StringBuilder.obj.InsertStringBuilder(this.builder, _string.builder, pos, looptimes)
return this
}
remove(start, length, looptimes := 1)
{
start -= cs.ahk_flag
cs.StringBuilder.obj.Remove(this.builder, start, length, looptimes)
return this
}
replace(haystack, needle := "", looptimes := 1)
{
cs.StringBuilder.obj.Replace(this.builder, haystack, needle, looptimes)
return this
}
toString()
{
return this.builder.ToString()
}
__delete()
{
this.builder.Length := 0
this.builder := ""
}
}
class Thread
{
static obj := CLR_CreateObject(cs.asm, "CS_Thread")
__new()
{
this.threadpool := []
this.funcpool := []
}
start(fn)
{
func := callbackcreate(fn)
this.funcpool.push(func)
thread := cs.Thread.obj.Start(func)
this.threadpool.push(thread)
return thread
}
end(index := this.threadpool.length)
{
cs.Thread.obj.End(this.threadpool[index])
this.threadpool.removeat(index)
this.funcpool.removeat(index)
}
__delete()
{
while this.threadpool.length
this.end()
}
}
}
CLR_LoadLibrary(AssemblyName, AppDomain:=0)
{
if !AppDomain
AppDomain := CLR_GetDefaultDomain()
try
return AppDomain.Load_2(AssemblyName)
static null := ComValue(13,0)
args := ComObjArray(0xC, 1), args[0] := AssemblyName
typeofAssembly := AppDomain.GetType().Assembly.GetType()
try
return typeofAssembly.InvokeMember_3("LoadWithPartialName", 0x158, null, null, args)
catch
return typeofAssembly.InvokeMember_3("LoadFrom", 0x158, null, null, args)
}
CLR_CreateObject(Assembly, TypeName, Args*)
{
if !(argCount := Args.Length)
return Assembly.CreateInstance_2(TypeName, true)
vargs := ComObjArray(0xC, argCount)
Loop argCount
vargs[A_Index-1] := Args[A_Index]
static Array_Empty := ComObjArray(0xC,0), null := ComValue(13,0)
return Assembly.CreateInstance_3(TypeName, true, 0, null, vargs, null, Array_Empty)
}
CLR_CompileCS(Code, References:="", AppDomain:=0, FileName:="", CompilerOptions:="")
{
return CLR_CompileAssembly(Code, References, "System", "Microsoft.CSharp.CSharpCodeProvider", AppDomain, FileName, CompilerOptions)
}
CLR_CompileVB(Code, References:="", AppDomain:=0, FileName:="", CompilerOptions:="")
{
return CLR_CompileAssembly(Code, References, "System", "Microsoft.VisualBasic.VBCodeProvider", AppDomain, FileName, CompilerOptions)
}
CLR_StartDomain(&AppDomain, BaseDirectory:="")
{
static null := ComValue(13,0)
args := ComObjArray(0xC, 5), args[0] := "", args[2] := BaseDirectory, args[4] := ComValue(0xB,false)
AppDomain := CLR_GetDefaultDomain().GetType().InvokeMember_3("CreateDomain", 0x158, null, null, args)
}
; ICorRuntimeHost::UnloadDomain
CLR_StopDomain(AppDomain) => ComCall(20, CLR_Start(), "ptr", ComObjValue(AppDomain))
; NOTE: IT IS NOT NECESSARY TO CALL THIS FUNCTION unless you need to load a specific version.
CLR_Start(Version:="") ; returns ICorRuntimeHost*
{
static RtHst := 0
; The simple method gives no control over versioning, and seems to load .NET v2 even when v4 is present:
; return RtHst ? RtHst : (RtHst:=COM_CreateObject("CLRMetaData.CorRuntimeHost","{CB2F6722-AB3A-11D2-9C40-00C04FA30A3E}"), DllCall(NumGet(NumGet(RtHst+0)+40),"uint",RtHst))
if RtHst
return RtHst
if Version = ""
Loop Files EnvGet("SystemRoot") "\Microsoft.NET\Framework" (A_PtrSize=8?"64":"") "\*","D"
if (FileExist(A_LoopFilePath "\mscorlib.dll") && StrCompare(A_LoopFileName, Version) > 0)
Version := A_LoopFileName
static CLSID_CorRuntimeHost := CLR_GUID("{CB2F6723-AB3A-11D2-9C40-00C04FA30A3E}")
static IID_ICorRuntimeHost := CLR_GUID("{CB2F6722-AB3A-11D2-9C40-00C04FA30A3E}")
DllCall("mscoree\CorBindToRuntimeEx", "wstr", Version, "ptr", 0, "uint", 0
, "ptr", CLSID_CorRuntimeHost, "ptr", IID_ICorRuntimeHost
, "ptr*", &RtHst:=0, "hresult")
ComCall(10, RtHst) ; Start
return RtHst
}
;
; INTERNAL FUNCTIONS
;
CLR_GetDefaultDomain()
{
; ICorRuntimeHost::GetDefaultDomain
static defaultDomain := (
ComCall(13, CLR_Start(), "ptr*", &p:=0),
ComObjFromPtr(p)
)
return defaultDomain
}
CLR_CompileAssembly(Code, References, ProviderAssembly, ProviderType, AppDomain:=0, FileName:="", CompilerOptions:="")
{
if !AppDomain
AppDomain := CLR_GetDefaultDomain()
asmProvider := CLR_LoadLibrary(ProviderAssembly, AppDomain)
codeProvider := asmProvider.CreateInstance(ProviderType)
codeCompiler := codeProvider.CreateCompiler()
asmSystem := (ProviderAssembly="System") ? asmProvider : CLR_LoadLibrary("System", AppDomain)
; Convert | delimited list of references into an array.
Refs := References is String ? StrSplit(References, "|", " `t") : References
aRefs := ComObjArray(8, Refs.Length)
Loop Refs.Length
aRefs[A_Index-1] := Refs[A_Index]
; Set parameters for compiler.
prms := CLR_CreateObject(asmSystem, "System.CodeDom.Compiler.CompilerParameters", aRefs)
, prms.OutputAssembly := FileName
, prms.GenerateInMemory := FileName=""
, prms.GenerateExecutable := SubStr(FileName,-4)=".exe"
, prms.CompilerOptions := CompilerOptions
, prms.IncludeDebugInformation := true
; Compile!
compilerRes := codeCompiler.CompileAssemblyFromSource(prms, Code)
if error_count := (errors := compilerRes.Errors).Count
{
error_text := ""
Loop error_count
error_text .= ((e := errors.Item[A_Index-1]).IsWarning ? "Warning " : "Error ") . e.ErrorNumber " on line " e.Line ": " e.ErrorText "`n`n"
throw Error("Compilation failed",, "`n" error_text)
}
; Success. Return Assembly object or path.
return FileName="" ? compilerRes.CompiledAssembly : compilerRes.PathToAssembly
}
; Usage 1: pGUID := CLR_GUID(&GUID, "{...}")
; Usage 2: GUID := CLR_GUID("{...}"), pGUID := GUID.Ptr
CLR_GUID(a, b:=unset)
{
DllCall("ole32\IIDFromString"
, "wstr", sGUID := IsSet(b) ? b : a
, "ptr", GUID := Buffer(16,0), "hresult")
return IsSet(b) ? GUID.Ptr : GUID
}
?感谢分享