commit
c4d7284ad4
8 changed files with 593 additions and 0 deletions
@ -0,0 +1,2 @@ |
|||||
|
* |
||||
|
!.gitignore |
@ -0,0 +1,60 @@ |
|||||
|
; Set default location and name convention for compiled scripts to use |
||||
|
;@Ahk2Exe-ExeName %A_MyDocuments%\AutoHotkey\bin\AHK-%A_ScriptName% |
||||
|
|
||||
|
; Install hooks to make sure script can get physical state of keys instead of logical state. |
||||
|
#InstallKeybdHook |
||||
|
#InstallMouseHook |
||||
|
|
||||
|
; Settings |
||||
|
#NoEnv ; Recommended for performance and compatibility with future AutoHotkey releases. |
||||
|
SendMode Input ; Recommended for new scripts due to its superior speed and reliability. |
||||
|
SetWorkingDir %A_ScriptDir% ; Ensures a consistent starting directory. |
||||
|
#UseHook ; All hotkeys are implemented through keyboard hook to avoid script activating itself. |
||||
|
#MenuMaskKey vkFF |
||||
|
|
||||
|
; |
||||
|
; Function definitions |
||||
|
; |
||||
|
|
||||
|
Hold(Primary, Secondary) { |
||||
|
Send {%Primary% down} |
||||
|
if ( Secondary.Length() != 0 ) { |
||||
|
ThisLoop := Func("HoldLoop").bind(Primary,Secondary) |
||||
|
SetTimer, %ThisLoop%, 50 |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
HoldLoop(Primary, Secondary) { |
||||
|
if GetKeyState(Primary,"P") { |
||||
|
SetTimer, , Delete |
||||
|
} |
||||
|
for index,key in Secondary { |
||||
|
if GetKeyState(key,"P") { |
||||
|
Send {%Primary% up} |
||||
|
SetTimer, , Delete |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
Repeat(Primary, Secondary) { |
||||
|
Send {%Primary% up} |
||||
|
Sleep 100 |
||||
|
RepeatVar := 0 |
||||
|
Loop { |
||||
|
if GetKeyState(Primary,"P") { |
||||
|
return |
||||
|
} |
||||
|
for index,key in Secondary { |
||||
|
if GetKeyState(key,"P") { |
||||
|
return |
||||
|
} |
||||
|
} |
||||
|
if (RepeatVar == 2) { |
||||
|
SendEvent, {%Primary%} |
||||
|
RepeatVar := 1 |
||||
|
} else { |
||||
|
RepeatVar++ |
||||
|
} |
||||
|
Sleep 50 |
||||
|
} |
||||
|
} |
@ -0,0 +1,72 @@ |
|||||
|
; Script can be directly run by or compiled into an .exe by the open-source software AutoHotkey |
||||
|
; https://www.autohotkey.com |
||||
|
|
||||
|
; |
||||
|
; Front Matter |
||||
|
; |
||||
|
|
||||
|
; Include general library |
||||
|
#Include ../lib/General.ahk |
||||
|
|
||||
|
; Only do hotkeys if relevant window is active |
||||
|
#IfWinActive, Minecraft |
||||
|
|
||||
|
; |
||||
|
; Hotkeys |
||||
|
; |
||||
|
|
||||
|
; Tab will be the hotkey |
||||
|
~Tab::return |
||||
|
|
||||
|
; Hold/Autoclick mouse buttons |
||||
|
; Holds if single click, autoclicks if double click |
||||
|
Tab & LButton UP:: |
||||
|
KeyWait, LButton, D, T0.2 |
||||
|
if (ErrorLevel = 0) { |
||||
|
Repeat("LButton",["RButton","MButton"]) |
||||
|
} else { |
||||
|
Hold("LButton",["RButton","MButton"]) |
||||
|
} |
||||
|
return |
||||
|
Tab & RButton UP:: |
||||
|
KeyWait, RButton, D, T0.2 |
||||
|
if (ErrorLevel = 0) { |
||||
|
Repeat("RButton",["LButton","MButton"]) |
||||
|
} else { |
||||
|
Hold("RButton",["LButton","MButton"]) |
||||
|
} |
||||
|
return |
||||
|
|
||||
|
; Autorun |
||||
|
Tab & w UP::Hold("w",["s"]) |
||||
|
Tab & s UP::Hold("s",["w"]) |
||||
|
Tab & a UP::Hold("a",["d","w","s"]) |
||||
|
Tab & d UP::Hold("d",["a","w","s"]) |
||||
|
|
||||
|
; Hold crouch |
||||
|
Tab & Shift UP:: |
||||
|
if GetKeyState("Alt","P") { |
||||
|
Hold("Shift",["Ctrl"]) |
||||
|
} else { |
||||
|
Hold("Shift",["Ctrl","Space"]) |
||||
|
} |
||||
|
return |
||||
|
|
||||
|
; Autojump/auto-ascend |
||||
|
Tab & Space UP::Hold("Space",["Shift"]) |
||||
|
|
||||
|
; Mouse button 4: auto-takeoff |
||||
|
; Macro assumes you have your fireworks in the first hotbar slot |
||||
|
XButton1:: |
||||
|
Loop, 5 { |
||||
|
Send {Space down} |
||||
|
Sleep 10 |
||||
|
} |
||||
|
Send {Space up}1 |
||||
|
Sleep 225 |
||||
|
Loop, 5 { |
||||
|
Send {Space down} |
||||
|
Sleep 10 |
||||
|
} |
||||
|
Send {Space up}{RButton} |
||||
|
return |
@ -0,0 +1,101 @@ |
|||||
|
; Script can be directly run by or compiled into an .exe by the open-source software AutoHotkey |
||||
|
; https://www.autohotkey.com |
||||
|
|
||||
|
; |
||||
|
; Front Matter |
||||
|
; |
||||
|
|
||||
|
; Include general library |
||||
|
#Include ../lib/General.ahk |
||||
|
|
||||
|
; Include ViGEm library |
||||
|
#Include ../thirdparty/AHK-ViGEm-Bus/AHK-ViGEm-Bus.ahk |
||||
|
; Create a new Xbox 360 controller |
||||
|
MyXbox := new ViGEmXb360() |
||||
|
|
||||
|
; Settings |
||||
|
SetTitleMatchMode,2 |
||||
|
DetectHiddenWindows,On |
||||
|
|
||||
|
; Set percent to deflect by for fine controls |
||||
|
Defl := 30 |
||||
|
|
||||
|
; Create Gui to show deflection percent |
||||
|
MyGuiTime = 1 |
||||
|
Gui, +AlwaysOnTop -Caption +ToolWindow |
||||
|
Gui, Margin, 0, 0 |
||||
|
Gui, Font, s20 CWhite |
||||
|
Gui, Color, Black |
||||
|
Gui, Add, Text, vMyGuiText +Center, Fine Controls: 100`% |
||||
|
Gui, Show, NoActivate, OuterWildsAhkGui |
||||
|
WinSet, TransColor, Black, OuterWildsAhkGui |
||||
|
|
||||
|
UpdateGui: |
||||
|
If (MyGuiTime != 0) { |
||||
|
Gui, Show, NoActivate |
||||
|
GuiControl, Text, MyGuiText, Fine Controls: %Defl%`% |
||||
|
MyGuiTime-- |
||||
|
If (MyGuiTime == 0) { |
||||
|
Gui, Hide |
||||
|
SetTimer, UpdateGui, Off |
||||
|
} |
||||
|
} |
||||
|
return |
||||
|
|
||||
|
; Only do hotkeys if relevant window is active |
||||
|
#IfWinActive, Outer Wilds |
||||
|
|
||||
|
; |
||||
|
; Hotkeys |
||||
|
; |
||||
|
|
||||
|
; Hold keys |
||||
|
*!w UP::Hold("w",["s"]) |
||||
|
*!s UP::Hold("s",["w"]) |
||||
|
*!a UP::Hold("a",["d","w","s"]) |
||||
|
*!d UP::Hold("d",["a","w","s"]) |
||||
|
*!Space UP::Hold("Space",["Shift"]) |
||||
|
*!Shift UP::Hold("Shift",["Space"]) |
||||
|
|
||||
|
; Alt+Scroll changes deflect percent |
||||
|
*!WheelUp:: |
||||
|
Defl := Min(Defl + 5,100) |
||||
|
MyGuiTime = 10 |
||||
|
SetTimer, UpdateGui, 100 |
||||
|
Goto UpdateGui |
||||
|
return |
||||
|
*!WheelDown:: |
||||
|
Defl := Max(Defl - 5,0) |
||||
|
MyGuiTime = 10 |
||||
|
SetTimer, UpdateGui, 100 |
||||
|
Goto UpdateGui |
||||
|
return |
||||
|
|
||||
|
; Reset all axes when capslock is pressed |
||||
|
~CapsLock:: |
||||
|
MyXbox.Axes.LY.SetState(50) |
||||
|
MyXbox.Axes.LX.SetState(50) |
||||
|
MyXbox.Axes.RT.SetState(0) |
||||
|
MyXbox.Axes.LT.SetState(0) |
||||
|
return |
||||
|
|
||||
|
; Fine control is active when caps lock is on |
||||
|
#If GetKeyState("CapsLock","T") |
||||
|
|
||||
|
W::MyXbox.Axes.LY.SetState(50+Defl*.5) |
||||
|
W UP::MyXbox.Axes.LY.SetState(50) |
||||
|
|
||||
|
S::MyXbox.Axes.LY.SetState(50-Defl*.5) |
||||
|
S UP::MyXbox.Axes.LY.SetState(50) |
||||
|
|
||||
|
D::MyXbox.Axes.LX.SetState(50+Defl*.5) |
||||
|
D UP::MyXbox.Axes.LX.SetState(50) |
||||
|
|
||||
|
A::MyXbox.Axes.LX.SetState(50-Defl*.5) |
||||
|
A UP::MyXbox.Axes.LX.SetState(50) |
||||
|
|
||||
|
Space::MyXbox.Axes.RT.SetState(Defl*.16) |
||||
|
Space UP::MyXbox.Axes.RT.SetState(0) |
||||
|
|
||||
|
Shift::MyXbox.Axes.LT.SetState(Defl*.16) |
||||
|
Shift UP::MyXbox.Axes.LT.SetState(0) |
@ -0,0 +1,207 @@ |
|||||
|
#include %A_LineFile%\..\CLR.ahk |
||||
|
|
||||
|
; Static class, holds ViGEm Client instance |
||||
|
class ViGEmWrapper { |
||||
|
static asm := 0 |
||||
|
static client := 0 |
||||
|
|
||||
|
Init(){ |
||||
|
if (this.client == 0){ |
||||
|
this.asm := CLR_LoadLibrary(A_LineFile "\..\ViGEmWrapper.dll") |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
CreateInstance(cls){ |
||||
|
return this.asm.CreateInstance(cls) |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
|
||||
|
; Base class for ViGEm "Targets" (Controller types - eg xb360 / ds4) to inherit from |
||||
|
class ViGEmTarget { |
||||
|
target := 0 |
||||
|
helperClass := "" |
||||
|
controllerClass := "" |
||||
|
|
||||
|
__New(){ |
||||
|
;~ this.asm := CLR_LoadLibrary(A_LineFile "\..\ViGEmWrapper.dll") |
||||
|
ViGEmWrapper.Init() |
||||
|
this.Instance := ViGEmWrapper.CreateInstance(this.helperClass) |
||||
|
|
||||
|
if (this.Instance.OkCheck() != "OK"){ |
||||
|
msgbox ViGEmWrapper.dll failed to load! |
||||
|
ExitApp |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
SendReport(){ |
||||
|
this.Instance.SendReport() |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
; DS4 (DualShock 4 for Playstation 4) |
||||
|
class ViGEmDS4 extends ViGEmTarget { |
||||
|
helperClass := "ViGEmWrapper.Ds4" |
||||
|
__New(){ |
||||
|
static buttons := {Square: 16, Cross: 32, Circle: 64, Triangle: 128, L1: 256, R1: 512, L2: 1024, R2: 2048 |
||||
|
, Share: 4096, Options: 8192, LS: 16384, RS: 32768 } |
||||
|
static specialButtons := {Ps: 1, TouchPad: 2} |
||||
|
static axes := {LX: 2, LY: 3, RX: 4, RY: 5, LT: 0, RT: 1} |
||||
|
|
||||
|
this.Buttons := {} |
||||
|
for name, id in buttons { |
||||
|
this.Buttons[name] := new this._ButtonHelper(this, id) |
||||
|
} |
||||
|
for name, id in specialButtons { |
||||
|
this.Buttons[name] := new this._SpecialButtonHelper(this, id) |
||||
|
} |
||||
|
|
||||
|
this.Axes := {} |
||||
|
for name, id in axes { |
||||
|
this.Axes[name] := new this._AxisHelper(this, id) |
||||
|
} |
||||
|
|
||||
|
this.Dpad := new this._DpadHelper(this) |
||||
|
base.__New() |
||||
|
} |
||||
|
|
||||
|
class _ButtonHelper { |
||||
|
__New(parent, id){ |
||||
|
this._Parent := parent |
||||
|
this._Id := id |
||||
|
} |
||||
|
|
||||
|
SetState(state){ |
||||
|
this._Parent.Instance.SetButtonState(this._Id, state) |
||||
|
this._Parent.Instance.SendReport() |
||||
|
return this._Parent |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
class _SpecialButtonHelper { |
||||
|
__New(parent, id){ |
||||
|
this._Parent := parent |
||||
|
this._Id := id |
||||
|
} |
||||
|
|
||||
|
SetState(state){ |
||||
|
this._Parent.Instance.SetSpecialButtonState(this._Id, state) |
||||
|
this._Parent.Instance.SendReport() |
||||
|
return this._Parent |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
class _AxisHelper { |
||||
|
__New(parent, id){ |
||||
|
this._Parent := parent |
||||
|
this._Id := id |
||||
|
} |
||||
|
|
||||
|
SetState(state){ |
||||
|
this._Parent.Instance.SetAxisState(this._Id, this.ConvertAxis(state)) |
||||
|
this._Parent.Instance.SendReport() |
||||
|
return this._Parent |
||||
|
} |
||||
|
|
||||
|
ConvertAxis(state){ |
||||
|
return round(state * 2.55) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
class _DpadHelper { |
||||
|
__New(parent){ |
||||
|
this._Parent := parent |
||||
|
this._Id := id |
||||
|
} |
||||
|
|
||||
|
SetState(state){ |
||||
|
static dPadDirections := {Up: 0, UpRight: 1, Right: 2, DownRight: 3, Down: 4, DownLeft: 5, Left: 6, UpLeft: 7, None: 8} |
||||
|
this._Parent.Instance.SetDpadState(dPadDirections[state]) |
||||
|
this._Parent.Instance.SendReport() |
||||
|
return this._Parent |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
; Xb360 |
||||
|
class ViGEmXb360 extends ViGEmTarget { |
||||
|
helperClass := "ViGEmWrapper.Xb360" |
||||
|
__New(){ |
||||
|
static buttons := {A: 4096, B: 8192, X: 16384, Y: 32768, LB: 256, RB: 512, LS: 64, RS: 128, Back: 32, Start: 16, Xbox: 1024} |
||||
|
static axes := {LX: 2, LY: 3, RX: 4, RY: 5, LT: 0, RT: 1} |
||||
|
|
||||
|
this.Buttons := {} |
||||
|
for name, id in buttons { |
||||
|
this.Buttons[name] := new this._ButtonHelper(this, id) |
||||
|
} |
||||
|
|
||||
|
this.Axes := {} |
||||
|
for name, id in axes { |
||||
|
this.Axes[name] := new this._AxisHelper(this, id) |
||||
|
} |
||||
|
|
||||
|
this.Dpad := new this._DpadHelper(this) |
||||
|
|
||||
|
base.__New() |
||||
|
} |
||||
|
|
||||
|
class _ButtonHelper { |
||||
|
__New(parent, id){ |
||||
|
this._Parent := parent |
||||
|
this._Id := id |
||||
|
} |
||||
|
|
||||
|
SetState(state){ |
||||
|
this._Parent.Instance.SetButtonState(this._Id, state) |
||||
|
this._Parent.Instance.SendReport() |
||||
|
return this._Parent |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
class _AxisHelper { |
||||
|
__New(parent, id){ |
||||
|
this._Parent := parent |
||||
|
this._id := id |
||||
|
} |
||||
|
|
||||
|
SetState(state){ |
||||
|
this._Parent.Instance.SetAxisState(this._Id, this.ConvertAxis(state)) |
||||
|
this._Parent.Instance.SendReport() |
||||
|
} |
||||
|
|
||||
|
ConvertAxis(state){ |
||||
|
value := round((state * 655.36) - 32768) |
||||
|
if (value == 32768) |
||||
|
return 32767 |
||||
|
return value |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
class _DpadHelper { |
||||
|
_DpadStates := {1:0, 8:0, 2:0, 4:0} ; Up, Right, Down, Left |
||||
|
__New(parent){ |
||||
|
this._Parent := parent |
||||
|
} |
||||
|
|
||||
|
SetState(state){ |
||||
|
static dpadDirections := { None: {1:0, 8:0, 2:0, 4:0} |
||||
|
, Up: {1:1, 8:0, 2:0, 4:0} |
||||
|
, UpRight: {1:1, 8:1, 2:0, 4:0} |
||||
|
, Right: {1:0, 8:1, 2:0, 4:0} |
||||
|
, DownRight: {1:0, 8:1, 2:1, 4:0} |
||||
|
, Down: {1:0, 8:0, 2:1, 4:0} |
||||
|
, DownLeft: {1:0, 8:0, 2:1, 4:1} |
||||
|
, Left: {1:0, 8:0, 2:0, 4:1} |
||||
|
, UpLeft: {1:1, 8:0, 2:0, 4:1}} |
||||
|
newStates := dpadDirections[state] |
||||
|
for id, newState in newStates { |
||||
|
oldState := this._DpadStates[id] |
||||
|
if (oldState != newState){ |
||||
|
this._DpadStates[id] := newState |
||||
|
this._Parent.Instance.SetButtonState(id, newState) |
||||
|
} |
||||
|
this._Parent.SendReport() |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
@ -0,0 +1,151 @@ |
|||||
|
; ========================================================== |
||||
|
; .NET Framework Interop |
||||
|
; https://autohotkey.com/boards/viewtopic.php?t=4633 |
||||
|
; ========================================================== |
||||
|
; |
||||
|
; Author: Lexikos |
||||
|
; Version: 1.2 |
||||
|
; Requires: AutoHotkey_L v1.0.96+ |
||||
|
; |
||||
|
|
||||
|
CLR_LoadLibrary(AssemblyName, AppDomain=0) |
||||
|
{ |
||||
|
if !AppDomain |
||||
|
AppDomain := CLR_GetDefaultDomain() |
||||
|
e := ComObjError(0) |
||||
|
Loop 1 { |
||||
|
if assembly := AppDomain.Load_2(AssemblyName) |
||||
|
break |
||||
|
static null := ComObject(13,0) |
||||
|
args := ComObjArray(0xC, 1), args[0] := AssemblyName |
||||
|
typeofAssembly := AppDomain.GetType().Assembly.GetType() |
||||
|
if assembly := typeofAssembly.InvokeMember_3("LoadWithPartialName", 0x158, null, null, args) |
||||
|
break |
||||
|
if assembly := typeofAssembly.InvokeMember_3("LoadFrom", 0x158, null, null, args) |
||||
|
break |
||||
|
} |
||||
|
ComObjError(e) |
||||
|
return assembly |
||||
|
} |
||||
|
|
||||
|
CLR_CreateObject(Assembly, TypeName, Args*) |
||||
|
{ |
||||
|
if !(argCount := Args.MaxIndex()) |
||||
|
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 := ComObject(13,0) |
||||
|
|
||||
|
return Assembly.CreateInstance_3(TypeName, true, 0, null, vargs, null, Array_Empty) |
||||
|
} |
||||
|
|
||||
|
CLR_CompileC#(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(ByRef AppDomain, BaseDirectory="") |
||||
|
{ |
||||
|
static null := ComObject(13,0) |
||||
|
args := ComObjArray(0xC, 5), args[0] := "", args[2] := BaseDirectory, args[4] := ComObject(0xB,false) |
||||
|
AppDomain := CLR_GetDefaultDomain().GetType().InvokeMember_3("CreateDomain", 0x158, null, null, args) |
||||
|
return A_LastError >= 0 |
||||
|
} |
||||
|
|
||||
|
CLR_StopDomain(ByRef AppDomain) |
||||
|
{ ; ICorRuntimeHost::UnloadDomain |
||||
|
DllCall("SetLastError", "uint", hr := DllCall(NumGet(NumGet(0+RtHst:=CLR_Start())+20*A_PtrSize), "ptr", RtHst, "ptr", ComObjValue(AppDomain))), AppDomain := "" |
||||
|
return hr >= 0 |
||||
|
} |
||||
|
|
||||
|
; 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 |
||||
|
EnvGet SystemRoot, SystemRoot |
||||
|
if Version = |
||||
|
Loop % SystemRoot "\Microsoft.NET\Framework" (A_PtrSize=8?"64":"") "\*", 2 |
||||
|
if (FileExist(A_LoopFileFullPath "\mscorlib.dll") && A_LoopFileName > Version) |
||||
|
Version := A_LoopFileName |
||||
|
if DllCall("mscoree\CorBindToRuntimeEx", "wstr", Version, "ptr", 0, "uint", 0 |
||||
|
, "ptr", CLR_GUID(CLSID_CorRuntimeHost, "{CB2F6723-AB3A-11D2-9C40-00C04FA30A3E}") |
||||
|
, "ptr", CLR_GUID(IID_ICorRuntimeHost, "{CB2F6722-AB3A-11D2-9C40-00C04FA30A3E}") |
||||
|
, "ptr*", RtHst) >= 0 |
||||
|
DllCall(NumGet(NumGet(RtHst+0)+10*A_PtrSize), "ptr", RtHst) ; Start |
||||
|
return RtHst |
||||
|
} |
||||
|
|
||||
|
; |
||||
|
; INTERNAL FUNCTIONS |
||||
|
; |
||||
|
|
||||
|
CLR_GetDefaultDomain() |
||||
|
{ |
||||
|
static defaultDomain := 0 |
||||
|
if !defaultDomain |
||||
|
{ ; ICorRuntimeHost::GetDefaultDomain |
||||
|
if DllCall(NumGet(NumGet(0+RtHst:=CLR_Start())+13*A_PtrSize), "ptr", RtHst, "ptr*", p:=0) >= 0 |
||||
|
defaultDomain := ComObject(p), ObjRelease(p) |
||||
|
} |
||||
|
return defaultDomain |
||||
|
} |
||||
|
|
||||
|
CLR_CompileAssembly(Code, References, ProviderAssembly, ProviderType, AppDomain=0, FileName="", CompilerOptions="") |
||||
|
{ |
||||
|
if !AppDomain |
||||
|
AppDomain := CLR_GetDefaultDomain() |
||||
|
|
||||
|
if !(asmProvider := CLR_LoadLibrary(ProviderAssembly, AppDomain)) |
||||
|
|| !(codeProvider := asmProvider.CreateInstance(ProviderType)) |
||||
|
|| !(codeCompiler := codeProvider.CreateCompiler()) |
||||
|
return 0 |
||||
|
|
||||
|
if !(asmSystem := (ProviderAssembly="System") ? asmProvider : CLR_LoadLibrary("System", AppDomain)) |
||||
|
return 0 |
||||
|
|
||||
|
; Convert | delimited list of references into an array. |
||||
|
StringSplit, Refs, References, |, %A_Space%%A_Tab% |
||||
|
aRefs := ComObjArray(8, Refs0) |
||||
|
Loop % Refs0 |
||||
|
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,-3)=".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" |
||||
|
MsgBox, 16, Compilation Failed, %error_text% |
||||
|
return 0 |
||||
|
} |
||||
|
; Success. Return Assembly object or path. |
||||
|
return compilerRes[FileName="" ? "CompiledAssembly" : "PathToAssembly"] |
||||
|
} |
||||
|
|
||||
|
CLR_GUID(ByRef GUID, sGUID) |
||||
|
{ |
||||
|
VarSetCapacity(GUID, 16, 0) |
||||
|
return DllCall("ole32\CLSIDFromString", "wstr", sGUID, "ptr", &GUID) >= 0 ? &GUID : "" |
||||
|
} |
Binary file not shown.
Binary file not shown.
Loading…
Reference in new issue