DStraathof Posted October 18, 2019 Share Posted October 18, 2019 Hi all, I have an issue with a custom C# library & functions trying to use the result of these functions in AutoIT. I have a custom library which can or will not be ported to AutoIT. It is however operational in C#. Therefor I started looking and searching for options to pass the result of a request to this library (using C#) to AutoIT. I found LarsJ's examples of a DotNet AutoIt library, which could be helpful in using the necessary libraries and C# code in AutoIT. The custom library will securely (using all types of verification and security levels) select user credentials for a given customerID. The following C# code will actually do that (sorry, won't be able to post the library DLLs itself) using System; using SecureLib; namespace CustomerDetails { class User { static void Main() { var userdetails = CMDB("23680"); // get the userdetails for customerID 23680 foreach (var item in userdetails) { Console.WriteLine(item); } Console.ReadLine(); } static public string[,] CMDB(string cmp) { var y = new SecLibrary.Control(); var testInfo = y.FetchTestInformation(ref cmp); string[,] SelectedUser = new string[,] { { "Username", testInfo.Username.ToString() }, { "Password", testInfo.Password.ToString() }, { "WebURL", testInfo.WebURL.ToString() } }; return SelectedUser; } } } Next, I tried to grab the given information from the CMDB static stringarray in AutoIT usoing the following: #include "..\..\..\..\Includes\DotNetAll.au3" Opt( "MustDeclareVars", 1 ) Example() Func Example() Local $oNetCode = DotNet_LoadCScode( FileRead( "Program.cs" ), "System.dll | C:\References\Secure Library\SecLibrary.dll | C:\References\Secure Library\Security.ServiceBus.Helpers.dll" ) Local $oUserDetails = DotNet_CreateObject( $oNetCode, "CustomerDetails" ) Local $aVariants = $oUserDetails.CMDB('23680') _ArrayDisplay( $aVariants ) EndFunc When running the C# code it will give me the user details for the given customerID, but when running the AutoIT code it will error on: The requested action with this object has failed.: Local $aVariants = $oUserDetails.CMDB('23680') Local $aVariants = $oUserDetails^ ERROR I surely hope that one of the "Walking C# AutoIT knowledge base guru's" 😉 can help me out here... Thanks in advance. Link to comment Share on other sites More sharing options...
LarsJ Posted October 20, 2019 Share Posted October 20, 2019 DotNet_CreateObject takes class as second parameter and if you use a namespace it must be "namespace.class". The method called in the AutoIt code must be defined relatively simple. In CMDB, the static keyword causes problems. The general solution is to add a new simple method to handle the communication between AutoIt and the C# code. Here getCMDB. I've tested this code: using System; namespace CustomerDetails { class User { public string[,] getCMDB(string cmp) { return CMDB(cmp); } static public string[,] CMDB(string cmp) { string[,] SelectedUser = new string[,] { { "Username", "Username" }, { "Password", "Password" }, { "WebURL", "WebURL" } }; return SelectedUser; } } } #include "DotNetAll.au3" #include <Array.au3> Opt( "MustDeclareVars", 1 ) Example() Func Example() Local $oNetCode = DotNet_LoadCScode( FileRead( "tst00.cs" ), "System.dll" ) Local $oUserDetails = DotNet_CreateObject( $oNetCode, "CustomerDetails.User" ) Local $aVariants = $oUserDetails.getCMDB('23680') _ArrayDisplay( $aVariants ) EndFunc Note that arrays are different in AutoIt and C# code as rows and columns are swapped. You may want to use this array in the C# code: { "Username", "Password", "WebURL" }, { "Username", "Password", "WebURL" } DinFuv 1 Controls, File Explorer, ROT objects, UI Automation, Windows Message MonitorCompiled code: Accessing AutoIt variables, DotNet.au3 UDF, Using C# and VB codeShell menus: The Context menu, The Favorites menu. Shell related: Control Panel, System Image ListsGraphics related: Rubik's Cube, OpenGL without external libraries, Navigating in an image, Non-rectangular selectionsListView controls: Colors and fonts, Multi-line header, Multi-line items, Checkboxes and icons, Incremental searchListView controls: Virtual ListViews, Editing cells, Data display functions Link to comment Share on other sites More sharing options...
DStraathof Posted October 21, 2019 Author Share Posted October 21, 2019 Hi LarsJ, Thank you for a clear reply. Using the extra getCMDB function works for returning the string array. The issue I'm currently facing is the usage of the SecureLib library with the 2 extra DLLs, and this function call in the C# code: var y = new SecLibrary.Control(); var testInfo = y.FetchTestInformation(ref cmp); Will try myself using another personally created DLL will face the same problem. Keep you posted! Link to comment Share on other sites More sharing options...
DStraathof Posted October 22, 2019 Author Share Posted October 22, 2019 I have tested with a more basic custom DLL, but I can't get it to work properly. It seems that loading the custom DLL works, but referring from the C# script to this, by AutoIT loaded, DLL doesn't seems to work: Here's my class DLL: using System; namespace SelectUser { public class Greetings { public static string Hello(string name) { return $"Greetings {name}"; } } } This is the Program.cs, using/including the SelectUser.dll class created using Visual Studio: using System; using SelectUser; namespace CustomerDetails { class User { public string getCMDB(string cmp) { return Greetings.Hello(cmp); } } } This is the AutoIT script: #include "..\..\..\..\Includes\DotNetAll.au3" #include <Array.au3> Opt( "MustDeclareVars", 1 ) Example() Func Example() Local $oNetCode = DotNet_LoadCScode( FileRead( "Program.cs" ), "System.dll | C:\References\SelectUser.dll" ) Local $oUserDetails = DotNet_CreateObject( $oNetCode, "CustomerDetails.User" ) Local $sVariants = $oUserDetails.getCMDB('23680') ConsoleWrite( $sVariants ) EndFunc Could it be the nesting namespacing (form the .cs and the .dll and functions in C# that are blocking? The expected output should be: "Greetings 23680" Thanks for the help. Program.cs ToAutoItCS.au3 Class1.cs Link to comment Share on other sites More sharing options...
LarsJ Posted October 23, 2019 Share Posted October 23, 2019 When running C# code through AutoIt, there are probably some restrictions over what you can do in pure C# code. In the examples with DotNet_LoadCScode(), only assemblies registered in the GAC are used. In contrast, assemblies not registered in the GAC are loaded with DotNet_LoadAssembly(). In a very short test, I also couldn't make your code work. But I've made this code work: using System; namespace SelectUser { public class Greetings { public static string Hello(string name) { return "Greetings " + name; } } } namespace CustomerDetails { class User { public string getCMDB(string cmp) { return SelectUser.Greetings.Hello(cmp); } } } #include "DotNetAll.au3" DotNet_LoadCScode( FileRead( "tst02.cs" ), "System.dll", 0, "tst02.dll" ) #include "DotNetAll.au3" Opt( "MustDeclareVars", 1 ) Example() Func Example() Local $oComErrFunc = ObjEvent( "AutoIt.Error", "ComErrFunc" ) Local $oNetCode = DotNet_LoadAssembly( "tst02.dll" ) Local $oUserDetails = DotNet_CreateObject( $oNetCode, "CustomerDetails.User" ) Local $sVariants = $oUserDetails.getCMDB('23680') ConsoleWrite( $sVariants ) EndFunc In Visual Studio, if you create a single assembly dll and load it with DotNet_LoadAssembly(), it might be the easiest. Run the AutoIt code in SciTE with F5 so you can see error messages in the console. In the code above I've added a COM error handler. FrancescoDiMuro 1 Controls, File Explorer, ROT objects, UI Automation, Windows Message MonitorCompiled code: Accessing AutoIt variables, DotNet.au3 UDF, Using C# and VB codeShell menus: The Context menu, The Favorites menu. Shell related: Control Panel, System Image ListsGraphics related: Rubik's Cube, OpenGL without external libraries, Navigating in an image, Non-rectangular selectionsListView controls: Colors and fonts, Multi-line header, Multi-line items, Checkboxes and icons, Incremental searchListView controls: Virtual ListViews, Editing cells, Data display functions Link to comment Share on other sites More sharing options...
DStraathof Posted October 28, 2019 Author Share Posted October 28, 2019 Hi LarsJ, Thanks for the reply. I will test it this tomorrow. The issue why I need to include extra external DLLs is, that I can't include the functions from the Security DLLs in my own coded DLL. The external DLLs being: C:\References\Secure Library\SecLibrary.dll | C:\References\Secure Library\Security.ServiceBus.Helpers.dll" I need to find a way to do this, but I'll try your example code and let you know 🙂 Thanks again for thinking this through. Link to comment Share on other sites More sharing options...
DStraathof Posted October 29, 2019 Author Share Posted October 29, 2019 As I was afraid.... I need both external DLLs to be loaded into the AutoIT script. I cannot use the 'concatenate' option as with the DotNet_LoadCScode() function to load both DLLs in the same AutoIT object: Local $oNetCode = DotNet_LoadAssembly( "C:\References\Secure Library\SecLibrary.dll | C:\References\Secure Library\Security.ServiceBus.Helpers.dll" ) It returns an error: ToAutoItCS.au3(1136): ==> COM Error intercepted! Err.number is: 0x000000A9 Err.windescription: Variable must be of type 'Object'. Err.description is: Err.source is: Err.helpfile is: Err.helpcontext is: Err.lastdllerror is: 0 Err.scriptline is: 1136 Err.retcode is: 0x00000000 Is it possible to have 2 objects, and assign the compiled functions both in one AutoIT DotNet_CreateObject (hence the { } ), i.e.: #include "Includes\DotNetAll.au3" #include <Array.au3> Opt( "MustDeclareVars", 1 ) Example() Func Example() Local $oComErrFunc = ObjEvent( "AutoIt.Error", "ComErrFunc" ) Local $oNetCodeLibrary = DotNet_LoadAssembly( "C:\References\Secure Library\SecLibrary.dll" ) Local $oNetCodeServiceBus = DotNet_LoadAssembly( "C:\References\Secure Library\Security.ServiceBus.Helpers.dll" ) Local $oSecureControl = DotNet_CreateObject( {$oNetCodeLibrary,$oNetCodeServiceBus}, "SecLibrary.Control" ) Local $oUserDetails = $oSecureControl.FetchTestInformation('23680') ConsoleWrite( $oUserDetails.Username ) EndFunc Thanks again for thinking with me 🙂 Link to comment Share on other sites More sharing options...
LarsJ Posted November 2, 2019 Share Posted November 2, 2019 I don't know. What did you see when you ran the code? I'll take a closer look at the problem with third party assembly dlls. But I need time. Until there is nothing else to do but separate C# and AutoIt code. If you need the results from C# in AutoIt, you'll have to pass them through a file or similar. Controls, File Explorer, ROT objects, UI Automation, Windows Message MonitorCompiled code: Accessing AutoIt variables, DotNet.au3 UDF, Using C# and VB codeShell menus: The Context menu, The Favorites menu. Shell related: Control Panel, System Image ListsGraphics related: Rubik's Cube, OpenGL without external libraries, Navigating in an image, Non-rectangular selectionsListView controls: Colors and fonts, Multi-line header, Multi-line items, Checkboxes and icons, Incremental searchListView controls: Virtual ListViews, Editing cells, Data display functions Link to comment Share on other sites More sharing options...
DStraathof Posted November 7, 2019 Author Share Posted November 7, 2019 Hi LarsJ, Because both DLLs won't be loaded, the error states: Unable to parse line.: Local $oSecureControl = DotNet_CreateObject( {$oNetCodeLibrary,$oNetCodeServiceBus}, "SecLibrary.Control" ) Local $oSecurecontrol = DotNet_CreateObject( ^ ERROR So basically no clear error about this. I myself was also thinking about exchanging data between C# and AutoIt through a file. I'll try and see what will happen there. Thanks for looking into it. Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now