I created a new VSIX extension project in Visual Studio 2012, and wrote a MEF classifier (as a test) that should simply highlight all text in a .mylang file. Here are the relevant parts of my .NET 4.5 code:
internal static class MyLangLanguage
{
public const string ContentType = "mylang";
public const string FileExtension = ".mylang";
[Export(typeof(ClassificationTypeDefinition))]
[Name(ContentType)]
[BaseDefinition("code")]
internal static ContentTypeDefinition MyLangSyntaxContentTypeDefinition = null;
[Export]
[FileExtension(FileExtension)]
[ContentType(ContentType)]
internal static FileExtensionToContentTypeDefinition MyLangSyntaxFileExtensionDefinition = null;
}
[Export(typeof(IClassifierProvider))]
[ContentType(MyLangLanguage.ContentType)]
[Name("MyLangSyntaxProvider")]
internal sealed class MyLangSyntaxProvider : IClassifierProvider
{
[Import]
internal IClassificationTypeRegistryService ClassificationRegistry = null;
public IClassifier GetClassifier(ITextBuffer buffer)
{
return buffer.Properties.GetOrCreateSingletonProperty(() => new MyLangSyntax(ClassificationRegistry, buffer));
}
}
internal sealed class MyLangSyntax : IClassifier { }
Here is the full code.
These are the relevant parts from my source.extension.vsixmanifest file. Based on suggestions and similar files I found across the web, I added the dependency on MPF and the two assets.
<?xml version="1.0" encoding="utf-8"?>
<PackageManifest Version="2.0.0" xmlns="http://schemas.microsoft.com/developer/vsx-schema/2011" xmlns:d="http://schemas.microsoft.com/developer/vsx-schema-design/2011">
<!-- ... -->
<Dependencies>
<Dependency Id="Microsoft.Framework.NDP" DisplayName="Microsoft .NET Framework" d:Source="Manual" Version="4.5" />
<Dependency d:Source="Installed" Id="Microsoft.VisualStudio.MPF.11.0" DisplayName="Visual Studio MPF 11.0" Version="[11.0,12.0)" />
</Dependencies>
<Assets>
<Asset Type="Microsoft.VisualStudio.VsPackage" d:Source="Project" d:ProjectName="%CurrentProject%" Path="|%CurrentProject%;PkgdefProjectOutputGroup|" />
<Asset Type="Microsoft.VisualStudio.MefComponent" d:Source="Project" d:ProjectName="%CurrentProject%" Path="|%CurrentProject%|" />
</Assets>
</PackageManifest>
I also tried a version 1.0 manifest:
<?xml version="1.0" encoding="utf-8"?>
<Vsix Version="1.0.0" xmlns="http://schemas.microsoft.com/developer/vsx-schema/2010">
<!-- ... -->
<References />
<Content>
<MefComponent>|%CurrentProject%|</MefComponent>
</Content>
</Vsix>
When I run it, it starts an experimental instance of Visual Studio 2012, and the Extensions and Updates window shows that my extension is active. However, it does not do anything when I load or create a .mylang file. Any exceptions I throw (as a test) from my extension are never thrown. Breakpoints are never hit, and get an exclamation mark with the following warning:
The breakpoint will not currently be hit. No symbols have been loaded for this document.
It feels as if my extension is never really loaded at all. My problem is similar to this problem and this problem, but I'm using Visual Studio 2012 which uses a new VSIX manifest format.
What I know:
I can find my DLL and VSIX file in the %localappdata%\Microsoft\VisualStudio\11.0Exp\Extensions\MyLang\VSIXProject1\1.0 folder, so I know they are copied.
Their timestamp corresponds to when I last built the project, so I know they are up-to-date.
Project Properties > Debug > Start external program: is already automatically set to C:\Program Files (x86)\Microsoft Visual Studio 11.0\Common7\IDE\devenv.exe, and the Command line arguments were automatically set to /rootsuffix Exp.
The Visual Studio log (created with the /log option) has two entries related to my extension: Successfully loaded extension... and Extension is enabled....
My DLL does not appear on the Modules tab (list of all loaded DLLs) of the debugging Visual Studio, while some (not all) other extensions do appear.
It doesn't get loaded in Visual Studio 2012 or 2010 both on my laptop and my desktop PC.
What I've tried:
Set <IncludeAssemblyInVSIXContainer> to true in the .csproj file, per this suggestion, but it did not make any difference.
I can't add the line <MefComponent>|%CurrentProject%|</MefComponent> to the source.extension.vsixmanifest file as it uses a different format (2.0) than VSIX projects for previous versions of Visual Studio (1.0).
This suggestion (setting IncludeAssemblyInVSIXContainer and friends in my .csproj to true) but it does not make a difference. And my breakpoints are still showing the warning and not being hit.
Reset the VS Experimental instance using the Reset the Visual Studio 2012 Experimental Instance shortcut in the Start Menu, as per this suggestion. It didn't make a difference.
How can I at the very least be sure my VSIX MEF extension is loaded and works? And if possible, how can I make by breakpoint work and debug it?
Edit: The problem is you've improperly exported your ContentTypeDefinition as a ClassificationTypeDefinition. You should use the following instead:
[Export] // <-- don't specify the type here
[Name(ContentType)]
[BaseDefinition("code")]
internal static ContentTypeDefinition MyLangSyntaxContentTypeDefinition = null;
Here's my two guesses right now:
Try removing the following line from your vsixmanifest. I assume you do not have a class in your project that extends Package, in which case Visual Studio might be refusing to load your package due to the following Asset line (your extension does not actually provide this asset).
<Asset Type="Microsoft.VisualStudio.VsPackage" d:Source="Project" d:ProjectName="%CurrentProject%" Path="|%CurrentProject%;PkgdefProjectOutputGroup|" />
If that fails, try replacing your current source.extension.vsixmanifest with one written to the old schema (version 1.0). I know this form still works in Visual Studio 2012 because all ~20 extensions I work on (with >10 public releases) use the old schema.
280Z28 solved the problem! For completeness, this is the full tried and tested code that will create a super simple VSIX Visual Studio MEF extension that colors all text in a .mylang file blue (or whatever the current keyword color is).
How to create a simple coloring MEF VSIX extension
Make sure you have the Visual Studio SDK installed. (VS2010 SP1 SDK, VS2012 SDK)
Create a new VSIX Project(From the template under Installed → Templates → Visual C# → Extensibility.)
Enter something in the Author field of the VSIX manifest editor, then save and close it.
Add references to the following libraries,version 10.0.0.0 for VS2010, or 11.0.0.0 for VS2012:
Microsoft.VisualStudio.CoreUtility.dll
Microsoft.VisualStudio.Language.StandardClassification.dll
Microsoft.VisualStudio.Text.Data.dll
Microsoft.VisualStudio.Text.Logic.dll
Microsoft.VisualStudio.Text.UI.dll
Microsoft.VisualStudio.Text.UI.Wpf.dll
Add a reference to the following library:
System.ComponentModel.Composition.dll version 4.0.0.0
Create and add a new code file MyLang.cs, and copy-and-paste the code below in it.
Edit source.extension.vsixmanifest as XML.
For Visual Studio 2010, add the following XML just before the closing tag </Vsix>, and save:
<Content>
<MefComponent>|%CurrentProject%|</MefComponent>
</Content>
(If there is already an empty <Content/>, remove it.)
For Visual Stuio 2012, add the following XML just before the closing tag </PackageManifest>, and save:
<Assets>
<Asset Type="Microsoft.VisualStudio.MefComponent" d:Source="Project" d:ProjectName="%CurrentProject%" Path="|%CurrentProject%|" />
</Assets>
(If there is already an empty <Assets/>, remove it.)
Only for Visual Studio 2010:
Unload the VSIX project (right-click the project → Unload project).
Edit the .csproj project file (right-click the project → Edit MyProject.csproj).
Change the value at <IncludeAssemblyInVSIXContainer> to true.
Save and close the file.
Reload the VSIX project (right-click the project → Reload project).
Now build and run it. When you load a .mylang file, all text should be colored blue (or whatever the default keyword color is).
MyLang.cs
using Microsoft.VisualStudio.Language.StandardClassification;
using Microsoft.VisualStudio.Text;
using Microsoft.VisualStudio.Text.Classification;
using Microsoft.VisualStudio.Utilities;
using System;
using System.Collections.Generic;
using System.ComponentModel.Composition;
namespace VSIXProject1
{
internal static class MyLangLanguage
{
public const string ContentType = "mylang";
public const string FileExtension = ".mylang";
[Export]
[Name(ContentType)]
[BaseDefinition("code")]
internal static ContentTypeDefinition MyLangSyntaxContentTypeDefinition = null;
[Export]
[FileExtension(FileExtension)]
[ContentType(ContentType)]
internal static FileExtensionToContentTypeDefinition MyLangSyntaxFileExtensionDefinition = null;
}
[Export(typeof(IClassifierProvider))]
[ContentType(MyLangLanguage.ContentType)]
[Name("MyLangSyntaxProvider")]
internal sealed class MyLangSyntaxProvider : IClassifierProvider
{
[Import]
internal IClassificationTypeRegistryService ClassificationRegistry = null;
public IClassifier GetClassifier(ITextBuffer buffer)
{
return buffer.Properties.GetOrCreateSingletonProperty(() => new MyLangSyntax(ClassificationRegistry, buffer));
}
}
internal sealed class MyLangSyntax : IClassifier
{
private ITextBuffer buffer;
private IClassificationType identifierType;
private IClassificationType keywordType;
public event EventHandler<ClassificationChangedEventArgs> ClassificationChanged;
internal MyLangSyntax(IClassificationTypeRegistryService registry, ITextBuffer buffer)
{
this.identifierType = registry.GetClassificationType(PredefinedClassificationTypeNames.Identifier);
this.keywordType = registry.GetClassificationType(PredefinedClassificationTypeNames.Keyword);
this.buffer = buffer;
this.buffer.Changed += OnBufferChanged;
}
public IList<ClassificationSpan> GetClassificationSpans(SnapshotSpan snapshotSpan)
{
var classifications = new List<ClassificationSpan>();
string text = snapshotSpan.GetText();
var span = new SnapshotSpan(snapshotSpan.Snapshot, snapshotSpan.Start.Position, text.Length);
classifications.Add(new ClassificationSpan(span, keywordType));
return classifications;
}
private void OnBufferChanged(object sender, TextContentChangedEventArgs e)
{
foreach (var change in e.Changes)
ClassificationChanged(this, new ClassificationChangedEventArgs(new SnapshotSpan(e.After, change.NewSpan)));
}
}
}
Set <IncludeAssemblyInVSIXContainer> to true in the .csproj file, per
this suggestion.
I had exactly the same problem and this solved it. Do a full rebuild.
Related
TL;DR
Created VSIX Package
Added Analyzer project item
Pressed F5.
The experimental instance starts but the analyzer is not loaded and can't be debugged.
Manually adding the analyzer works.
Question: how to autoload the analyzer?
Problem description:
There are lots of tutorials (even official docs) that start with a project template: Analyzer with Code Fix (NuGet + VSIX). However, in the latest version of .NET Compiler Platform, I don't have such project template.
So, I've created a VSIX project. Then, I have created a Analyzer project item. Note that I don't have a CodeFix item as I don't need to fix code, only show some warnings.
This is what I've got (I've made a few changes):
[DiagnosticAnalyzer(LanguageNames.CSharp)]
public class MyAnalyzer : DiagnosticAnalyzer
{
public const string DiagnosticId = "MyAnalyzer";
internal static readonly LocalizableString Title = "MyAnalyzer Title";
internal static readonly LocalizableString MessageFormat = "MyAnalyzer";
internal const string Category = "MyAnalyzer Category";
internal static DiagnosticDescriptor Rule = new DiagnosticDescriptor(DiagnosticId, Title, MessageFormat, Category, DiagnosticSeverity.Warning, true);
public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics
=> ImmutableArray.Create(Rule);
public override void Initialize(AnalysisContext context)
{
context.RegisterSyntaxNodeAction(Analyze, SyntaxKind.IfStatement);
}
private void Analyze(SyntaxNodeAnalysisContext context)
{
IfStatementSyntax ifStatement = context.Node as IfStatementSyntax;
if(ifStatement == null)
return;
context.ReportDiagnostic(
Diagnostic.Create(
Rule,
context.Node.GetLocation(),
"Hey, this is an IF statement."));
}
}
}
That's it. The project contains only this file, a .vsixmanifest and a packages.config.
When I run the project in debug mode (with F5), the experimental instance is loaded and I can see the package in Extensions and Updates. However, no breakpoints are being hit (no symbols loaded) and the analyzer is not visible in the list of analyzers (in solution explorer).
Then I do the following:
Rename .vsix file in output folder to .vsix.zip and open it
Extract the assembly DLL from the zip
Right-click analyzers in solution explorer
Manually browse/add the analyzer's assembly DLL
Then all of a sudden, symbols are loaded and the debugger stops on breakpoints.
Is there any way to load analzyer automatically in the experimental instance? Am I missing some configuration?
The VSIX template is available from the Visual Studio gallery.
I suspect that what's missing from your vsix project is the correct list of components in the VSIX package manifest. You need to define both a MefComponent and an Analyzer in your list of assets:
I am trying to include a custom language support for Visual Studio.
To start with, I need to have GoToDefinition support. And I am struggling to get the context menu to include this command.
I have defined a ContentTypeDefinition and have included the FileExtensionToContentTypeDefinition such as:
internal sealed class GaugeFileContentType
{
[Export]
[Name("Gauge")]
[BaseDefinition("code")]
internal static ContentTypeDefinition GaugeContentTypeDefinition = null;
[Export]
[FileExtension(".spec")]
[ContentType("Gauge")]
internal static FileExtensionToContentTypeDefinition GaugeFileExtensionDefinition = null;
}
Now, despite this, on debugging, I see that DTE.ActiveDocument.Type is text, despite me adding the [BaseDefinition('code')] attribute. What am I missing here?
Are the above definitions enough to tell Visual Studio to bring up Context menu for code?
I am using Visual Studio 2013 Ultimate.
After a few days of head banging, I managed to figure out a way.
I was using the Experimental Instance for debugging, and it did not clean and reinstall the extension, and thus Visual Studio continued to treat the ContentType as 'Plain Text', since that was what I had originally.
When I build a VSIX and installed, opened the same file in a new instance of Visual Studio, it brought up the right context menu.
However, it brought out more than what I wanted (i.e Run Unit Tests from Resharper). So I did some more digging up.
In order to ensure that Visual Studio can handle a command, it checks for it by calling IOleCommandTarget.QueryStatus method.
All I had to do was set the CommandFlag as (uint)OLECMDF.OLECMDF_ENABLED | (uint)OLECMDF.OLECMDF_SUPPORTED and return VSConstants.S_OK when the cmdId is VSConstants.VSStd97CmdID.GotoDefn.
The final method looks like this:
public int QueryStatus(ref Guid pguidCmdGroup, uint cCmds, OLECMD[] prgCmds, IntPtr pCmdText)
{
if ((VSConstants.VSStd97CmdID)prgCmds[0].cmdID == VSConstants.VSStd97CmdID.GotoDefn)
{
prgCmds[0].cmdf = (uint)OLECMDF.OLECMDF_ENABLED | (uint)OLECMDF.OLECMDF_SUPPORTED;
return VSConstants.S_OK;
}
return Next.QueryStatus(pguidCmdGroup, cCmds, prgCmds, pCmdText);
}
I'm trying to allow a user to enter data into a textbox that will be added to the web.config file. I've added the relevent lines to the web.config file but when I make this class all goes wrong.
I keep getting the are you missing a using directive or assembly refenrence error whenever I try to run my app. I have looked at the other times this question has been asked and can't seem to figure out where I'm going wrong. The thing is that I am extremely new to Visual Studio and am just left blank at what could be the answer.
Below here is the class file that's generating the error. I hope I've included everything you need to assist me. Thank you.
using System.Collections.Generic;
using System.Linq;
using System.Configuration;
namespace WebConfigDemo
{
public class CompanyConfigSection : ConfigurationSection
{
[ConfigurationProperty("", IsRequired = true, IsDefaultCollection = true)]
public CompanyConfigCollection Companies
{
get
{
return (CompanyConfigCollection)this[""];
}
set
{
this[""] = value;
}
}
}
public class CompanyConfigElement : ConfigurationElement
{
[ConfigurationProperty("id", IsKey = true, IsRequired = true)]
public int Id
{
get
{
return (int)this["id"];
}
set
{
this["id"] = value;
}
}
[ConfigurationProperty("name", IsRequired = true)]
public string Name
{
get
{
return this["name"].ToString();
}
set
{
this["name"] = value;
}
}
} '
public class CompanyConfigCollection : ConfigurationElementCollection
{
protected override ConfigurationElement CreateNewElement()
{
return new CompanyConfigElement();
}
protected override object GetElementKey(ConfigurationElement element)
{
return ((CompanyConfigElement)element).Id;
}
}
public class CompaniesConfig
{
private static readonly Dictionary<int, CompanyConfigElement>
Elements;
static CompaniesConfig()
{
Elements = new Dictionary<int, CompanyConfigElement>();
var section = (CompanyConfigSection)ConfigurationManager.GetSection ("companies");
foreach (CompanyConfigElement system in section.Companies)
Elements.Add(system.Id, system);
}
public static CompanyConfigElement GetCompany(int companyId)
{
return Elements[companyId];
}
public static List<CompanyConfigElement> Companies
{
get
{
return Elements.Values.ToList();
}
}
}
} '
Any help is appreciated
You probably don't have the System.Configuration dll added to the project references. It is not there by default, and you have to add it manually.
Right-click on the References and search for System.Configuration in the .net assemblies.
Check to see if it is in your references...
Right-click and select Add Reference...
Find System.Configuration in the list of .Net Assemblies, select it, and click Ok...
The assembly should now appear in your references...
.Net framework of the referencing dll should be same as the .Net framework version of the Project in which dll is referred
If you've tried the above solutions and haven't found the answer, make sure that the .NET versions of all projects are the same.
I ran into this problem when importing a .NET version 4.6.1 into a .NET version 4.6.2 project. Without any warnings from Visual Basic!
More Info: The type or namespace name could not be found
Your using statements appear to be correct.
Are you, perhaps, missing the assembly reference to System.configuration.dll?
Right click the "References" folder in your project and click on "Add Reference..."
This problem would be caused by your application missing a reference to an external dll that you are trying to use code from. Usually Visual Studio should give you an idea about which objects that it doesn't know what to do with so that should be a step in the right direction.
You need to look in the solution explorer and right click on project references and then go to add -> and look up the one you need. It's most likely the System.Configuration assembly as most people have pointed out here while should be under the Framework option in the references window. That should resolve your issue.
I have observed a quote ' in your 1st line and also at the end of your last line.
'using System.Collections.Generic;
Is this present in your original code or some formatting mistake?
I had the same problem earlier today. I could not figure out why the class file I was trying to reference was not being seen by the compiler. I had recently changed the namespace of the class file in question to a different but already existing namespace. (I also had using references to the class's new and previous namespaces where I was trying to instantiate it)
Where the compiler was telling me I was missing a reference when trying to instantiate the class, I right clicked and hit "generate class stub". Once Visual Studio generated a class stub for me, I coped and pasted the code from the old class file into this stub, saved the stub and when I tried to compile again it worked! No issues.
Might be a solution specific to my build, but its worth a try.
In some cases, when necessary using has been obviously added and studio can't see this namespace, studio restart can save the day.
I was getting warnings about different versions in .NET framework; I ignored them.
The project compiles fine making the change in the solution's properties.
I'm using Visual Studio Code and could not use instructions from above so I found another way to fix the problem with referencing to namespace from another file.
All what need to be done is to add include to your .csproj file e.g:
<ItemGroup>
<Compile Include="filename.cs" />
</ItemGroup>
Then you can use namespaces from filename.cs
The following technique worked for me:
1) Right click on the project Solution -> Click on Clean solution
2) Right click on the project Solution -> Click on Rebuild solution
I have defined a Visual Studio template called classDB.cs. I would like the default name for the class to appear as [projectname]DB.cs, where [projectname] is the name of the current project (as entered in the Create Project dialog). Is there a way to achieve this? I tried setting the name of the class to $safeprojectname$DB.cs, but that didn't work.
UPDATE
I modified my project template but give's this error when it's generating the project
here's the template class
namespace $safeprojectname$.Models
{
public class $safeprojectname$DB : DbContext
{
}
}
I have been battling with a similar error to this for days, and I finally figured it out. Visual Studio escapes the $ in the .csproj file. So you will have a node that looks like this:
<Compile Include="Models\%24safeprojectname%24DB.cs" />
Open up the .csproj file in a text editor, and change it to:
<Compile Include="Models\$safeprojectname$DB.cs" />
And save the file. Your project will reload, but it won't try to escape the filename again! Export your template, and you should find that the parameter now gets replaced.
Try a template like this:
using System;
//...
namespace $rootnamespace$ {
class $safeitemname$DB {
}
}
Works for me.
Make sure you update the correct template (should be located under C:\Users\[user]\Documents\Visual Studio 2010\Templates\ItemTemplates on Windows 7) and restart Visual Studio.
EDIT
The above code is for an Item Template, but that shouldn't differ from a Project Template. According to MSDN, the $safeitemname$ and $safeprojectname$ parameters behaves the same:
safeitemname
The name provided by the user in the Add New Item dialog box, with all unsafe characters and spaces removed.
safeprojectname
The name provided by the user in the New Project dialog box, with all unsafe characters and spaces removed.
I am currently trying to create an addin for Visual Studio 2008 that will list all files which are not excluded from the current build configuration.
I currently have test C++ console application that has 10 files, 2 of which are "Excluded From Build". This is a property that will allow a specific file to be excluded from a specific configuration (i.e. Debug or Release). This property is located when you right click on a file in the solution explorer and select Properties->Configuration Properties->General->Excluded From Build
At the moment I have the following code that will loop though all project files and get the properties for each file.
foreach (Project theProject in _applicationObject.Solution.Projects)
{
getFiles(theProject.ProjectItems);
}
private void getFiles(ProjectItems theItems)
{
foreach (ProjectItem theItem in theItems)
{
string theItemName = theItem.Name;
foreach (Property theProp in theItem.Properties)
{
string thePropName = theProp.Name;
}
getFiles(theItem.ProjectItems);
}
}
The issue I am having is that I cant seem to find the "Excluded From Build" property. I cannot find very good documentation on what properties are listed where. Where is this Excluded From Build property located within the _applicationObject object?
I'm not familiar with the Visual Studio object model, but in the documentation for VS2005 the following objects have an ExcludedFromBuild property:
VCFileConfiguration
VCFileConfigurationProperties
VCPreBuildEventTool
VCPreLinkEventTool
VCPostBuildEventTool
VCWebDeploymentTool
Hopefully this will lead you down the right path.