Sending WM_COPYDATA but getting WM_ACTIVATEAPP on the receiving side - c#

I have the following scenario:
My app gets some data from the command line.
After getting executed by the first time, my app runs always one instance and that instance will be in memory until the use explicitly tells it to shutdown instead of just hiding the form when not needed.
When the user tries to run the app a second time, the process starts, checks if there is another one in memory and if that is true, it sends a WM_COPYDATA message to the process in memory with the data it got from the command line and exits.
That all works well when the it«s the user who runs the app.
I needed to ran it from the Microsoft Word 2003 toolbar so i used a "Add-in" for that. The problem is that when my app is started from that Add-In (using Process class), it seems that the process already in memory gets a WM_ACTIVATEAPP message instead of a WM_COPYDATA one, so i can't get the needed data sent from the process started by the Add-In.
I have no idea on why is that happening and how to fix it. I've googled for hours and nothing helped...
Can anyone help?

Getting a WM_ACTIVATEAPP message is quite normal, part of the usual notifications that Windows sends. Don't assume that the first message you'll get is WM_COPYDATA, keep looking. If you don't get it at all then the window handle that you used to send the message was wrong. Which is a very common problem, it is not that easy to accurately find a window back.
The .NET framework already has very good support for single-instance apps that can retrieve the command line from a second instance. Consider using it instead. Check this blog post.

Related

CefSharp crashes with "Destroying nonempty message queue"

