Partilhar via


How to add your own Exception Assistant content

The question has been asked on the Visual Studio Forums several times.  I guess it might be worth to post some information here.

The content of the exception assistant are saved in xml files under “Visual studio InstallDir\ExceptionAssistantContent\LCID” directory. For the English version of the VS, the LCID is 1033. The Visual Studio will load all files under this directory with extension "xml" once, when the feature is used. The default DefaultContent.xml is a good sample how to create a content file. It is better to leave your content in another file, and do not modify the DefaultContent file. Because the VS will not check the content file after it loads them, you do have to restart the VS if you add or change anything there.

The head of the content file, the <ContentInfo>...</ContentInfo> block is not used today. But do include them there, because it might be used later.

In the DefaultContent.xml, all HelpIDs are F1Keywords in the MSDN library. However, a HTTP link is also allowed here. For example, this is a valid rule in the content file:

<Exception HelpID=https://www.AnotherCompany.com/HelpContent/MyException.html>

<Type>AnotherCompany.API.MyException</Type>

</Exception>

The <Type> block is used to match the type of the exception. You must use the full class name here, (including the namespace name). It is also case sensitive. In the early same, it links the default link of the MyException to the web page. (The default link is “Get general help for this exception.” on the help window.)

You can add blocks to show a tip when a defined condition is matched:

<Exception>

<Type>Exception Type Name</Type>

<Context>Function Name</Context>

<Demand>Security Permission</Demand>

<Precondition>condition expression</Precondition>

<Tip HelpID="F1Keyword or HTTP link">

<Description>Description String</Description>

</Tip>

</Exception>

<Context>, <Demand>, <Precondition> blocks are all optional.

<Context> block is used to match function name called by the user code. It must be a full name like “System.Console.WindowLeft.set”.

<Demand> block are only useful when it is a System.Security.SecurityException. It must be a full name of a permission type.

<Precondition> block contains a condition expression.

Remember while those condition blocks do allow you target the exactly condition, it might cause a tip not to show in some conditions, because other limitations. For example, the feature requires evaluating values in the debuggee to match the demand condition, but if the current state of the debugger does not allow the evaluation, or the evaluation fails, the tip may not be shown.

The Precondition block is a little bit complex, and I don't want to go to detail here. However, it does allow you to match condtions better. For example, you can show the tip only when the user code is written in VB:

$UserLanguage = "Basic"

(The language name could be seen on the call stack window.)

Or matching a part of the error message:

$Message ~ ".*System.Security.Permissions.SecurityPermission.*"

(Remember, matching message may be a problem when the debuggee is localized.)

Or hiding the message when the assistant shows as a smart tag when the exception is caught:

!$InCatchBlock

Or the function called by the user code belongs to System.Console class:

$Context ~ "System\.Console\..*"

...