
This week I was asked if GP Power Tools could automatically handle the login to email dialogs. Initially, I was thinking that this would not be possible as the login dialogs for both the Exchange Web Service and Multi Factor Authentication modes are not Dexterity based.
Then I decided to experiment with the .Net SendKeys Class using a .Net Execute script in GP Power Tools to see if the dialogs could be controlled by using code to insert keystrokes into the keyboard buffer.
To get this working, we would need to add a trigger just before the dialog is opened so we can insert the required keystrokes into the keyboard buffer to populate the dialog and press Enter.
Exchange Web Service
The Exchange Web Service (EWS) dialog opens when the Mail_LogOn() Function Library command is executed. Many of the Dexterity Function Library commands are actually global functions in the DEX.DIC runtime engine dictionary wrapping system commands. By registering a trigger before this function with the handling script to load and execute a .Net Execute script, we can use SendKeys.Send() to send User@Domain.com<Tab>Password<Enter> to the dialog.
This method worked most of the time, but I noticed it failed sometimes if the dialog was slow to open as the first few keystrokes would be lost. I decided that it was good enough for now and started work on the next part of the problem.
Multi Factor Authentication
Using the Administration >> Setup >> Company >> Email Settings window and entering the Application Client ID for your instance of Exchange on Office 365 enables Multi Factor Authentication (MFA) mode.
Now when a connection to mail is required, GP will call the MSGraphEmail_Logon() of form syEmailObj function. Registering a trigger before this function with the handling script to load and execute a .Net Execute script to call SendKeys.Send() failed all the time as the keystrokes were not going to the dialog.
Note: I did manually work out that you need to press <Tab> then six Shift <Tab> keystrokes and then <Enter> to select the Use another account option as the first step. Then we can actually enter an email address and password as steps 2 and 3 respectively.
The failure of this code was probably because there was a much longer delay before the MFA dialog opened. We needed a different approach.
The Problem
You might think that adding a delay to the code before calling SendKeys would help, but as this code was running before the call which opens the dialog, it would just delay the dialog opening without actually delaying the keystrokes relative to the dialog opening.
What we need is a way to wait for the dialog to open so we can send keystrokes but without stopping the underlying code from running. The problem is that when a call to an external process is made, execution of Dexterity code is paused until the external process completes and returns control to Dexterity. This is how calls to Win32 DLLs, COM, .Net and even SQL Server are handled. Dexterity is a 32-bit single threaded application and cannot perform more than one action at a time.
Before you ask about the Background process queue in Dexterity, this is still within the same single thread. The background queue runs scripts while the foreground user interface is idling waiting for the user to do something. This is not multi-threading, but just smart use of idle time on a single thread.
The Solution
This where things get a little creative. By combining a number of different techniques, we have a method works perfectly and can be used to control any external dialog or application and probably can be used against Microsoft Dynamics GP windows as well.
- If you use SendKeys.SendWait() it is slower but makes sure that the application processes the keystrokes.
- Using FindWindow@user32.dll you can get the pointer to any open window.
- Using SetForegroundWindow@user32.dll you can bring that window to the foreground so that it has the keyboard focus.
- You can use Thread.Sleep() to pause for a number of milliseconds.
- You can use Thread.Start() to start a secondary thread allowing the primary thread to complete and the Microsoft Dynamics GP code to continue.
Putting this all together, we have a trigger that runs just before the dialog opens, it loads and executes a .Net Execute script. That script creates a second thread and returns back to GP so it can open the dialog.
Meanwhile, the second thread sleeps for a bit to give the dialog time to open, it then finds the window and makes it the foreground window. Finally, it starts sending keystrokes to the dialog with appropriate sleep pauses each time the dialog updates to ensure keystrokes are not missed.
Once this approach was working for the MFA dialog, it made sense to go back and use the same approach for the EWS dialog which made it reliable.
Conclusion
There is massive potential in these techniques. It provides the ability to control non-Dexterity dialogs or dialogs that are not of a type that GP Power Tools triggers can work with. It could also be used to control external applications and also windows within GP.
Note: Native Dexterity does support triggers on modal dialogs.
Here is the Project with two triggers for the two email modes (MFA and EWS) with two .Net Execute Scripts using the Multi-Threaded technique.
There is also a Runtime Execute script which can be used to test the dialogs. It will logout and then log back in forcing the dialog to open. The mode is controlled by whether a Client ID has been entered on the Email Settings window.
The last .Net Execute Script was the first technique for the EWS dialog which works faster but was not 100% reliable.
Downloading and Installing
Download the example code, import using the Project Setup window (now possible for first time imports with Build 28.8 onwards), or use Configuration Export/Import window (for older builds):
The code will be active on next login or after switching companies, or you can use start the triggers manually from the Project Setup window.
More Information
For Dexterity based modal dialogs and system dialogs please see:
- #GPPT Controlling System Dialogs using Modal Dialog Focus Triggers
- #GPPT Automating or Customizing the Report Destination Window Revisited
For more information see:
- GP Power Tools Portal: http://winthropdc.com/GPPT
- GP Power Tools Samples: http://winthropdc.com/GPPT/Samples
- GP Power Tools Videos: http://winthropdc.com/GPPT/Videos
Hope you like the techniques used in this project and can find other uses for them.
I already have some ideas to try out…
David
05-Jan-2024: Added links for how to control Dexterity modal and system dialogs.
This article was originally posted on http://www.winthropdc.com/blog.




2 thoughts on “#GPPT Controlling Any Dialog. Automatic Email Login”