We are writing a program that uses CefSharp to get data from some javascript heavy webpages.
After operating for a while, usually after we are finished but sometimes before, a message is logged to the console saying Destroying nonempty message queue and the program freezes.
I am at a loss as I can't even pause the debugger when the message appears, VS crashes with a debugger timeout when trying.
What causes the message queue to be deleted?
At the moment we did not solve the problem, instead we have figured out a way to tell when the process has crashed (basically we wait for three minutes and if we don't have a reply from the browser we assume it crashed), when the process is stopped we return a partial result to the user and it is the user's responsibility to ask for the rest of the data.
Regarding the crash itself, it isn't clear why exactly but it seems like we are doing something to crash the render process, and because we don't ask for anything over the WCF channel we have no idea that something has crashed.

Debugging non-responding application in VS

I'm now working on some pretty big application with really nasty code. The problem is that from time to time the whole GUI of the app is freezing and stops responding (and after some time Windows wants to take the app down). I have a really big problem to even look where to debug the app, mostly because when this thing happens and I pause it in the VS debugger, it highlight the line:
CardWindow.ShowDialog();
It's not helpfull at all. Also when this thing happens it tends to grow the app size in the memory, ocasionally throwing OutOfMemoryException.
I also checked whether it might be some kind of an infinite loop in one of created threads, but VS shows me that only the main thread is active, and the rest are either ended or not running at all (the thread implememtation is also really poorly written).
The application uses remote objects within local networks, and some threads are used to transfer photos and other data from clients to server, but I don't know how to check if this is what it's causing it. But when the server app hangs, the clients are still fully capable to connect with it.
Short info of how it's made: the app uses Firebird engine to store its data. The DB is on the server machine, and the clients are connected via local LAN to it using standard Firebird C# library, and the app instances communicates with each other using remote object (the server is also a client).
It's the second week of debugging and I'm getting pretty desperate as I'm getting out of ideas of even how to check what's wrong. The fact that the bug appears randomly also doesn't help.
Can anyone give me some ideas of how to find a trace of this bug?
Using C# .NET 4.5 and WPF with Visual Studio Ultimate 2013 and Firebird 2.5
I'd suggest using a profiling tool to assist in finding the problem
What Are Some Good .NET Profilers?
In addition to #DerekTomes. The System.Windows.ShowDialog method, Described in: Window.ShowDialog Method, all other windows are disabled and return only when the window is closed. Check to make sure the window is eventually closed(this.Close() in the CardWindow.xaml.cs or whatever .cs file) or use CardWindow.Show() instead of CardWindow.ShowDialog() so other windows remain running while the CardWindow is running.
I finally figured it out.
When the function that usually hanged the app after 30th run launched, I could see that some of it ran (the window's title changed as it was supposed to). I've found this function and after every single line put:
this.Title = "1";
SomeFunction();
this.Title = "2";
AnotherFunction();
this.Title = "3";
// and so on
I localized what was causing the problem; there was a function that changed the GUI significantly (lots of foo.Visibility and foo.Opacity) and ran in some weird loop. It was fine for the first 20 times to run it, but after 30th it slowed down the app, and after 40th - caused crash.
It now runs only once when it needs to and the problem does not appear. I suppose it caused GUI memory overflow of some kind.
Anyway, thank you for your answers - I ran memory profiling, but it slowed my app down to that point it was impossible to use it.

Single instance C# window that repaints

What I thought would be pretty easy is quickly defeating me. I'm not a native C# programmer, but was asked to create a WinForm application that has a single instance. I''ve seen the Mutex examples already on StackOverflow, but the one thing that eludes me is the ability to pass parameters to window on the command line, parse the values and repaint the form with the new values.
Anyone have an example of this? The main thing that seems to be tripping me up is the threading. I want to run my.exe and show the window. Each time the form is run, I don't want a new form -- just to get the new parameters and show them in the form.
Any/All replies are appreciated!
When you starting another instance of your application, you are running same code, but on different process. So, you need to look on passing data between processes. Something like Named Pipes or Remoting.
#lazyberezovsky is right. Invoking again the application from the command line will spawn a different, unrelated process and you would require inter-process communication to forward the new parameters to the previously running app instance, before quitting the new process being invoked.
IMHO, the easiest way (not the best certainly) to communicate between these two processes would be using the Windows Registry, as this is already thread-safe and the API is very simple.
First, when the application runs, before showing the main form, I would perform a check to see if another instance of the app is running.
If false, it is the first time the app runs and I would process the command line and show the form as regular. I would also clear the registry key used for inter-process communication (see below).
If true, then I would store the command line in the registry on a specific key that will serve for inter-process communication and then I would terminate the application without even showing the main form.
Your running application (the first instance) will require to start a polling mechanism (could be a Windows timer firing once each second) that regularly examines the registry key where a new command line is expected . It would normally find and empty string and do nothing, but if the retrieved value is not empty, then it would mean the user spawned again the application with a different set of parameters, then you can proceed to decode your command line and repaint the window as necessary. After this, make sure you clear the registry entry again, so the polling mechanism resumes and detects the next time the application is invoked by the user.
Named pipes, WCF, .remoting or TCP sockets are IPC mechanisms that can be used and won't require a polling mechanism, that may be frowned upon by some. ;)
Hope this helps!

C# WinForms ScrollToCaret Buggy?

Is the ScrollToCaret in WinForms buggy?
I have a server that processes messages, a server that allows irc style communication.
I'm working on a WinForms gui that interacts with the server.
The WinForms gui has a component that does reads/writes to the newtork. This component launches a thread to do continuous reading (receive) on the socket. This thread takes a delegate that allows the read message to be processed right away instead of being placed on an internal read queue that is built into the component. Then I have the main form that shows chat messages received and sent, among other things. Chat messages are stored in a RichTextBox. The chat log is update via method of the main form:
private void UpdateChatWindow(string text)
{
lock (rtxt_msgLog)
{
rtxt_msgLog.Text += Environment.NewLine + text;
rtxt_msgLog.SelectionStart = rtxt_msgLog.Text.Length;
rtxt_msgLog.ScrollToCaret();
}
}
The above method is called from the main form as well as the thread that does the continuous reading of a socket.
If I have one GUI window open, the msgLog updates fine, scrolls to bottom. Focus() is not an issue, as the RichTextBox is never in focus as indicated by Focused property which always returns 'false'.
Weirdness stars when I launch a second GUI and log into the server. I start receiving
on the first GUI launched when I do a send from it, while the second GUI works fine - receives the message sent from the first GUI, scrolls correctly to the bottom of the msgLog. After I send a few messages on the Error GUI, the error stops occurring on the first GUI and moves on to the second GUI. Now I receive the Error when trying to do a msg send on the second GUI. While all this is happening. When I send a msg on the first (now a non Error GUI) both GUIs scroll as they should. But when I send a msg on the Error GUI, none of the GUIs scroll, but they do receive the msg.
Interestingly enough, the Error never occurs when writing a received msg to the msgLog, which also makes use of the UpdateChatWindow method kicked off from the component thread I mentioned at the beginning. The send is initiated on the main form, so a separate thread from the one started by the network read/write component.
After typing this post up, I went back to my open GUIs and for the next few tries the Error was jumping between the GUIs, once shows up on the first GUI, next on the second, then back on the first, finally it's back on the second GUI and stays there. While the error was jumping between the GUIs, one GUI scrolled while the other did not, which also changed based on where the error was occurring.
I did see something on this site that might explain this. Is the reason behind my weirdness related to:
"you are not able to directly do UI operations from another thread than the main UI thread"
Or is there more to it?
UPDATE 1
Apparently there are some conflicts on my system, WinXP SP2 64bit. May even have to do with my numerous .Net runtimes installed. GUI works without a hitch on my laptop WinXP SP3 32bit. Have 3 windows open and all work flawlessly. As soon as I open a GUI on my development comp, join the same server as the 3 laptop GUIs are on, the new GUI gets this Error, while the GUIs on the laptop are still fine. Typed in my problem into google and it seemed from the results like it may be a system configuration issue and it looks to be just that :(

System.IO.Ports.SerialPort Write() Timeout

The program I'm working on in C# (.Net Framework 2.0) calls for the ability to switch over to a 'remote mode' and send ascii data to another screen via Bluetooth. I'll start by saying I'm not a very experienced programmer, and I know nothing about networking, but after fooling around with the SerialPort class yesterday I was able to work up a little chat program that worked nicely between two Bluetooth-connected devices.
The chat program, however, only sent data when the user hit a button to "send" data. If the two devices weren't properly connected I just threw a TimeoutException along with an error message. The program I'm working on now is much larger, and tries to write data constantly so long as it has the COM port open.
That means if the two devices aren't immediately connected, it has to throw a TimeoutException, and it will continue to throw it, again and again until they ARE properly connected. That's totally unacceptable. It slows the program down to the point where it isn't usable, and litters the Debug output with "TimeoutException Thrown Here" error messages.
Is there a better solution for how to do this? Some way that I can get it to only write the data out if I can confirm that the two devices are connected, without constantly checking (and subsequently getting Timeout Errors while checking).
No. A serial connection is stateless.
This means you don't know if someone is on the other side. All you can do is sending something out and take a look if something meaningful is coming back.
The easiest example for this is the good old analog modem. To find out if it is connected is to send out a AT and check if an OK comes back.
So your solution is the right one, but maybe not properly implemented. You should put your connection built-up sequence into a BackgroundWorker. So these tries will be done in another thread while your GUI stays responsive to the user.

Categories

Resources