CLR compiling - continuation section tricks

Post your working scripts, libraries and tools for AHK v1.1 and older
burque505
Posts: 1736
Joined: 22 Jan 2017, 19:37

CLR compiling - continuation section tricks

27 Apr 2019, 12:07

This script is in part a result of some back-and-forth with @sancarn and @evilC the threads at
this link, Topic: .NET Framework Interop (CLR, C#, VB), and some of this code is probably sancarn's or evilC's, or at least based on it.

First, this is NOT an attempt to show any 'right way' to do any .NET programming. I'm absolutely not the person to undertake that task.

The only real purpose of this is to show that you can dynamically alter C# or VB programs/scripts before compiling them via CLR.ahk.

Do this by preparing a 'template' script with a continuation section, using command-syntax, with variable references enclosed in '%[...]%' (%MyFirstString%, %MySecondString%, %MyThirdString% here), then dereference these values in another variable. This dereferencing pre-compilation keeps the CLR compiler from choking on the AHK variables. Here, the precompilation variable is 'presharp', and the variable to be compiled is 'csharp'. Not required. Code edited.

(There may be some useful program snippets in the code (I hope), primarily for inserting and removing items, but these aren't anything you can't find in two minutes with an online search, and they are not the motivation for this post.)

N.B. Obviously you don't have to limit yourself to just variables you'd use in your CLR language script - you could dynamically include entire scripts, individual methods, etc. This may make templating a bit easier.

Code: Select all

/* This script is in part a result of the threads at
https://www.autohotkey.com/boards/viewtopic.php?f=6&t=4633&p=220326&hilit=clr+arrays+burque505#p220326
(Topic: .NET Framework Interop (CLR, C#, VB)
First, this is NOT an attempt to show the 'right way' to do any .NET programming.

The only real purpose of this is to show that you can dynamically alter C#
or VB programs/scripts before compiling via CLR.ahk.

(There may be some useful program snippets in the code (I hope),
primarily for inserting and removing items, but these aren't anything
you can't find in two minutes with an online search, and they are not the reason for this script.)

Regards,
burque505
*/


#NoEnv  ; Recommended for performance and compatibility with future AutoHotkey releases.
; #Warn  ; Enable warnings to assist with detecting common errors.
SendMode Input  ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir%  ; Ensures a consistent starting directory.

gui, add, text, w200, Enter first pre-compilation variable
gui, add, edit, w300 y+5 vMyFirstString
gui, add, text, y+5 w200, Enter second pre-compilation variable
gui, add, edit, w300 y+5 vMySecondString
gui, add, text, y+5 w200, Enter third pre-compilation variable
gui, add, edit, w300 y+5 vMyThirdString
gui, add, text, y+5 w250, The following variables will be used post-compile
gui, add, text, y+10 w200, Enter variable for key "4"
gui, add, edit, w300 y+5 vAdd4
gui, add, text, y+10 w200, Enter variable for key "5"
gui, add, edit, w300 y+5 vAdd5
gui, add, text, y+10 w200, Enter variable to insert at index 5
gui, add, edit, w300 y+5 vAddInsert
gui, add, Button, y+5 Default, Submit
gui show, w350 h330, Dynamic compilation test

return

ButtonSubmit:
Gui, submit

csharp =

(
using System.Collections.Generic;
using System.Windows.Forms;

class Foo
{
    private List<KeyValuePair<int, string>> list = new List<KeyValuePair<int, string>>();
    public void Create()
    {
        // Create List of key-value pairs.

        list.Add(new KeyValuePair<int, string>(1, "%MyFirstString%"));
        list.Add(new KeyValuePair<int, string>(2, "%MySecondString%"));
        list.Add(new KeyValuePair<int, string>(3, "%MyThirdString%"));
        // These AHK variables will be expanded before compilation.

        // Loop over pairs.
        foreach (KeyValuePair<int, string> pair in list)
        {
            // Get key.
            int key = pair.Key;
            // Get value.
            string value = pair.Value;
            // Display.
            MessageBox.Show(key.ToString() + " " + value.ToString());
        }
    }

    public void Add(int key, string val)
    {
        list.Add(new KeyValuePair<int, string>(key, val));
    }

    public void Insert(int index, int key, string val)
    {
        list.Insert(index, new KeyValuePair<int, string>(key, val));
    }

    public void RemoveAt(int index)
    {
        list.RemoveAt(index);
    }
    
        public void Remove(int key, string val)
    {
        list.Remove(new KeyValuePair<int, string>(key, val));
    }


    public void Show()
    {
        string myString = "";
        foreach (KeyValuePair<int, string> pair in list)
        {
            // Get key.
            int key = pair.Key;
            // Get value.
            string value = pair.Value;
            // Display.
            myString += pair.Value + " ";
        }
        // Display.
        MessageBox.Show(myString);
    }
}

)


msgbox %csharp% 
/*  Uncomment the line above if you want to be sure
    that the variables are actually being expanded.
*/

asm := CLR_CompileC#(csharp,"System.dll|System.Windows.Forms.dll|System.Collections.dll")
obj := CLR_CreateObject(asm,"Foo")
; First create a list of k/v pairs with some members initialized
obj.Create()
; Add a couple of key-value pairs
obj.Add(4, Add4)
obj.Add(5, Add5)
; Now, convert the values to a string and display.
obj.Show()
; list.Insert() takes (int, int, string)
obj.Insert(5, 6, AddInsert)
obj.Show()
; list.RemoveAt operates on the index, NOT the key,
; so this will remove the fifth element of the
; list, NOT the fourth (zero-based index).
obj.Remove(6, AddInsert)
obj.Show()
obj.RemoveAt(4)
obj.Show()

ExitApp

Escape::
guiclose:
ExitApp

Regards,
burque505
DynaComp.gif
DynaComp.gif (370.49 KiB) Viewed 2445 times
User avatar
evilC
Posts: 4823
Joined: 27 Feb 2014, 12:30

Re: CLR compiling - continuation section tricks

29 Apr 2019, 04:23

"The only real purpose of this is to show that you can dynamically alter C# or VB programs/scripts before compiling them"
Sorry, not seeing how this code does that - it just seems to create a collection and add some values to it.
Am I missing something?

Code: Select all

asm := CLR_CompileC#(csharp,"System.dll|System.Windows.Forms.dll|System.Collections.dll")
obj := CLR_CreateObject(asm,"Foo")
; First create a list of k/v pairs with some members initialized
obj.Create()
; Add a couple of key-value pairs
obj.Add(4, Add4)
burque505
Posts: 1736
Joined: 22 Jan 2017, 19:37

Re: CLR compiling - continuation section tricks

29 Apr 2019, 08:08

@evilC, in the OP the variables are expanded before compilation ("dynamically" - whether rightly or wrongly - referring to the fact that they were obtained from the GUI and not declared statically within the code) and variables are also added after compilation.

Code: Select all

        list.Add(new KeyValuePair<int, string>(1, "%MyFirstString%"));
        list.Add(new KeyValuePair<int, string>(2, "%MySecondString%"));
        list.Add(new KeyValuePair<int, string>(3, "%MyThirdString%"));
        // These AHK variables will be expanded before compilation.
In the code snippet you show, values are also being added afterwards. (Now in this particular case, granted, I could just add values afterwards - that's not always easy or even possible, especially with many 3rd-party .NET dlls.)

The value of the exercise to me is that I can now more easily deal with .NET dlls that don't lend themselves to creation with 'Clr_LoadLibrary' and manipulation following 'Clr_CreateObject', in AHK alone, without compiling any more C#. In the next day or so I'll be posting a find-and-replace script for .docx files, using DocX.dll, where I've had to use exactly the approach outlined above.
User avatar
evilC
Posts: 4823
Joined: 27 Feb 2014, 12:30

Re: CLR compiling - continuation section tricks

29 Apr 2019, 10:36

Ohhhh I get it, "%MyFirstString%" is not opening a string, specifying a variable, then closing the string, it's closing the string, specifying a variable, then opening the string again
Apologies...
burque505
Posts: 1736
Joined: 22 Jan 2017, 19:37

Re: CLR compiling - continuation section tricks

29 Apr 2019, 10:49

No apologies needed :)
I appreciate your interest, as always.
Regards,
burque505
sancarn
Posts: 224
Joined: 01 Mar 2016, 14:52

Re: CLR compiling - continuation section tricks

02 Jun 2019, 07:04

Cool stuff. IIRC you should use @"%var%" because I think the @ makes it a heredoc. See this example. This way it can easily deal with new lines and stuff :)
burque505
Posts: 1736
Joined: 22 Jan 2017, 19:37

Re: CLR compiling - continuation section tricks

06 Feb 2021, 11:17

@sancarn, apparently I missed your post a year and a half ago. Good point, thanks!
Spoiler
Regards,
burque505

Return to “Scripts and Functions (v1)”

Who is online

Users browsing this forum: No registered users and 266 guests