3

I'd like to get information about a third party application's controls such as a list of its properties and their values: something like RTTI information but for a third-party Delphi application.

I see that this is possible. For example TestComplete has the ObjectSpy window which can give many useful information about the control, including RTTI information. How can this be done ?

enter image description here

Edit: To explain why I'm investigating this issue... I'm a registered user of TestComplete/TestExecute and I do like... most of it. I can get over the minor things but the one major problem for me is their license verification system which requires me to have a physical computer (not a virtual machine) always on just for the sake of running a license server so that TestExecute can run at night. As I have basic testing needs (compare screenshots and check basic Delphi component's properties) I wondered how hard it would be to make my own private very simple "TestExecute-like" application.

menjaraz
  • 7,551
  • 4
  • 41
  • 81
jonjbar
  • 3,896
  • 1
  • 25
  • 46
  • @RRUZ No, you don't need to add any unit to your Delphi program to get that information. I've just tried with my own and it is reporting properties just fine. – jonjbar Apr 13 '12 at 17:12
  • Do you mean you want to inspect a running App written with Delphi with a custom utility (the one you are going to write)? I am not sure to grasp your requirement. – menjaraz Apr 13 '12 at 18:09
  • 1
    I think he wants to write his own TestComplete-equivalent, at least as far as the above screenshot shows, a property inspector inspecting into a running visible form for a Delphi application. Perhaps with debug information included in the executable, but no source code access. – Warren P Apr 13 '12 at 18:17
  • You mean Yet-another-TestComplete ! – menjaraz Apr 13 '12 at 18:49
  • I am still confused. My point is that *static analysis tool* also can be used to achieve what is stated in the header. – menjaraz Apr 13 '12 at 19:20
  • 1
    How would a static analysis tool read information like the VALUE of the `TPanel.Color` for instance? – Warren P Apr 13 '12 at 19:47
  • You are right: given it's a mutable property, inspecting it at runtime is the best way to tell. But isn'it possible to take a snapshot of the memory and do some static analysis based on the dump? – menjaraz Apr 14 '12 at 06:52
  • 1
    @menjaraz Yes I need to be able to request for the property value of a component at run-time and from another application. I can retrieve the handle of the component and was wondering how to get more information out of it (name, color...) knowing that this is a Delphi application. – jonjbar Apr 14 '12 at 08:50
  • 2
    Yep, that's called Writing your own non-breakpoint-based non-interactive debugger. – Warren P Apr 15 '12 at 14:20
  • @Warren P: It's rather an "out of process" runtime inspector, isn't that feasible? – menjaraz Apr 17 '12 at 17:07
  • Something that reads debug information and hooks into a running processes memory space and understands it enough to build a call stack, with function names, and to be able to parse the types of the parameters on that call stack, and then locate the local variables, and globals and so on, is called a debugger. – Warren P Apr 17 '12 at 18:13

2 Answers2

3

To go further, I suggest you these relevant resources found here on SO


I strongly suggest you to port to Delphi this c++ project entitled Get Process Info with NtQueryInformationProcess: A hands on experience on using ReadProcessMemory to access the CommandLine used to launch another process.


Last Edit:

Community
  • 1
  • 1
menjaraz
  • 7,551
  • 4
  • 41
  • 81
  • Those resources are very helpful and I'll study them. Thank you very much menjaraz. – jonjbar Apr 19 '12 at 07:51
  • @John Riche: Glad to help you. I am interested in you project. Tenez moi au courant svp:-). – menjaraz Apr 19 '12 at 07:59
  • See also [RRUZ](http://stackoverflow.com/users/91299/rruz) answer using `NtQuerySystemInformation` : [Delphi - get what files are opened by an application](http://stackoverflow.com/a/1575933/576719). – LU RD Apr 19 '12 at 08:45
  • @LU RD: Made an edit with due correct attribution for sake of visibility. I'll tidy this comment later. Thank you. – menjaraz Apr 19 '12 at 09:27
2

When we want to take another application which is compiled with debug information and get stuff out of it at runtime, what we are dealing with is the problem of "how to write my own custom debugger/profiler/automated-test kernel".

TestComplete and other AutomatedQA programs contain a Debugger and Profiler Kernel which can start up, run and remotely control apps, and parse their Debug information in several formats, including the TurboDebugger TD32 information attached to these executables. Their profiling kernel also can see each object as it is created, and can iterate the RTTI-like debug information to determine that an object that was created is of a particular class type, and then see what properties exist in that object.

Now, TestComplete adds on top of the AQTime-level of stuff, the ability to introspect Window handles, and intuit from Window Handles, the Delphi class Names that are behind it. However, it's much easier for you (or me) to write a program which can tell you that the mouse is over a window handle that belongs to a TPanel, than to know which version of Delphi created that particular executable, what version of TPanel that is, then, and what properties it would contain, and to read those values back from a running program, which requires that you implement your own "debugger engine". I am not aware of any open source applications that you could even use to get a start writing your own debugger, and you certainly can't use the ones that are inside AQTime/TestComplete, or the one inside Delphi itself, in your own apps.

I could not write you a sample program to do this, but even if I could, it would require a lot of third-party library support. To see the window classes for a window handle which your mouse is over, look for how to implement something like the MS Spy++ utility.

An easy case is if your mouse is mousing over a window inside your own application. For that, see this about.com link, which simply uses RTTI.

Warren P
  • 65,725
  • 40
  • 181
  • 316
  • @Warren P: As far as I can tell, TestComplete is able to get basic component information from applications which do not include debug information. Your example with TPanel is exactly what I'd like to achieve. Do you mean that just getting the "name" of a TPanel would be a very hard task involving creating a custom debugger engine ? – jonjbar Apr 14 '12 at 08:55
  • @menjaraz This is not useful as optaining the class name for a control is easy and I need other properties too. Also this application doesn't come with source code. – jonjbar Apr 14 '12 at 12:46
  • John: If in doubt, read the docs! TestComplete 8 docs say that you need debug info to get at the properties of delphi objects from testcomplete: http://support.smartbear.com/viewarticle/11168/?FullScreen=0 – Warren P Apr 15 '12 at 14:16
  • @menjaraz it looks like ReadProcessMemory is the way to go. Unfortunately, I couldn't find any suitable examples for my need. Thanks anyways. Warren: I'll accept your answer as it looks like this is the most complete I'll ever have even though I was hoping for a ready to use example. Thank you. – jonjbar Apr 18 '12 at 11:17
  • If I knew how to write one, I would definitely do so. having such a weapon in your arsenal would be a great thing indeed. If you ever do find a real working sample, please come back here, and answer your own question and change the accepted answer. (It's more important that StackOverflow's content be helpful than I get my little green checkmark, and my points, which don't matter anyways.) – Warren P Apr 18 '12 at 18:24
  • I'll make sure to do so if I ever get a working sample. Thanks. – jonjbar Apr 19 '12 at 07:50