Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
Taras Shevchuk
@Saratsin
As I see here are discussions only about extensions for Windows version. Extensions API for Mac is quite different currently, and there's not so much information about its development in the Internet
Matt Lacey
@mrlacey
Any advice for debugging a VSIX install? The file, when launched after downloading from the Marketplace, shows the installer UI only briefly while showing an "Initializing..." message but then closes. Where should I look for a log file?
Cameron
@cameron314
@mrlacey Maybe run VsixInstaller.exe under a debugger and look for exceptions? It's a .NET app
Momchil Stefanov
@momchilstefanov
@mrlacey the vsix installer log is created by default in the %temp% folder. If you run it through the command line you could add switch /logFile:filename to specify custom location for the log file. In the %temp% look for log files starting with dd_VSIXInstaller
Matt Lacey
@mrlacey
@momchilstefanov thanks for the pointer about log files. Sadly, I found a lot of zero length error log files.
@cameron314 Good tip on debugging the installer. I found a StackOverflowException was causing the process to be killed.
A little guess-work and knowing I was doing something "unusual" and I've found out the problem. Now to file a bug in VSIXInstaller.
Rion Williams
@rionmonster
Hi folks, recently I've had some free time and I've been making some attempts to add support for Visual Studio 2019 to my extension Glyphfriend. Both the 2015 and 2017 versions share a single Package.cs file (along with some supporting classes via a Shared Project), with each of the individual extensions containing their own respective references / dependencies. I figured that for 2019 I could essentially do the same except for major API changes I could handle those via conditional compilation (e.g. `#if VS2019 ... #else ... #endif) and just updating the various components that changed (e.g. HtmlEditor, CssEditor, etc.)
I've made some progress, however when one of my completion providers is called from a triggering event, I receive the following exception:
CompositionContractMismatchException: Cannot cast the underlying exported value of type 'Microsoft.WebTools.Languages.Html.Editor.Completion.Def.IHtmlCompletionListProvider' to type 'Microsoft.WebTools.Languages.Html.Editor.Completion.Def.IHtmlCompletionListProvider'.
Rion Williams
@rionmonster
A larger snippet from the Activity Log can be seen here:
<entry>
    <record>2653</record>
    <time>2020/01/12 01:24:32.323</time>
    <type>Error</type>
    <source>Editor or Editor Extension</source>
    <description>System.ComponentModel.Composition.CompositionContractMismatchException: Cannot cast the underlying exported value of type &apos;Microsoft.WebTools.Languages.Html.Editor.Completion.Def.IHtmlCompletionListProvider&apos; to type &apos;Microsoft.WebTools.Languages.Html.Editor.Completion.Def.IHtmlCompletionListProvider&apos;.&#x000D;&#x000A;   at System.ComponentModel.Composition.ExportServices.CastExportedValue[T](ICompositionElement element, Object exportedValue)&#x000D;&#x000A;   at System.ComponentModel.Composition.ExportServices.GetCastedExportedValue[T](Export export)&#x000D;&#x000A;   at System.ComponentModel.Composition.ExportServices.&lt;&gt;c__DisplayClass11_0`2.&lt;CreateStronglyTypedLazyOfTM&gt;b__1()&#x000D;&#x000A;   at System.Lazy`1.CreateValue()&#x000D;&#x000A;   at System.Lazy`1.LazyInitValue()&#x000D;&#x000A;   at System.Lazy`1.get_Value()&#x000D;&#x000A;   at Microsoft.WebTools.Languages.Html.Editor.Completion.Engine.HtmlCompletionEngine.GetAttributeCompletionProviders(String completionType, String attributePrefix, String attributeName)&#x000D;&#x000A;   at Microsoft.WebTools.Languages.Html.Editor.Completion.Engine.HtmlCompletionEngine.GetCompletionForAttributeValues(AttributeNode attribute, String&amp; completionType)&#x000D;&#x000A;   at Microsoft.WebTools.Languages.Html.Editor.Completion.Engine.HtmlCompletionEngine.GetAttributeValueCompletions(RootNode rootNode, Int32 position, HtmlPositionType positionType, ElementNode element, AttributeNode attribute, ITextRange&amp; range, String&amp; completionType)&#x000D;&#x000A;   at Microsoft.WebTools.Languages.Html.Editor.Completion.Engine.HtmlCompletionEngine.GetCompletionForLocation(RootNode rootNode, IContentType contentType, Int32 position, ElementNode&amp; element, AttributeNode&amp; attribute, ITextRange&amp; range, String&amp; completionType, Boolean autoShownCompletion)&#x000D;&#x000A;   at Microsoft.WebTools.Languages.Html.Editor.Completion.HtmlCompletionSource.PopulateCompletionList(Int32 position, ICompletionSession session, IList`1 completionSets)&#x000D;&#x000A;   at Microsoft.WebTools.Languages.Html.Editor.Completion.HtmlCompletionSource.AugmentCompletionSession(ICompletionSession session, IList`1 completionSets)&#x000D;&#x000A;   at Microsoft.VisualStudio.Language.Intellisense.Implementation.CompletionSession.Start()&#x000D;&#x000A;   at Microsoft.VisualStudio.Language.Intellisense.Implementation.CompletionBroker.TriggerCompletion(ITextView textView)&#x000D;&#x000A;   at Microsoft.WebTools.Languages.Shared.Editor.Completion.CompletionController.TriggerCompletion()&#x000D;&#x000A;   at Microsoft.WebTools.Languages.Shared.Editor.Completion.CompletionController.ShowCompletion(Boolean autoShownCompletion)&#x000D;&#x000A;   at Microsoft.WebTools.Languages.Html.Editor.Completion.HtmlCompletionController.&lt;&gt;c__DisplayClass29_0.&lt;OnCompletionSessionCommitted&gt;b__0()&#x000D;&#x000A;   at Microsoft.WebTools.Languages.Shared.Editor.Utility.GuardedOperations.InvokeExtensionPoint(Object errorSource, Action action)&#x000D;&#x000A;--- End of stack trace from previous location where exception was thrown ---&#x000D;&#x000A;   at Microsoft.VisualStudio.Telemetry.WindowsErrorReporting.WatsonReport.GetClrWatsonExceptionInfo(Exception exceptionObject)</description>
  </entry>
Rion Williams
@rionmonster
I suspect it's related to some potential shifts in how the completion provider expects to load the completion items themselves, but the method that does all the work is fairly simple:
[HtmlCompletionProvider(CompletionTypes.Values, "*", "class")]
    [ContentType("htmlx")]
    internal class GlyphCompletionListProvider : BaseHtmlCompletionListProvider
    {
        [Import]
        protected SVsServiceProvider GlobalServiceProvider { get; private set; }

        public override string CompletionType { get { return CompletionTypes.Values; } }

        public override IList<HtmlCompletion> GetEntries(HtmlCompletionContext context)
        {
            VSPackage package = (VSPackage)EnsurePackageLoaded();
            if (package == null)
            {
                return new List<HtmlCompletion>();
            }

            var glyphCompletionItems = new List<HtmlCompletion>();

            // Get the filtered set of enabled glyphs
            var enabledGlyphs = package.Glyphs.Where(g => g.Enabled);
            foreach (var glyph in enabledGlyphs)
            {
                glyphCompletionItems.Add(CreateItem(glyph.Name, glyph.Image, context.Session));
            }

            return glyphCompletionItems;
        }

        private IVsPackage EnsurePackageLoaded()
        {
            return GlobalServiceProvider.GetShell().LoadPackage<VSPackage>();
        }
    }
Perhaps it's the direct referencing of the Glyphs item within the Package itself? Maybe the changes to an AsyncPackage are causing difficulties? Since Glyphs is populated on startup? Maybe some async love is needed?
 [PackageRegistration(UseManagedResourcesOnly = true, AllowsBackgroundLoading = true)]
    [ProvideAutoLoad(Constants.HtmlFileLoadedContext, PackageAutoLoadFlags.BackgroundLoad)]
    [Guid(Constants.HtmlFileLoadedContext)]
    [ProvideMenuResource("GlyphfriendMenu.ctmenu", 1)]
    [ProvideUIContextRule(Constants.HtmlFileLoadedContext,
        name: "HTML File Loaded",
        expression: "HtmlConfig",
        termNames: new[] { "HtmlConfig" },
        termValues: new[] { "ActiveEditorContentType:htmlx" })]
    public sealed class VSPackage : AsyncPackage
    {
        internal Package _instance;
        internal List<Glyph> Glyphs { get; private set; }
        internal static string AssemblyLocation => Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);

        protected override async Task InitializeAsync(CancellationToken cancellationToken, IProgress<ServiceProgressData> progress)
        {
            _instance = this;

            DeserializeGlyphsFromBinary();

            await JoinableTaskFactory.SwitchToMainThreadAsync();

            GlyphfriendPreferences.Initialize(_instance);
            ToggleLibraryCommand.Initialize(_instance);
        }

        private void DeserializeGlyphsFromBinary()
        {
            Glyphs = DeserializeBinaryGlyphs();
        }

        private List<Glyph> DeserializeBinaryGlyphs()
        {
            var binaryPath = Path.Combine(AssemblyLocation, "glyphs.bin");
            using (var fs = File.Open(binaryPath, FileMode.Open))
            {
                var glyphs = Serializer.Deserialize<List<Glyph>>(fs);
                glyphs.ForEach(g => g.GenerateImage());
                return glyphs;
            }
        }
    }
