I have a Windows forms application which I have a bit of a sporadic issue with. The application would randomly start/spawn another instance of itself without any warning or reason. I only have one use of Process.Start in the whole application (15 forms/files and about 5000 lines of code) and that calls a net use command to map a network drive.
I've not been able to reproduce this in my testing and therefore I made the project a Windows Assembly Framework single instance application (pros/cons of this I know). This has obviously stopped any other instances of the application from running, but now at random intervals their program will minimise and snap to another application they have running. I don't know for certain whether this is related but they certainly sound a bit close for comfort!
Any ideas/pointers/thoughts appreciated.
Thanks,
Jamie
This could happen if the application, at some point, calls Application.Restart.
Related
I have a desktop Windows Forms application I built.
As we try out improvements to the program, I make the changes on a test version of the application, which connects to a test copy of the Microsoft SQL database on the back end.
Basically, to start out, I just copied the program to a different directory, re-named the assembly, created a different PublicTokenKey and used that.
The problem is when I try to run a the test copy and the live copy at the same time. It pretty clearly thinks they are the same program (when I click on the second one, the "busy" circle simple turns for a second, then the already-opened icon in the taksbar gets highlighted), even though they show up in the Task Manager as differently named applications.
What do I need to tweak in Visual Studio so Windows 10 will recognize them as different, separate programs?
I'm new to VB, and so forgive me if this is a simple question.
I will be running multiple time consuming (single thread) processes in a program (that allows automation thru COM). And so to save some time, I want to open two or more instances of this program and run them simultaneously. But anything that I try to do on the program, it happens on the first opened program. This is what I have which my intentions are to open two instances of the program (which does correctly), and open a new document in each of the instances (which what it does is open two new documents in myProcess0 and none in myProcess1. Note: I have System.Diagnostics namespace activated.
Using myProcess0 As Process = Process.Start(programPath)
myProcess0.WaitForInputIdle()
pws0 = New COMprogram.Document
End Using
Using myProcess1 As Process = Process.Start(programPath)
myProcess1.WaitForInputIdle()
pws1 = New COMprogram.Document
End Using
Note: The COM program does not allow to create an handle for the program (like Matlab allows with MLApp.MLApp)
Any help will be appreciated it! Thanks in advance!
This is not exactly a solution, but my current "brute" workaround. This works if your iterations are independent of each other and wish to use multiple instances of a program in the same computer to perform these iterations (but for some reason that is unknown to me, any "Application" objects created point back only to the first instance of the Application).
What I'm doing, is tricking the code by using "desktops": http://technet.microsoft.com/en-us/sysinternals/cc817881.aspx
I simply open the VB code and a Application instance in each desktop, and for some reason the VB code only interacts with the Application opened in the current desktop and not on the others. This happens as well with Matlab somehow. For some reason, all Matlab Application objects reference the first instance.
This will be up to the COMprogram API. With Word or Excel, for example, you can't specify which instance you're accessing without manipulating an Application object.
I have upgraded a 60 KLOC Windows VB.NET application to VS 2012 and Windows 8.
Everything looked fine, except when I deployed it yesterday to ClickOnce.
The ClickOnce application is incredibly slow to load every form the first time that form is launched, IF the form uses binding. If a form is not using binding (but selecting data from a DB query) they load normally.
The most funny part is that while debugging in VS2012 they load in less then 1 second. When launched from the ClickOnce version they spend more than 60 seconds to load.
If I close one of these forms in the ClickOnce application and re-open it, they load normally in less then 1 second.
It seems that Binding in VS2012 is very bad the first time a form is loaded, but I prefer to think I'm doing something wrong.
Any ideas about this issue?
EDIT 2013/01/18:
After one day cutting unnecessary code, I have arrived to a solution that reproduces the slowness and that has no unnecessary code, so that it will be easier (I hope) to find what is not working proprly in it.
ClickOnce application is here:
http://www.octet.it/Reproduce/
Source files are here:
http://www.octet.it/Reproduce/Reproduce.zip
I can state that slowness is NOT depending on:
SQL Server (I have cut all the code that was accessing SQL server DB).
Binding (there is no binding at all, now).
Development environment: if you run the application from VS2012 it works as expected.
Instruction for reproducing slowness:
Install the ClickOnce application on a Windows 8 machine (mine is
x64, I had not a x86 to test).
Start Task Manager.
Start the "Reproduce" application.
When the MDI form has loaded, hit [Return] key (this will fire a MDIChild form).
Have a look at task Manager, showing how the "Reproduce" app will saturate one of the CPUs of your
machine and occupy about 650 MB of your RAM.
After about 45-60 seconds a MDIChild form will appear.
Close the MDIChild form.
Hit [Return] again and see the MDIChild appearing almost istantly and Task Manager showing no CPU saturation or RAM increases
As I told, before Win 8 the MDIChild (with binding and SQL acces to various tables) appeared in about 2-3 seconds.
Source files are not so interesting to see: they will just show a MDIparent form calling a MDIChild form, but I have included them in the .ZIP file if you want to do some experiments.
MANY thanks in advance for your time.
Let me know what I can do to solve this problem. Any suggestions is welcome.
How are you compiling the application? Are you targeting mixed platforms? Try targeting x86. I had a similar issue that was resolved by targeting x86 when I compiled, which should work fine on your x64 box unless you have some crazy x64 dependencies in your application. Note that this will change the clickonce manifest, which is a headache, but I'm curious if this fixes your issue.
Background
We have a .NET WinForms application written in C# that interfaces to a handheld store scanner via a console application. The console application is written in good ol' VB6-- no managed code there. The VB6 application consists of several COM objects.
The .NET WinForms application refreshes the data in the scanner by invoking the console application with the right parameters. When the console application starts, it pops up a modal form reminding the user to place the handheld device into its cradle.
Problem
A customer has a bizarre situation in which the call to start the console application appears to hang before it displays the reminder form. If the user presses any key-- even something innocent like Shift or Alt-- the application unfreezes, and the reminder form appears. While it is hung, the CPU usage of the console application is very high.
We have obtained a memory dump from the command line application using ProcDump. I have some experience debugging managed dump files, but this VB 6 dump is strange to me.
We captured several full memory dumps in a row. In some of them, there appears to be COM glue stacks. For example, several dump files show a call stack like this:
msvbm60!BASIC_DISPINTERFACE_GetTICount
msvbm60!_vbaStrToAnsi
msvbm60!IIDIVbaHost
msvbm60!rtcDoEvents
msvbm60!IIDIVbaHost
msvbm60!BASICCLASS_QueryInterface
[our code which I think is trying to create and invoke a COM object]
It doesn't help that the only symbols I have are from our code. The Microsoft symbol server does not have a PDB file for msvbm60.dll (or at least not from their version which is 6.0.98.2).
Questions
I am suspecting there may be some COM threading issue that is happening only on their system.
1) How can I determine the thread state of each thread in a dump file? If this were a managed dump file, I would look at !threads and then !threadstate to figure out the thread states. There is no managed code, so I can't use sos.dll. I didn't see any hints using ~ and !teb.
2) Is there a way to see what COM objects have been created in a dump file? Again, in a managed dump, I can do a !dumpheap to get a list of managed objects. Is there something similar I can find for COM objects?
3) Can I determine the threading model of COM objects in the dump file?
You can dump thread state by using command:
~*
this will not display 'background' as a state, you will only see running, frozen or suspended.
I'm not sure how you can get information from COM objects, I have never tried but will investigate and get back to you, regards to threading model it will be difficult to infer that without painful monitoring of application state after stepping through and even with that, when you step through all other threads will run unless you use .bpsync 1 which syncs all threads to the current one, but that could cause a hang (e.g. gui thread has now been told to freeze) so I think it will be difficult unless you have access to the source code.
I can only answer question 1. Use !runaway to find the thread or threads consuming the CPU. To get all thread stacks use ~*kb1000.
I'm writing managed code that has to interact with a vendor's COM automation server that runs out of process. I have found that this server becomes unstable if more than one client connects to it. For example, if I have managed code in process A and managed code in process B both connecting to this COM server, a single process will be spun up for the COM server and it's behavior is less than reliable. I'm hoping there's a way to force a separate process for each client - server connection. Ideally, I'd like to end up with:
Managed Process A talking to COM Server in process C1
Managed Process B talking to COM Server in process C2
One thought that came to mind was that if I ran process A and process B with different security identities, that that might cause the COM infrastructure to create separate server processes. I'd rather not go down that road, however. Managed Process A and Managed Process B are actually Windows Services. And I'm running them with identity Local System (because I need them to be able to interact with the desktop, and you can't check the "Interact with Desktop" box on the services applet for services that don't run as Local System). And the reason I need to interact with desktop is that this COM server occasionally throws up a dialog box on the screen and if the service itself cannot interact with the desktop then the COM server is spawns can't display the dialog (I believe it is displayed on a hidden WinStation).
Place the component registered at COM+, this put an isolation layer at your.
Use : Control Panel->Administrative Tools
or cmd/execute DCOMCNFG
Component Services->Computers->My Computer->COM+ Application, right click, new application, next, Create an empty application, enter app name “COM+ your.dll”, next, select Local Service, next, next, next, finish.
In new item made, expand, at Components, right click, new component, next, select Install new component, select your component.
Click Component properties, tab Identity, select System Account.
For errors in calls see Event after.
It's been a while since I've done this, so my memory is hazy.
If you configure the OOP COM server as a DCOM server using the DCOM config tool, I believe you can specify the isolation level. I did this years ago with a non-threadsafe in-process DLL that needed to be accessed in a threadsafe fashion from IIS and it worked a charm.
Let me know if it works for you :)
Your best bet would be to get the vendor to fix the component. After all, if it won't handle multiple clients, there could be other bugs lurking. If you can't do this, there are some other things to try.
With in-process COM objects I've had occassion to manually load the dll and access the interfaces directly without going through COM.
I haven't done this myself with out-of-process COM, but there are some things you could try. Ultimately the library is just a process sitting there receiving messages which invoke functions.
You might be able to manually start the a new copy of the process for each client and then send it messages. You may run into some hiccups with this. For example, the process may check to see if it's already running and refuse to start or otherwise be unhappy.
If you have a known upper limit on the number of clients, another approach you could consider would be to make multiple copies of the original .exe file and then use binary patching (something similar to the detours library from Microsoft Research) to override the COM registration functions and register each copy as a separate COM object.