Is it possible to refresh WCF service reference from VS2010 addin?
Asked Answered
K

2

9

I want to "simulate" the Right click/Update service reference command in a VS2010 addin. I have a reference to the containing (Silverlight...) project, I know the name of the service reference and the url of the service.
I've found this: http://dedjo.blogspot.com/2007/03/adding-web-references-to-your-vs.html , but it only works for asmx (it uses System.Web.Services instead of System.ServiceModel), not wcf. Is there any choice but call svcutil from code? if so, how? (do I use svcutil or slsvcutil? How do I call it from inside the addin?)
thanks

Kindrakindred answered 11/1, 2011 at 16:27 Comment(1)
noone? please, this is the last piece missing from my class generation addin...Kindrakindred
C
7

I believe the visual studio command for this is "Project.UpdateServiceReference". So I guess you can try to select the node you're interested in, and run this command, like this:

envDTE.Windows.Item(vsWindowKindSolutionExplorer).Activate();
envDTE.ActiveWindow.Object.GetItem(@"MyProject\Service References\Proxy").Select(vsUISelectionType.vsUISelectionTypeSelect);
envDTE.ExecuteCommand("Project.UpdateServiceReference");
Cosby answered 26/2, 2011 at 10:57 Comment(2)
OMG, thanks! I'll try it out first thing on monday, to see if it works! (to award you the 50...), one thing though: can I refresh the service WITHOUT selecting it in solution explorer?Kindrakindred
Okay, I got this one working, and since I didn't specify that the selection couldn't change I rather wrote an easy workaround so I can use this, easier approach! :)Kindrakindred
U
2

If you're looking for the more programmatic way to do this, you can do something like the following. This approach does not require using the DTE automation layer which will change the user's selection and execute a command. Note that this is within the context of a VSPackage with an IServiceProvider so that it can get instances to the core Visual Studio interfaces, etc...

You may also be able to do this from within an Addin, but you'd need to get an IServiceProvider and add references to (at least) Microsoft.VisualStudio.Shell.Interop.dll and Microsoft.VisualStudio.WCFReference.Interop. Reference assemblies for these binaries are available in the Visual Studio 2010 SDK.

IVsSolution solution = GetService(typeof(SVsSolution)) as IVsSolution;
if (solution != null)
{
    IVsHierarchy solutionHierarchy = solution as IVsHierarchy;
    if (null != solutionHierarchy)
    {
        IEnumHierarchies enumHierarchies;
        Guid nullGuid = Guid.Empty;

        ErrorHandler.ThrowOnFailure(solution.GetProjectEnum((uint)__VSENUMPROJFLAGS.EPF_ALLINSOLUTION, ref nullGuid, out enumHierarchies));
        if (enumHierarchies != null)
        {
            uint fetched;
            IVsHierarchy[] hierarchies = new IVsHierarchy[1];
            IVsWCFReferenceManagerFactory wcfReferenceManagerFactory = GetService(typeof(SVsWCFReferenceManagerFactory)) as IVsWCFReferenceManagerFactory;
            if (wcfReferenceManagerFactory != null)
            {
                while (enumHierarchies.Next(1, hierarchies, out fetched) == 0 && fetched == 1)
                {
                    if (wcfReferenceManagerFactory.IsReferenceManagerSupported(hierarchies[0]) == 1)
                    {
                        IVsWCFReferenceManager referenceManager = wcfReferenceManagerFactory.GetReferenceManager(hierarchies[0]);
                        var referenceGroupCollection = referenceManager.GetReferenceGroupCollection();
                        referenceGroupCollection.UpdateAll(null);
                    }
                }
            }
        }
    }
}

I'd also recommend looking at the WCF Service Consumption Tools samples for the Visual Studio 2010 SDK.

Unpromising answered 26/2, 2011 at 15:59 Comment(3)
what class has a GetService method? I've read the link you sent, but I cannot figure out how to get a IServiceProvider from DTE...Kindrakindred
I tried casting the DTE to IServiceProvider (with cast operator, because using "as" returned null) I've got Unable to cast COM object of type 'System.__ComObject' to interface type 'System.IServiceProvider'. This operation failed because the QueryInterface call on the COM component for the interface with IID '{8F10F540-7F5D-3F37-8D79-1E0AEB074AA0}' failed due to the following error: No such interface supported (Exception from HRESULT: 0x80004002 (E_NOINTERFACE)).Kindrakindred
Okay, managed to get IServiceProvider (see here ), the while cycle gets called four times, and then it throws exception (Operation is not valid due to the current state of the object.) - which is weird, since I have only one service reference in my entire solution!Kindrakindred

© 2022 - 2024 — McMap. All rights reserved.