Automating Millennium
Through Third Party or
Home Grown Utilities
Terry Reese
Oregon State University
terry.reese@oregonstate.edu
http://oregonstate.edu/~reeset/presentations/index.html
NWIUG Fall, 2003
University of Portland, Oregon
Roadmap
• Why we are here
• Current state of automation in Millennium
– Shortcomings that I see
– Possible remedies
• 3rd Party (for cost) solutions
• Custom solutions
– How one goes about interacting with Millennium
– Examples
• Where do we go from here
Why are we here?
Why are we here?
• Automation use to be simple
– Character-based provides many
automation alternatives
• Server-side scripts (expect, perl, python,
java)
• Client-side solutions (Passport/CatMe using
OML, QTERM (macro language)
Why are we here?
• Character-based was familiar
– deep down, we all prefer the old command-
line – right?
Why we are here?
• Character-based made us happy
– Interface was intuitive
– Fast (which is good when automating)
– Transparent (for the most part)
• ie., no “messages” or events were hidden
from view
State of automation
• For all practical purposes – it doesn‟t exist
– Millennium macros
• Essentially a fancy sendkey program
• Provides only procedural automation
– i.e., key1, key2, key3, key4
– No ability to add conditional execution because
Millennium provides no facility for testing data
structures within the program
– Short-cut keys
Shortcomings (as I see „em)
• Millennium “Macros”
– Hidden from the user
• By placing them in the login manager, III has
essentially made Millennium “macro” free for most
users.
– Are in name only
• Essentially just keystrokes
• No conditionals
• Useful for:
– Entering constant data
– Automating repetitive key stroke sequences
Shortcomings (as I see „em)
• Millennium “Macros”
– Macros are tied to a user‟s Millennium
login
• Makes sharing “macros” between logins
difficult if each users has their own
Millennium login
Example
Possible Remedies
• Built-in Macro language
• Publish communication specs. to allow
3rd party interaction with the
database (designing your own client)
• Stop advertising that Millennium
supports macros (confuses
administrators)
Automation Solutions
• Don‟t ever use Millennium (not very
realistic)
• Buy something
– Limitations in regards to the type of
interaction available.
• Make something
– Limitation in regards to the type of
interactions available.
3rd Party solutions
• Interactions limited to:
– Keystroke interactions (though may
allow for some conditionality)
– Data being sent by a port
• example: Workstation Deskjet setup
A closer look
• MacroExpress:
http://www.macros.com/macexpdo.htm
– Creates a set of hotkeys (shortcuts)
• Can be used globally
• Can be application specific
– Basically provides a more robust version of
Millennium‟s built in “macro” facility – but with
a recorder to help in constructing the
keystroke sequences.
Building it yourself
• Problems
– Millennium is a closed application (i.e., no
published method to interact with the
software)
– Form-based
– No documentation (goes hand in hand with
being a closed system)
– III seems to have little interest in allowing
this level of interaction (not unusual for a
propriety vendor)
Taking a closer look
• Opportunities for automation
– Finding ways to work with data outside
of Millennium (using Windows as a
mediator
– Taking advantage of all data Millennium
does offer
Taking a closer look
• Using Windows as a mediator
– Why? Direct automation doesn‟t seem
possible
– How? Using the Clipboard represents
one opportunity to work with data
outside the system.
Example: Using the
Clipboard
• Example has 3 components
– Milsub.exe
• Subclasses the Windows Message Pump allowing you
to create global shortcut keys using the Windows key
– HelperClass.dll
• Wraps functionality not available in vbscript (like
accessing the clipboard)
– Vbscripts
• Does the actual data processing.
Milsub.exe
Private Sub RegKeys()
'****************************
'REGISTER YOUR HOT KEY HERE !
'****************************
Dim i As Boolean
Dim FF As Long
Dim str_Data As String
Dim arr_Data() As String
Dim ID As Long
Dim lng_Key As Long
ID = 0
FF = FreeFile
Open App.Path & "\config.ini" For Input As FF
Do While Not EOF(FF)
Line Input #FF, str_Data
If Len(Trim$(str_Data)) 0 And Left$(str_Data, 1) "'" Then
arr_Data = Split(str_Data, ",")
If IsNumeric(arr_Data(0)) = False Then
lng_Key = Asc(UCase$(arr_Data(0)))
Else
lng_Key = Val(arr_Data(0))
End If
ReDim Preserve str_app(0 To ID)
str_app(ID) = arr_Data(1)
i = RegisterHotKey(hwnd, ID, MOD_WIN, lng_Key)
ID = ID + 1
End If
Loop
Close FF
If Not i Then
MsgBox "Error: Keys could not be set"
Else
lng_Pause = False
WinProc = SetWindowLong(hwnd, GWL_WNDPROC, AddressOf ProcessWin)
End If
End Sub
HelperClass.dll
• Wraps functions that vbscript
doesn‟t support (in this case –
clipboard support)
Public Function GetText() As String
GetText = Clipboard.GetText
End Function
Public Function SetText(ByVal sText As String, Optional ByVal lFormat As ClipBoardConstants = vbCFText)
As String
Clipboard.SetText sText, lFormat
End Function
Public Sub ClearData()
Clipboard.Clear
End Sub
vbscripts
• Scripts are designed to do the actual
data processing
• Scripts are called from Milsub.exe
• Scripts are defined in config.ini,
which is in the same directory as
Milsub.exe
Take a look
Example: Data from a
Port
• Example: Creating a Label Printer
– How?
• Millennium can print to an HP JetDirect
• HP JetDirect Port is 9100
• Example creates a client server that listens
on the 9100 port and processes data as it
comes in.
iiijet.exe
• Written in PowerBasic
(http://www.powerbasic.com)
• Program Outline
1. Create a windowless dialog
2. Subclass dialog and open port 9100 and
listen for connection request.
iiijet.exe
• Program Outline
3. On connect, send data to the tcp
callback functions
4. Clean data and modify format
according to iiijet.ini config.
Specifications (ini file is found in the
iiijet.exe program directory)
iiijet.exe
Where do we go from
here?
??????
References
• Source for all examples referenced can be
found at:
http://oregonstate.edu/~reeset/presenta
tions/index.html
• Sources written in:
Visual Basic: Milsub.exe, Helperclass.dll
PowerBasic: iiijet.exe