Visual Studio Extension MEF class not instantiated when installed via an MSI - visual-studio

I am writing a VS 2012 plug-in, which contains a Package as well as an IWpfTextViewCreationListener MEF extension class.
It is installed using a WiX project created MSI, placing all of the files in C:\Program Files\...[Application]; which creates the Packages registry entry to point to the DLL containing the Package implementation.
When debugging the plug-in in an experimental Visual Studio instance, everything runs correctly.
When running the MSI installer, the Package code runs fine, but the MEF class is not instantiated.
Note: if I install the package using the VSIX (which I do not use for MSI install) everything also works fine.
The MEF class (in same Assembly as Package):
[Export(typeof (IWpfTextViewCreationListener))]
[ContentType("text")]
[TextViewRole(PredefinedTextViewRoles.Document)]
internal sealed class HighlightAdornerFactory : IWpfTextViewCreationListener
{
[Import]
public IClassificationTypeRegistryService ClassificationRegistry = null;
[Import]
public IClassificationFormatMapService FormatMapService = null;
[Export(typeof (AdornmentLayerDefinition))]
[Name(HighlightAdornment.Name)]
[Order(After = PredefinedAdornmentLayers.Selection, Before = PredefinedAdornmentLayers.Text)]
public AdornmentLayerDefinition editorAdornmentLayer = null;
public void TextViewCreated(IWpfTextView textView)
{ /** ... **/ }
}
I used VisualMEFX to examine the DLL that this is packaged in. It reports that no exports match IClassificationTypeRegistryService. This doesn't explain why it works when installed with VSIX, or debugged via the IDE. But it might be useful to know in troubleshooting the problem.
[Export] MySolution.HighlightAdornerFactory (ContractName="Microsoft.VisualStudio.Text.Editor.IWpfTextViewCreationListener")
[Export] MySolution.Adornment.HighlightAdornerFactory.editorAdornmentLayer (ContractName="Microsoft.VisualStudio.Text.Editor.AdornmentLayerDefinition")
[Import] MySolution.Adornment.HighlightAdornerFactory.ClassificationRegistry (ContractName="Microsoft.VisualStudio.Text.Classification.IClassificationTypeRegistryService")
[Exception] System.ComponentModel.Composition.ImportCardinalityMismatchException: No exports were found that match the constraint:
ContractName Microsoft.VisualStudio.Text.Classification.IClassificationTypeRegistryService
RequiredTypeIdentity Microsoft.VisualStudio.Text.Classification.IClassificationTypeRegistryService
at System.ComponentModel.Composition.Hosting.ExportProvider.GetExports(ImportDefinition definition, AtomicComposition atomicComposition)
at System.ComponentModel.Composition.Hosting.ExportProvider.GetExports(ImportDefinition definition)
at Microsoft.ComponentModel.Composition.Diagnostics.CompositionInfo.AnalyzeImportDefinition(ExportProvider host, IEnumerable`1 availableParts, ImportDefinition id) in C:\Temp\MEF_Beta_2\Samples\CompositionDiagnostics\Microsoft.ComponentModel.Composition.Diagnostics\CompositionInfo.cs:line 157
[Import] MySolution.HighlightAdornerFactory.FormatMapService (ContractName="Microsoft.VisualStudio.Text.Classification.IClassificationFormatMapService")
[Exception] System.ComponentModel.Composition.ImportCardinalityMismatchException: No exports were found that match the constraint:
ContractName Microsoft.VisualStudio.Text.Classification.IClassificationFormatMapService
RequiredTypeIdentity Microsoft.VisualStudio.Text.Classification.IClassificationFormatMapService
at System.ComponentModel.Composition.Hosting.ExportProvider.GetExports(ImportDefinition definition, AtomicComposition atomicComposition)
at System.ComponentModel.Composition.Hosting.ExportProvider.GetExports(ImportDefinition definition)
at Microsoft.ComponentModel.Composition.Diagnostics.CompositionInfo.AnalyzeImportDefinition(ExportProvider host, IEnumerable`1 availableParts, ImportDefinition id) in C:\Temp\MEF_Beta_2\Samples\CompositionDiagnostics\Microsoft.ComponentModel.Composition.Diagnostics\CompositionInfo.cs:line 157
I have tried adding all the referenced libraries from my assembly into the MSI, but this did not help. I am not seeing any exceptions being thrown, the IWpfTextViewCreationListener class simply does not get loaded.

