Visual Studio Development Bookmark and Share   
 index > Visual Studio Extensibility > C# Package not receiving TaskRemoved event from ErrorList changes
 

C# Package not receiving TaskRemoved event from ErrorList changes

Hello,

I'm working on a C# package in VS2005 in which I'm presenting database-stored VB.NET code documents to the user, who may then modify the code and save it back to the database. To prevent code with syntax errors from being saved to the database, I want to validate it first - ideally at each TextEditorEvents.LineChanged event but without the hit of a full Build action. The shell seems to be automatically building or parsing on every LineChanged event itself because the ErrorList window gets updated constantly so I was hoping to take advantage of this and subscribe to the DTE2.Events.TaskListEvents TaskAdded and TaskRemoved events. The idea only half works, though: the TaskAdded event fires every time bad text/code is inserted but the TaskRemoved never fires if the bad text is removed.

<code>
//Class level (custom UserControl in a ToolWindow)
private DTE2 _applicationObject;
private TaskListEvents taskEvents;
//Function level (Initialization sub called after class constructor is finished)
taskEvents = _applicationObject.Events.get_TaskListEvents(""); //I've tried (Events2)_applicationObject.Events, as well
taskEvents.TaskAdded += new _dispTaskListEvents_TaskAddedEventHandler(taskEvents_TaskAdded);
taskEvents.TaskRemoved += new _dispTaskListEvents_TaskRemovedEventHandler(taskEvents_TaskRemoved);
//Implementation
        void taskEvents_TaskRemoved(TaskItem TaskItem)
        {
            //haven't gotten this to fire at all
            //call to validation routine...
        }

        void taskEvents_TaskAdded(TaskItem TaskItem)
        {
            //this fires every time
            //call to validation routine...
        }
</code>

The user control is receiving SVsRunningDocumentTable, SVsShellMonitorSelection, BuildEvents and my own custom events successfully so I'm finding it really strange that the TaskAdded event will work but not TaskRemoved - surely it must be something simple. Has anyone run into this problem before? If, so is it fixable or is there a workaround? If I have to I'll settle for a manual re-Build and validation just prior to saving back to the database but would rather track the current state of the code documents as they change (multiple simultaneous open).

Thanks!

Phil
scsibluesmaster  Wednesday, October 07, 2009 11:16 PM
Hello Phil,
I tried use ErrorListProvider.Tasks.Remove() method, to remove an error item, it still doesn't work. This issue may be a problem in automation model.
Could you use  ErrorListProvider class to substitude? capture the save command first, and use  ErrorListProvider.Tasks to traverse all the error items to see wthether there is any error before you save?
Hope this could help!
Thanks
Chao
Chao Kuo  Friday, October 09, 2009 9:07 AM
Validating the code on file-save sounds like a good place to do so in the overall process, even if a dynamic validation on LineChanged events were also possible. I'll give that a try. I was really hoping that I was just doing something dumb in the code because I have a similar problem in getting the DTE2.Events.MiscFilesEvents.ItemRemoved event to fire when a project file / ProjectItem is removed.

Also, with regard to the TaskRemoved event, I noticed in the online MSDN articles the following Permissions comment:
         "Full trust for the immediate caller. This member cannot be used by partially trusted code. For more information, see Using Libraries from Partially Trusted Code."

Is it possible that I'm running into a security issue? The comment exists in the .NET 3.5 and 4.0 framework notes but not in the 2.0 notes, so perhaps it doesn't apply but who can be sure?.
http://msdn.microsoft.com/en-us/library/envdte.tasklisteventsclass.taskremoved.aspx

Thanks,

Phil
scsibluesmaster  Friday, October 09, 2009 1:54 PM
Hi, Phil
In order to make ItemRemoved work, you should use the following statement.
projItemEvents = ((EnvDTE80.Events2)_applicationObject.Events).ProjectItemsEvents;
If you write the code by you own, you code is fully trusted.If your code is from other place, it maybe partially trusted, it can not use the TaskRemoved event.
Maybe you need how to initialize the class, now the code below will show you how to initialize this class.
ServiceProvider sp = new ServiceProvider((IOleServiceProvider)_applicationObject);
ErrorListProvider provider = new ErrorListProvide(sp);

And you should add the following reference
Using IOleServiceProvider=Microsoft.VisualStudio.OLE.Interop.IServiceProvide;
using Microsoft.VisualStudio.Shell;
using Microsoft.VisualStudio.Shell.Interop;

Please let me know whether it helps
Thanks
Chao
Chao Kuo  Monday, October 12, 2009 3:55 AM

Hello, Phill
We are changing the issue type to “General Discussion” because you have not followed up with the necessary information. If you have more time to look at the issue and provide more information, please feel free to change the issue type back to “Question” by opening the Options list at the top of the post window, and changing the type. If the issue is resolved, we will appreciate it if you can share the solution so that the answer can be found and used by other community members having similar questions.

Thank you!
Chao

Chao Kuo  Wednesday, October 14, 2009 2:16 AM
Hi Chao,

I haven't had a chance to try your last suggestion but do intend to do so as soon as I can. In the mean time, for anyone else interested, intercepting the DocumentEvents DocumentSaved event and initiating a full rebuild of the project seems to work well and provides a fair way of ensuring any set of compilable code has been checked for errors, assuming the intended business process can accommodate a file-save prior to an upload to a database would occur.

Thanks,

Phil
scsibluesmaster  Wednesday, October 14, 2009 10:03 PM
Hi, Phil
Glad to hear that you continue following up with me.  And for how to capture the Save command. I have written the sample fragment below.
 CommandEvents cmdEvent;
public void Exec(string commandName, vsCommandExecOption executeOption, ref object varIn, ref object varOut, ref bool handled)
		{
			handled = false;
			if(executeOption == vsCommandExecOption.vsCommandExecOptionDoDefault)
			{
				if(commandName == "AddinCaptureCmd.Connect.AddinCaptureCmd")
				{
                    cmdEvent = _applicationObject.Events.get_CommandEvents("{5efc7975-14bc-11cf-9b2b-00aa00573819}", 331);
                    //cmdEvent.BeforeExecute += new _dispCommandEvents_BeforeExecuteEventHandler(cmdEvent_BeforeExecute);
                    cmdEvent.AfterExecute += new _dispCommandEvents_AfterExecuteEventHandler(cmdEvent_AfterExecute);

					handled = true;
					return;
				}
			}
		}
 void cmdEvent_BeforeExecute(string Guid, int ID, object CustomIn, object CustomOut, ref bool CancelDefault)
        {
            MessageBox.Show("Before execute!");
        }
        void cmdEvent_AfterExecute(string Guid, int ID, Object CustomIn, Object CustomOut)
        {
            MessageBox.Show("Äfter execute!");
        }

Hope this could help!

Thanks

Chao

Chao Kuo  Thursday, October 15, 2009 3:03 AM

You can use google to search for other answers

Custom Search

More Threads

• DSL Setup not working correctly.
• VSX CoDe Focus Magazine online
• IronPython
• SDK VSPackage: how to use variable of VSITEMID datatype correctly?
• VS User Interface : How to customize the "Add a New Item" window
• Fail to add coponent with IDesignerHost in WebApp
• Placing my toolwindow in the main document area
• 'Double' command contexts
• Using an Intellisense Completor from within an Add-On (not a package)
• Need complete documentation on how to use Web Setup Project