Ok so I am running tests in WatiN and I am using the SendKeys method. According to the MSDN website I can enter:
System.Windows.Forms.SendKeys.SendWait("{LEFT 2}");
And this will enter left two times. This however does not work, I believe because the application needs time between each keypress. I order to do what I need the program to do I used Thread.Sleep between each keypress to ensure they were getting read. Is there a more efficient/proper way to do this? This is my current method code:
System.Windows.Forms.SendKeys.SendWait("{LEFT}");
Thread.Sleep(500);
System.Windows.Forms.SendKeys.SendWait("{LEFT}");
Thread.Sleep(500);
System.Windows.Forms.SendKeys.SendWait("{ENTER}");
Unfortunately, I don't believe there is. According to MSDN there are timing issues with SendKeys:
The SendKeys class is susceptible to timing issues, which some
developers have had to work around. The updated implementation is
still susceptible to timing issues, but is slightly faster and may
require changes to the workarounds.
The SendKeys class tries to use
the previous implementation first, and if that fails, uses the new
implementation.
As a result, the SendKeys class may behave differently
on different operating systems. Additionally, when the SendKeys class
uses the new implementation, the SendWait method will not wait for
messages to be processed when they are sent to another process. If
your application relies on consistent behavior regardless of the
operating system, you can force the SendKeys class to use the new
implementation by adding the following application setting to your
app.config file.
<appSettings>
<add key="SendKeys" value="SendInput"/>
</appSettings>
To force the SendKeys class to use the previous implementation, use the value "JournalHook" instead.
You could try changing between implementations to see if there is a change in your results.
Alternately, according to this post just using Thread.Sleep(0); after your input should work. Not the most elegant solution but if it works it would be faster than a 500ms pause.
Related
I have an application (C# + WPF) that attempts to wrest control of the graphical interface of any process passed to it as an input and resize/reposition for my own purposes.
It does its job rather well, I think. Upon expected termination (the base class inherits from IDisposable) the "captured" process is released - its parent is set to the original, its windowstyle is reset, etc. etc.
In fact, on testing, I can capture, release, recapture, and so on, the same process as many times as I want with no issues.
However, upon unexpected termination (say another process forcefully kills it), the process never regains its graphical interface! I can tell its still running but I can never set that process back to its original state.
It almost seems like the process doesn't respond to window-based Win32 API calls that set specific window features anymore (for example, I can get information with GetParent, GetWindowThreadProcessId, etc but calling ShowWindow or related results in nothing).
Any suggestions on why this is happening? I'm guessing that since I set the parent of the process to my WPF application (which then unexpectedly closes) it causes some issue in trying to recover the initial interface?
This is why it's happening (or, at least, an indication of why I had so much difficulty finding the issue out on my own); can I recover from it? And, if so, how?
Edit -
IInspectable makes a good point in the comments, question adjusted to make better sense for this particular application.
It seems I've gotten my answer; so, for the sake of completeness I'll post what I've gotten here in case anyone else has a similar issue.
According to the information provided by IInspectable in here and here (with more context in the comments), it seems that what I'm trying to do here (assign a new parent cross-process) is essentially unsupported behavior.
My Solution:
Recovering (at least at the point that I'm talking about - i.e. unexpected crashes or exits) probably isn't feasible, as we've already gone off the end in undetermined/unknown behavior. So I've decided to go for the preventative route.
Our current project already makes use of the Nancy framework to communicate across servers/processes so I'm going to "refine" our shutdown procedure a bit for my portion of the program to allow it to exit more gracefully.
In the case of a truely unexpected termination, I'm still at a loss. I could just restart the processes (actually services with a console output, in our case, but w/e) but my application is just a GUI/Interface and isn't very important when compared to the function these processes serve. I may make some sort of semaphore file that indicates whether a successful shutdown occurs and branch my code off so that it indicates that the processes are no longer visible until the next time they're restarted.
I'm pretty new to profiling so I don't know how to even approach this issue. Basically, I want to discover why some hiccups in the UI are occurring. Profiler seems to be made for solving these kinds of issues so I went with that. I'm using Visual Studio 2010 on a Windows 8 machine so my only option is instrumentation profiling.
Unfortunately, what I get is a bunch of distracting hot paths that occur because of MessageBox.Show calls and long-running threads waiting for data with Monitor.Wait. These methods, of course, take orders of magnitude longer than the issues I'm trying to understand.
Is there no way to somehow filter-out these long-running methods? Ideally by function name or some other criteria, perhaps elapsed exclusive time.
Profiling is not for UI. Profiling is for calculations and other logic. If you really need to profile UI (which you should not) you can hide message boxes and simulate button clicks. Something like:
#if PROFILE_VERSION
DialogResult result = DialogResult.OK;
#else
DialogResult result = MessageBox.Show();
#endif
Of course you'll need to define PROFILE_VERSION and create new configuration for this.
But really, you should only test your logic.
Aside from hot paths being some of the pointless information profilers give you, here is how I would approach finding your "hiccups".
Most of the time I use random pausing.
I try to collect samples during the slow times (the "hiccups") so I can see what it's doing in that time.
If I get samples that I can see are not relevant, I just ignore those.
If the hiccups happen too fast to do that, there's a more difficult method.
It requires setting a few-millisecond timer interrupt with a handler.
When the suspect code starts, it enables the timer, and when it finishes it disables the timer.
That way, if it takes longer than normal to finish, the timer goes off. If I set a breakpoint in the handler, I can look to see what the program was doing when the timer went off.
That's a way to get a sample.
If I get several samples, that's usually enough to show the problem.
I would like to hook all the functions calls of all running processes. I can hook certain function("ws2_32.dll!recv") of all processes using deviare by:
CreateSpyMgr(out mgr);
hook = mgr.CreateHook("ws2_32.dll!recv");
hook.Attach(mgr.get_Processes(0));
mgr.set_ReportProcessCreation(DeviareCommonLib.ReportMethod._create_process_hook_and_polling, 0);
hook.set_HookNewProcesses(0, 1);
hook.OnFunctionCalled += new DHookEvents_OnFunctionCalledEventHandler(hook_OnFunctionCalled);
hook.Hook();
How can I hook all function calls instead of just one? is it possible?
Or should I create hooks collection(of all functions which is way hard) using INktSpyMgr::CreateHooksCollection and add hooks to it, then call hook method and pass the INktHooksEnum object as the parameter. Is this the only way to do this?
My aim is to make a tool that counts all system calls for each running process. Feel free to give any suggestions.
First a word of advice: be very very careful about which APIs you hook. If anything you do within your hook method results in a call to one of the APIs you are hooking then you are creating an infinite recursion that could potentially wreck your computer. Bear that in mind. You'll probably want to filter out the API calls for your own process as well, otherwise you'll end up logging entries about the disk access caused by logging entries, and before you know it your memory is full and the hard drive is fully occupied with logging about logging.
There appears to be nothing in the Deviare API that allows you to create hooks on multiple methods - no wildcards or 'hook everything' calls - so you'll have to enumerate the APIs (see INktModule.ExportedFunctions for some ideas) and hook them. I'd suggest that you use a hook collection (see INktSpyMgr.CreateHookCollection and INktHooksEnum) so that you can setup all your hooks and then attach and detach them in one operation.
As for the logging aspect, give some thought to using a queue of some sort - ConcurrentQueue<T> by preference - to pass the actual logging operations off to another thread. That way you spend a minimum of time in the actual hook function as well as reducing the chances of your hooks causing recursion. You'll have to experiment with filtering in the logging thread vs the hook functions to find out which has the smaller performance impact on the system.
Always make sure you know how much data your program is dealing with and have a plan in place for dealing with the volume of data. You're going to have to do some serious profiling to find the pain points, then put in plenty of work on reducing the overheads so that your program doesn't mess up the system too badly.
Personally I'd start with a small subset of the APIs you ultimately want to monitor, write code that works as well as you can make it, then move up to the full set of APIs. Less chance that you'll kill your computer that way.
I'm using the following code to copy text to Clipboard.
System.Windows.Forms.SendKeys.SendWait("^c");
Then I use
Clipboard.GetText()
to get the text from Clipboard. It works fine, but it looks like it's delaying when I work with clipboard in a loop and I get content that should be overwritten with next copied text. If I put the Thread.sleep, it works fine. How could I fast copy and get the right content from Clipboard in a loop without delay?
This appears to be a documented issue. MSDN acknowledges "timing issues" but doesn't include a way to completely get around them, although there does appear to be a "newer" method that you need to tell your program to use by default. Here's a portion of the documentation:
The SendKeys class has been updated for the .NET Framework 3.0. The SendKeys class is susceptible to timing issues, which some developers have had to work around. The updated implementation is still susceptible to timing issues, but is slightly faster and may require changes to the workarounds. The SendKeys class tries to use the previous implementation first, and if that fails, uses the new implementation. As a result, the SendKeys class may behave differently on different operating systems. Additionally, when the SendKeys class uses the new implementation, the SendWait method will not wait for messages to be processed when they are sent to another process.
If your application relies on consistent behavior regardless of the operating system, you can force the SendKeys class to use the new implementation by adding the following application setting to your app.config file.
<appSettings>
<add key="SendKeys" value="SendInput"/>
</appSettings>
I found a similar (old) issue on another bulletin board, but unfortunately their fix was the same as yours - to delay for a fraction of a second before accessing the clipboard. I couldn't find any other workarounds for the issue. Considering there's a Send and a SendWait, it doesn't seem too much to expect the latter to actually wait after the send! :)
You definitely can NOT update the clipboard in a loop and expect the data to be available (and accessible to your app) immediately. The application that you're sending the keystroke to is running in its own process, and windows is multi-processing, multi-threading, etc.. So you're looking for the clipboard to be updated, before the other app has gotten a chance to copy it.
Furthermore, since there can be other programs running on the system, monitoring the clipboard for updates (clipboard viewers), you are going to be colliding with those programs when you attempt to get the data from the clipboard.
I don't know why you're trying to do what you're doing, but you should be aware that it's not going to work all the time. You may be able to get it to work in some cases, but not all cases. Unless this is an educational exercise for your own use, you should abandon this approach.
And please read this quote on the subject:
"Programs should not transfer data into our out of the clipboard without an explicit instruction from the user.”
— Charles Petzold, Programming Windows 3.1, Microsoft Press, 1992
I want a certain action request to trigger a set of e-mail notifications. The user does something, and it sends the emails. However I do not want the user to wait for page response until the system generates and sends the e-mails. Should I use multithreading for this? Will this even work in ASP.NET MVC? I want the user to get a page response back and the system just finish sending the e-mails at it's own pace. Not even sure if this is possible or what the code would look like. (PS: Please don't offer me an alternative solution for sending e-mails, don't have time for that kind of reconfiguration.)
SmtpClient.SendAsync is probably a better bet than manual threading, though multi-threading will work fine with the usual caveats.
http://msdn.microsoft.com/en-us/library/x5x13z6h.aspx
As other people have pointed out, success/failure cannot be indicated deterministically when the page returns before the send is actually complete.
A couple of observations when using asynchronous operations:
1) They will come back to bite you in some way or another. It's a risk versus benefit discussion. I like the SendAsync() method I proposed because it means forms can return instantly even if the email server takes a few seconds to respond. However, because it doesn't throw an exception, you can have a broken form and not even know it.
Of course unit testing should address this initially, but what if the production configuration file gets changed to point to a broken mail server? You won't know it, you won't see it in your logs, you only discover it when someone asks you why you never responded to the form they filled out. I speak from experience on this one. There are ways around this, but in practicality, async is always more work to test, debug, and maintain.
2) Threading in ASP.Net works in some situations if you understand the ThreadPool, app domain refreshes, locking, etc. I find that it is most useful for executing several operations at once to increase performance where the end result is deterministic, i.e. the application waits for all threads to complete. This way, you gain the performance benefits while still having a clear indication of results.
3) Threading/Async operations do not increase performance, only perceived performance. There may be some edge cases where that is not true (such as processor optimizations), but it's a good rule of thumb. Improperly used, threading can hurt performance or introduce instability.
The better scenario is out of process execution. For enterprise applications, I often move things out of the ASP.Net thread pool and into an execution service.
See this SO thread: Designing an asynchronous task library for ASP.NET
I know you are not looking for alternatives, but using a MessageQueue (such as MSMQ) could be a good solution for this problem in the future. Using multithreading in asp.net is normally discouraged, but in your current situation I don't see why you shouldn't. It is definitely possible, but beware of the pitfalls related to multithreading (stolen here):
•There is a runtime overhead
associated with creating and
destroying threads. When your
application creates and destroys
threads frequently, this overhead
affects the overall application
performance. •Having too many threads
running at the same time decreases the
performance of your entire system.
This is because your system is
attempting to give each thread a time
slot to operate inside. •You should
design your application well when you
are going to use multithreading, or
otherwise your application will be
difficult to maintain and extend. •You
should be careful when you implement a
multithreading application, because
threading bugs are difficult to debug
and resolve.
At the risk of violating your no-alternative-solution prime directive, I suggest that you write the email requests to a SQL Server table and use SQL Server's Database Mail feature. You could also write a Windows service that monitors the table and sends emails, logging successes and failures in another table that you view through a separate ASP.Net page.
You probably can use ThreadPool.QueueUserWorkItem
Yes this is an appropriate time to use multi-threading.
One thing to look out for though is how will you express to the user when the email sending ultamitely fails? Not blocking the user is a good step to improving your UI. But it still needs to not provide a false sense of success when ultamitely it failed at a later time.
Don't know if any of the above links mentioned it, but don't forget to keep an eye on request timeout values, the queued items will still need to complete within that time period.