@@ -63,7 +63,8 @@ internal abstract partial class ProjectNode : HierarchyNode,
6363 IBuildDependencyUpdate ,
6464 IVsProjectSpecialFiles ,
6565 IVsProjectBuildSystem ,
66- IOleCommandTarget {
66+ IOleCommandTarget ,
67+ IVsReferenceManagerUser {
6768 #region nested types
6869
6970#if DEV14_OR_LATER
@@ -1383,71 +1384,191 @@ public virtual VSADDRESULT RunWizard(HierarchyNode parentNode, string itemName,
13831384 }
13841385
13851386 /// <summary>
1386- /// This overrides the base class method to show the VS 2005 style Add reference dialog. The ProjectNode implementation
1387- /// shows the VS 2003 style Add Reference dialog.
1387+ /// Shows the Add Reference dialog.
13881388 /// </summary>
1389- /// <returns>S_OK if succeeded. Failure other wise</returns>
1390- public virtual int AddProjectReference ( ) {
1391- IVsComponentSelectorDlg2 componentDialog ;
1392- Guid guidEmpty = Guid . Empty ;
1393- VSCOMPONENTSELECTORTABINIT [ ] tabInit = new VSCOMPONENTSELECTORTABINIT [ 4 ] ;
1394- string strBrowseLocations = Path . GetDirectoryName ( ProjectHome ) ;
1389+ /// <returns>S_OK if succeeded. Failure otherwise</returns>
1390+ public int AddProjectReference ( ) {
1391+ var referenceManager = this . GetService ( typeof ( SVsReferenceManager ) ) as IVsReferenceManager ;
1392+ if ( referenceManager != null ) {
1393+ var contextGuids = new [ ] {
1394+ VSConstants . ProjectReferenceProvider_Guid ,
1395+ VSConstants . FileReferenceProvider_Guid
1396+ } ;
1397+ referenceManager . ShowReferenceManager (
1398+ this ,
1399+ SR . GetString ( SR . AddReferenceDialogTitle ) ,
1400+ "VS.ReferenceManager" ,
1401+ contextGuids . First ( ) ,
1402+ false ) ;
1403+ return VSConstants . S_OK ;
1404+ } else {
1405+ return VSConstants . E_NOINTERFACE ;
1406+ }
1407+ }
13951408
1396- //Add the Project page
1397- tabInit [ 0 ] . dwSize = ( uint ) Marshal . SizeOf ( typeof ( VSCOMPONENTSELECTORTABINIT ) ) ;
1398- // Tell the Add Reference dialog to call hierarchies GetProperty with the following
1399- // propID to enable filtering out ourself from the Project to Project reference
1400- tabInit [ 0 ] . varTabInitInfo = ( int ) __VSHPROPID . VSHPROPID_ShowProjInSolutionPage ;
1401- tabInit [ 0 ] . guidTab = VSConstants . GUID_SolutionPage ;
1409+ #region IVsReferenceManagerUser Members
14021410
1403- // Add the Browse for file page
1404- tabInit [ 1 ] . dwSize = ( uint ) Marshal . SizeOf ( typeof ( VSCOMPONENTSELECTORTABINIT ) ) ;
1405- tabInit [ 1 ] . guidTab = VSConstants . GUID_COMPlusPage ;
1406- tabInit [ 1 ] . varTabInitInfo = 0 ;
1411+ void IVsReferenceManagerUser . ChangeReferences ( uint operation , IVsReferenceProviderContext changedContext ) {
1412+ var op = ( __VSREFERENCECHANGEOPERATION ) operation ;
1413+ __VSREFERENCECHANGEOPERATIONRESULT result ;
14071414
1408- // Add the Browse for file page
1409- tabInit [ 2 ] . dwSize = ( uint ) Marshal . SizeOf ( typeof ( VSCOMPONENTSELECTORTABINIT ) ) ;
1410- tabInit [ 2 ] . guidTab = VSConstants . GUID_BrowseFilePage ;
1411- tabInit [ 2 ] . varTabInitInfo = 0 ;
1415+ try {
1416+ if ( op == __VSREFERENCECHANGEOPERATION . VSREFERENCECHANGEOPERATION_ADD ) {
1417+ result = this . AddReferences ( changedContext ) ;
1418+ } else {
1419+ result = this . RemoveReferences ( changedContext ) ;
1420+ }
1421+ } catch ( InvalidOperationException e ) {
1422+ Debug . Fail ( e . ToString ( ) ) ;
1423+ result = __VSREFERENCECHANGEOPERATIONRESULT . VSREFERENCECHANGEOPERATIONRESULT_DENY ;
1424+ }
14121425
1413- // Add the WebPI page
1414- tabInit [ 3 ] . dwSize = ( uint ) Marshal . SizeOf ( typeof ( VSCOMPONENTSELECTORTABINIT ) ) ;
1415- tabInit [ 3 ] . guidTab = typeof ( WebPiComponentPickerControl ) . GUID ;
1416- tabInit [ 3 ] . varTabInitInfo = 0 ;
1426+ if ( result == __VSREFERENCECHANGEOPERATIONRESULT . VSREFERENCECHANGEOPERATIONRESULT_DENY ) {
1427+ throw new InvalidOperationException ( ) ;
1428+ }
1429+ }
14171430
1418- uint pX = 0 , pY = 0 ;
1431+ Array IVsReferenceManagerUser . GetProviderContexts ( ) {
1432+ return this . GetProviderContexts ( ) ;
1433+ }
14191434
1420- componentDialog = GetService ( typeof ( SVsComponentSelectorDlg ) ) as IVsComponentSelectorDlg2 ;
1421- try {
1422- // call the container to open the add reference dialog.
1423- if ( componentDialog != null ) {
1424- // Let the project know not to show itself in the Add Project Reference Dialog page
1425- ShowProjectInSolutionPage = false ;
1426-
1427- // call the container to open the add reference dialog.
1428- ErrorHandler . ThrowOnFailure ( componentDialog . ComponentSelectorDlg2 (
1429- ( System . UInt32 ) ( __VSCOMPSELFLAGS . VSCOMSEL_MultiSelectMode | __VSCOMPSELFLAGS . VSCOMSEL_IgnoreMachineName ) ,
1430- ( IVsComponentUser ) this ,
1431- 0 ,
1432- null ,
1433- SR . GetString ( SR . AddReferenceDialogTitle ) , // Title
1434- "VS.AddReference" , // Help topic
1435- ref pX ,
1436- ref pY ,
1437- ( uint ) tabInit . Length ,
1438- tabInit ,
1439- ref guidEmpty ,
1440- AddReferenceExtensions . Replace ( '|' , '\0 ' ) + "\0 " ,
1441- ref strBrowseLocations ) ) ;
1442- }
1443- } catch ( COMException e ) {
1444- Trace . WriteLine ( "Exception : " + e . Message ) ;
1445- return e . ErrorCode ;
1446- } finally {
1447- // Let the project know it can show itself in the Add Project Reference Dialog page
1448- ShowProjectInSolutionPage = true ;
1435+ #endregion
1436+
1437+ protected virtual Array GetProviderContexts ( ) {
1438+ var referenceManager = this . GetService ( typeof ( SVsReferenceManager ) ) as IVsReferenceManager ;
1439+
1440+ var contextProviders = new [ ] {
1441+ CreateProjectReferenceProviderContext ( referenceManager ) ,
1442+ CreateFileReferenceProviderContext ( referenceManager ) ,
1443+ } ;
1444+
1445+ return contextProviders ;
1446+ }
1447+
1448+ private IVsReferenceProviderContext CreateProjectReferenceProviderContext ( IVsReferenceManager mgr ) {
1449+ var context = mgr . CreateProviderContext ( VSConstants . ProjectReferenceProvider_Guid ) as IVsProjectReferenceProviderContext ;
1450+ context . CurrentProject = this ;
1451+
1452+ var referenceContainer = this . GetReferenceContainer ( ) ;
1453+ var references = referenceContainer
1454+ . EnumReferences ( )
1455+ . OfType < ProjectReferenceNode > ( ) ;
1456+ foreach ( var reference in references ) {
1457+ var newReference = context . CreateReference ( ) as IVsProjectReference ;
1458+ newReference . Identity = reference . ReferencedProjectGuid . ToString ( "B" ) ;
14491459 }
1450- return VSConstants . S_OK ;
1460+
1461+ return context as IVsReferenceProviderContext ;
1462+ }
1463+
1464+ private IVsReferenceProviderContext CreateFileReferenceProviderContext ( IVsReferenceManager mgr ) {
1465+ var context = mgr . CreateProviderContext ( VSConstants . FileReferenceProvider_Guid ) as IVsFileReferenceProviderContext ;
1466+
1467+ context . BrowseFilter = AddReferenceExtensions . Replace ( '|' , '\0 ' ) + "\0 " ;
1468+ return context as IVsReferenceProviderContext ;
1469+ }
1470+
1471+ private __VSREFERENCECHANGEOPERATIONRESULT AddReferences ( IVsReferenceProviderContext context ) {
1472+ var addedReferences = this . GetAddedReferences ( context ) ;
1473+
1474+ var referenceContainer = this . GetReferenceContainer ( ) ;
1475+ foreach ( var selectorData in addedReferences ) {
1476+ referenceContainer . AddReferenceFromSelectorData ( selectorData ) ;
1477+ }
1478+
1479+ return __VSREFERENCECHANGEOPERATIONRESULT . VSREFERENCECHANGEOPERATIONRESULT_ALLOW ;
1480+ }
1481+
1482+ protected virtual IEnumerable < VSCOMPONENTSELECTORDATA > GetAddedReferences ( IVsReferenceProviderContext context ) {
1483+ var addedReferences = Enumerable . Empty < VSCOMPONENTSELECTORDATA > ( ) ;
1484+
1485+ if ( context . ProviderGuid == VSConstants . ProjectReferenceProvider_Guid ) {
1486+ addedReferences = GetAddedReferences ( context as IVsProjectReferenceProviderContext ) ;
1487+ }
1488+ else if ( context . ProviderGuid == VSConstants . FileReferenceProvider_Guid ) {
1489+ addedReferences = GetAddedReferences ( context as IVsFileReferenceProviderContext ) ;
1490+ }
1491+
1492+ return addedReferences ;
1493+ }
1494+
1495+ private __VSREFERENCECHANGEOPERATIONRESULT RemoveReferences ( IVsReferenceProviderContext context ) {
1496+ var removedReferences = this . GetRemovedReferences ( context ) ;
1497+
1498+ foreach ( var refNode in removedReferences ) {
1499+ refNode . Remove ( true /* delete from storage*/ ) ;
1500+ }
1501+
1502+ return __VSREFERENCECHANGEOPERATIONRESULT . VSREFERENCECHANGEOPERATIONRESULT_ALLOW ;
1503+ }
1504+
1505+ protected virtual IEnumerable < ReferenceNode > GetRemovedReferences ( IVsReferenceProviderContext context ) {
1506+ var removedReferences = Enumerable . Empty < ReferenceNode > ( ) ;
1507+
1508+ if ( context . ProviderGuid == VSConstants . ProjectReferenceProvider_Guid ) {
1509+ removedReferences = GetRemovedReferences ( context as IVsProjectReferenceProviderContext ) ;
1510+ }
1511+ else if ( context . ProviderGuid == VSConstants . FileReferenceProvider_Guid ) {
1512+ removedReferences = GetRemovedReferences ( context as IVsFileReferenceProviderContext ) ;
1513+ }
1514+
1515+ return removedReferences ;
1516+ }
1517+
1518+ private IEnumerable < VSCOMPONENTSELECTORDATA > GetAddedReferences ( IVsProjectReferenceProviderContext context ) {
1519+ var selectedReferences = context
1520+ . References
1521+ . OfType < IVsProjectReference > ( )
1522+ . Select ( reference => new VSCOMPONENTSELECTORDATA ( ) {
1523+ type = VSCOMPONENTTYPE . VSCOMPONENTTYPE_Project ,
1524+ bstrTitle = reference . Name ,
1525+ bstrFile = new FileInfo ( reference . FullPath ) . Directory . FullName ,
1526+ bstrProjRef = reference . ReferenceSpecification ,
1527+ } ) ;
1528+
1529+ return selectedReferences ;
1530+ }
1531+
1532+ private IEnumerable < ReferenceNode > GetRemovedReferences ( IVsProjectReferenceProviderContext context ) {
1533+ var selectedReferences = context
1534+ . References
1535+ . OfType < IVsProjectReference > ( )
1536+ . Select ( asmRef => new Guid ( asmRef . Identity ) ) ;
1537+
1538+ var referenceContainer = this . GetReferenceContainer ( ) ;
1539+ var references = referenceContainer
1540+ . EnumReferences ( )
1541+ . OfType < ProjectReferenceNode > ( )
1542+ . Where ( refNode => selectedReferences . Contains ( refNode . ReferencedProjectGuid ) ) ;
1543+
1544+ return references ;
1545+ }
1546+
1547+ private IEnumerable < VSCOMPONENTSELECTORDATA > GetAddedReferences ( IVsFileReferenceProviderContext context ) {
1548+ var selectedReferences = context
1549+ . References
1550+ . OfType < IVsFileReference > ( )
1551+ . Select ( reference => new VSCOMPONENTSELECTORDATA ( ) {
1552+ type = VSCOMPONENTTYPE . VSCOMPONENTTYPE_File ,
1553+ bstrFile = reference . FullPath ,
1554+ } ) ;
1555+
1556+ return selectedReferences ;
1557+ }
1558+
1559+ private IEnumerable < ReferenceNode > GetRemovedReferences ( IVsFileReferenceProviderContext context ) {
1560+ var selectedReferences = context
1561+ . References
1562+ . OfType < IVsFileReference > ( )
1563+ . Select ( fileRef => fileRef . FullPath ) ;
1564+
1565+ var referenceContainer = this . GetReferenceContainer ( ) ;
1566+ var references = referenceContainer
1567+ . EnumReferences ( )
1568+ . OfType < ReferenceNode > ( )
1569+ . Where ( refNode => selectedReferences . Contains ( refNode . Url ) ) ;
1570+
1571+ return references ;
14511572 }
14521573
14531574 protected virtual string AddReferenceExtensions {
0 commit comments