The behavior you are seeing is by design; assemblies are included in the MEF composition only if they're listed in a .vsixmanifest somewhere. When you added the Package registry keys through your MSI, this will not add your assemblies to the MEF composition. When were you were testing in the experimental hive or installing the extension directily, you were including your assembly into the MEF composition as you expected.
You have a few ways to fix this, in my order of recommendation:
Don't use an MSI. I strongly encourage this if possible. VSIXes are quite powerful, and offer many advantages for the user: they are easier to install and uninstall, and they integrate with the extension manager and Visual Studio gallery. Unless you can prove that a VSIX is unacceptable for your scenario, please use them.
Use WiX 3.6, which has a VsixPackage element which will install your VSIX for you. The documentation is available here.
Have your MSI install the contents of your VSIX into [Program Files]\Microsoft Visual Studio 11.0\Common7\IDE\Extensions\[Your Product Name] and then run devenv /setup as a part of a custom action. This is very tricky to do and requires a bunch of manual WiX authoring. Option #2 exists for a reason -- the WiX folks actually know what they're doing. ;-)

Related

VS 2013 Error-"No exports were found that match the constraint:"

I am using Visual Studio 2013 on Windows 10, Today I am getting error "No exports were found that match the constraint:"
I did following but still having same issue:
Solution giving in link
Error message "No exports were found that match the constraint contract name"
by removing/renaming "ComponentModelCache" folder, but still problem.
Run VS Repair, but still having same problem.
Finally, I Uninstalled Visual Studio 2013 and reinstalled, but still having
same problem.
Please suggest what do do now?
Finally, I did find answer myself, instead of deleting/renaming 'ComponentModelCache' folder in path
C:\Users\'username'\AppData\local\Microsoft\VisualStudio\12.0
I renamed folder 'Microsoft' in path
C:\Users\'username'\AppData\local\
This works for me.
You can see here more solutions which require deleting the cache in %APPDATA%.
In my case, the problem was that I was initializing and using class with the MEF framework but didn't declare the class as a MEF class.
How to import a MEF class:
[Import(typeof(ICalculator))]
public ICalculator calculator;
How to define and export a MEF class:
public interface ICalculator
{
String Calculate(String input);
}
[Export(typeof(ICalculator))]
class MySimpleCalculator : ICalculator
{
}
The code example is taken from here
Apologies for contributing to an old "answered" thread. however for me, using Win 10, VS 2013. I had to remove the 'ComponentModelCache' folder from each version of VS that I had installed before this issue was resolved.

Can't see params while stepping through .NET 4.0 source in C#/VS2010

