3

I am building a Visual Studio package/extension using Visual Studio 2013 update 4 Community Edition. I am using the standard project template that comes with the Visual Studio SDK under the extensibility projects group. enter image description here

What I need is the SVsColorThemeService but when I add the following line in my Initialize method

 var svc = GetGlobalService(typeof(SVsColorThemeService)) as IVsColorThemeService;

I get two build errors:

Cannot find the interop type that matches the embedded interop type 'Microsoft.Internal.VisualStudio.Shell.Interop.SVsColorThemeService'. Are you missing an assembly reference?

Cannot find the interop type that matches the embedded interop type 'Microsoft.Internal.VisualStudio.Shell.Interop.IVsColorThemeService'. Are you missing an assembly reference?

enter image description here

The referenced assemblies were not touched at all.

So looking for SVsColorThemeService the decompiler finds it in

// Decompiled with JetBrains decompiler
// Type: Microsoft.Internal.VisualStudio.Shell.Interop.SVsColorThemeService
// Assembly: Microsoft.VisualStudio.Shell.12.0, Version=12.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
// MVID: B8FCA7E4-7D13-4E4B-A74B-6B6B01263DAF
// Assembly location: C:\Program Files (x86)\Microsoft Visual Studio 12.0\VSSDK\VisualStudioIntegration\Common\Assemblies\v4.0\Microsoft.VisualStudio.Shell.12.0.dll

using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

namespace Microsoft.Internal.VisualStudio.Shell.Interop
{
  [CompilerGenerated]
  [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
  [TypeIdentifier]
  [Guid("0D915B59-2ED7-472A-9DE8-9161737EA1C5")]
  [ComImport]
  public interface SVsColorThemeService
  {
  }
}

enter image description here

As you can see that assembly is already referenced. So the question is how to get hold of SVsColorThemeServie and use it the proper way?

EDIT1: After some research and following the @Simon Mourier suggestion I've added the following code to the solution:

using System;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

namespace Microsoft.Internal.VisualStudio.Shell.Interop
{
    [ComImport]
    [Guid("0D915B59-2ED7-472A-9DE8-9161737EA1C5")]
    [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    public interface SVsColorThemeService
    {
    }

    [ComImport]
    [Guid("EAB552CF-7858-4F05-8435-62DB6DF60684")]
    [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    public interface IVsColorThemeService
    {
        IVsColorTheme CurrentTheme { get; }

        IVsColorThemes Themes { get; }

        void _VtblGap1_4();
        void _VtblGap2_1();
    }

    [ComImport]
    [Guid("98192AFE-75B9-4347-82EC-FF312C1995D8")]
    [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    public interface IVsColorThemes
    {
        IVsColorTheme GetThemeFromId([In] Guid ThemeId);
    }

    [ComImport]
    [Guid("413D8344-C0DB-4949-9DBC-69C12BADB6AC")]
    [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    public interface IVsColorTheme
    {
        Guid ThemeId { get; }

        void _VtblGap1_1();

        void Apply();
    }
}

What it does is to provide the missing interfaces for the COM objects. However it still won't build, throwing the same errors + warmings for conflicting types.

Warning 3   The type 'Microsoft.Internal.VisualStudio.Shell.Interop.IVsColorTheme' in 'c:\Users\Codemaster\Documents\Visual Studio 2013\Projects\VSPackage1\VSPackage1\Class1.cs' conflicts with the imported type 'Microsoft.Internal.VisualStudio.Shell.Interop.IVsColorTheme' in 'c:\Program Files (x86)\Microsoft Visual Studio 12.0\VSSDK\VisualStudioIntegration\Common\Assemblies\v4.0\Microsoft.VisualStudio.Shell.12.0.dll'. Using the type defined in 'c:\Users\Codemaster\Documents\Visual Studio 2013\Projects\VSPackage1\VSPackage1\Class1.cs'.    c:\users\codemaster\documents\visual studio 2013\Projects\VSPackage1\VSPackage1\Class1.cs   19  9   VSPackage1

Here is a Link where you can download the sample project: https://drive.google.com/file/d/0B7jBoLH-qaqTV09Mb1VCa3hld1E/view?usp=sharing

SLaks
  • 868,454
  • 176
  • 1,908
  • 1,964
Mihail Shishkov
  • 14,129
  • 7
  • 48
  • 59

1 Answers1

1

Some types in those VS assemblies require other assemblies (PIA). This is explained here: Troubleshooting Errors When Embedding Type Information (Doug Rothaus).

In this Visual Studio specific case, I don't know how to solve it (where are those assemblies?) other than recreate the types manually (hint: use tools like .NET reflector to help you in that matter because the DLL does contain the definition). For example, here is how to compile your code, just add this somewhere:

namespace MyInterop
{
    [ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("0D915B59-2ED7-472A-9DE8-9161737EA1C5")]
    public interface SVsColorThemeService
    {
    }
    [ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("EAB552CF-7858-4F05-8435-62DB6DF60684")]
    public interface IVsColorThemeService {
        void _VtblGap1_4();
        IVsColorThemes Themes { [return: MarshalAs(UnmanagedType.Interface)] get; }
        IVsColorNames ColorNames { [return: MarshalAs(UnmanagedType.Interface)] get; }
        IVsColorTheme CurrentTheme { [return: MarshalAs(UnmanagedType.Interface)] get; }
    }
    [ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("98192AFE-75B9-4347-82EC-FF312C1995D8")]
    public interface IVsColorThemes {
        [return: MarshalAs(UnmanagedType.Interface)]
        IVsColorTheme GetThemeFromId([In] Guid ThemeId);
    }
    [ComImport, Guid("413D8344-C0DB-4949-9DBC-69C12BADB6AC"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    public interface IVsColorTheme {
        void _VtblGap1_1();
        IVsColorEntry this[ColorName Name] { [return: MarshalAs(UnmanagedType.Interface)] get; }
        Guid ThemeId { get; }
    }
    [ComImport, TypeIdentifier, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("BBE70639-7AD9-4365-AE36-9877AF2F973B")]
    public interface IVsColorEntry {
        ColorName ColorName { get; }
        byte BackgroundType { get; }
        byte ForegroundType { get; }
        uint Background { get; }
        uint Foreground { get; }
    }
    public struct ColorName {
        public Guid Category;
        [MarshalAs(UnmanagedType.BStr)]
        public string Name;
    }
    [ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("92144F7A-61DE-439B-AA66-13BE7CDEC857")]
    public interface IVsColorNames {
        void _VtblGap1_2();
        int Count { get; }
        System.Collections.IEnumerator GetEnumerator();
    }
}
Simon Mourier
  • 132,049
  • 21
  • 248
  • 298
  • Still no luck, check out the edited answer. I've shared a link to the sample project. Thanks for the help thou, it pointed me in the right direction. – Mihail Shishkov Apr 29 '15 at 16:20
  • Yeah, you should put these definition in another namespace. It shouln't be an issue since there are COM classes. – Simon Mourier Apr 30 '15 at 06:10