|
|
Comments and Discussions
|
|
 |

|
Hi ,
The program is working great in 32 bit system , but I am having trouble in 64 bit OS . I tried to compile Inject Lib for x64 and ObjectSpyLib for x32 but its not working. Please suggest the corrections.
|
|
|
|

|
I'm pretty sure it doesn't work if you try compiling ObjectSpyLib to x32. I would leave it at "AnyCPU", causing the JIT compiler to compile the IL code to 32 or 64 bit as needed at runtime.
If this is not solving the problem, I would check the sizes of the various structures especially in InjectLib - maybe one of them does not adjust to 64 bit.
|
|
|
|

|
I tried compiling objectspylib for AnyCpu , but now also its not working , Control browser is not displayed.
|
|
|
|

|
Hi,
Can i use this tool to fetch properties of a web application?
if so tell me how and if not tell me how to modify the existing so that i can use this for web applications.
Thanks,
Karthik
|
|
|
|

|
In a web application, the .NET code is running server side and delivers HTML/script code to the client. This means there is no .NET code on the client, so you can't use .NET Object Spy on the client.
|
|
|
|

|
Hi,
Thanks for the update.
I have a requirement to develop a similar tool which will work for web application, to recognize objects,
Like tool Object Spy with Hat in QTP and Coded UI Test Builder(Visual Studio Ulimate 2010 and 2012)
Please suggest me on how to proceed.
Thanks
-Karthik
|
|
|
|

|
The code runs on the server, so it is not possible to make a similar tool. Please read the other comments and my replies to understand why.
|
|
|
|

|
doesn't work on win7. It injects-aok, but doesn't show hierachy.
|
|
|
|

|
Are you sure the form you are injecting it onto is coded in .NET? If not, it cannot read it's content using .NET reflection.
|
|
|
|

|
I am never sure of anything, but I just cked, My PC here is win7. Perhaps I did it wrong.
|
|
|
|

|
Checked what?
The OS (e.g. Windows 7, Vista or XP) doesn't matter (although 64 bit requires modification/recompilation - see the other threads)
But what matters (and what I suspect is your problem) is that you are not injecting it into a .NET application. As I've mentioned in the introduction, this tool was intended to help debugging .NET applications. It is not capable of providing debugging information about e.g. native applications.
|
|
|
|

|
I plan on using this code. Dunno yet if it will help me in debugging creating Desktops within a Service.
|
|
|
|

|
Hi bjarneds
I wonder in case I embed my DLL to .exe (small application with all dll in one exe file) make an easier way to distribute it to customer.
http://www.digitallycreated.net/Blog/61/combining-multiple-assemblies-into-a-single-exe-for-a-wpf-application[^]
My case is the DLL i want to be inject already inside .exe file @_@ ! of-course the call from injector can not found that DLL (assemblyFile)
object Injector.InvokeRemote(IntPtr hWnd, string assemblyFile, …)
So, is there a way to overcome this problem but still make our program 1 file ?
Or I mean is there a way to inject an embedded DLL ?
Regards, Dien Vu
|
|
|
|

|
I'm not sure I fully understand what you are trying to do, but I guess you mean that the DLL you want to inject is embedded in the .EXE file you are using to inject it (not the application you are injecting it to). And that you are only using InjectLib (not ObjectSpy or ObjectSpyLib).
I noted that the article you refer to mentions subscribing to AppDomain.CurrentDomain.AssemblyResolve. Note that InjectLib also do that, to ensure that the receiving application can resolve the InjectLib assembly. My guess is that you need to extend this event handler, to make it able to resolve not only InjectLib, but also the DLL that you are injecting. Currently, the AssemblyResolve event handler doesn't look at the input parameters, it just always returns the InjectLib assembly.
|
|
|
|

|
Control.FromHandle returns null after injecting into other winforms applications (x86 or x64).
Could you please help?
|
|
|
|

|
Maybe some forms in the WinForms application is native forms? Or some forms may belong to another AppDomain than where the code is injected?
|
|
|
|