Not terribly sure, but any advice is welcome. If you want to take a look at the current code (or some state that's close to this one), the project itself is open source and accessible here:
josetr
@josetr

@Hiran91 @mrlacey

Is anyone here who has experience in Automating (Unit Test) an extension created for Visual Studio?

https://github.com/josetr/VsixTesting can be used to test Visual Studio extensions.

borhadepravina
@borhadepravina
Hi, I have been looking for a WPF Search Box control, that would update the data grid as the user types in the textBox, but couldn't find any.
We can develop a custom user control to achieve this behavior. Are there any technical limitations to this? What could be the reason that WPF doesn't provide such control? We are just trying to figure out if it's feasible to develop such custom user control.
Kirk Fertitta
@kfertitta
@borhadepravina If your goal is to use this within VS (and I assume it is, considering you're posting to this particular room), then you should definitely not use a custom control (of your own or any 3rd party). Rather, you should use the built-in search box hosting capabilities of VS. That allows you to host a search box that exactly matches the VS ones (including theming) anywhere within your WPF content within the shell. The interface to get started with are IVsWindowSearchHostFactory. There are sample online if various places demonstrating usage.
borhadepravina
@borhadepravina
@kfertitta Thanks for your response. I intent to use this search box custom user control in VS extension. I will take a look at IVsWindowSearchHostFactory interface. Just wondering why the use of custom control is not a good practice?
Kirk Fertitta
@kfertitta
@borhadepravina Because you want to match the look of VS itself. That’s much more difficult to do if you invent a control yourself and immitate the native control. And it’s not necessary if they’ve done it for you. In fact, this control was invented to keep the various VS teams themselves from doing exactly what you’re contemplating - rolling their own control. You’ll notice that all of the search boxes in the various VS tool windows are the same.
Hiran91
@Hiran91

Hi @mrlacey and @carlos-quintero . Thanks for the heads up. What my intention and work currently doing is to Automate an extension (my organization created) for Visual Studio 2019 and I use WinAppDriver i.e. Windows Application Driver as the automation tool. But as of now, the WinAppDriver gives an error consistently as "{"status":13,"value":{"error":"unknown error","message":"Operation timed out. (Exception from HRESULT: 0x80131505)"}}"

I'm tired of this error and I don't see any build or code compilation errors at my code at all. Since I'm sunk to my neck with the project deadline, could any one help me through this please? You will be a life saver!

Matt Lacey
@mrlacey
@Hiran91 The prospect of trying to automate VS with WinAppDriver was something I did not want to even attempt. With all the async loading involved, you'd need loads of long pauses to allow everything a chance to load. Doing anything but trivial manipulation will need lots of trial and error and resilience in your tests. Plus maintaining the environment and test projects for the tests will also be a challenge. Have you looked at the project @josetr shared? That might be a possibility.
One other thing I've done for custom UI in an extension is to put that in a control and then have a separate app that loads the control and used WinAppDriver to perform tests on the separate app.
It's not ideal, but I've also found WinAppDriver to be more reliable when everything (VS, WAD, other scripts, etc.) is run as Admin. I also stop and restart the WinAppDriver process as often as possible as that seems to help with reliability.
DeveloperSet
@DeveloperSet
Hi, I need to write a 'code generating' extension that: 1) Can create new project folders and project items (cs source files) 2) Remove existing project folders/items 3) Amend existing project item files 4) Add project references. I've spent ages scouring the extension sample apps but I can't spot any that do this kind of thing. Any guidance would be greatly appreciated.
hadecker
@hadecker
Hi, my team has created a custom designer in VS2019 making use of the following interfaces (IVsEditorFactory, IVsDeferredDocView, and IVsMultiViewDocumentView). Things work but our question is, in the SDK documentation on Microsoft, at the bottom of the respective pages, it only says 'Applies to Visual Studio SDK 2017, 2015' and not 2019. Is the documentation out of date and should also list 2019 in the 'Applies to' and we are OK to use these interfaces in our VS2019 extension or should we be using different/upgraded interfaces instead, if so, can we get pointed to the right interfaces? Thanks
Carlo Kok
@carlokok
We have a [Export(typeof(INuGetProjectProvider))] [Name("OxygeneNuGetProjectProvider")] [Order(After = "ProjectKNuGetProjectProvider")] public class OxygeneNuGetProjectProvider : INuGetProjectProvider MEF implementation. Due to the ref to INuGetProjectProvider this triggers a hard link to NuGet.PackageManagement, Version=4.9.2.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35
However, updating vs will break the version number. Does VS/MEF offer any solution to this?
(Yes I can update the local nuget version ofc; but that's not a solution long term)
Hiran91
@Hiran91
@mrlacey Absolutely, yes I had to give so many time intervals in order to avoid any session time outs or any jumps out of my session. So is there any persistent solution to automate an extension made for Visual Studio? Can't we proceed through Selenium?
Matt Lacey
@mrlacey
@Hiran91 If you really must test with an automated instance of VS then I don't have any alternative solutions. Sorry. It's just something I strive to avoid because of the issues you've encountered. :(
Matt Lacey
@mrlacey

In case anyone else is affected with new extensions not being viewable in the search in Visual Studio. It's a known issue that is under investigation.
Sergey M
@usysware
Hi guys. Got a tagger question please. I've got an extension that creates glyph tags using tracking spans. Having ITrackingSpan on hand, is there any way to figure out when line with that span's deleted? I'd like to automatically delete glyph tags on their corresponding line deletion. It's OK if preceding line's deleted though as tracking span does its job just fine then. Thanks.
Hiran91
@Hiran91
@mrlacey Yeah I understand. Thanks a lot sir. Appreciate your insights given. :)
Sergey M
@usysware

