Tuesday, January 23, 2007

Linux Mini PC MacroView Demo

I was preparing for a demo scenario today where MacroView Windows Desktop needs to connect to a Linux or Unix system to show X windows connectivity and integration. Because of this, just a straight Windows laptop wasn't enough. I also didn't want to have to depend on Internet or even Intranet access to proceed with any demonstrations. The hardware I'm going to use is a Linux (Fedora Core 5) server running MacroView and a Windows laptop running the various client side software packages that are going to be demonstrated. A Linux server was borrowed from Sentient Computing. Thats the Linux server on the left in the pictures. Its a sweet little unit and is made up of a 1.5GHz Pentium M processor, 1GB RAM and an 80GB hard disk. Man ... I can remember when PSTN modems were way bigger than the Linux box in question.

The laptop is a Toshiba tablet with 512MB RAM and a 1.6MHz Pentium M. They're connected by a cross over ethernet cable. A nice aspect of the Fedora+mini-pc combination is that it boots without stopping even if no monitor, keyboard or mouse is connected. This means demo set up is quite easy. There is an external power supply which is a bit of a pain but all in all, the unit is quite nifty. The first picture below shows MacroView Windows Desktop with a VNC session running the KDE desktop. The second picture shows the MacroView XAML module running. The photos of the Toshiba screen are average and this is probably due to the nature of tablet pc screen surfaces.



Ranorex and Screenscraping/Automation

After many web searches looking into screen scraping technologies for automating legacy Windows applications, I came across a testing automation product from Ranorex. It's oriented towards the development process, but technically could also be used to script/automate interaction with a legacy Windows appplication. Check out this screencast where interaction with a Nokia DB2 Manager windows program was automated.


Wednesday, January 17, 2007

xops3 Command Line Arguments

I recently received a request from a customer for information on all the command line options for the MacroView xops3 executable. This post is a quick summary of the command line options:

-checkMemory
Runs xops3 in a memory buffer checking mode. This mechanism was included in the original MacroView Version 3 development from ~1992 as a means of chasing down memory faults in C++ applications. It is rarely used these days as tools such as Purify provide a more effective memory debugging approach. When used, every dynamically allocated memory segment is logged in a memory manager and header/footer segments surround the memory allocation. A memory manager then checks for allocation/deallocation pairs and memory overruns. It reports on any memory corruptions found and detects memory leaks. Note that program execution speed is of course much slower when run in this mode.
-file <dgtfile>
By default xops3 displays the base.dgt file in the configuration directory. This command line option allows a different startup graphic dgt file to be used.
-updateRate <seconds>
Sets the default scan rate for graphic updates in the xops3 session. This can be over-ridden by individual graphic metafiles in the dgt header.
-reportTimes
Reports on graphic dgt file load and display times. It is useful for measuring draw time performance.
-edit
Puts xops3 in EzEng configuration and editing mode.
-highlight
Displays dynamic graphic objects with a rectangular highlight box to allow an engineer to see the bounds of the object at run time.
-processEvents <n>
The metascript variable management system in xops3 will automatically inform all graphic objects that reference it that the variable has changed. The graphic objects can then immediately update their graphic state. The process events count defines how many of these events are process in a cycle. Note that a graphic object display update can potentially cause the variable to be set again. The event processing limit stops this potential recursion from continuing indefinitely. A zero value turns off the variable change event processing which means that graphic display updates occur at the dgt page's update rate. The default is that all events in the variable set event queue are processed.
-olderr
The xops3 error processing system handles each internally generated error message and either stores the error in an internal (table variable based) list or sends the error as a system alarm to the system message queue. Previous versions of xops3 sent all internal errors to the system message queue and didn't keep an internal list. The -olderr command line option reverts operation to this older message processing implementation.
-noConfig
Runs the xops3 session with no configuration directory i.e. the entities, sources and type attribute databases are not read.
-lastGoodValue
By default, xops3 expects a shared memory driver to update an entity.attribute value on a regular basis and will display -999 values if it is not updated regularly. The determination of "regular" is data source specific and is based on the requested update rate configured in that data source. The -lastGoodValue command line option turns this check off so that the last good value is displayed even if the communications driver is failing to meet the configured update rate for that entity.attribute. This functionality is not supported in the Windows version of the executable.
-consoleSet
A defunct command line option for an xops3 feature called "Console Sets" that is no longer supported.
-letScript <filename>
Instructs xops3 to run a metascript from the supplied file every time a LET command is executed on a PLC or sorted image data source entity.attribute. The metascript is run with 3 arguments in the following order: entity name, attribute name and a value string. This allows xops3 to perform LET action side effects across a whole graphic configuration instead of having to embed calls throughout a graphic configuration.
-iocount
Reports the IO count for the current configuration. This is the number of entity.attribute instances derived from the configuration. It is also the value used for IO count licensing checks.
-dlm
A defunct command line option for an xops3 feature for logging database changes that is no longer supported.
-metascriptProgramTime <seconds>
Sets the maximum amount of time a metascript can take to run within the xops3 GUI environment before it is automatically terminated. The default is 10 seconds which is also the minimum setting. A value of -1 turns of the maximum execution time checks.
-startMaximized
Starts xops3 in a maximized window state rather than the default window size.
Xt command line arguments
xops3 on Unix/Linux also supports standard Xt command line arguments such as -geometry.

