Visual Studio Extension: Wait for all projects to complete loading with IVsSolutionEvents OnAfterOpenSolution - visual-studio-2010

I am looking for an event/interface to use that notifies me once all projects have loaded in a solution after opening a solution.
I have implemented OnAfterOpenSolution in IVsSolutionEvents2 interface. This gets called immediately after the solution opens... so any code I run against the UI thread, even asycnhronously, locks up the IDE prior to the project(s) loading.
Is there a similar technique to implementing `OnAfterOpenSolution', that is called once all the projects for the solution have opened?

The OnAfterBackgroundSolutionLoadComplete event in the IVsSolutionLoadEvents interface is fired after all projects for the solution have completed loading. The implementation for this will still need to implement or extend from an implementation of one of the IVsSolutionEvents interfaces in order to attach the event using IVsSolution.AdviseSolutionEvents(..) method.
Upon Further investigation in this area, the OnAfterBackgroundSolutionLoadComplete only occurs if projects are set to load in the background. If the background loading has been disabled this event will not occur. You will likely also have to implement IVsSolutionLoadManager and ensure that at least 1 project has a background load priority if you intend to rely on the OnAfterBackgroundSolutionLoadComplete event, or switch based on how the user has set their loading priority.

Related

How to analyze UWP application UI freeze?

My UWP app goes into UI freeze state sometimes and I don't know why。 I've checked the code about view model and async-await calls. And I've tried to use the performance profile tool in Visual Studio to get timeline but it only shows the time and duration time about the UI freeze. I have run out of ideas now.
I tried the dotTrace but it seems that I cannot use it to profile UWP application. Even I " disable the Compile with .NET Native tool chain option in Visual Studio (via the menu Project | Properties... | Build) and rebuild the project."
https://learn.microsoft.com/en-gb/visualstudio/profiling/profiling-feature-tour?view=vs-2019
There are many reasons for UI freezing, including code endless loops, asynchronous methods are not handled properly, program errors, etc.
Most of them occur in asynchronous method processing and UI rendering.
When calling asynchronous methods, use the async/await keywords, like:
//define
public async Task asyncMethod()
{ }
//use
await asyncMethod();
Reduce resource consumption when rendering a large number of data templates through virtualization.
If you have a large list to render, if virtualization is not enabled (referring to controls with virtualization, such as ListView), or used, but the conditions of virtualization are destroyed (such as adding ScrollViewer outside ListView ), This will also cause the UI to freeze and will not return to normal until the list is rendered.
Please check your code for the above problems, or provide a minimal reproducible demo so that we can analyze where the problem occurs.
Best regards.
I would suggest you try to use the Visual Studio debugger to find out what the code is doing.
First, make sure that you are set "Debug" mode and that the debugger is going to run on "Local Machine" (there are other options here, but I'm trying to keep things simple).
Then, click on the "Local Machine" button to run your app using the debugger.
Once your app freezes, click on Debug-Break All:
After that, I suggest you use the various Debug commands to further debug your application.
For example, you can use the "Call Stack" menu item/window to view what your code is doing. You can also use the "Threads" menu to see what threads are running. If you have suspect areas in your code, you might consider adding System.Diagnostics.Debug.WriteLine() statements to print out informative messages, and then use the "Output" menu item/window to see what is happening.
If your app first freezes, and then crashes after some time, then this could be because your tasks don't have correct exception handling. You might consider adding an UnobservedTaskException handler to your code to help you find this problem.

Eclipse RCP Project Explorer focus event

Is there a way to detect when the user makes focus on the Project Explorer window in a RCP application? Is there an event I could use?
I researched and found that Project Explorer's id is org.eclipse.ui.navigator.ProjectExplorer but I still didn't find any solution to my problem.
You can use org.eclipse.ui.IPartListener to listen for changes to which part is active (and several other events).
You call the IPartService addPartListener method to set this up. You can get the part service in several ways depending on where you code is running. One of these is:
IPartService partService = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getPartService();
partService.addPartListener(listener);

In a Visual Studio Extension, how to detect when the debugger Continues

I need my Visual Studio extension to react to debugging events. I've registered a IDebugEventCallback2 and I'm receiving events, but all I get for each event is an opaque IDebugEvent2 and a Guid, many of which are not only undocumented but don't appear anywhere on the web (or in my registry).
My specific requirement at the moment is to know when the process is Continued - ie. the user has hit Continue, Run to cursor, etc. What Guid should I be looking for?
Or is there some other event family that I should be subscribing to?
(More generally, is there some way I'm missing to find out about the events that are delivered to my IDebugEventCallback2::Event callback, when many of them don't appear in MSDN or anywhere else? Thanks!)
There is no easy way to do this. Actions such as Continue and Run to cursor are abstractions implemented by Visual Studio and do not correspond to any unique event(s) with respect to the debug engine. The debug engine event reporting interface IDebugEventCallback2 will enable you to get notified only on fine-grained events such as when creating a breakpoint or reaching a breakpoint.
While Visual Studio enables you to perform actions such as Continue and Run to cursor programmatically, it does not provide a direct way to get notified when they are taken.
You can use EnvDTE.DebuggerEvents.OnXxx events to get notified when something is about to happen. In particular, the OnEnterBreakMode event enables you to intercept a breakpoint hit and possibly take an action. You can also inspect all the details of the reached breakpoint(s) using the current EnvDTE.Debugger inside the event handler.
Now with some effort, you can use these constructs to implement events that correspond to all Visual Studio debugging actions including Continue and Run to cursor accurately. If you require additional events not provided by EnvDTE.DebuggerEvents (such as when a breakpoint is inserted), you have no choice but use IDebugEventCallback2.Event. In this case if you have specific events in mind, please mention them explicitly and I might be able to tell you the corresponding IDebugEventCallback2.Event GUIDs.
You probably got off on the wrong foot here, the IDebugXxx interfaces were really intended to create your own debugging engine. Still useful perhaps to see what is going on in the existing engine, you are suppose to use QueryInterface() to discover the specific interface that matches the event. Like IDebugEngineCreateEvent2, IDebugProcessCreateEvent2, IDebugProcessDestroyEvent2, etcetera. There are a bunch of them, they are listed in the VSSDK\VisualStudioIntegration\Common\Inc\msdbg.h header and include their IID.
Best thing to do is peek at this sample, it shows how to crack the event notification into the specific interfaces. The AD7Events.cs source file shows the wrappers. Do keep in mind that this sample was made to show how to create an engine, not how to use the one already built into VS.
But yes, you are not going to get a "continue debug" event out of this. A debugging engine does not need that event since it is already responsible for taking care of that by itself. It already knows when it calls IDebugProgram3::Continue().
Surely what you are looking for is IVsDebugger.AdviseDebuggerEvents(). That's the one that tells you what the built-in debugger is doing. You need to pass an object of a class that implements IVsDebuggerEvents, your OnModeChanged() method will be called with a DBGMODE notification. I don't see a lot of fantastic examples that demonstrate usage, this web page might be helpful.

Does the VB6 compiler actually run the ActiveX during the Build process? [duplicate]

I am trying to compile a VB6 application, but it fails with the error, "Run-time error '91': Object variable or With block variable not set". It turns out the Resize event of a user control is firing during compilation and calling code that attempts to access an object that has not been instantiated yet.
Why is an event firing during compilation and is there any way to stop it?
Edit: I had some code here, but it's not relevant. The problem results from the fact that UserControl code (namely the Initialize, ReadProperties, Resize, and WriteProperties events) can execute at unexpected times. If the code in these events relies on other code to initialize any of its data structures, there's a good chance it's going to fail because that initialization code may not have executed. Especially during compilation when nothing is supposed to be executing! I'd call this a bug, but I'm sure Microsoft can rationalize it somehow.
Here's is a good article on the lifecyle of user control events
Understanding Control Lifetime and Key Events
Here is one snippet
Compiling the Project
When the project is compiled into an
application or component, Visual Basic
loads all the form files invisibly,
one after another, in order to write
the information they contain into the
compiled file. A control instance gets
the Initialize, ReadProperties, and
WriteProperties events. The control's
property settings are compiled into
the finished executable.
It doesn't mention resize (which happens during run-time or when you physically resize the usercontrol on a container in design-time). Maybe your Initialize event is resizing the user control?
To avoid the error you can check if the offending object has been created before doing anything:
If Not Object Is Nothing then
do something
I think some events for user controls get executed during design time, at least for the purpose of rendering them in a consistent way.

CMFCToolbar ReplaceButton() causes button to disappear

Using Visual Studio 2010 and working with an MFC SDI Application.
I have a CMFCToolbar object owned by the Main Frame.
When the document in this application is created, the MainFrame calls a function to replace one of the buttons in the CMFCToolbar object with a CMFCToolbarMenuButton. The contents of the menu button are populated with information from the document. The menu creation always works. The call to ReplaceButton always succeeds. But there's a visual symptom of the call that I haven't yet figured out.
Any time ReplaceButton is called, the button disappears. Not only is it not drawn, it's not clickable. It's temporarily gone. I assume this is because there's a dangling reference to the old button, which I have just destroyed with the call to ReplaceButton.
I've tried calling Invalidate(), RecalcLayout() to trigger a re-draw, but neither has worked yet. The only reliable method I have for getting the button to show up is re-sizing the application window manually or by un-docking/re-docking the toolbar. I assume there's some kind of lower-level refresh that occurs in these situations, but I don't know how to trigger it manually.
Is there a way to make sure my button is drawn immediately?
Edit: code sample
Count = m_Doc->...->GetCount();
for (Index = 0; Index < Count; ++Index)
{
Caption.Format(L"%s", m_Doc->...->GetName());
m_pLayerMenu->AppendMenu(MF_ENABLED | MF_STRING, LAYER_DROP_SEED+Index, Caption.GetData());
}
m_wndBrushBar.ReplaceButton(ID_BRUSH_TERRAIN,
CMFCToolBarMenuButton(ID_BRUSH_TERRAIN, *m_pLayerMenu, GetCmdMgr()->GetCmdImage(ID_BRUSH_TERRAIN)));
Update:
Calling m_wndBrushBar.AdjustLayout() seems to stabilize the visual behavior of these CMFCToolbar buttons. So that's a partial solution.
Partial because of the following:
It's hard to tell what the real visual behavior is. It turns out that all visual settings/states are stored in the Registry with these MFC objects, and it can hold onto states of dynamically created objects that really alter the startup behavior of the app.
I've gone in to delete the registry values under
Current User -> "Local App-Wizard Generated Applications" -> [My App Name].
Done this a number of times, just to find out what the real behavior of my app is. Feel like I'm missing some fundamental knowledge with the current version of MFC. Lots of bugs arising from the registry deal.
Is there a way to prevent registry settings for certain objects, or to shut off this behavior altogether? Otherwise, I guess my shutdown process will have to be a LOT more thorough with resetting all the visual elements. Registry values seem to ignore, override, or bypass my startup code. I can code how I want an object to look at startup, but if there are values in the registry, it does no good.
You've discovered a sometimes annoying aspect for the CMFC code. That is, the concept of a Workspace. The Workspace manages the concept of the application state. I, too, have had problems like the one you describe. But, you have the flexibility to manage how those objects are recreated by overriding the LoadState () and SaveState () methods.

Resources