Hi guys. Got a tagger question please.

Replying to self... never mind, figured it out. Thanks.

Rion Williams
@rionmonster
Does anyone have any ideas why I might be receiving this exception (trying to do some HtmlCompletion):
System.ComponentModel.Composition.CompositionContractMismatchException: Cannot cast the underlying exported value of type 'Microsoft.WebTools.Languages.Html.Editor.Completion.Def.IHtmlCompletionListProvider' to type 'Microsoft.WebTools.Languages.Html.Editor.Completion.Def.IHtmlCompletionListProvider'
Sound familiar to anyone?
Kaveesh Dashora
@kaveeshd
@rionmonster Have you tried resetting your experimental instance?
@rprouse My team is also working on adding debugger support for my custom project. If you don't mind can you please share a few code samples which would help us get started?
Rion Williams
@rionmonster
@kaveeshd I hadn't tried that yet, going to give it a shot now.
Rion Williams
@rionmonster
@kaveeshd It looks like that did the trick. It had been a while since I touched this project and I had completely forgotten about that. Thanks again!
Kaveesh Dashora
@kaveeshd
@rionmonster You're welcome. Glad to hear it worked out!
Rion Williams
@rionmonster
It looks like I've managed to get just about everything working locally (via the experimental instance), however when I attempt to actually install my VSIX, I get an ArgumentNullException when a completion event is attempted.
When checking the logs I saw the following:
<entry>
    <record>1157</record>
    <time>2020/01/19 21:23:09.736</time>
    <type>Error</type>
    <source>Editor or Editor Extension</source>
    <description>System.ArgumentNullException: Value cannot be null.&#x000D;&#x000A;Parameter name: member&#x000D;&#x000A;   at Microsoft.Requires.NotNull[T](T value, String parameterName)&#x000D;&#x000A;   at Microsoft.VisualStudio.Composition.RuntimeExportProviderFactory.RuntimeExportProvider.SetImportingMember(Object part, MemberInfo member, Object value)&#x000D;&#x000A;   at Microsoft.VisualStudio.Composition.RuntimeExportProviderFactory.RuntimeExportProvider.RuntimePartLifecycleTracker.SatisfyImports()&#x000D;&#x000A;   at Microsoft.VisualStudio.Composition.ExportProvider.PartLifecycleTracker.SatisfyImmediateImports()&#x000D;&#x000A;   at Microsoft.VisualStudio.Composition.ExportProvider.PartLifecycleTracker.MoveNext(PartLifecycleState nextState)&#x000D;&#x000A;   at Microsoft.VisualStudio.Composition.ExportProvider.PartLifecycleTracker.MoveToState(PartLifecycleState requiredState)&#x000D;&#x000A;   at Microsoft.VisualStudio.Composition.ExportProvider.PartLifecycleTracker.GetValueReadyToExpose()&#x000D;&#x000A;   at Microsoft.VisualStudio.Composition.ExportProvider.&lt;&gt;c__DisplayClass53_0.&lt;CreateExport&gt;b__0()&#x000D;&#x000A;   at System.Lazy`1.CreateValue()&#x000D;&#x000A;   at System.Lazy`1.LazyInitValue()&#x000D;&#x000A;   at System.Lazy`1.get_Value()&#x000D;&#x000A;   at Microsoft.VisualStudio.Composition.NetFxAdapters.MefV1ExportProvider.&lt;&gt;c__DisplayClass10_0.&lt;UnwrapExport&gt;b__1()&#x000D;&#x000A;   at System.ComponentModel.Composition.Primitives.Export.GetExportedValueCore()&#x000D;&#x000A;   at System.ComponentModel.Composition.Primitives.Export.get_Value()&#x000D;&#x000A;   at System.ComponentModel.Composition.ExportServices.GetCastedExportedValue[T](Export export)&#x000D;&#x000A;   at System.ComponentModel.Composition.ExportServices.&lt;&gt;c__DisplayClass11_0`2.&lt;CreateStronglyTypedLazyOfTM&gt;b__1()&#x000D;&#x000A;   at System.Lazy`1.CreateValue()&#x000D;&#x000A;   at System.Lazy`1.LazyInitValue()&#x000D;&#x000A;   at System.Lazy`1.get_Value()&#x000D;&#x000A;   at Microsoft.WebTools.Languages.Html.Editor.Completion.Engine.HtmlCompletionEngine.GetAttributeCompletionProviders(String completionType, String attributePrefix, String attributeName)&#x000D;&#x000A;   at Microsoft.WebTools.Languages.Html.Editor.Completion.Engine.HtmlCompletionEngine.GetCompletionForAttributeValues(AttributeNode attribute, String&amp; completionType)&#x000D;&#x000A;   at Microsoft.WebTools.Languages.Html.Editor.Completion.Engine.HtmlCompletionEngine.GetAttributeValueCompletions(RootNode rootNode, Int32 position, HtmlPositionType positionType, ElementNode element, AttributeNode attribute, ITextRange&amp; range, String&amp; completionType)&#x000D;&#x000A;   at Microsoft.WebTools.Languages.Html.Editor.Completion.Engine.HtmlCompletionEngine.GetCompletionForLocation(RootNode rootNode, IContentType contentType, Int32 position, ElementNode&amp; element, AttributeNode&amp; attribute, ITextRange&amp; range, String&amp; completionType, Boolean autoShownCompletion)&#x000D;&#x000A;   at Microsoft.WebTools.Languages.Html.Editor.Completion.HtmlCompletionSource.PopulateCompletionList(Int32 position, ICompletionSession session, IList`1 completionSets)&#x000D;&#x000A;   at Microsoft.WebTools.Languages.Html.Editor.Completion.HtmlCompletionSource.AugmentCompletionSession(ICompletionSession session, IList`1 completionSets)&#x000D;&#x000A;   at Microsoft.VisualStudio.Language.Intellisense.Implementation.CompletionSession.Start()&#x000D;&#x000A;   at Microsoft.VisualStudio.Language.Intellisense.Implementation.CompletionBroker.TriggerCompletion(ITextView textView)&#x000D;&#x000A;   at Microsoft.WebTools.Languages.Shared.Editor.Completion.CompletionController.TriggerCompletion()&#x000D;&#x000A;   at Microsoft.WebTools.Languages.Shared.Editor.Completion.CompletionController.ShowCompletion(Boolean autoShownCompletion)&#x000D;&#x000A;   at Mic
It works just fine when launching via the Experimental Instance, but not after installing via the VSIX. It sounds like that would be an issue related to the VSIX being built, but I'm not entirely sure what.
Rion Williams
@rionmonster
I'd be glad to share any code related to the completion provider, but I it really sounds like some difference between the VSIX that gets installed vs the experimental instance.