As I step into .NET source (.NET source stepping is enabled in Debugging Options and Just my Code is disabled), for some reason in the Autos and Watch windows in VS2010, I can't view parameters in .NET framework functions in the watch or autos panes. I can see local variables however. Why is this?
Update:
This is a debug 64-bit (x64) build with no optimizations.
There is no error, I just can't "watch" parameters in functions like:
// Enumerable.cs
public class Lookup<TKey, TElement> : IEnumerable<IGrouping<TKey, TElement>>, ILookup<TKey, TElement>{
...
internal static Lookup<TKey, TElement> Create<TSource>(IEnumerable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector, IEqualityComparer<TKey> comparer) {
Update 2: It seems that by default, only the release build of the .NET 4.0 framework is installed. You can still step into it, but you may not see some function parameters and local variables (and set breakpoints on some lines). What I guess I would really like is to use a Debug build of the .NET 4.0 framework so that I can see all params, locals and put breakpoints on all lines. How do I go about installing this, if I have VS2010 Premium already installed?
You probably need to disable optimizations.
Edit by Michael Goldshteyn - the question's author:
Here are the full instructions from that URL:
The following environment variable must be set before VS2010 is started:
set COMPLUS_ZapDisable=1
The VS hosting process must be disabled:
To disable the hosting process in VS2010
1.Open a project in Visual Studio.
2.On the Project menu, click Properties.
3.Click the Debug tab.
4.Clear the Enable the Visual Studio hosting process check box.
You may be debugging a release build - check that you are running a debug build. (what you can 'watch' seems to be rather variable in release builds)
Do you need to unset COMPLUS if you want to re-enable optimised debugging. Is this advised? Do you reset as follows
set COMPLUS_ZapDisable=0
From http://reflectorblog.red-gate.com/2012/03/debugging-debugging-experience/
Create a file in your executable folder named YourAppName.ini, where YourAppName is replaced with the name of your assembly's filename. So if you have SampleApp.exe, you will create SampleApp.ini.
The contents of this ini file should contain
[.NET Framework Debugging Control]
GenerateTrackingInfo=1
AllowOptimize=0
Save the file and start debugging. You may not need to disable the VS Studio Hosting process when doing this. Disabling the hosting process, as others have suggested, causes intermittent crashes when using the Immediate Window, which is an integral part of the debugging experience.
Happy debugging!

Building a Visual Studio Package based on another one

I want to add my own project type based on IronStudio. So,
I downloaded the source for and compiled the latest version of IronPython, then
I created a new Visual Studio Package.
I added the Templates\Projects\MyProject folders, and added a file to it, and set its property "Include in VSIX" to true.
Then modified the main Package class to be derived from IronStudio's PythonProjectPackage instead, and set the ProvideProjectFactory property:
[ProvideProjectFactory(
typeof(PythonProjectFactory),
"Django Project",
"Django Project Files (*.myproj);*.myproj",
"myproj", "myproj",
#"Templates\Projects\MyProject",
LanguageVsTemplate="MyProject")]
public sealed class MyPackage : PythonProjectPackage
And ran it. But MyProject isn't showing up in the project templates. Why not?
The generated .pkgdef file looks like this:
[$RootKey$\InstalledProducts\VSPackage3Package]
#="#110"
"Package"="{5cd7435c-7461-459f-80bc-c0c79e9d462f}"
"PID"="1.0"
"ProductDetails"="#112"
"LogoID"="#400"
[$RootKey$\Packages\{5cd7435c-7461-459f-80bc-c0c79e9d462f}]
#="Microsoft.VSPackage3.VSPackage3Package, VSPackage3, Version=1.0.0.0, Culture=neutral, PublicKeyToken=a4f1577d825253f8"
"InprocServer32"="$WinDir$\SYSTEM32\MSCOREE.DLL"
"Class"="Microsoft.VSPackage3.VSPackage3Package"
"CodeBase"="$PackageFolder$\VSPackage3.dll"
[$RootKey$\Editors\{888888c4-36f9-4453-90aa-29fa4d2e5706}]
"Package"="{5cd7435c-7461-459f-80bc-c0c79e9d462f}"
[$RootKey$\Editors\{888888c4-36f9-4453-90aa-29fa4d2e5706}\Extensions]
"py"=dword:00000020
[$RootKey$\Editors\{888888c4-36f9-4453-90aa-29fa4d2e5706}\LogicalViews]
"{7651a701-06e5-11d1-8ebd-00a0c90f26ea}"=""
[$RootKey$\Editors\{888888c4-36f9-4453-90aa-29fa4d2e5706}\LogicalViews]
"{7651a702-06e5-11d1-8ebd-00a0c90f26ea}"=""
[$RootKey$\Editors\{888888c4-36f9-4453-90aa-29fa4d2e5706}\LogicalViews]
"{7651a703-06e5-11d1-8ebd-00a0c90f26ea}"=""
[$RootKey$\CLSID\{888888fd-3c4a-40da-aefb-5ac10f5e8b30}]
#="Microsoft.IronPythonTools.Project.PythonGeneralPropertyPage"
"InprocServer32"="$WinDir$\SYSTEM32\MSCOREE.DLL"
"Class"="Microsoft.IronPythonTools.Project.PythonGeneralPropertyPage"
"CodeBase"="$PackageFolder$\VSPackage3.dll"
"ThreadingModel"="Both"
[$RootKey$\Projects\{888888a0-9f3d-457c-b088-3a5042f75d52}]
#="PythonProjectFactory"
"DisplayName"="My Project"
"DisplayProjectFileExtensions"="My Project Files (*.myproj);*.myproj"
"Package"="{5cd7435c-7461-459f-80bc-c0c79e9d462f}"
"DefaultProjectExtension"="myproj"
"PossibleProjectExtensions"="myproj"
"ProjectTemplatesDir"="$PackageFolder$\Templates\Projects\MyProject"
"Language(VsTemplate)"="MyProject"
[$RootKey$\NewProjectTemplates\TemplateDirs\{5cd7435c-7461-459f-80bc-c0c79e9d462f}\/1]
#="My Project"
"SortPriority"=dword:00000064
"TemplatesDir"="$PackageFolder$\Templates\Projects\MyProject"
[$RootKey$\Projects\{888888a0-9f3d-457c-b088-3a5042f75d52}]
#="PythonProjectFactory"
"DisplayName"="IronPython"
"DisplayProjectFileExtensions"="IronPython Project Files (*.pyproj);*.pyproj"
"Package"="{5cd7435c-7461-459f-80bc-c0c79e9d462f}"
"DefaultProjectExtension"="pyproj"
"PossibleProjectExtensions"="pyproj"
"ProjectTemplatesDir"="$PackageFolder$\.\NullPath"
"Language(VsTemplate)"="IronPython"
[$RootKey$\NewProjectTemplates\TemplateDirs\{5cd7435c-7461-459f-80bc-c0c79e9d462f}\/1]
#="IronPython"
"SortPriority"=dword:00000064
"TemplatesDir"="$PackageFolder$\.\NullPath"
[$RootKey$\Services\{b98e41c4-581e-3532-beee-06829b683d39}]
#="{5cd7435c-7461-459f-80bc-c0c79e9d462f}"
"Name"="IPythonStarter"
I just want to get the bare bones up and running so I can start overriding some functionality (like the Add New Item dialog).
Update:
Reading my initial analysis once again increases my impression that some of the required components are missing (e.g. a dedicated ProjectFactory) and/or wired up incorrectly - from the MSDN documentation of the ProvideProjectFactoryAttribute Class:
ProvideProjectFactoryAttribute declares that a package provides a project factory.
And further:
If a VSPackage declares that it provides a project factory, it should create the factory and offer it to Visual Studio in the Initialize method of the Package-derived class.
You package is declaring to provide PythonProjectFactory, but (likely) doesn't offer it to VS, rather it is offered by the IronPython package. In turn you are providing arguments within the ProvideProjectFactory attribute list which PythonProjectFactory won't know about when asked for by VS.
Consequently you should at least provide a dedicated ProjectFactory yourself as per the walkthrough, wire up the classes accordingly and see how this turns out regarding the issues outlined below.
Initial analysis:
There appear to be several issues here at first sight - have you followed any tutorial on how to do this? In case, please note that some of those easily discoverable via search engines are outdated still. Either way I'd try working through and/or comparing your result with Walkthrough: Part 1 - Creating a Basic Project System from the MSDN documentation for VS 2010; please note that even this one is claimed to be outdated a bit according to the Community Content section on the bottom of the page.
Here is what I'd look into myself given the code you present, comparing with the walkthrough on the fly for more insights:
You realized already that the duplicate fragment starting with the GUID above PythonProjectFactory doesn't make sense - this is essentially trying to register two packages at once, which, even if allowed at all syntactically (which I doubt), can't possibly work like so due to both being registered with the same GUID [cross checking with the sample file in section Examining the Template Registration confirms this suspicion, as expected there is only one such fragment].
Please note that the GUID in question is the one identifying PythonProjectFactory (as per the respective source code), see below for more on this.
[Guid(PythonConstants.ProjectFactoryGuid)]
public class PythonProjectFactory : ProjectFactory {
Given .pkgdef is a generated file the next question is where this duplication/violation stems from. When two generated artifacts end up with the same GUID the respective definition in the sources is most likely messed up somehow, usually due to copy&paste duplication. Consequently you should verify whether {5cd7435c-7461-459f-80bc-c0c79e9d462f} is defined and referenced as intended, though here might be one or two other causes as well for this, see below.
A Package class needs to be identified by a GUID and the VS wizard generates some already in Guids.cs and references it accordingly on the class definition, however, the following is missing in your fragment [cross checking with the sample fragment in section To register the project template confirms this omission as well]:
[Guid(GuidList.guidMyPackagePkgString)]
public sealed class MyPackage : Package
Likewise it appears incorrect to derive MyPackage from PythonProjectPackage but reference PythonProjectFactory still rather than providing MyFactory as well (including a dedicated GUID), because the latter tells Visual Studio the location of your project template folder [see section Creating a Skeletal Project Factory]:
While it might well be possible to simply reuse all functionality from the base class PythonProjectFactory, inheriting is likely required simply because the factory must have a dedicated GUID too (as outlined in the walkthrough) in order to properly wire up the attribute specified data.
Likely unrelated, but still suspicious is that your two code blocks don't relate, as the Package class definition specifies Django Project Files (*.myproj);*.myproj, yet the result shows My Project Files (*.myproj);*.myproj.
Have you by chance mixed this from different builds or is this really a result of a clean one?
Good luck!
This stackoverflow posting might be helpful: VS2010: VSIX installation doesn't deploy item templates inside it
If this is not what you're looking for, try to see if you're missing something around the creation of custom project templates, I believe that's where the "missing link" is:
For VS 2008:
http://blogs.msdn.com/b/webdevelopertips/archive/2008/12/02/tip-32-did-you-know-how-to-easily-create-your-own-project-templates.aspx
For VS 2010:
http://blog.reybango.com/2010/09/21/how-to-create-html5-website-and-page-templates-for-visual-studio-2010/
and on MSDN:
http://msdn.microsoft.com/en-us/library/s365byhx.aspx
and here is how to create a project
template manually:
http://msdn.microsoft.com/en-us/library/ms185291.aspx
and here is how to create a new item template in VS 2010: http://msdn.microsoft.com/en-us/library/ms247113.aspx
Hope this helps
$PackageFolder$.\NullPath may have something to do with it.

Why are "Extracted Interfaces" Internal rather than Public?

Visual Studio includes a refactoring function called "Extract Interface" that generates an interface based on a class implementation.
The extracted interfaces are Internal by default. Problem is, we end up changing nearly all of them to Public.
Does anyone know why it's Internal by default? Better yet, is there a way to customize this to default to Public?
It might work if you change the Visual Studio template for interfaces (I haven't tried that but assume this should work).
For Visual Studio 2008 the template is stored at
"C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE\ItemTemplates
\CSharp\Code\1033\Interface.zip"
This is described in more detail in this answer.
I don't have a reference, but I have a wild guess as to why it is internal by default.
Let's say you have 3 projects / assemblies: log4net (a 3rd party API), MyApp.Util, and MyApp.Web (a Web project). Web references Util, which references log4net. Web does not reference log4net, and you want to keep it that way.
Inside of DAL, say you have an internal class, and one of its members references a type defined in log4net. It could be the return type or one of the parameter types of a method, or the type of a property.
Let's say you extract an interface from the aforementioned class, including the aforementioned member that references log4net. Well, if you make that member public (part of a public interface) and reference a type that implements it, you then require that the Web project reference log4net.
By making the interface internal, Web may continue to be ignorant of log4net.

How to create a COM dll using Visual Studio 2008

How do I create a COM dll using Visual Studio 2008? What are the custom settings needed for creating the dll? That dll should be used in Microsoft Navision(ERP PACKAGE).
Simply create a class library. In the project properties, open the dialog where you can change assembly information and mark the "Make assembly COM-visible" checkbox (sorry, don't know the exact name of the option, using German VS 2008).
Then, add the following attributes to any class that should be used from Navision:
[ClassInterface(ClassInterfaceType.AutoDual)]
[ProgId("YOUR-ID-GOES-HERE")]
[ComVisible(true)]
[Guid("xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx")]
public class ComVisbleClass
{
....
}
I suggest that you also manually assign Disp-IDs to the public methods and properties using the DispId attribute. Otherwise, inserting new public methods or properties may break Navision functionality, as the Disp-IDs may be changed upon compilation.
Navision would then refer to the old Disp-IDs which may now "point" to different methods. This is a PITA to debug and solve, so use the DispId attribute from the start.

Resources