Thursday, January 11, 2007

Weird ImageListStreamer InvalidOperationException

One of our MacroView Studio customers sent a strange stack trace from an application crash yesterday. It's strange in that the standard Windows Forms ImageListStreamer class is where the exception occurs. The exception being thrown is a TargetInvocationException wrapping an InvalidOperationException and occurs as a result of very basic form constructor code which is run many times in the application and hence many users will run that code during normal operation. As is typical with tough to resolve faults, I can't reproduce it in the office and will wait for more information from the customer if it occurs again. Regardless the symptoms and some results of web research into the problem has been posted here for any other poor souls that encounter it and also for my own benefit as a record. Here's the stack trace:


Exception Details:
System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.InvalidOperationException: Loading of the ImageList did not succeed.
at System.Windows.Forms.ImageListStreamer..ctor(SerializationInfo info, StreamingContext context)
--- End of inner exception stack trace ---
at System.RuntimeMethodHandle._SerializationInvoke(Object target, SignatureStruct& declaringTypeSig, SerializationInfo info, StreamingContext context)
at System.RuntimeMethodHandle.SerializationInvoke(Object target, SignatureStruct declaringTypeSig, SerializationInfo info, StreamingContext context)
at System.Reflection.RuntimeConstructorInfo.SerializationInvoke(Object target, SerializationInfo info, StreamingContext context)
at System.Runtime.Serialization.ObjectManager.CompleteISerializableObject(Object obj, SerializationInfo info, StreamingContext context)
at System.Runtime.Serialization.ObjectManager.FixupSpecialObject(ObjectHolder holder)
at System.Runtime.Serialization.ObjectManager.DoFixups()
at System.Runtime.Serialization.Formatters.Binary.ObjectReader.Deserialize(HeaderHandler handler, __BinaryParser serParser, Boolean fCheck, Boolean isCrossAppDomain, IMethodCallMessage methodCallMessage)
at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream serializationStream, HeaderHandler handler, Boolean fCheck, Boolean isCrossAppDomain, IMethodCallMessage methodCallMessage)
at System.Resources.ResourceReader.DeserializeObject(Int32 typeIndex)
at System.Resources.ResourceReader.LoadObjectV2(Int32 pos, ResourceTypeCode& typeCode)
at System.Resources.ResourceReader.LoadObject(Int32 pos, ResourceTypeCode& typeCode)
at System.Resources.RuntimeResourceSet.GetObject(String key, Boolean ignoreCase, Boolean isString)
at System.Resources.RuntimeResourceSet.GetObject(String key, Boolean ignoreCase)
at System.Resources.ResourceManager.GetObject(String name, CultureInfo culture, Boolean wrapUnmanagedMemStream)
at System.Resources.ResourceManager.GetObject(String name)
at Syncfusion.Windows.Forms.Edit.FindReplaceDlg.InitializeComponent()
at Syncfusion.Windows.Forms.Edit.FindReplaceDlg..ctor()
at Syncfusion.Windows.Forms.Edit.EditControl..ctor()
at MacroView.Script.MetascriptEditControl.InitializeComponent()
at MacroView.Script.MetascriptEditControl..ctor()
at MacroView.Script.MetascriptEditor.InitializeComponent()
at MacroView.Script.MetascriptEditor..ctor()


Some links that are relevant:


It appears from web searches on the problem is that it is likely to be caused by accessing winform controls from other than the GUI thread and/or the visual styles functionality. This theory is re-enforced by looking at the code for the System.Windows.Forms.ImageListStreamer class serialization constructor using Reflector. The constructor includes native platform theming calls and synchronization support. I don't what goes on to cause the fault but it's very subtle and is rare. At first I suspected the Syncfusion (legacy) edit control of perform winform control actions across threads but the debugger showed that although the thread code was there, it shouldn't ever be called in the MacroView Studio application scenario.




IntPtr ptr1 = UnsafeNativeMethods.ThemingScope.Activate();


try


{


MemoryStream stream1 = new MemoryStream(this.Decompress(buffer1));


lock (ImageListStreamer.internalSyncObject)


{


SafeNativeMethods.InitCommonControls();


this.nativeImageList = new ImageList.NativeImageList(SafeNativeMethods.ImageList_Read(


new UnsafeNativeMethods.ComStreamFromDataStream(stream1)));


}


}


finally


{


UnsafeNativeMethods.ThemingScope.Deactivate(ptr1);


}


if (this.nativeImageList.Handle == IntPtr.Zero)


{


throw new InvalidOperationException(SR.GetString("ImageListStreamerLoadFailed"));


}



Friday, January 05, 2007

Line Margin Selection Edit Control Request

This post is a request to Syncfusion for an additional feature in their Edit Control functionality. The blog was just a convenient place to put a screencast related to the feature request submitted on their site. Showing a concept rather than describing it in text can often be a better way to communicate.