Products, the Universe and Everything

The Riverblade Developer's Blog

Beth demonstrating Visual Lint at the ACCU Conference 2008  Anna taking part in a discussion panel at the European Software Conference 2007 

Welcome to our developer's blog. We hope that this forum provides an insight into us, our products and how we develop them. Please feel free to write to us if you have anything to add to any of the posts here.

Current Entries | Archives |


Visual Lint 1.0.2.43 has been released
Wednesday, January 18, 2006

We are pleased to announce that Visual Lint 1.0.2.43 is now available.

This version primarily addresses issues we have enountered with the RTM version of Visual Studio 2005 (we received our copies just before Christmas) which is proving to be significantly more picky and difficult to interface to than its predecessors.

There is still more to do (notably support for additional platforms and compatibility testing with other extensibility products with newly released VS2005 compatible versions) so there will be further releases in due course, but we are confident that the most significant issues have now been addressed.

The following changes are included in this version:

  • The Configuration Wizard now correctly reads the include folder configuration under VS2005, which no longer supports the "Platforms" property previously used to expose Visual C++ platform specific configurations. Note that of the platforms supported by VS2005 (Win32, x64, Pocket PC 2003 and Smartphone 2003) the wizard currently only supports the Win32 platform - this will be expanded in a subsequent release to include the other available platforms.

  • A DTE interface pointer obtained from the COM Global Interface Table (GIT) is now used while loading solutions. This avoids potential problems caused by marshalling of COM interfaces which can occur when running under VS2005. In order to allow threads using the GIT to operate correctly, worker threads within the add-in are now implemented as multithreaded appartments.

  • The "BeforeExecute" command event handler no longer pauses analysis if the "Active Configuration" property is about to change, as under some circumstances VS2005 RTM will source this event regularly even though the configuration is not changing. In such cases this could cause the solution analysis state to unilaterally switch back to "Paused" when the user presses "Play".

  • When running under VS2005 the include folder and active configuration are not checked periodically as they are under VS2002/2003. Not only is it unnecessary with VS2005 (which does not have the command event bug which makes it necessary for VS2002/2003) but it can cause instability in the VS2005 IDE.

  • The eAction parameter received by the "BuildBegin" event handler is now cached, as under VS2005 the companion "BuildDone" event can receive an invalid value. This caused Visual Lint to fail to restart analysis after a Rebuild All (but not Build, which works correctly).

  • The VCProjectEngineLibrary::_dispVCProjectEngineEvents "ItemPropertyChange" event has an additional parameter in VS2005. Visual Lint now handles this event correctly, irrespective of whether the add-in is running under VS2002, VS2003 or VS2005.

  • Fixed an intermittent crash when a solution is closed or a message in the Analysis Results Display is activated while the display is being updated.

  • Analysis results now appear correctly when a source file is analysed while no solution is open.

  • Three +linebuf parameters are now included in the PC-Lint command line to reduce the likelyhood of a buffer overflow in PC-Lint during analysis.

  • The way unloaded projects are handled has been improved. In particular, they are now identified by name when the solution is loaded (the name is accessible, the pathname is not!) and removing an unloaded project from the solution no longer results in an uncaught exception.

  • Added additional safeguards to ensure that the add-in does not interfere with the VS2005 project conversion wizard, which seems to be somewhat more picky than its predecessors.

  • The "Show Display" commands now reset the position of a floating toolwindow if its size is far too small (this can happen from time to time due to a bug in Visual Studio itself). This provides an easier way of recovering a "lost" toolwindow than resetting the IDE's window layout.

  • Removed unnecessary status window activation calls.

  • When the add-in is being uninstalled the user is now prompted as to whether it should attempt to remove its commands and warns that this could affect IDE customisations (at least under VS2005).

  • The parent window of uninstallation prompts and the progress dialog is now set correctly.

  • Error messages returned while writing HTML reports are now written to the Status Display for diagnostic purposes.

  • Updated the PC-Lint message database to PC-Lint 8.00u. Also improved the formatting of messages containing code samples.
As an aside, Visual Lint is now built with WTL 7.5 final (7.5.5333.0). I can't emphasise how much easier the availability of a lightweight, well supported UI framework has helped us during the development of this product - in the past I've written similar projects using MFC, but this is by far more customisable and lightweight.

If you haven't looked at WTL yet, I'd strongly recommend you do so. It's certainly changed the way we look at new designs.

Posted by Anna at 21:33 | Get Link

 

Why on earth can't they just leave interfaces alone?
Tuesday, January 17, 2006

...or: "why is it so difficult to figure out how to read the Visual C++ Include Folder configuration in VS2005?"

The answer is of course that the interfaces have been changed. I don't know why, but I do know that the method recommended by Microsoft no longer works.

In VS2002 and VS2003 expose interfaces to a collection of VCPlatform objects via DTE's properties collection, indexed by the name of the platform. Once you have a VCPlatform interface pointer, reading the include folder configuration is simplicity itself:


CString GetVcIncludeFolders(EnvDTE::_DTE* pDTE, const CString& sPlatform /*= _T("Win32")*/ )
{
CString sIncludeFolders;

try
{
EnvDTE::_DTEPtr ptrDTE;
pDTE->QueryInterface(&ptrDTE);

EnvDTE::PropertiesPtr ptrProperties = ptrDTE->GetProperties(L"Projects", L"VCDirectories");

VCProjectEngineLibrary::IVCCollectionPtr ptrPlatforms = ptrProperties->Item(L"Platforms")->GetObject();
ATLASSERT(ptrPlatforms != NULL);

if (ptrPlatforms != NULL)
{
VCProjectEngineLibrary::VCPlatformPtr ptrPlatform = ptrPlatforms->Item(_bstr_t(sPlatform) );

_bstr_t bsFolders = ptrPlatform->GetIncludeDirectories();

sIncludeFolders = COLE2CT( ptrPlatform->Evaluate(bsFolders) );
}
}
catch (const _com_error& e)
{
#ifdef _DEBUG
CString sMsg;
sMsg.Format(_T("Unexpected exception 0x%X (%s) in %s()\n"),
e.Error(),
e.ErrorMessage(),
CA2CT( __FUNCTION__ ) );

ATLTRACE(sMsg);
ATLASSERT(false);
#endif
}
return sIncludeFolders;
}

Unfortunately, the available properties have changed in VS2005, and the "Platforms" collection is no longer exposed in this way, as a glance at the properties shown by the Extensibility Browser will show:


VCDirectories properties in VS2003



VCDirectories properties in VS2005



When we realised this our first thought was to try to obtain a VCProjectEngine interface somehow - from there the Platforms collection is directly accessible. Unfortunately all the examples in MSDN and elsewhere show VCProjectEngine interfaces being obtained from an EnvDTE::Project object, as follows (apologies for the VB!), and we can't use this method if there is no solution open:


' add reference to Microsoft.VisualStudio.VCProjectEngine
Imports EnvDTE
Imports Microsoft.VisualStudio.VCProjectEngine

Public Module Module1
Sub Test()
Dim prj As VCProject
Dim cfgs, tools As IVCCollection
Dim cfg As VCConfiguration
Dim p As VCPlatform
Dim x As String
prj = DTE.Solution.Projects.Item(1).Object
p = prj.Platforms(1)
x = p.IncludeDirectories
p.IncludeDirectories = x + ";something"
MsgBox(p.IncludeDirectories)
End Sub
End Module

The key was finding a way to obtain a VCProjectEngine interface pointer without going through a Project. Although Microsoft suggest you can create an instance of this object directly like this:


VCProjectEngineLibrary::VCProjectEnginePtr ptrEngine;

ptrEngine.CreateInstance( __uuidof(VCProjectEngineLibrary::VCProjectEngineObject),
NULL,
CLSCTX_INPROC_SERVER);

this is not a safe operation to perform within the IDE, certainly under VS2005. We saw some sorts of strange and unpleasant side effects when we explored this route!

Thankfully there is another way, albeit an undocumented one. The VCProjects collection (accessible via a property of DTE itself) can be used to obtain a VCProjectEngine interface pointer, and thereafter it is straightforward:


CString GetVcIncludeFolders(EnvDTE::_DTE* pDTE, const CString& sPlatform /*= _T("Win32")*/)
{
CString sIncludeFolders;

if (pDTE != NULL)
{
try
{
EnvDTE::_DTEPtr ptrDTE;
pDTE->QueryInterface(&ptrDTE);

EnvDTE::ProjectsPtr ptrProjects = pDTE->GetObject(L"VCProjects");

VCProjectEngineLibrary::VCProjectEnginePtr ptrProjectEngine =
ptrProjects->GetProperties()->Item(L"VCProjectEngine")->GetObject();

if (ptrProjectEngine != NULL)
{
VCProjectEngineLibrary::IVCCollectionPtr ptrVcPlatforms =
ptrVCProjectEngine->GetPlatforms();

VCProjectEngineLibrary::VCPlatformPtr ptrPlatform = ptrVcPlatforms->Item( _bstr_t(sPlatform) );

sIncludeFolders = COLE2CT( ptrPlatform->Evaluate( ptrPlatform->GetIncludeDirectories() ) );
}
}
catch (const _com_error& e)
{
#ifdef _DEBUG
CString sMsg;
sMsg.Format(_T("Unexpected exception 0x%X (%s) in %s()\n"),
e.Error(),
e.ErrorMessage(),
CA2CT( __FUNCTION__() ) );

ATLTRACE(sMsg);
ATLASSERT(false);
#endif
}
}
ATLASSERT(!sIncludeFolders.IsEmpty() );

return sIncludeFolders;
}
Fortunately, the same code also works in VS2002 and VS2003.

Posted by Anna at 23:49 | Get Link