|
System.BadImageFormatException: Could not load file or assembly File name: at Bds.ObjectSpy.MainForm.Browse_Click(Object sender, EventArgs e)
at System.Windows.Forms.ToolStripItem.RaiseEvent(Object key, EventArgs e)
at System.Windows.Forms.ToolStripMenuItem.OnClick(EventArgs e)
at System.Windows.Forms.ToolStripItem.HandleClick(EventArgs e)
at System.Windows.Forms.ToolStripItem.HandleMouseUp(MouseEventArgs e)
at System.Windows.Forms.ToolStrip.OnMouseUp(MouseEventArgs mea)
at System.Windows.Forms.ToolStripDropDown.OnMouseUp(MouseEventArgs mea)
at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Forms.ToolStrip.WndProc(Message& m)
at System.Windows.Forms.ToolStripDropDown.WndProc(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
|
|
|
|

|
Take a look on the other comments, and you will see that the problem is 32 vs. 64 bit.
|
|
|
|

|
well it is really great work but i tried something more & i failed , i tried to make a windows service to inject a dll inside the Explorer , it worked when i tried it from an application but it failed when i try it from a windows service
any info about that
thanks
bye
|
|
|
|

|
Well, I haven't tried doing it from a service. However, I have had problems injecting into an application running under a different user account (started with "run as"). In fact, it doesn't even have to be another account. As long as the injecting application and the application you are injecting into is not running in the same logon session (I think this is what it is called), the injection seems to fail. I would suspect that this could be the case for Explorer and a Windows Service. I haven't had time to dig further into it, so unfortunately I don't have a solution.
|
|
|
|

|
Hi,
i want to write an Addon for Pokerstars.
But the major hurdle is to get the messages in chat box on the PokerStars client..
I found a solution ( http://www.codingthewheel.com/archives/how-i-built-a-working-online-poker-bot-7 )
but it is in c++ and i have less experience with c++ and win API
I hope you can help me in c# or vb.net.
|
|
|
|

|
Well, I just quickly skimmed through the page you are linking through. Seems quite interesting, however I noted the following explanation as to why Spy++ just sees empty text:
Because the Poker Stars game chat window isn't a standard Windows control, with well-defined behavior.
This wouldn't necessarily be bad - this might be something ObjectSpy could help with. However, the explanation continues:
It's a custom window, likely implemented using MFC (we know this because of the characteristic "Afx:" window class).
MFC means not .NET, and since ObjectSpy is limited to .NET, it cannot help you. Sorry.
Actually, I don't think the page gives you a solution to get messages into the the chat box, it's more like modifying the text that the chatbox outputs on the screen, using the text rendering APIs in Windows. This may look the same to a user, but I'm afraid you'll have to deal with C++ and the Windows API to accomplish this.
|
|
|
|

|
Thank you for the informations.
Its many years ago i learnd c++.
Now i ve to take my old c++ books from my bookshelv. Maybe you cam recommend me a Win API book or tutorial.
|
|
|
|

|
This examples not work on windows 7.
I get message: "System.BadImageFormatException: Nie można załadować pliku lub zestawu 'InjectLib, Version=1.0.3694.26047, Culture=neutral, PublicKeyToken=null' lub jednej z jego zależności. Próbowano załadować program w niepoprawnym formacie."
|
|
|
|

|
You seem to be right, I just tried it on my media center PC running Windows 7 (64-bit), and got the same exception. However, it might also be the 64-bit that is causing problems, have you tried it on 32-bit?
I don't have the time right now to look into it, but here's a few suggestions you could try (a quick search seems to indicate some patching may be needed to make this possible on express editions):
- Compile InjectLib to 64-bit
- Compile ObjectSpy and/or the target application to x86 (default is "any CPU", meaning JIT will take it to 32 or 64 bit as needed)
|
|
|
|

|
Hi!
The sample works fine on Win7 32bit. The exception you get seems to indicate that there's a problem with mixing 32bit and 64bit.
Regards,
mav
--
Black holes are the places where God divided by 0...
|
|
|
|

|
Solution: Set the project to compile to 'x86' instead of 'Any CPU'
|
|
|
|

|
Hi,
It is really good job. Do you know how to get menu item texts (i.e. File, Edit and their submenu texts) ?
|
|
|
|

|
That depends on what control that has been used to implement the menus. Assuming that the MenuStrip class in the .NET Framework Class Library is used, the File menu's text would typically be Items[0].Text, it's first submenu's text would be Items[0].DropDownItems[0].Text etc. This assumes you have injected the Object Browser directly on the MenuStrip control, if it is injected e.g. on the form instead, you have to first browse to the MenuStrip using its name (e.g. menuStrip1).
Generally, you can find this information using the API documentation of whatever class you are interested in (e.g. for MenuStrip, see here: http://msdn.microsoft.com/en-us/library/system.windows.forms.menustrip_properties.aspx[^]).
|
|
|
|

|
I want to write a C++ program to read texts of any windows. I can get the handles of windows and its controls by using API some functions (i.e. FindWindow, GetClassName) but I cannot get menu texts. How can I do this by API functions?
Thank you for your answer.
|
|
|
|

|
To get the text of any window or control, you can simply use GetWindowText once you have the handle - you don't need ObjectSpy for this (in fact, ObjectSpy uses this technique itself, watch the textbox labelled "Text:" while you drag the crosshair around to different windows/controls).
The problem arises when a control doesn't just have one, but a lot of texts. As you have discovered, this includes menus, other typical examples are lists, trees and grids. These texts are stored internally in the control, windows has no knowledge of these. This means you cannot use a Win32 API function like GetWindowText to read these.
For some controls, it might be possible to read some of these texts by sending an appropiate windows message to the control (you will have to look in the documentation for the control to find out if this is possible, and what message to send).
For .NET controls, another approach is to use reflection. This is what ObjectSpy does. If you want to use this functionality from your own C++ program, you need to do the same as the ObjectSpyEE sample application does, i.e. make a call like this:
string result = (string)Injector.InvokeRemote(hWnd, "ObjectSpyLib.dll",
"Bds.ObjectSpy.ObjectSpyEvaluator", "Evaluate",
new object[] { hWnd, "Items[0].Text" });
Note that this is .NET code, so you need to make a mixed-mode C++ program (or alternatively expose a C/C++ function in the InjectLib library that wraps this call).
Again, please note this approach only works for .NET controls. See some of my other replies (here[^]) and here[^]) for details.
|
|
|
|

|
Thank you for detailed information. It gives me the answeres to the questions that make me confused
|
|
|
|

|
Is there any reason for the popup menu "Inject object browser" ??? Why not directly show the object browser window ?
|
|
|
|

|
Since showing the browser injects and runs code in another process, it could actually affect the stability of that process. So I wanted a way to cancel the operation, e.g. if you accidently released the mouse button on the wrong application (like VS with 2 hours of unsaved code).
Also, sometimes I use it just to find window handles or see how an application is divided in controls, without wanting to inject and start the browser window.
But if it suits you better to bypass the popup, it should be an easy task to modify the code.
|
|
|
|

|
Great job, but I tried to compile it with VC#2005, and it fails to evaluate other process' objects
(it says "InvokeRemote Failed System.InvalidCastException: Unable to cast object of type Bds.Inject.RequestMessage to type Bds.Inject.RequestMessage at MessageHookProc(...)
Any suggestions?
Thanks a lot.
|
|
|
|

|
I don't think it has anything to do with C# 2005 (I compiled it with C# 2005 Express). Also, the error message seems to indicate that it not evaluating objects in the other process that is the problem, instead the problem is type-casting the data transmitted to the other process by calling InjectLib's InvokeRemote method. These data are "packaged" as a RequestMessage value type defined in InjectLib, which is then serialized in the sending process and deserialized in the receiving process, followed by a typecast which fails.
A few suggestions for debugging:
- Note that InjectLib is not a C# project, but managed C++. Have you compiled your own version of that, or are you using the version I compiled?
- Are you sure that the InjectLib.dll you have in the folder from which you are running ObjectSpy is the same version as the version you compiled ObjectSpy against?
- The buffer for transferring data from one process to another has a hardcoded size, 2000 bytes (defined in InjectLib). Are you exceeding this size? (shouldn't really be possible, unless you modified ObjectSpy's call to InvokeRemote, or you are using this call in your own project)
|
|
|
|

|
bjarneds wrote: - Note that InjectLib is not a C# project, but managed C++. Have you compiled your own version of that, or are you using the version I compiled?
I used both your InjectLib.dll and Visual C++ compiled one.
bjarneds wrote: - Are you sure that the InjectLib.dll you have in the folder from which you are running ObjectSpy is the same version as the version you compiled ObjectSpy against?
What do you mean? I have compiled everything (InjectLib, ObjectSpyEE and ObjectSpyLib) and placed
the appropriate DLL's into the executable directory.
bjarneds wrote: - The buffer for transferring data from one process to another has a hardcoded size, 2000 bytes (defined in InjectLib). Are you exceeding this size? (shouldn't really be possible, unless you modified ObjectSpy's call to InvokeRemote, or you are using this call in your own project)
The buffer size is not exceeded.
Anyway, I'll check it again. But I think I've learned a lot from your project - I never used
.NET until now - I have to write a .NET spy module. YOU'VE REALLY REALLY HELPED ME.
Best regards.
|
|
|
|

|
jjrv wrote: bjarneds wrote:
- Are you sure that the InjectLib.dll you have in the folder from which you are running ObjectSpy is the same version as the version you compiled ObjectSpy against?
What do you mean? I have compiled everything (InjectLib, ObjectSpyEE and ObjectSpyLib) and placed
the appropriate DLL's into the executable directory.
What I meant was, that ObjectSpy (and ObjectSpyEE) references InjectLib. So if ObjectSpy(EE) uses one version of InjectLib (and thus serializes one version of RequestMessage), while the target process somehow finds and loads a different version of InjectLib (and thus attempts to typecast the deserialized data to another version of RequestMessage), I would imagine this kind of error to occur.
As far as I know, not only name but also version (and culture) of a type is included in binary serialization. This means that if the above is what happens, it doesn't matter if the two versions are identical codewise, the version number also matters. And since this may be incremented automatically when you build, compile order is also important (compile InjectLib first, then ObjectSpy(EE)).
By the way, now that I see you use ObjectSpyEE instead of ObjectSpy, note that the 2000 bytes limit includes the expression that you enter. And note that in .NET, strings are unicode and thus takes 2 bytes per character.
Also, have you tried ObjectSpy insted of ObjectSpyEE, and if so, does this work? This may be interesting because there is no difference between how the two projects uses InjectLib.
|
|
|
|

|
hi.
i want to capture all properties of web page. could u please guide me. how can i capture properties of any web application , using this object spy
Thanks
ROhit
|
|
|
|

|
Well, I'm not sure exactly what you mean by web page/web application. Object Spy is capable of browsing members in a .NET application. Although I haven't tried it, I assume it will also work for .NET controls running in a browser. It will NOT work for ASP.NET applications, since the .NET code is running server side and delivers HTML/script code to the browser.
|
|
|
|

|
Hi
Thanks for your reply ,, but i wann to create a spy which can able to capture or recognize all properties of ASP.NEt application and websites. Please reply me soon. i need of it..
so i can able to create a web spy,
thanks for reply
|
|
|
|

|
Please see my response to your questions in the thread "Have you checked Hawkeye?".
|
|
|
|

|
This tool is very usefull. Thanks a lot!
Geniality is in simplicity.
|
|
|
|

|
Would development of this kind of program be possible for use on unmanaged apps?
|
|
|
|

|
If by unmanaged, you mean native, then no (at least not without additional debug information). For .NET applications, ObjectSpy is able to look into the objects because .NET classes includes metadata that describes them, thus enabling reflection. I don't know it there are other languages (e.g. Java) that also includes metadata about the memory layout.
|
|
|
|
|

|
Hi
I was looking for spy utility to get contents of an object from an application e.g. Grap text from a textbox. Is it possible ?
Can we obtain object or text from the given mouse-click ?
cheer,
sanong
|
|
|
|

|
Thanks.
Yes, you can get text from a textbox (and since textboxes have a window handle, so can many other spy-tools). If you were thinking of something more automated/code-based instead of browsing (e.g. for validation of automated GUI tests), I've just submitted an update with this feature. I think it may take some days for the editors to make it available.
For everything with a window handle (textboxes etc.), it would be possible to obtain the text by clicking the mouse (although my approach is dropping a crosshair). There is however no guarantee that the text property is the text rendered at that location (for instance, a TreeView renders a lot of other texts in its area). Likewise, there is no generic way to obtain an object whose text property is the text rendered at a given location (there might not even be an object representing a given text).
|
|
|
|

|
hi,
Thank you for reply. My idea is toe capture text from the Java applet Screen which protected. You dont know the handle. The only thing I can think of is the OCR from select rantangle from screen.
Any idea ?
sanong
|
|
|
|

|
If it has a window handle, it is possible to find it. ObjectSpy (and several others) can do it, just drag the crosshair above the applet, and notice the frame that indicates the window. The handle is shown in ObjectSpy's main window. From a programmatic point, ObjectSpy uses the Win32 API method WindowFromPoint. Another useful method is FindWindow, that finds the handle given the title of the window. Once you have the handle, you can always get the text using GetWindowText. Whether that text is actually what is rendered is however not necessarily the case.
For .NET applications, ObjectSpy is able to dig further because .NET classes includes metadata that describes them, thus enabling reflection. My knowledge of Java is very limited, so if something similar is possible there I don't know (but ObjectSpy will definately not be able to do so). Other than that, I don't have any ideas.
|
|
|
|
 |
|
|
General News Suggestion Question Bug Answer Joke Rant Admin
Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.
|
A tool for browsing public and private members in any running .NET application (and a generic InvokeRemote method that wraps the code injection).
| Type | Article |
| Licence | CPOL |
| First Posted | 21 Nov 2006 |
| Views | 115,241 |
| Downloads | 5,308 |
| Bookmarked | 148 times |
|
|