My MFC program remotes a WMP instance to catch WMP events and is using IWMPCore, IWMPCore3, IWMPPlaylistCollection, IWMPMediaCollection to interact with WMP using COM. The remote instance is working find and it is avle to catch the events, but when I started fetching all the details of all songs(almost 5100 songs), WMP stops responding until my application fetches all the songs and release all the above instance. Can anyone please help me out with the issue and how can it be fixed?
WMP ActiveX control is an STA COM object, so all interaction (method calls) goes through instantiation thread, which is in most cases the UI thread. That is, whatever you do with the interfaces, the calls block GUI for the time of the call.
You need to either pump window messages in the middle of your activity to unblock UI (show progress and let user hit Cancel button), or create a worker thread initialized as STA and obtain the collection details using a secondary invisible instance of WMP there.
Related
I have experienced this behavior in my automation application: when I "click" a button by calling the InvokePattern.Invoke() method everything stops until the handler of the click event inside the automated application finishes.
While this can make some thing simple (for example I don't have to write tons of code to wait for a dialog with progress bar to disappear, because I simply get the control back when everything is done), but I can't do anything else. It even blocks the access to the Automation API in another thread where it continues after the click handler is done.
This causes problems when click handler in the automated application opens a modal dialog, then I can't do anything, the access to the application through automation API is blocked until the dialog is manually closed.
Has anybody solved this somehow and can help me?
Thanks,
Karel
PS: Reference source is saying this:
Request that the control initiate its action.
/// Should return immediately without blocking.
/// There is no way to determine what happened, when it happend, or whether
/// anything happened at all
public void Invoke() { ... }
Edit: It works perfectly when automating Windows notepad application which is not a .NET application. And it does not work for a Notepad clone (C# WinForms aplication).
I've got a single instance (set up via .net) program that operates mostly from the system tray but also has a window.
Users often lose the program among their other system tray icons and believe the program isn't running, trying to open it again from the executable.
How can I detect, within my running program, that the executable is opened again? (So that I can maximize the window)
Thanks in advance.
Opening another copy of a single instance program will bring your form to the front by default, but when the form isn't visible, this won't have any effect.
This is what I was looking for
The MyApplication_StartupNextInstance event occurs when another instance is started. This can be used to call any additional functions you need.
In Project Properties, You can navigate to Application -> View Application Events and handle Me.StartupNextInstance from within Partial Friend Class MyApplication.
Direct all thanks to the comments.
I need to write a log when the application starts and exits. Obviously when it starts it easy to write the log. But a user can close an application in multiple ways, even shut it down in task manager. is there sort of a global event when shutting an application down it will call a specific event from anywhere and I can add my logging code?
In visual Studio, go to the project properties window, Application tab. AT the bottom is a button labelled 'View Application Events' This takes you to a code view where you can add handlers for the application events including the shutdown event. However, this isn't always fired if your application crashes ^H^H^H^H^H closes in an 'unusual' way.
The startup event is useful too - you could put your startup logging code in there- we use it a lot to put in all the application setup code, with only a splash screen showing, then when the startup code completes the main window will pop up.
Finally, the Unhandled Exception event is a handy place to put a final catch-all backstop error handler
I wrote a VB.NET Windows Forms app that requests a string from an out-of-process COM object every time the activate event fires. My form has two tabs, so I need to programmatically flip to the correct tab every time my window gains focus. Works fine, until...
By chance, someone ran a vbscript (yes, script, not exe) that contains:
Set shell = CreateObject("WScript.Shell")
shell.AppActivate("Window Title That Matches My App")
This script consistently crashes my app. Usually so badly that the Exception dialog usually can't paint itself. I have to kill it from task manager. Sometimes the Exception is readable. (I also confirmed the exception by attaching to the running exe with Visual Studio). It's: "System.Runtime.InteropServices.COMException (0x8001010D): An outgoing call cannot be made since the application is dispatching an input-synchronous call."
What's really messing with my mind is that my app has multiple instance detection using a mutex, and if an existing instance is running, my own code (compiled) uses VB.NET's own AppActivate keyword, and this does NOT crash my app. It activates the running instance and exits the redundant instance as expected.
The problem seems solely to be triggered by cscript/wscript's AppActivate. I wrote a 3-liner .vbs to confirm this. It's repeatable.
Is there a way to trap or avoid this in my compiled app?
It's not clear to me WHY this approach actually fixes the problem, but it DOES work:
Add a timer to the form.
Move all the _Activated code to the timer's _Tick event.
Make the _Activated event start the timer.
Make the _Tick event stop the timer then perform the COM stuff.
I want to run some cleanup code(like unregistering scheduled notifications) when a user quits the application by using the Alt-F4 or swipe down gesture. Is there any way to handle an application exit in WinJS? I've read the docs for the WinJS.Application object but don't see any methods to handle user exits.
There is no special event that indicates that an app is being closed:
There's no special event to indicate that the user has closed an app. After an app has been closed by the user, it's suspended and terminated, entering the NotRunning state within about 10 seconds. If an app has registered an event handler for the Suspending | suspending event, it is called when the app is suspended. You can use this event handler to save relevant application and user data to persistent storage.
So you'll want to handle a suspend/resume instead. The gory details for handling a suspend are here, but here's a summary:
Register for the checkpoint event that will tell your app that it's being suspended.
Save whatever data you need to save in the event handler for that event.
Release resources, suspend notifications, etc. in the event handler as well.
On resume, you can check if the app was closed by the user using the ApplicationExecutionState enum. That may or may not be relevant to you, since there doesn't seem to be a way to differentiate why checkpoint event was fired and your only option is to save your state in the event handler no matter why it happened.
There are additional suspend/resume guidelines here, and you may find this sample app helpful.