|
Yes, i first ask generally about a method to log open windows, etc. and i thought i can take this method also for windows mobile 2003 SE.
That's not good i have already read a lot about windows hooks, that's a pity that windows mobile 2003 SE don't support that.
So there is no chance to log on a PocketPC when a Window opens, destroys or a command in the window executes?
Have you got more exactly details about your solution you quoted in the previous posting?
thanks in advance.
yours sincerely,
patrick
|
|
|
|
|
I gave you the code already to enumerate windows. Just add a Timer class to your code and hook-up the appropriate event handler depending on which Timer class you use (make sure you use one supported by the .NET CF). In the handler is where you enumerate the Windows and do whatever else you need to. Make sure your timer interval is long enough that you don't have overlap when enumerating windows, otherwise you'll be a bottleneck in the system (every 5 seconds should be more than adequate).
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
hello,
thanks first of all for all your information!
okay i looked in the MSDN for the Timer Class and for every method it is noted if the method is supported by the .NET Compact Framework. Unfortunately at the two events tick and dispose nothing is noted - if there are supported or not...?
If the tick-event is supported by the .NET Compact Framework i would probably write the code in that way:
public class Class1 {
static System.Windows.Forms.Timer myTimer = new System.Windows.Forms.Timer();
private static void TimerEventProcessor(Object myObject,
EventArgs myEventArgs) {
myTimer.Enabled = true;
[llImport("user32.dll")]
private static extern bool EnumWindows(EnumWindowsProc proc, IntPtr lParam);
private delegate bool EnumWindowsProc(IntPtr hWnd, IntPtr lParam);
[DllImport("user32.dll", CharSet=CharSet.Auto)]
private static extern IntPtr GetWindowText(IntPtr hWnd,
[Out] string title, IntPtr maxCount);
public void EnumWindows()
{
EnumWindows(new EnumWindowsProc(Callback), IntPtr.Zero);
}
private bool Callback(IntPtr hWnd, IntPtr lParam)
{
string title = new string('\0', 260);
if (GetWindowText(hWnd, title, 260)!= IntPtr.Zero)
Log(string.Format("{0:x8}: {1}", hWnd, title);
...//and here i want to save the titles of the windows in a file, do i have do consider certain things? - because when more windows are open the string title has more values one time the enumWindows-method counts the open windows?
}
}
public static int Main() {
myTimer.Tick += new EventHandler(TimerEventProcessor);
myTimer.Interval = 5000;
myTimer.Start();
Application.DoEvents();
}
return 0;
}
It would be nice if you can give me feedback to this code-fragment?
thanks in advance.
yours sincerely,
patrick
|
|
|
|
|
If ".NET Compact Framework" is not listed in the support section, then it's not supported. Use the System.Threading.Timer class instead (which takes a callback and you'll need to set it up each time - see the example).
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
Strange, because i already use the System.Threading.Timer - class. But appearant the tick-event is really not supported bei the CF. the only event founded which supports the CF is the dispose-event, but no example for it. Sorry but there is no example for the use of the dispose-event? - is it the same way as the tick event? - I hope i do not nerve you, but with this dispose event i do not really look through it....?
yours sincerely
patrick
|
|
|
|
|
No, actually according to the code you posted you're using the System.Windows.Forms.Timer class. Like I said, there's three Timer classes.
You have to understand that the .NET CF (Compact Framework) is slimmed-down to fit on a standard PocketPC. It lacks a lot of things that the .NET Framework for a non-Windows Mobile would have.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
hello,
i know the that the .NET CF is a slimmed-down version of the .NET Framework. I found something with the callback and delegate at http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfsystemthreadingtimerclasstopic.asp.
I have to look at this exactly because for know i do not look through it how it works with the example on this site and the delegate and callback and AutoResetEvent, etc..
yours sincerely
patrick
|
|
|
|
|
Yes - that's the URL for the System.Threading.Timer class I've mentioned twice. It's the only one fully supported by the .NET CF.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
hello,
i looked at delegates and TimerCallback and so on, but i don't still look really through it. I tried to write the code but i'm very insecure if this is correct.
I implement a TimeExample Class which calls the timerDelegate which calls the checkWindows method which should check which windows are open.
using System;
using System.Threading;
public class TimeExample
{
public TimeExample()
{
//
// TODO: Add constructor logic here
//
}
public static void Main()
{
AutoResetEvent autoEvent = new AutoResetEvent(false);
WindowsChecker windowsChecker = new WindowsChecker(100);
}
TimerCallback timerDelegate = new TimerCallback(windowsChecker.checkWindows);
Timer stateTimer = new Timer(timerDelegate, autoEvent, 1000, 250);
//autoEvent.WaitOne(5000, false);
//stateTimer.Dispose();
//Console.WriteLine("\nDestroying timer.");
}
--------------------------------------------------------------------------
In the WindowsChecker-class i fill in your code fragment and i defined a checkWindow-method in which should be checked which windows are open and this should be then logged in a file. For now there is only a check about the counter in the checkWindow-Method.
public class WindowsChecker
{
int invokeCount, maxCount;
public WindowsChecker(int count)
{
maxCount = count;
}
[DllImport("user32.dll")]
private static extern bool EnumWindows(EnumWindowsProc proc, IntPtr lParam);
private delegate bool EnumWindowsProc(IntPtr hWnd, IntPtr lParam);
[DllImport("user32.dll", CharSet=CharSet.Auto)]
private static extern IntPtr GetWindowText(IntPtr hWnd,
[Out] string title, IntPtr maxCount);
public void EnumWindows()
{
EnumWindows(new EnumWindowsProc(Callback), IntPtr.Zero);
}
private bool Callback(IntPtr hWnd, IntPtr lParam)
{
string title = new string('\0', 260);
if (GetWindowText(hWnd, title, 260)!= IntPtr.Zero)
Log(string.Format("{0:x8}: {1}", hWnd, title);
}
public void checkWindows (Object stateInfo)
{
AutoResetEvent autoEvent = (AutoResetEvent)stateInfo;
++invokeCount;
if (maxCount==invokeCount)
{
invokeCount = 0;
autoEvent.Set();
}
}
}
----------------------------------------------------------------------------
I hope you can give me any further help? either i'm too stupid to solve this problem or i don't know...
thanks in advance.
yours sincerely,
patrick
|
|
|
|
|
pat270881 wrote:
either i'm too stupid to solve this problem or i don't know
This is why you read, or forever be a newbie.
You're doing several things wrong, here. First, you can't declare a variable inside one scope (i.e., method) and access it from another (like your AutoResetEvent ). You have to declare this as a field, but you can instantiate and assign an instance to that field in another method.
Second, you're instantiating your callback outside of a method. This is not supported by C# or even the CLI (the specs on which .NET is built).
To top it all off, do you even know what the AutoResetEvent is and why you're using it? You should've read about that, too. It's all in the .NET Framework SDK which should be installed locally if you took the default installation options for VS.NET, and is always available online at http://msdn.microsoft.com/library[^].
The examples you see require some understanding. They are seldom complete. Be sure to read about the Timer class and don't just rely on the examples, or you'll never learn anything.
If you were to put that original code I gave you for enumerating windows into a method, the following is roughly what you should use:
using System;
using System.Threading;
class Example
{
bool stop = false;
AutoResetEvent waitHandle;
static void Main()
{
waitHandle = new AutoResetEvent(false);
Timer t = new Timer(new TimerCallback(EnumerateWindows), null, 5000,
Timeout.Infinite);
waitHandle.WaitOne();
}
static void EnumerateWindows(object state)
{
if (stop) waitHandle.Set();
else
{
}
}
} You should definitely read about any class, property, method, etc. that you don't understand first before asking questions. The class library documentation should always be the first place you check.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
hello,
thanks first for your time and effort. I have already experience with the .NET Classes, properties, methods and so on, i developed extensive WEbServices and ASP.NET Clients and ADO.NET for Database-Connectivity, but there for i needed not delegates - callbacks, the AutoResetEvent and so on, that's why these things are new for me.
Today and yesterday i read a lot about these things and i know what this things are and so on but the implementation of them is more difficult. I know that the AutoResetEvent handles the communication between the threads and the delegate wrap methods or objects and passes them to other methods but between theorie and implementation is a little difference.
Let me try to interpret your example: In the main-method you create a new AutoResetEvent-object and set it to false - means that the Event does not give up a signal to trigger. then you create a new Timer-object with the delegate-method, null, 5000 - means that in five seconds the enumerateWindows-method should first be called and the Infinite means that it is undefined when the next time the EnumerateWindows-method should be called. When the Timer-Object is created the EnumerateWindows-Method would be called and it goes further in the else tree of the method because stop is false.
I found an other example and i also tried to interpret and would ask you for correctness:
using System;
using System.Threading;
namespace ConsoleApplication8
{
class Class1
{
public void TimerCallback(Object obj)
{
Console.WriteLine("Timer triggered");
((AutoResetEvent) obj).Set();
Thread.Sleep(1000);
((AutoResetEvent) obj).Set();
}
static void Main(string[] args)
{
Class1 obj = new Class1();
AutoResetEvent ev =
new AutoResetEvent(false);
Timer timer = new Timer(
new TimerCallback(obj.TimerCallback),
ev, 1000, 0);
ev.WaitOne();
Console.WriteLine("Event Fired");
ev.WaitOne();
Console.WriteLine("Event Fired");
}
}
}
It begins in the main-method. A Class1-object and a AutoResetEvent-object which is set to false are created. Then a new Timer-Object is created - as parameters the call of the TimerCallback-method, the AutoResetEvent-object (for what do i need this parameter?) and so on. When the Timer-Object is created the TimerCallback-method is called and the Class1-object is cast to AutoResetEvent-object and is set - this means that the Event gives up a signal and the first "Event Fired" will be write out on the console. Then the thread sleeps one second and gives up a signal again and the event write out "Event Fired" a second time.
I do not know if i interpret your example and my example in a correct way? - especially for what do i need the ev.WaitOne() in my example? (I know what this method do, but why i need this method here?).
I hope you do not think i don't read in the literatur and only want that you tell me how it goes. I spent a lot of time yesterday, the day before and today to get a clear understanding about the terms i need for my implementation but it is not so easy.
i hope you will find time to help me again.
thanks in advance.
yours sincerely,
patrick
|
|
|
|
|
pat270881 wrote:
know that the AutoResetEvent handles the communication between the threads and the delegate wrap methods or objects and passes them to other methods but between theorie and implementation is a little difference.
Actually, an AutoResetEvent has little or nothing to do with threads. It's a wait handle - like a mutex - that helps synchronize threads (it can be used - though pointlessly - without threads).
A delegate is a "managed function pointer". It references only a method and allows you to synchronously or asynchronously invoke a method. This is like a CALLBACK in native C/C++, except that delegates can reference methods (functions declared on a class) unlike callbacks (has to do with the address in memory).
I'm really not sure what the other example you posted is trying to accomplish. It seems to do nothing just by looking at it. The example I posted is very much what you need.
Here's an example I threw together:
using System;
using System.Runtime.InteropServices;
using System.Threading;
class Test
{
static AutoResetEvent evt;
static int count = 1;
static void Main(string[] args)
{
if (args.Length > 0)
{
try
{
count = int.Parse(args[0]);
}
catch {}
}
evt = new AutoResetEvent(false);
Timer t = new Timer(new TimerCallback(TimerCallback), null, 0, 5000);
evt.WaitOne();
}
static void TimerCallback(object state)
{
Console.WriteLine("Enumerating windows at {0:t}...", DateTime.Now);
EnumWindows(new EnumWindowsProc(EnumWindowsCallback), IntPtr.Zero);
if (--count == 0) evt.Set();
}
static bool EnumWindowsCallback(IntPtr hWnd, IntPtr lParam)
{
if (hWnd != IntPtr.Zero)
{
string title = new string('\0', 260);
int ret = GetWindowText(hWnd, title, 260);
if (ret != 0)
Console.WriteLine("0x{0:x8}: {1}", hWnd.ToInt64(),
title.Substring(0, ret));
}
return true;
}
[DllImport("user32.dll")]
static extern bool EnumWindows(EnumWindowsProc proc, IntPtr lParam);
delegate bool EnumWindowsProc(IntPtr hWnd, IntPtr lParam);
[DllImport("user32.dll", CharSet=CharSet.Auto)]
static extern int GetWindowText(IntPtr hWnd, [Out] string title,
int maxCount);
}
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
I read this, because in the MSDN is noted that the AutoResetEvent handles that threads can give signalys to each other.
I hope i can interpret this sample code right:
First of all you defined a AutoResetEvent-object and an int named count.
It begins in the Main-Thread: First there is a if-call, whether a parameter was taken over at a call of the Test.cs. (This count says how often the EnumWindowsCallback-method will be executed?)
Then the AutoResetEvent evt is initialized and set to false - this means that the Event does not give up a signal to an other thread.
Then a new Timer-Object is initialized and in the course of this initialization the delegate-method will be called. (why don't you hand over the evt-object in the constructor of the Timer-object?)
What value has the TimerCallback-paramter in the constructor of the TimerCallback?
Then when the Timer-object is initialized and the TimerCallback-method is called, the today's date is write out on the console.
Then the EnumWindows-method is called. In the course of that the EnumWindowsCallback-method is called. (What values have the parameter of the EnumWindows-method?)
Within the EnumWindowsCallback-method there is a if-call - apperantly, if there are any windows open? - then the method GEtWindowText asks if the window has a title - if true the title will be write out on the console. (what means the nWnd.ToInt64() and the 0x{0:x8)?)
You see the course and order of events are still not clear for me...
I'm already afraid to ask you again for help..
yours sincerely,
patrick
|
|
|
|
|
pat270881 wrote:
why don't you hand over the evt-object in the constructor of the Timer-object?
And marshal it across thread boundaries for no reason? That's inefficient and unecessary. Just because the .NET Framework makes some things so easy does't mean you should do it that way. And passing a value type (like count ) as an object requires boxing and unboxing, which is very expensive (in terms of CPU time). Even casting reference types takes extra cycles that aren't necessary by keeping it as a field.
pat270881 wrote:
What value has the TimerCallback-paramter in the constructor of the TimerCallback?
It's the method that the delegate references. As I said before, a delegate is like a managed function pointer.
pat270881 wrote:
What values have the parameter of the EnumWindows-method?
It's in the Platform SDK for EnumWindows .
pat270881 wrote:
what means the nWnd.ToInt64() and the 0x{0:x8)?
It's in the .NET Framework SDK. Look-up IntPtr.ToInt64 and string formatting. There's no purpose explaining this if you haven't even read about it yet. If you have questions beyond that, this is the place to ask.
As far as the flow of execution you are right. The code is pretty self-explanitory if you understand the types and members used in the code.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
hello,
yes i will look for this in the SDK.
But my biggest problem i still have is the Delegate-Callback mechanism? I do not simply understand how this mechanism functions, respectively in your sample code.
I read the things to delegates and TimerCallback in the MSDN and looked at the samples but i did not understand how this exactly goes?
That is for sure still my biggest problem... I do not find the logic in this mechanism..i hope i express me the right way...
yours sincerely,
patrick
|
|
|
|
|
As I've said several times, a delegate is a managed function pointer. This allows you to pass a method as a parameter and execute it without knowledge of the actual method that needs to be executed. Just like with the EnumWindows API - in native code you pass a function pointer. In .NET, you pass a delegate (a function pointer managed by the CLR). See the Delegate class in the .NET Framework SDK for more details.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
yes i know defintion of the delegate, but the thoughts behind why you build up this sample in that way is not clear.
You have explicit the EnumWindowsProc-delegate but you have not explicit declare the TimerCallback-delegate?
And why do we need the evt.WaitOne(); after the creation of the Timer-object? - the AutoResetEvent evt is already set to false.
yours sincerely,
patrick
|
|
|
|
|
The TimerCallback is a delegate that's already declared in the .NET Framework and the .NET CF. Why would I declare it? You don't re-declare the TimerCallback , you instantiate it with reference to a method that you must define. That's a delegate.
Why do I call AutoResetEvent.WaitOne ? Because the Main method has to block until signalled otherwise the application will terminate immediately since the Timer was started on a different thread. That certainly is not what you want.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
okay that's clear.
You said the main-method and the TimerCallback-method run in different threads. How is it distinguished that the TimerCallback runs in a different thread? - when it would not run in a different thread i wouldn't need the evt.WaitOne()? - because the execution of the class goes only forward when the TimerCallback-method runs through and calls the EnumWindowsCallback and so on?
yours sincerely,
patrick
|
|
|
|
|
...and do you know any further method besides the record of the titles of the open windows that i can log to get more detailed information about what do user do or which commands he executes?
Thanks in advance.
Yours sincerely,
patrick
|
|
|
|
|
hello,
i have now a little application which writes the title of the active window in a xml-file, but when i want to deploy it with the Emulator there will occur the following exception and i do simply not know why this error occurs??
A managed MissingMethodException
occured at
Test:TimerCallback+0x25
Test:TimerCallback+0x25
Timer:ring+0x59
Ok to terminate.
Can somebody please tell me what went wrong?
thanks in advance.
regards
patrick
|
|
|
|
|
I looked in the MSDN for some helpful topics but i only found "An Introduction to P/Invoke and Marshaling on the Microsoft .NET Compact Framework". I do not know, if this topic helps me..but i don't think so.
Without any example code it is very difficult for me to realize your idea with the EnumWindows, Timer-Class, etc, because i do not work yet with this classes (EnumWindows,etc.), regardless of array lists and hashtables.
Have you got further tipps or hints?
thanks in advance.
yours sincerely,
patrick
|
|
|
|
|
If you look at the code I gave, I already showed you how to P/Invoke EnumWindows and how to declare the EnumWindowsProc delegate (what you name it doesn't matter, though). For the various Timer classes, look in the .NET Framework SDK (it's installed locally if you took the default installation for VS.NET: just type "Timer class" in the index and check to make sure at the bottom of the page that they support the .NET CF). They should all have examples of use.
Being given the answer won't teach you everything. The hardest part of this solution is the P/Invoke, which I already gave you code for earlier.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
hello,
i have some problems with the NSpring Framework. I want to use this framework to log in a file, which events occurs in a ASP.NET Application. But i do not really know how i can use this framework and how to start with it.
The situation is as follows: i developed a ASP.NET Application for a PDA and now i want to change the code in that way that it would be logged in a file on the PDA what actions a user execute (which events would be execute, which method, at what time,..).
Can anybody help me with this problem?
thanks in advance.
yours sincerely
patrick
A Comprehensive Logging Package for .NET
|
|
|
|
|
If you have specific problems with an application/library, you should ask the authors and/or their support contacts. Since NSpring is hosted on SourceForge, there are a couple differnet forums you can use.
If you have questions specific to C#, this is the place to ask.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|