How to do logging when writing an Visual Studio MEF extension - visual-studio

I'm writing a Visual Studio extension using MEF an I'm wondering how to add logging to the code.
When writing a VsPackage one could use the "Action Log" like shown in MSDN. But this isn't possible in a MEF extension.
How should I do my logging? Is it even possible to write to the VS access log using a MEF extension? Should I do my own logging using nlog or similar.

You can still use the IVsActivityLog. The only thing that changes is the way you get access to the IVsActivityLog instance. Instead of this:
IVsActivityLog log = GetService(typeof(SVsActivityLog)) as IVsActivityLog;
You would first [Import] the SVsServiceProvider:
[Import] internal SVsServiceProvider ServiceProvider = null;
Then you can call IServiceProvider.GetService:
IVsActivityLog log = ServiceProvider.GetService(typeof(SVsActivityLog)) as IVsActivityLog;

Related

Visual Studio tries to locate AutoMapper's PrimitiveExtensions.cs

I have a model that I'm mapping to DTO. All the mapping should be set up correctly. I'm using:
Mapper.AssertConfigurationIsValid();
I retrieve the model from the db. Its properties, including its child entities are correct and they are exactly what is found in the tables.
However, when I try to map it to DTO:
var entity = myService.Get(id)
var dto = Mapper.Map<myDTO>(entity);
Visual Studio shows the Open File dialog and tries to open the file PrimitiveExtensions.cs. I can't stop the app, and I need to end Visual Studio from the Task Manager.
This problem occurs for only one particular model (and it's child entities). Does it occur because the mapping is not set up correctly?
Most likely your VS tries to open the source file because it breaks on a first chance exception. Usually you should be able to cancel the file open dialog and then analyze the call stack or simply continue running the code.
You can disable breaking on first chance exception in the Debug -> Exceptions dialog.
In case it isn't only a first chance exception but an unhandled one you can tell VS to not try to open the library code by enabling "Enable just my code" in Tools - Options - Debugging.

Can I pass an argument/switch/parameter to a VSPackage MenuCommand?

I was hoping someone here might be able to help me out with this. I'm not the most experienced programmer but I'm making progress on a project.
I've got a need to programmatically interact with Visual Studio. Some success has been had using EnvDTE Interop stuff, but it seems that some of what I need to do needs to be done inside VS so I'm attempting to utilize a VSPackage MenuCommand to do various things. Sorry the vagueness.
I'm currently successfully creating a custom MenuCommand with a VSPackage extension, and also am able to trigger that MenuCommand programmatically from another application using the DTE.
What I'm wondering is: is it possible to define a MenuCommand that CAN take arguments passed along to it from the triggering external application?
Using the VS Package Template in Visual Studio 2012 using the Menu Command option, all my code lives inside this method:
private void MenuItemCallback(object sender, EventArgs e)
{
// my code...
}
There is obviously a lot of other auto-generated code plumbing this all together, but all MY code lives in this method. Is there a way to alter this method so that it will allow parameters to be passed to it? What other changes must I make to the other files to declare/register this differently-functioning method once I do so (if I can)?
For example:
static void Main(string[] args)
{
Type visualStudioType = Type.GetTypeFromProgID("VisualStudio.DTE.11.0");
DTE dte = Activator.CreateInstance(visualStudioType) as DTE;
dte.MainWindow.Visible = true;
dte.ExecuteCommand("myCommand");
}
This works. But what I'd like to do is change that last command to:
dte.ExecuteCommand("myCommand", "myArguments");
When I attempt to do something like this, I receive the following exception:
"Command \"myCommand\" does not accept arguments or switches."
Sorry if I'm not being clear. Any help would be greatly appreciated.
Commands created from add-ins accept parameters by default.
Commands created from packages need to specify the <CommandFlag>AllowParams</CommandFlag> when defining the command in the .vsct file. See: http://msdn.microsoft.com/en-us/library/bb491716.aspx
And see also this thread:
IOleComandTarget::exec for commands with parameters
https://social.msdn.microsoft.com/Forums/en-US/134983e8-049c-40e1-a212-312fa637698b/iolecomandtargetexec-for-commands-with-parameters?forum=vsx
Then, it should work, either using dte.ExecuteCommand or dte.Commands.Raise(...). See:
HOWTO: Pass parameters programmatically to a command from a Visual Studio add-in
http://www.visualstudioextensibility.com/articles/add-ins/

Visual Studio custom wizard - add additional configuration

I am writing a visual studio custom wizard for creating C++ project.
I need to define additional build configuration, that inherits the debug configuration.
I googled a lot, but couldn't find anything.
I guess this should be done in the JScript file (default.js), AddConfig function, by calling proj.Object.AddConfiguration. But I couldn't find examples, nor syntax rules.
The only thing I found is : http://www.codeproject.com/Articles/200039/A-Visual-Studio-Wizard-to-add-more-project-configu but it is way too complicated, and I couldn't figure it out.
Can you please help?
Found it. It can be done using C# code:
solution.SolutionBuild.SolutionConfigurations.Add("Conf", "Debug", true);
//set Conf to be active build configuration
solution.SolutionBuild.SolutionConfigurations.Item("Conf").Activate();
//Get project
VCProject pro = solution.Projects.Item(1).Object;
//Get comiler tool for project
VCCLCompilerTool tool = pro.Configurations.item("Conf").Tools("VCCLCompilerTool");
//set Prprocessor definition for Conf
tool.PreprocessorDefinitions = "NEW";

Getting started with Watin

I am trying to do the quick start example, I bring in the ref's using NuGet in VS2010, I scrape the sample code on the webpage, I see my NUnit Session window, I click the green arrow, but the browser doesn't get invoked (doesn't start). What am I missing?
using System;
using NUnit.Framework;
using WatiN.Core;
namespace FirstWatinProject
{
[TestFixture]
public class Class1
{
[Test]
[STAThread]
public void SearchForWatiNOnGoogle()
{
using (var browser = new IE("http://www.google.com"))
{
browser.TextField(Find.ByName("q")).TypeText("WatiN");
browser.Button(Find.ByName("btnK")).Click();
Assert.IsTrue(browser.ContainsText("WatiN"));
}
}
}
}
I am getting the following error in NUnit Sessions window;
SearchForWaitOnGoogle Failed: System.IO.FileNotFoundException: Could
not load file or assembly 'Interop.SHDocVw, Version=1.1.0.0,
Culture=neutral etc...
Okay, solved the error, it is as the following other overflow thread concludes;
WatiN System.IO.FileNotFoundException Interop.SHDocVw
BUT, a key action in the sequence is to build the class library project AFTER setting the Interop.SHDocVw dlls' 'Embed Interop Types' property to 'False';
Then you can hit the green arrow in NUNIT Sessions window and you will see the IE browser startup after a second or two. Simply click it and you will see whatever actions you have programmed.
God is in the details!
Setting the Interop.SHDocVw, Microsoft.mshtml dlls' 'Embed Interop Types' property to 'False';
Of course Visual Studio would give you warnings on how to amend.
The Use of Nugget Package Manager
Check for the availability of Interop.SHDocVw.dll,
Make sure that your project has a reference to Interop.SHDocVw.dll and the dll is present in the Bin/Release Folder depending upon how you are running..
Just select Build from the main menu...then select Configuration Manager. In the list select you project and change its Plateform 'Any CPU' etc to x86.
If you have only Only CPU option, you can use ... option when chosing platform and create new setting, that is for X86 platform and then choose it.
ref:
Change target to x86 in VS2010
I already had a reference to Interop.SHDocVw. The easiest fix for me was simply changing .NET from 4.5 to 3.5 in Visual Studio settings. After making the change, it worked fine.

Creating a Visual Studio Tool Window - VsAddin or VsPackage

Simple question - I found two ways to add a tool window to Visual Studio (2008): create an addin or create a package.
(Addin: http://www.codeproject.com/KB/dotnet/vstoolwindow.aspx)
(Package: http://msdn.microsoft.com/en-us/library/bb165051.aspx)
What's the "right" way?
You can do either, and I've done both. In some ways, addins are a bit easier, but they suffer from some annoying drawbacks.
Add-in:
+No requirement to install the Visual Studio SDK
+No requirement to use a Package Load Key (PLK) or sign your distributed binaries
+Easier development process when you use the Extensibility API (simplified code in many ways)
+Easier installation process (no wacky registry stuff)
-Doesn't seem to behave as well as VSPackage-based tool panes
-I've run into performance issues which prompted me to use the VS SDK COM interfaces instead of the Extensibility ones, leading to a significant performance bump. In other words, my "add-in" is now based on the VS SDK and is only really an add-in because it loads via an XML file instead of the registry. (Also, from everything I can tell, the Extensibility interfaces are just a large utility wrapper around the SDK.)
VSPackages:
+You can harness the full power of the VS SDK, both its feature set and (potentially, when carefully used) performance advantage
+Seems to behave more reliably than add-ins
-Requires signed binaries, a PLK, and a complicated installation procedure
-Steep learning curve, and many seemingly simple actions are nasty/convoluted. I now have an assembly providing extension methods to perform "obvious (to me)" actions on the COM interfaces. Between that and experience things have improved over time. There are similar options available to the community, which you should seriously consider if you go this route.
I think 280Z28 was perfectly correct prior VS2010. But now VS2010 and VS012:
Do not require officially signed packages (may only those that go to the Gallery have to);
Thanks to VSIX it can very easily install VSPackages that can also be deployed to the Gallery.
Moreover VS2010 supports another kind of extensibility: those are MEF extensions, that are lightweight plugins that trigger only at specific events of the IDE, like text editor events. An example is FixMixedTabs extension.
Just a create a VSPackage empty package (no menus, commands, ...) and copy this in the main class to create a VSPackage that basically loads when there's an active solution and just get a reference to the DTE2. In this way you can just use it as an Add-in.
// This attribute tells the PkgDef creation utility (CreatePkgDef.exe) that this class is
// a package.
[PackageRegistration(UseManagedResourcesOnly = true)]
// This attribute is used to register the informations needed to show the this package
// in the Help/About dialog of Visual Studio.
[InstalledProductRegistration("#110", "#112", "1.0", IconResourceID = 400)]
[Guid(GuidList.guidVSPackage1PkgString)]
// Load this package when a solution is loaded (VSConstants.UICONTEXT_SolutionExists)
[ProvideAutoLoad("{f1536ef8-92ec-443c-9ed7-fdadf150da82}")]
public sealed class VSPackage1Package : Package
{
/// <summary>
/// Default constructor of the package.
/// Inside this method you can place any initialization code that does not require
/// any Visual Studio service because at this point the package object is created but
/// not sited yet inside Visual Studio environment. The place to do all the other
/// initialization is the Initialize method.
/// </summary>
public VSPackage1Package()
{
Trace.WriteLine(string.Format(CultureInfo.CurrentCulture, "Entering constructor for: {0}", this.ToString()));
}
/// <summary>
/// Initialization of the package; this method is called right after the package is sited, so this is the place
/// where you can put all the initilaization code that rely on services provided by VisualStudio.
/// </summary>
protected override void Initialize()
{
Trace.WriteLine (string.Format(CultureInfo.CurrentCulture, "Entering Initialize() of: {0}", this.ToString()));
base.Initialize();
IVsExtensibility extensibility =
GetService(typeof(EnvDTE.IVsExtensibility)) as
IVsExtensibility;
DTE2 dte = extensibility.GetGlobalsObject(null).DTE as DTE2;
}
}
If you are just creating a simple tool window then I suggest going the Add-in route.
Both Packages and Add-Ins are ways of extending Visual Studio. Generally speaking they have the same functionality. Packages are a bit more powerful and allow deeper integration into Visual Studio. But that deeper integration comes with a cost including bigger ramp up times and installation procedures.
Add-ins are designed to be a more light weight extension mechanism. Smaller ramp up time and easier installation.
If all you are doing is tool window with basic interaction of the editor our code model then add-in is the best route.

Resources