This commit is contained in:
vitaliiy@outlook.com 2014-03-12 20:32:09 -07:00
parent 8b61ca41fa
commit 17883e16e1
41 changed files with 3173 additions and 0 deletions

View File

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<TestSettings
id="85f80678-5acf-4267-a4f8-e5bf47bd5e87"
name="Integration Tests"
enableDefaultDataCollectors="false"
xmlns="http://microsoft.com/schemas/VisualStudio/TeamTest/2010">
<Description>This test run configuration uses the VS IDE host type in the test run.</Description>
<Deployment enabled="false" />
<Execution>
<Hosts>
<VSSDKTestHostRunConfig name="VS IDE" HiveName="12.0Exp" xmlns="http://microsoft.com/schemas/VisualStudio/SDK/Tools/IdeHostAdapter/2006/06" />
</Hosts>
</Execution>
</TestSettings>

9
UnitTests.testsettings Normal file
View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<TestSettings
id="906380a7-c058-43a6-8f36-966013e5a9eb"
name="Unit Tests"
enableDefaultDataCollectors="false"
xmlns="http://microsoft.com/schemas/VisualStudio/TeamTest/2010">
<Deployment enabled="false" />
<Description>This test run configuration is used for running the unit tests</Description>
</TestSettings>

View File

@ -0,0 +1,11 @@
// This file is used by Code Analysis to maintain SuppressMessage
// attributes that are applied to this project. Project-level
// suppressions either have no target or are given a specific target
// and scoped to a namespace, type, member, etc.
//
// To add a suppression to this file, right-click the message in the
// Error List, point to "Suppress Message(s)", and click "In Project
// Suppression File". You do not need to add suppressions to this
// file manually.
[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1017:MarkAssembliesWithComVisible")]

15
VSPackageInstall/Guids.cs Normal file
View File

@ -0,0 +1,15 @@
// Guids.cs
// MUST match guids.h
using System;
namespace VitaliiGanzha.VSPackageInstall
{
static class GuidList
{
public const string guidVSPackageInstallPkgString = "a527a9c1-ec2f-46a0-a6e3-371859c5845b";
public const string guidVSPackageInstallCmdSetString = "4fddc919-41be-47b6-ae59-7125c75d1f1e";
public const string guidToolWindowPersistanceString = "a6862923-42ae-438f-ac76-7a68be1011e3";
public static readonly Guid guidVSPackageInstallCmdSet = new Guid(guidVSPackageInstallCmdSetString);
};
}

BIN
VSPackageInstall/Key.snk Normal file

Binary file not shown.

View File

@ -0,0 +1,17 @@
<UserControl x:Class="VitaliiGanzha.VSPackageInstall.MyControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
Background="{DynamicResource VsBrush.Window}"
Foreground="{DynamicResource VsBrush.WindowText}"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300"
Name="MyToolWindow">
<Grid>
<StackPanel Orientation="Vertical">
<TextBlock Margin="10" HorizontalAlignment="Center">VS Ding</TextBlock>
<Button Content="_Click Me!" Click="button1_Click" Width="120" Height="80" Name="button1"/>
</StackPanel>
</Grid>
</UserControl>

View File

@ -0,0 +1,35 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace VitaliiGanzha.VSPackageInstall
{
/// <summary>
/// Interaction logic for MyControl.xaml
/// </summary>
public partial class MyControl : UserControl
{
public MyControl()
{
InitializeComponent();
}
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1300:SpecifyMessageBoxOptions")]
private void button1_Click(object sender, RoutedEventArgs e)
{
MessageBox.Show(string.Format(System.Globalization.CultureInfo.CurrentUICulture, "We are inside {0}.button1_Click()", this.ToString()),
"VS Ding");
}
}
}

View File

@ -0,0 +1,47 @@
using System;
using System.Collections;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Windows;
using System.Runtime.InteropServices;
using Microsoft.VisualStudio.Shell.Interop;
using Microsoft.VisualStudio.Shell;
namespace VitaliiGanzha.VSPackageInstall
{
/// <summary>
/// This class implements the tool window exposed by this package and hosts a user control.
///
/// In Visual Studio tool windows are composed of a frame (implemented by the shell) and a pane,
/// usually implemented by the package implementer.
///
/// This class derives from the ToolWindowPane class provided from the MPF in order to use its
/// implementation of the IVsUIElementPane interface.
/// </summary>
[Guid("a6862923-42ae-438f-ac76-7a68be1011e3")]
public class MyToolWindow : ToolWindowPane
{
/// <summary>
/// Standard constructor for the tool window.
/// </summary>
public MyToolWindow() :
base(null)
{
// Set the window title reading it from the resources.
this.Caption = Resources.ToolWindowTitle;
// Set the image that will appear on the tab of the window frame
// when docked with an other window
// The resource ID correspond to the one defined in the resx file
// while the Index is the offset in the bitmap strip. Each image in
// the strip being 16x16.
this.BitmapResourceID = 301;
this.BitmapIndex = 1;
// This is the user control hosted by the tool window; Note that, even if this class implements IDisposable,
// we are not calling Dispose on this object. This is because ToolWindowPane calls Dispose on
// the object returned by the Content property.
base.Content = new MyControl();
}
}
}

View File

@ -0,0 +1,13 @@
// PkgCmdID.cs
// MUST match PkgCmdID.h
using System;
namespace VitaliiGanzha.VSPackageInstall
{
static class PkgCmdIDList
{
public const uint cmdidVsDing = 0x100;
public const uint cmdidVsDingWnd = 0x101;
};
}

View File

@ -0,0 +1,36 @@
using System;
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("VSPackageInstall")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Vitalii Ganzha")]
[assembly: AssemblyProduct("VSPackageInstall")]
[assembly: AssemblyCopyright("")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
[assembly: ComVisible(false)]
[assembly: CLSCompliant(false)]
[assembly: NeutralResourcesLanguage("en-US")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Revision and Build Numbers
// by using the '*' as shown below:
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: InternalsVisibleTo("VSPackageInstall_IntegrationTests, PublicKey=00240000048000009400000006020000002400005253413100040000010001004bcbc34c62abe4c7cbb70dd208ebb4958e5f0fa40d49b5cb7745114737e7deba8e9227e32bb0c06fba88912c428184c837e96865ef4f98d7302d5f9f184a93906e2fdd69f9defe190ad7605078c48a780222cd33b3655512d71febdf8bfcf755ccb9037b9369939cd85bcc0b1ef12938bd1b6802f9284e657dd7d386555209b5")]
[assembly: InternalsVisibleTo("VSPackageInstall_UnitTests, PublicKey=00240000048000009400000006020000002400005253413100040000010001004bcbc34c62abe4c7cbb70dd208ebb4958e5f0fa40d49b5cb7745114737e7deba8e9227e32bb0c06fba88912c428184c837e96865ef4f98d7302d5f9f184a93906e2fdd69f9defe190ad7605078c48a780222cd33b3655512d71febdf8bfcf755ccb9037b9369939cd85bcc0b1ef12938bd1b6802f9284e657dd7d386555209b5")]

81
VSPackageInstall/Resources.Designer.cs generated Normal file
View File

@ -0,0 +1,81 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:2.0.50727.42
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace VitaliiGanzha.VSPackageInstall {
using System;
/// <summary>
/// A strongly-typed resource class, for looking up localized strings, etc.
/// </summary>
// This class was auto-generated by the StronglyTypedResourceBuilder
// class via a tool like ResGen or Visual Studio.
// To add or remove a member, edit your .ResX file then rerun ResGen
// with the /str option, or rebuild your VS project.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "2.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class Resources {
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal Resources() {
}
/// <summary>
/// Returns the cached ResourceManager instance used by this class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("VitaliiGanzha.VSPackageInstall.Resources", typeof(Resources).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// Overrides the current thread's CurrentUICulture property for all
/// resource lookups using this strongly typed resource class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set {
resourceCulture = value;
}
}
/// <summary>
/// Looks up a localized string similar to Can not create tool window..
/// </summary>
internal static string CanNotCreateWindow {
get {
return ResourceManager.GetString("CanNotCreateWindow", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to My Tool Window.
/// </summary>
internal static string ToolWindowTitle {
get {
return ResourceManager.GetString("ToolWindowTitle", resourceCulture);
}
}
}
}

View File

@ -0,0 +1,135 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
VS SDK Notes: This resx file contains the resources that will be consumed directly by your package.
For example, if you chose to create a tool window, there is a resource with ID 'CanNotCreateWindow'. This
is used in VsPkg.cs to determine the string to show the user if there is an error when attempting to create
the tool window.
Resources that are accessed directly from your package *by Visual Studio* are stored in the VSPackage.resx
file.
-->
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="CanNotCreateWindow" xml:space="preserve">
<value>Can not create tool window.</value>
</data>
<data name="ToolWindowTitle" xml:space="preserve">
<value>VS Ding</value>
</data>
</root>

Binary file not shown.

After

Width:  |  Height:  |  Size: 994 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

View File

@ -0,0 +1,143 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
VS SDK Notes: This resx file contains the resources that will be consumed from your package by Visual Studio.
For example, Visual Studio will attempt to load resource '400' from this resource stream when it needs to
load your package's icon. Because Visual Studio will always look in the VSPackage.resources stream first for
resources it needs, you should put additional resources that Visual Studio will load directly into this resx
file.
Resources that you would like to access directly from your package in a strong-typed fashion should be stored
in Resources.resx or another resx file.
-->
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<data name="110" xml:space="preserve">
<value>VSPackageInstall</value>
</data>
<data name="112" xml:space="preserve">
<value>Visual Studio sound notifications</value>
</data>
<data name="400" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>Resources\Package.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="301" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>Resources\Images.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
</root>

View File

@ -0,0 +1,193 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="12.0">
<PropertyGroup>
<MinimumVisualStudioVersion>12.0</MinimumVisualStudioVersion>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">12.0</VisualStudioVersion>
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
</PropertyGroup>
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')"/>
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{20191d13-7cc1-4f9b-9cb8-42f22ace4ca6}</ProjectGuid>
<ProjectTypeGuids>{82b43b9b-a64c-4715-b499-d71e9ca2bd60};{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>VitaliiGanzha.VSPackageInstall</RootNamespace>
<AssemblyName>VSPackageInstall</AssemblyName>
<SignAssembly>True</SignAssembly>
<AssemblyOriginatorKeyFile>Key.snk</AssemblyOriginatorKeyFile>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<RunCodeAnalysis>true</RunCodeAnalysis>
</PropertyGroup>
<ItemGroup>
<Reference Include="Microsoft.CSharp" />
<Reference Include="Microsoft.VisualStudio.OLE.Interop" />
<Reference Include="Microsoft.VisualStudio.Shell.Interop" />
<Reference Include="Microsoft.VisualStudio.Shell.Interop.8.0" />
<Reference Include="Microsoft.VisualStudio.Shell.Interop.9.0" />
<Reference Include="Microsoft.VisualStudio.Shell.Interop.10.0" />
<Reference Include="Microsoft.VisualStudio.Shell.Interop.11.0">
<EmbedInteropTypes>true</EmbedInteropTypes>
</Reference>
<Reference Include="Microsoft.VisualStudio.Shell.Interop.12.0">
<EmbedInteropTypes>true</EmbedInteropTypes>
</Reference>
<Reference Include="Microsoft.VisualStudio.TextManager.Interop" />
<Reference Include="Microsoft.VisualStudio.Shell.12.0" />
<Reference Include="Microsoft.VisualStudio.Shell.Immutable.10.0" />
<Reference Include="Microsoft.VisualStudio.Shell.Immutable.11.0" />
<Reference Include="Microsoft.VisualStudio.Shell.Immutable.12.0" />
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Data" />
<Reference Include="System.Design" />
<Reference Include="System.Drawing" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml" />
<Reference Include="PresentationCore" />
<Reference Include="PresentationFramework" />
<Reference Include="WindowsBase" />
<Reference Include="System.Xaml" />
</ItemGroup>
<ItemGroup>
<COMReference Include="EnvDTE">
<Guid>{80CC9F66-E7D8-4DDD-85B6-D9E6CD0E93E2}</Guid>
<VersionMajor>8</VersionMajor>
<VersionMinor>0</VersionMinor>
<Lcid>0</Lcid>
<WrapperTool>primary</WrapperTool>
<Isolated>False</Isolated>
<EmbedInteropTypes>False</EmbedInteropTypes>
</COMReference>
<COMReference Include="EnvDTE100">
<Guid>{26AD1324-4B7C-44BC-84F8-B86AED45729F}</Guid>
<VersionMajor>10</VersionMajor>
<VersionMinor>0</VersionMinor>
<Lcid>0</Lcid>
<WrapperTool>primary</WrapperTool>
<Isolated>False</Isolated>
<EmbedInteropTypes>False</EmbedInteropTypes>
</COMReference>
<COMReference Include="EnvDTE80">
<Guid>{1A31287A-4D7D-413E-8E32-3B374931BD89}</Guid>
<VersionMajor>8</VersionMajor>
<VersionMinor>0</VersionMinor>
<Lcid>0</Lcid>
<WrapperTool>primary</WrapperTool>
<Isolated>False</Isolated>
<EmbedInteropTypes>False</EmbedInteropTypes>
</COMReference>
<COMReference Include="EnvDTE90">
<Guid>{2CE2370E-D744-4936-A090-3FFFE667B0E1}</Guid>
<VersionMajor>9</VersionMajor>
<VersionMinor>0</VersionMinor>
<Lcid>0</Lcid>
<WrapperTool>primary</WrapperTool>
<Isolated>False</Isolated>
<EmbedInteropTypes>False</EmbedInteropTypes>
</COMReference>
<COMReference Include="Microsoft.VisualStudio.CommandBars">
<Guid>{1CBA492E-7263-47BB-87FE-639000619B15}</Guid>
<VersionMajor>8</VersionMajor>
<VersionMinor>0</VersionMinor>
<Lcid>0</Lcid>
<WrapperTool>primary</WrapperTool>
<Isolated>False</Isolated>
<EmbedInteropTypes>False</EmbedInteropTypes>
</COMReference>
<COMReference Include="stdole">
<Guid>{00020430-0000-0000-C000-000000000046}</Guid>
<VersionMajor>2</VersionMajor>
<VersionMinor>0</VersionMinor>
<Lcid>0</Lcid>
<WrapperTool>primary</WrapperTool>
<Isolated>False</Isolated>
<EmbedInteropTypes>False</EmbedInteropTypes>
</COMReference>
</ItemGroup>
<ItemGroup>
<Compile Include="MyControl.xaml.cs">
<DependentUpon>MyControl.xaml</DependentUpon>
</Compile>
<Compile Include="MyToolWindow.cs" />
<Compile Include="Guids.cs" />
<Compile Include="Resources.Designer.cs">
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
<Compile Include="GlobalSuppressions.cs" />
<Compile Include="VSPackageInstallPackage.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="PkgCmdID.cs" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
<SubType>Designer</SubType>
</EmbeddedResource>
<EmbeddedResource Include="VSPackage.resx">
<MergeWithCTO>true</MergeWithCTO>
<ManifestResourceName>VSPackage</ManifestResourceName>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<None Include="source.extension.vsixmanifest">
<SubType>Designer</SubType>
</None>
</ItemGroup>
<ItemGroup>
<None Include="Key.snk" />
</ItemGroup>
<ItemGroup>
<VSCTCompile Include="VSPackageInstall.vsct">
<ResourceName>Menus.ctmenu</ResourceName>
</VSCTCompile>
</ItemGroup>
<ItemGroup>
<None Include="Resources\Images.png" />
</ItemGroup>
<ItemGroup>
<Content Include="Resources\Package.ico" />
</ItemGroup>
<ItemGroup>
<Page Include="MyControl.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
</ItemGroup>
<PropertyGroup>
<UseCodebase>true</UseCodebase>
</PropertyGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<Import Project="$(VSToolsPath)\VSSDK\Microsoft.VsSDK.targets" Condition="'$(VSToolsPath)' != ''" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

View File

@ -0,0 +1,125 @@
<?xml version="1.0" encoding="utf-8"?>
<CommandTable xmlns="http://schemas.microsoft.com/VisualStudio/2005-10-18/CommandTable" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<!-- This is the file that defines the actual layout and type of the commands.
It is divided in different sections (e.g. command definition, command
placement, ...), with each defining a specific set of properties.
See the comment before each section for more details about how to
use it. -->
<!-- The VSCT compiler (the tool that translates this file into the binary
format that VisualStudio will consume) has the ability to run a preprocessor
on the vsct file; this preprocessor is (usually) the C++ preprocessor, so
it is possible to define includes and macros with the same syntax used
in C++ files. Using this ability of the compiler here, we include some files
defining some of the constants that we will use inside the file. -->
<!--This is the file that defines the IDs for all the commands exposed by VisualStudio. -->
<Extern href="stdidcmd.h"/>
<!--This header contains the command ids for the menus provided by the shell. -->
<Extern href="vsshlids.h"/>
<!--The Commands section is where we the commands, menus and menu groups are defined.
This section uses a Guid to identify the package that provides the command defined inside it. -->
<Commands package="guidVSPackageInstallPkg">
<!-- Inside this section we have different sub-sections: one for the menus, another
for the menu groups, one for the buttons (the actual commands), one for the combos
and the last one for the bitmaps used. Each element is identified by a command id that
is a unique pair of guid and numeric identifier; the guid part of the identifier is usually
called "command set" and is used to group different command inside a logically related
group; your package should define its own command set in order to avoid collisions
with command ids defined by other packages. -->
<!-- In this section you can define new menu groups. A menu group is a container for
other menus or buttons (commands); from a visual point of view you can see the
group as the part of a menu contained between two lines. The parent of a group
must be a menu. -->
<Groups>
<Group guid="guidVSPackageInstallCmdSet" id="MyMenuGroup" priority="0x0600">
<Parent guid="guidSHLMainMenu" id="IDM_VS_MENU_TOOLS"/>
</Group>
</Groups>
<!--Buttons section. -->
<!--This section defines the elements the user can interact with, like a menu command or a button
or combo box in a toolbar. -->
<Buttons>
<!--To define a menu group you have to specify its ID, the parent menu and its display priority.
The command is visible and enabled by default. If you need to change the visibility, status, etc, you can use
the CommandFlag node.
You can add more than one CommandFlag node e.g.:
<CommandFlag>DefaultInvisible</CommandFlag>
<CommandFlag>DynamicVisibility</CommandFlag>
If you do not want an image next to your command, remove the Icon node /> -->
<Button guid="guidVSPackageInstallCmdSet" id="cmdidVsDing" priority="0x0100" type="Button">
<Parent guid="guidVSPackageInstallCmdSet" id="MyMenuGroup" />
<Icon guid="guidImages" id="bmpPic1" />
<Strings>
<ButtonText>VisualStudioDing</ButtonText>
</Strings>
</Button>
<Button guid="guidVSPackageInstallCmdSet" id="cmdidVsDingWnd" priority="0x0100" type="Button">
<Parent guid="guidSHLMainMenu" id="IDG_VS_WNDO_OTRWNDWS1"/>
<Icon guid="guidImages" id="bmpPic2" />
<Strings>
<ButtonText>VS Ding</ButtonText>
</Strings>
</Button>
</Buttons>
<!--The bitmaps section is used to define the bitmaps that are used for the commands.-->
<Bitmaps>
<!-- The bitmap id is defined in a way that is a little bit different from the others:
the declaration starts with a guid for the bitmap strip, then there is the resource id of the
bitmap strip containing the bitmaps and then there are the numeric ids of the elements used
inside a button definition. An important aspect of this declaration is that the element id
must be the actual index (1-based) of the bitmap inside the bitmap strip. -->
<Bitmap guid="guidImages" href="Resources\Images.png" usedList="bmpPic1, bmpPic2, bmpPicSearch, bmpPicX, bmpPicArrows"/>
</Bitmaps>
</Commands>
<Symbols>
<!-- This is the package guid. -->
<GuidSymbol name="guidVSPackageInstallPkg" value="{a527a9c1-ec2f-46a0-a6e3-371859c5845b}" />
<!-- This is the guid used to group the menu commands together -->
<GuidSymbol name="guidVSPackageInstallCmdSet" value="{4fddc919-41be-47b6-ae59-7125c75d1f1e}">
<IDSymbol name="MyMenuGroup" value="0x1020" />
<IDSymbol name="cmdidVsDing" value="0x0100" />
<IDSymbol name="cmdidVsDingWnd" value="0x0101" />
</GuidSymbol>
<GuidSymbol name="guidImages" value="{d803fcb0-9af3-476e-a494-3dbb574f3b33}" >
<IDSymbol name="bmpPic1" value="1" />
<IDSymbol name="bmpPic2" value="2" />
<IDSymbol name="bmpPicSearch" value="3" />
<IDSymbol name="bmpPicX" value="4" />
<IDSymbol name="bmpPicArrows" value="5" />
<IDSymbol name="bmpPicStrikethrough" value="6" />
</GuidSymbol>
</Symbols>
</CommandTable>

View File

@ -0,0 +1,147 @@
using System;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Runtime.InteropServices;
using System.ComponentModel.Design;
using EnvDTE;
using EnvDTE80;
using Microsoft.Win32;
using Microsoft.VisualStudio;
using Microsoft.VisualStudio.Shell.Interop;
using Microsoft.VisualStudio.OLE.Interop;
using Microsoft.VisualStudio.Shell;
namespace VitaliiGanzha.VSPackageInstall
{
/// <summary>
/// This is the class that implements the package exposed by this assembly.
///
/// The minimum requirement for a class to be considered a valid package for Visual Studio
/// is to implement the IVsPackage interface and register itself with the shell.
/// This package uses the helper classes defined inside the Managed Package Framework (MPF)
/// to do it: it derives from the Package class that provides the implementation of the
/// IVsPackage interface and uses the registration attributes defined in the framework to
/// register itself and its components with the shell.
/// </summary>
// 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 information needed to show this package
// in the Help/About dialog of Visual Studio.
[InstalledProductRegistration("#110", "#112", "1.0", IconResourceID = 400)]
// This attribute is needed to let the shell know that this package exposes some menus.
[ProvideMenuResource("Menus.ctmenu", 1)]
// This attribute registers a tool window exposed by this package.
[ProvideToolWindow(typeof(MyToolWindow))]
[Guid(GuidList.guidVSPackageInstallPkgString)]
public sealed class VSPackageInstallPackage : Package
{
private DTE2 applicationObject;
private AddIn addInInstance;
/// <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 VSPackageInstallPackage()
{
Debug.WriteLine(string.Format(CultureInfo.CurrentCulture, "Entering constructor for: {0}", this.ToString()));
}
/// <summary>
/// This function is called when the user clicks the menu item that shows the
/// tool window. See the Initialize method to see how the menu item is associated to
/// this function using the OleMenuCommandService service and the MenuCommand class.
/// </summary>
private void ShowToolWindow(object sender, EventArgs e)
{
// Get the instance number 0 of this tool window. This window is single instance so this instance
// is actually the only one.
// The last flag is set to true so that if the tool window does not exists it will be created.
ToolWindowPane window = this.FindToolWindow(typeof(MyToolWindow), 0, true);
if ((null == window) || (null == window.Frame))
{
throw new NotSupportedException(Resources.CanNotCreateWindow);
}
IVsWindowFrame windowFrame = (IVsWindowFrame)window.Frame;
Microsoft.VisualStudio.ErrorHandler.ThrowOnFailure(windowFrame.Show());
}
/////////////////////////////////////////////////////////////////////////////
// Overridden Package Implementation
#region Package Members
/// <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 initialization code that rely on services provided by VisualStudio.
/// </summary>
protected override void Initialize()
{
try
{
Debug.WriteLine(string.Format(CultureInfo.CurrentCulture, "Entering Initialize() of: {0}", this.ToString()));
base.Initialize();
// Add our command handlers for menu (commands must exist in the .vsct file)
OleMenuCommandService mcs = GetService(typeof(IMenuCommandService)) as OleMenuCommandService;
if (null != mcs)
{
// Create the command for the menu item.
CommandID menuCommandID = new CommandID(GuidList.guidVSPackageInstallCmdSet, (int)PkgCmdIDList.cmdidVsDing);
MenuCommand menuItem = new MenuCommand(MenuItemCallback, menuCommandID);
mcs.AddCommand(menuItem);
// Create the command for the tool window
CommandID toolwndCommandID = new CommandID(GuidList.guidVSPackageInstallCmdSet, (int)PkgCmdIDList.cmdidVsDingWnd);
MenuCommand menuToolWin = new MenuCommand(ShowToolWindow, toolwndCommandID);
mcs.AddCommand(menuToolWin);
}
applicationObject = (DTE2)GetService(typeof(DTE));
applicationObject.Events.BuildEvents.OnBuildDone += BuildEventsOnOnBuildDone;
}
catch (Exception e)
{
File.WriteAllText(@"c:\temp\test.txt", e.Message);
}
}
private void BuildEventsOnOnBuildDone(vsBuildScope scope, vsBuildAction action)
{
System.Media.SystemSounds.Asterisk.Play();
}
#endregion
/// <summary>
/// This function is the callback used to execute a command when the a menu item is clicked.
/// See the Initialize method to see how the menu item is associated to this function using
/// the OleMenuCommandService service and the MenuCommand class.
/// </summary>
private void MenuItemCallback(object sender, EventArgs e)
{
// Show a Message Box to prove we were here
IVsUIShell uiShell = (IVsUIShell)GetService(typeof(SVsUIShell));
Guid clsid = Guid.Empty;
int result;
Microsoft.VisualStudio.ErrorHandler.ThrowOnFailure(uiShell.ShowMessageBox(
0,
ref clsid,
"VSPackageInstall",
string.Format(CultureInfo.CurrentCulture, "Inside {0}.MenuItemCallback()", this.ToString()),
string.Empty,
0,
OLEMSGBUTTON.OLEMSGBUTTON_OK,
OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST,
OLEMSGICON.OLEMSGICON_INFO,
0, // false
out result));
}
}
}

View File

@ -0,0 +1,359 @@

namespace Microsoft.VsSDK.IntegrationTestLibrary
{
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using System.Threading;
using Microsoft.VisualStudio.Shell.Interop;
using Microsoft.VisualStudio.Shell;
/// <summary>
/// This class is responsible to close dialog boxes that pop up during different VS Calls
/// </summary>
internal class DialogBoxPurger : IDisposable
{
/// <summary>
/// The default number of milliseconds to wait for the threads to signal to terminate.
/// </summary>
private const int DefaultMillisecondsToWait = 3500;
/// <summary>
/// Object used for synchronization between thread calls.
/// </summary>
internal static volatile object Mutex = new object();
/// <summary>
/// The IVsUIShell. This cannot be queried on the working thread from the service provider. Must be done in the main thread.!!
/// </summary>
private IVsUIShell uiShell;
/// <summary>
/// The button to "press" on the dialog.
/// </summary>
private int buttonAction;
/// <summary>
/// Thread signales to the calling thread that it is done.
/// </summary>
private bool exitThread = false;
/// <summary>
/// Calling thread signales to this thread to die.
/// </summary>
private AutoResetEvent threadDone = new AutoResetEvent(false);
/// <summary>
/// The queued thread started.
/// </summary>
private AutoResetEvent threadStarted = new AutoResetEvent(false);
/// <summary>
/// The result of the dialogbox closing for all the dialog boxes. That is if there are two of them and one fails this will be false.
/// </summary>
private bool dialogBoxCloseResult = false;
/// <summary>
/// The expected text to see on the dialog box. If set the thread will continue finding the dialog box with this text.
/// </summary>
private string expectedDialogBoxText = String.Empty;
/// <summary>
/// The number of the same dialog boxes to wait for.
/// This is for scenarios when two dialog boxes with the same text are popping up.
/// </summary>
private int numberOfDialogsToWaitFor = 1;
/// <summary>
/// Has the object been disposed.
/// </summary>
private bool isDisposed;
/// <summary>
/// Overloaded ctor.
/// </summary>
/// <param name="buttonAction">The botton to "press" on the dialog box.</param>
/// <param name="numberOfDialogsToWaitFor">The number of dialog boxes with the same message to wait for. This is the situation when the same action pops up two of the same dialog boxes</param>
/// <param name="expectedDialogMesssage">The expected dialog box message to check for.</param>
internal DialogBoxPurger(int buttonAction, int numberOfDialogsToWaitFor, string expectedDialogMesssage)
{
this.buttonAction = buttonAction;
this.numberOfDialogsToWaitFor = numberOfDialogsToWaitFor;
this.expectedDialogBoxText = expectedDialogMesssage;
}
/// <summary>
/// Overloaded ctor.
/// </summary>
/// <param name="buttonAction">The botton to "press" on the dialog box.</param>
/// <param name="numberOfDialogsToWaitFor">The number of dialog boxes with the same message to wait for. This is the situation when the same action pops up two of the same dialog boxes</param>
internal DialogBoxPurger(int buttonAction, int numberOfDialogsToWaitFor)
{
this.buttonAction = buttonAction;
this.numberOfDialogsToWaitFor = numberOfDialogsToWaitFor;
}
/// <summary>
/// Overloaded ctor.
/// </summary>
/// <param name="buttonAction">The botton to "press" on the dialog box.</param>
/// <param name="expectedDialogMesssage">The expected dialog box message to check for.</param>
internal DialogBoxPurger(int buttonAction, string expectedDialogMesssage)
{
this.buttonAction = buttonAction;
this.expectedDialogBoxText = expectedDialogMesssage;
}
/// <summary>
/// Overloaded ctor.
/// </summary>
/// <param name="buttonAction">The botton to "press" on the dialog box.</param>
internal DialogBoxPurger(int buttonAction)
{
this.buttonAction = buttonAction;
}
/// <summary>
#region IDisposable Members
void IDisposable.Dispose()
{
if (this.isDisposed)
{
return;
}
this.WaitForDialogThreadToTerminate();
this.isDisposed = true;
}
/// <summary>
/// Spawns a thread that will start listening to dialog boxes.
/// </summary>
internal void Start()
{
// We ask for the uishell here since we cannot do that on the therad that we will spawn.
IVsUIShell uiShell = Package.GetGlobalService(typeof(SVsUIShell)) as IVsUIShell;
if (uiShell == null)
{
throw new InvalidOperationException("Could not get the uiShell from the serviceProvider");
}
this.uiShell = uiShell;
System.Threading.Thread thread = new System.Threading.Thread(new ThreadStart(this.HandleDialogBoxes));
thread.Start();
// We should never deadlock here, hence do not use the lock. Wait to be sure that the thread started.
this.threadStarted.WaitOne(3500, false);
}
/// <summary>
/// Waits for the dialog box close thread to terminate. If the thread does not signal back within millisecondsToWait that it is shutting down,
/// then it will tell to the thread to do it.
/// </summary>
internal bool WaitForDialogThreadToTerminate()
{
return this.WaitForDialogThreadToTerminate(DefaultMillisecondsToWait);
}
/// <summary>
/// Waits for the dialog box close thread to terminate. If the thread does not signal back within millisecondsToWait that it is shutting down,
/// then it will tell to the thread to do it.
/// </summary>
/// <param name="millisecondsToWait">The number milliseconds to wait for until the dialog purger thread is signaled to terminate. This is just for safe precaution that we do not hang. </param>
/// <returns>The result of the dialog boxes closing</returns>
internal bool WaitForDialogThreadToTerminate(int numberOfMillisecondsToWait)
{
bool signaled = false;
// We give millisecondsToWait sec to bring up and close the dialog box.
signaled = this.threadDone.WaitOne(numberOfMillisecondsToWait, false);
// Kill the thread since a timeout occured.
if (!signaled)
{
lock (Mutex)
{
// Set the exit thread to true. Next time the thread will kill itselfes if it sees
this.exitThread = true;
}
// Wait for the thread to finish. We should never deadlock here.
this.threadDone.WaitOne();
}
return this.dialogBoxCloseResult;
}
/// <summary>
/// This is the thread method.
/// </summary>
private void HandleDialogBoxes()
{
// No synchronization numberOfDialogsToWaitFor since it is readonly
IntPtr[] hwnds = new IntPtr[this.numberOfDialogsToWaitFor];
bool[] dialogBoxCloseResults = new bool[this.numberOfDialogsToWaitFor];
try
{
// Signal that we started
lock (Mutex)
{
this.threadStarted.Set();
}
// The loop will be exited either if a message is send by the caller thread or if we found the dialog. If a message box text is specified the loop will not exit until the dialog is found.
bool stayInLoop = true;
int dialogBoxesToWaitFor = 1;
while (stayInLoop)
{
int hwndIndex = dialogBoxesToWaitFor - 1;
// We need to lock since the caller might set context to null.
lock (Mutex)
{
if (this.exitThread)
{
break;
}
// We protect the shell too from reentrency.
this.uiShell.GetDialogOwnerHwnd(out hwnds[hwndIndex]);
}
if (hwnds[hwndIndex] != IntPtr.Zero)
{
StringBuilder windowClassName = new StringBuilder(256);
NativeMethods.GetClassName(hwnds[hwndIndex], windowClassName, windowClassName.Capacity);
// The #32770 is the class name of a messagebox dialog.
if (windowClassName.ToString().Contains("#32770"))
{
IntPtr unmanagedMemoryLocation = IntPtr.Zero;
string dialogBoxText = String.Empty;
try
{
unmanagedMemoryLocation = Marshal.AllocHGlobal(10 * 1024);
NativeMethods.EnumChildWindows(hwnds[hwndIndex], new NativeMethods.CallBack(FindMessageBoxString), unmanagedMemoryLocation);
dialogBoxText = Marshal.PtrToStringUni(unmanagedMemoryLocation);
}
finally
{
if (unmanagedMemoryLocation != IntPtr.Zero)
{
Marshal.FreeHGlobal(unmanagedMemoryLocation);
}
}
lock (Mutex)
{
// Since this is running on the main thread be sure that we close the dialog.
bool dialogCloseResult = false;
if (this.buttonAction != 0)
{
dialogCloseResult = NativeMethods.EndDialog(hwnds[hwndIndex], this.buttonAction);
}
// Check if we have found the right dialog box.
if (String.IsNullOrEmpty(this.expectedDialogBoxText) || (!String.IsNullOrEmpty(dialogBoxText) && String.Compare(this.expectedDialogBoxText, dialogBoxText.Trim(), StringComparison.OrdinalIgnoreCase) == 0))
{
dialogBoxCloseResults[hwndIndex] = dialogCloseResult;
if (dialogBoxesToWaitFor++ >= this.numberOfDialogsToWaitFor)
{
stayInLoop = false;
}
}
}
}
}
}
}
finally
{
//Let the main thread run a possible close command.
System.Threading.Thread.Sleep(2000);
foreach (IntPtr hwnd in hwnds)
{
// At this point the dialog should be closed, if not attempt to close it.
if (hwnd != IntPtr.Zero)
{
NativeMethods.SendMessage(hwnd, NativeMethods.WM_CLOSE, 0, new IntPtr(0));
}
}
lock (Mutex)
{
// Be optimistic.
this.dialogBoxCloseResult = true;
for (int i = 0; i < dialogBoxCloseResults.Length; i++)
{
if (!dialogBoxCloseResults[i])
{
this.dialogBoxCloseResult = false;
break;
}
}
this.threadDone.Set();
}
}
}
/// <summary>
/// Finds a messagebox string on a messagebox.
/// </summary>
/// <param name="hwnd">The windows handle of the dialog</param>
/// <param name="unmanagedMemoryLocation">A pointer to the memorylocation the string will be written to</param>
/// <returns>True if found.</returns>
private static bool FindMessageBoxString(IntPtr hwnd, IntPtr unmanagedMemoryLocation)
{
StringBuilder sb = new StringBuilder(512);
NativeMethods.GetClassName(hwnd, sb, sb.Capacity);
if (sb.ToString().ToLower().Contains("static"))
{
StringBuilder windowText = new StringBuilder(2048);
NativeMethods.GetWindowText(hwnd, windowText, windowText.Capacity);
if (windowText.Length > 0)
{
IntPtr stringAsPtr = IntPtr.Zero;
try
{
stringAsPtr = Marshal.StringToHGlobalAnsi(windowText.ToString());
char[] stringAsArray = windowText.ToString().ToCharArray();
// Since unicode characters are copied check if we are out of the allocated length.
// If not add the end terminating zero.
if ((2 * stringAsArray.Length) + 1 < 2048)
{
Marshal.Copy(stringAsArray, 0, unmanagedMemoryLocation, stringAsArray.Length);
Marshal.WriteInt32(unmanagedMemoryLocation, 2 * stringAsArray.Length, 0);
}
}
finally
{
if (stringAsPtr != IntPtr.Zero)
{
Marshal.FreeHGlobal(stringAsPtr);
}
}
return false;
}
}
return true;
}
#endregion
}
}

View File

@ -0,0 +1,154 @@
/***************************************************************************
Copyright (c) Microsoft Corporation. All rights reserved.
This code is licensed under the Visual Studio SDK license terms.
THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
***************************************************************************/
namespace Microsoft.VsSDK.IntegrationTestLibrary
{
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using System.Threading;
using Microsoft.VisualStudio.Shell.Interop;
/// <summary>
/// Defines pinvoked utility methods and internal VS Constants
/// </summary>
internal static class NativeMethods
{
internal delegate bool CallBack(IntPtr hwnd, IntPtr lParam);
// Declare two overloaded SendMessage functions
[DllImport("user32.dll")]
internal static extern UInt32 SendMessage(IntPtr hWnd, UInt32 Msg,
UInt32 wParam, IntPtr lParam);
[DllImport("user32.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto)]
internal static extern bool PeekMessage([In, Out] ref Microsoft.VisualStudio.OLE.Interop.MSG msg, HandleRef hwnd, int msgMin, int msgMax, int remove);
[DllImport("user32.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto)]
internal static extern bool TranslateMessage([In, Out] ref Microsoft.VisualStudio.OLE.Interop.MSG msg);
[DllImport("user32.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto)]
internal static extern int DispatchMessage([In] ref Microsoft.VisualStudio.OLE.Interop.MSG msg);
[DllImport("user32.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto)]
internal static extern bool AttachThreadInput(uint idAttach, uint idAttachTo, bool attach);
[DllImport("user32.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto)]
internal static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);
[DllImport("kernel32.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto)]
internal static extern uint GetCurrentThreadId();
[DllImport("user32")]
internal static extern int EnumChildWindows(IntPtr hwnd, CallBack x, IntPtr y);
[DllImport("user32")]
internal static extern bool IsWindowVisible(IntPtr hDlg);
[DllImport("user32.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto)]
internal static extern IntPtr SetFocus(IntPtr hWnd);
[DllImport("user32")]
internal static extern int GetClassName(IntPtr hWnd,
StringBuilder className,
int stringLength);
[DllImport("user32")]
internal static extern int GetWindowText(IntPtr hWnd, StringBuilder className, int stringLength);
[DllImport("user32")]
internal static extern bool EndDialog(IntPtr hDlg, int result);
[DllImport("Kernel32")]
internal static extern long GetLastError();
internal const int QS_KEY = 0x0001,
QS_MOUSEMOVE = 0x0002,
QS_MOUSEBUTTON = 0x0004,
QS_POSTMESSAGE = 0x0008,
QS_TIMER = 0x0010,
QS_PAINT = 0x0020,
QS_SENDMESSAGE = 0x0040,
QS_HOTKEY = 0x0080,
QS_ALLPOSTMESSAGE = 0x0100,
QS_MOUSE = QS_MOUSEMOVE | QS_MOUSEBUTTON,
QS_INPUT = QS_MOUSE | QS_KEY,
QS_ALLEVENTS = QS_INPUT | QS_POSTMESSAGE | QS_TIMER | QS_PAINT | QS_HOTKEY,
QS_ALLINPUT = QS_INPUT | QS_POSTMESSAGE | QS_TIMER | QS_PAINT | QS_HOTKEY | QS_SENDMESSAGE;
internal const int Facility_Win32 = 7;
internal const int WM_CLOSE = 0x0010;
internal const int
S_FALSE = 0x00000001,
S_OK = 0x00000000,
IDOK = 1,
IDCANCEL = 2,
IDABORT = 3,
IDRETRY = 4,
IDIGNORE = 5,
IDYES = 6,
IDNO = 7,
IDCLOSE = 8,
IDHELP = 9,
IDTRYAGAIN = 10,
IDCONTINUE = 11;
internal static long HResultFromWin32(long error)
{
if (error <= 0)
{
return error;
}
return ((error & 0x0000FFFF) | (Facility_Win32 << 16) | 0x80000000);
}
/// <devdoc>
/// Please use this "approved" method to compare file names.
/// </devdoc>
public static bool IsSamePath(string file1, string file2)
{
if (file1 == null || file1.Length == 0)
{
return (file2 == null || file2.Length == 0);
}
Uri uri1 = null;
Uri uri2 = null;
try
{
if (!Uri.TryCreate(file1, UriKind.Absolute, out uri1) || !Uri.TryCreate(file2, UriKind.Absolute, out uri2))
{
return false;
}
if (uri1 != null && uri1.IsFile && uri2 != null && uri2.IsFile)
{
return 0 == String.Compare(uri1.LocalPath, uri2.LocalPath, StringComparison.OrdinalIgnoreCase);
}
return file1 == file2;
}
catch (UriFormatException e)
{
System.Diagnostics.Trace.WriteLine("Exception " + e.Message);
}
return false;
}
}
}

View File

@ -0,0 +1,401 @@
using System;
using System.IO;
using System.Text;
using System.Reflection;
using System.Diagnostics;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel.Design;
using System.Runtime.InteropServices;
using Microsoft.VisualStudio.Shell.Interop;
using Microsoft.VisualStudio.Shell;
using EnvDTE;
using EnvDTE80;
using Microsoft.Win32;
using IOleServiceProvider = Microsoft.VisualStudio.OLE.Interop.IServiceProvider;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.VSSDK.Tools.VsIdeTesting;
using Microsoft.VisualStudio;
namespace Microsoft.VsSDK.IntegrationTestLibrary
{
/// <summary>
/// </summary>
public class TestUtils
{
#region Methods: Handling embedded resources
/// <summary>
/// Gets the embedded file identified by the resource name, and converts the
/// file into a string.
/// </summary>
/// <param name="resourceName">In VS, is DefaultNamespace.FileName?</param>
/// <returns></returns>
public static string GetEmbeddedStringResource(Assembly assembly, string resourceName)
{
string result = null;
// Use the .NET procedure for loading a file embedded in the assembly
Stream stream = assembly.GetManifestResourceStream(resourceName);
if (stream != null)
{
// Convert bytes to string
byte[] fileContentsAsBytes = new byte[stream.Length];
stream.Read(fileContentsAsBytes, 0, (int)stream.Length);
result = Encoding.Default.GetString(fileContentsAsBytes);
}
else
{
// Embedded resource not found - list available resources
Debug.WriteLine("Unable to find the embedded resource file '" + resourceName + "'.");
Debug.WriteLine(" Available resources:");
foreach (string aResourceName in assembly.GetManifestResourceNames())
{
Debug.WriteLine(" " + aResourceName);
}
}
return result;
}
/// <summary>
///
/// </summary>
/// <param name="embeddedResourceName"></param>
/// <param name="baseFileName"></param>
/// <param name="fileExtension"></param>
/// <returns></returns>
public static void WriteEmbeddedResourceToFile(Assembly assembly, string embeddedResourceName, string fileName)
{
// Get file contents
string fileContents = GetEmbeddedStringResource(assembly, embeddedResourceName);
if (fileContents == null)
throw new ApplicationException("Failed to get embedded resource '" + embeddedResourceName + "' from assembly '" + assembly.FullName);
// Write to file
StreamWriter sw = new StreamWriter(fileName);
sw.Write(fileContents);
sw.Close();
}
/// <summary>
/// Writes an embedded resource to a file.
/// </summary>
/// <param name="assembly">The name of the assembly that the embedded resource is defined.</param>
/// <param name="embeddedResourceName">The name of the embedded resource.</param>
/// <param name="fileName">The file to write the embedded resource's content.</param>
public static void WriteEmbeddedResourceToBinaryFile(Assembly assembly, string embeddedResourceName, string fileName)
{
// Get file contents
Stream stream = assembly.GetManifestResourceStream(embeddedResourceName);
if (stream == null)
throw new InvalidOperationException("Failed to get embedded resource '" + embeddedResourceName + "' from assembly '" + assembly.FullName);
// Write to file
BinaryWriter sw = null;
FileStream fs = null;
try
{
byte[] fileContentsAsBytes = new byte[stream.Length];
stream.Read(fileContentsAsBytes, 0, (int)stream.Length);
FileMode mode = FileMode.CreateNew;
if (File.Exists(fileName))
{
mode = FileMode.Truncate;
}
fs = new FileStream(fileName, mode);
sw = new BinaryWriter(fs);
sw.Write(fileContentsAsBytes);
}
finally
{
if (fs != null)
{
fs.Close();
}
if (sw != null)
{
sw.Close();
}
}
}
#endregion
#region Methods: Handling temporary files and directories
/// <summary>
/// Returns the first available file name on the form
/// [baseFileName]i.[extension]
/// where [i] starts at 1 and increases until there is an available file name
/// in the given directory. Also creates an empty file with that name to mark
/// that file as occupied.
/// </summary>
/// <param name="directory">Directory that the file should live in.</param>
/// <param name="baseFileName"></param>
/// <param name="extension">may be null, in which case the .[extension] part
/// is not added.</param>
/// <returns>Full file name.</returns>
public static string GetNewFileName(string directory, string baseFileName, string extension)
{
// Get the new file name
string fileName = GetNewFileOrDirectoryNameWithoutCreatingAnything(directory, baseFileName, extension);
// Create an empty file to mark it as taken
StreamWriter sw = new StreamWriter(fileName);
sw.Write("");
sw.Close();
return fileName;
}
/// <summary>
/// Returns the first available directory name on the form
/// [baseDirectoryName]i
/// where [i] starts at 1 and increases until there is an available directory name
/// in the given directory. Also creates the directory to mark it as occupied.
/// </summary>
/// <param name="directory">Directory that the file should live in.</param>
/// <param name="baseDirectoryName"></param>
/// <returns>Full directory name.</returns>
public static string GetNewDirectoryName(string directory, string baseDirectoryName)
{
// Get the new file name
string directoryName = GetNewFileOrDirectoryNameWithoutCreatingAnything(directory, baseDirectoryName, null);
// Create an empty directory to make it as occupied
Directory.CreateDirectory(directoryName);
return directoryName;
}
/// <summary>
///
/// </summary>
/// <param name="directory"></param>
/// <param name="baseFileName"></param>
/// <param name="extension"></param>
/// <returns></returns>
private static string GetNewFileOrDirectoryNameWithoutCreatingAnything(string directory, string baseFileName, string extension)
{
// - get a file name that we can use
string fileName;
int i = 1;
string fullFileName = null;
while (true)
{
// construct next file name
fileName = baseFileName + i;
if (extension != null)
fileName += '.' + extension;
// check if that file exists in the directory
fullFileName = Path.Combine(directory, fileName);
if (!File.Exists(fullFileName) && !Directory.Exists(fullFileName))
break;
else
i++;
}
return fullFileName;
}
#endregion
#region Methods: Handling solutions
/// <summary>
/// Closes the currently open solution (if any), and creates a new solution with the given name.
/// </summary>
/// <param name="solutionName">Name of new solution.</param>
public void CreateEmptySolution(string directory, string solutionName)
{
CloseCurrentSolution(__VSSLNSAVEOPTIONS.SLNSAVEOPT_NoSave);
string solutionDirectory = GetNewDirectoryName(directory, solutionName);
// Create and force save solution
IVsSolution solutionService = (IVsSolution)VsIdeTestHostContext.ServiceProvider.GetService(typeof(IVsSolution));
solutionService.CreateSolution(solutionDirectory, solutionName, (uint)__VSCREATESOLUTIONFLAGS.CSF_SILENT);
solutionService.SaveSolutionElement((uint)__VSSLNSAVEOPTIONS.SLNSAVEOPT_ForceSave, null, 0);
DTE dte = VsIdeTestHostContext.Dte;
Assert.AreEqual(solutionName + ".sln", Path.GetFileName(dte.Solution.FileName), "Newly created solution has wrong Filename");
}
public void CloseCurrentSolution(__VSSLNSAVEOPTIONS saveoptions)
{
// Get solution service
IVsSolution solutionService = (IVsSolution)VsIdeTestHostContext.ServiceProvider.GetService(typeof(IVsSolution));
// Close already open solution
solutionService.CloseSolutionElement((uint)saveoptions, null, 0);
}
public void ForceSaveSolution()
{
// Get solution service
IVsSolution solutionService = (IVsSolution)VsIdeTestHostContext.ServiceProvider.GetService(typeof(IVsSolution));
// Force-save the solution
solutionService.SaveSolutionElement((uint)__VSSLNSAVEOPTIONS.SLNSAVEOPT_ForceSave, null, 0);
}
/// <summary>
/// Get current number of open project in solution
/// </summary>
/// <returns></returns>
public int ProjectCount()
{
// Get solution service
IVsSolution solutionService = (IVsSolution)VsIdeTestHostContext.ServiceProvider.GetService(typeof(IVsSolution));
object projectCount;
solutionService.GetProperty((int)__VSPROPID.VSPROPID_ProjectCount, out projectCount);
return (int)projectCount;
}
#endregion
#region Methods: Handling projects
/// <summary>
/// Creates a project.
/// </summary>
/// <param name="projectName">Name of new project.</param>
/// <param name="templateName">Name of project template to use</param>
/// <param name="language">language</param>
/// <returns>New project.</returns>
public void CreateProjectFromTemplate(string projectName, string templateName, string language, bool exclusive)
{
DTE dte = (DTE)VsIdeTestHostContext.ServiceProvider.GetService(typeof(DTE));
Solution2 sol = dte.Solution as Solution2;
string projectTemplate = sol.GetProjectTemplate(templateName, language);
// - project name and directory
string solutionDirectory = Directory.GetParent(dte.Solution.FullName).FullName;
string projectDirectory = GetNewDirectoryName(solutionDirectory, projectName);
dte.Solution.AddFromTemplate(projectTemplate, projectDirectory, projectName, false);
}
#endregion
#region Methods: Handling project items
/// <summary>
/// Create a new item in the project
/// </summary>
/// <param name="parent">the parent collection for the new item</param>
/// <param name="templateName"></param>
/// <param name="language"></param>
/// <param name="name"></param>
/// <returns></returns>
public ProjectItem AddNewItemFromVsTemplate(ProjectItems parent, string templateName, string language, string name)
{
if (parent == null)
throw new ArgumentException("project");
if (name == null)
throw new ArgumentException("name");
DTE dte = (DTE)VsIdeTestHostContext.ServiceProvider.GetService(typeof(DTE));
Solution2 sol = dte.Solution as Solution2;
string filename = sol.GetProjectItemTemplate(templateName, language);
parent.AddFromTemplate(filename, name);
return parent.Item(name);
}
/// <summary>
/// Save an open document.
/// </summary>
/// <param name="documentMoniker">for filebased documents this is the full path to the document</param>
public void SaveDocument(string documentMoniker)
{
// Get document cookie and hierarchy for the file
IVsRunningDocumentTable runningDocumentTableService = (IVsRunningDocumentTable)VsIdeTestHostContext.ServiceProvider.GetService(typeof(IVsRunningDocumentTable));
uint docCookie;
IntPtr docData;
IVsHierarchy hierarchy;
uint itemId;
runningDocumentTableService.FindAndLockDocument(
(uint)Microsoft.VisualStudio.Shell.Interop._VSRDTFLAGS.RDT_NoLock,
documentMoniker,
out hierarchy,
out itemId,
out docData,
out docCookie);
// Save the document
IVsSolution solutionService = (IVsSolution)VsIdeTestHostContext.ServiceProvider.GetService(typeof(IVsSolution));
solutionService.SaveSolutionElement((uint)__VSSLNSAVEOPTIONS.SLNSAVEOPT_ForceSave, hierarchy, docCookie);
}
public void CloseInEditorWithoutSaving(string fullFileName)
{
// Get the RDT service
IVsRunningDocumentTable runningDocumentTableService = (IVsRunningDocumentTable)VsIdeTestHostContext.ServiceProvider.GetService(typeof(IVsRunningDocumentTable));
Assert.IsNotNull(runningDocumentTableService, "Failed to get the Running Document Table Service");
// Get our document cookie and hierarchy for the file
uint docCookie;
IntPtr docData;
IVsHierarchy hierarchy;
uint itemId;
runningDocumentTableService.FindAndLockDocument(
(uint)Microsoft.VisualStudio.Shell.Interop._VSRDTFLAGS.RDT_NoLock,
fullFileName,
out hierarchy,
out itemId,
out docData,
out docCookie);
// Get the SolutionService
IVsSolution solutionService = VsIdeTestHostContext.ServiceProvider.GetService(typeof(IVsSolution)) as IVsSolution;
Assert.IsNotNull(solutionService, "Failed to get IVsSolution service");
// Close the document
solutionService.CloseSolutionElement(
(uint)__VSSLNSAVEOPTIONS.SLNSAVEOPT_NoSave,
hierarchy,
docCookie);
}
#endregion
#region Methods: Handling Toolwindows
public bool CanFindToolwindow(Guid persistenceGuid)
{
IVsUIShell uiShellService = VsIdeTestHostContext.ServiceProvider.GetService(typeof(SVsUIShell)) as IVsUIShell;
Assert.IsNotNull(uiShellService);
IVsWindowFrame windowFrame;
int hr = uiShellService.FindToolWindow((uint)__VSFINDTOOLWIN.FTW_fFindFirst, ref persistenceGuid, out windowFrame);
Assert.IsTrue(hr == VSConstants.S_OK);
return (windowFrame != null);
}
#endregion
#region Methods: Loading packages
public IVsPackage LoadPackage(Guid packageGuid)
{
IVsShell shellService = (IVsShell)VsIdeTestHostContext.ServiceProvider.GetService(typeof(SVsShell));
IVsPackage package;
shellService.LoadPackage(ref packageGuid, out package);
Assert.IsNotNull(package, "Failed to load package");
return package;
}
#endregion
/// <summary>
/// Executes a Command (menu item) in the given context
/// </summary>
public void ExecuteCommand(CommandID cmd)
{
object Customin = null;
object Customout = null;
string guidString = cmd.Guid.ToString("B").ToUpper();
int cmdId = cmd.ID;
DTE dte = VsIdeTestHostContext.Dte;
dte.Commands.Raise(guidString, cmdId, ref Customin, ref Customout);
}
}
}

View File

@ -0,0 +1,66 @@
using System;
using System.Globalization;
using System.ComponentModel.Design;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.VisualStudio.OLE.Interop;
using Microsoft.VisualStudio.Shell.Interop;
using Microsoft.VisualStudio.Shell;
using Microsoft.VsSDK.IntegrationTestLibrary;
using Microsoft.VSSDK.Tools.VsIdeTesting;
namespace VSPackageInstall_IntegrationTests
{
[TestClass()]
public class MenuItemTest
{
private delegate void ThreadInvoker();
private TestContext testContextInstance;
/// <summary>
///Gets or sets the test context which provides
///information about and functionality for the current test run.
///</summary>
public TestContext TestContext
{
get
{
return testContextInstance;
}
set
{
testContextInstance = value;
}
}
/// <summary>
///A test for lauching the command and closing the associated dialogbox
///</summary>
[TestMethod()]
[HostType("VS IDE")]
public void LaunchCommand()
{
UIThreadInvoker.Invoke((ThreadInvoker)delegate()
{
CommandID menuItemCmd = new CommandID(VitaliiGanzha.VSPackageInstall.GuidList.guidVSPackageInstallCmdSet, (int)VitaliiGanzha.VSPackageInstall.PkgCmdIDList.cmdidVsDing);
// Create the DialogBoxListener Thread.
string expectedDialogBoxText = string.Format(CultureInfo.CurrentCulture, "{0}\n\nInside {1}.MenuItemCallback()", "VSPackageInstall", "VitaliiGanzha.VSPackageInstall.VSPackageInstallPackage");
DialogBoxPurger purger = new DialogBoxPurger(NativeMethods.IDOK, expectedDialogBoxText);
try
{
purger.Start();
TestUtils testUtils = new TestUtils();
testUtils.ExecuteCommand(menuItemCmd);
}
finally
{
Assert.IsTrue(purger.WaitForDialogThreadToTerminate(), "The dialog box has not shown");
}
});
}
}
}

View File

@ -0,0 +1,59 @@
using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.VSSDK.Tools.VsIdeTesting;
using Microsoft.VisualStudio.Shell.Interop;
using Microsoft.VisualStudio.Shell;
using EnvDTE;
namespace VSPackageInstall_IntegrationTests
{
/// <summary>
/// Integration test for package validation
/// </summary>
[TestClass]
public class PackageTest
{
private delegate void ThreadInvoker();
private TestContext testContextInstance;
/// <summary>
///Gets or sets the test context which provides
///information about and functionality for the current test run.
///</summary>
public TestContext TestContext
{
get
{
return testContextInstance;
}
set
{
testContextInstance = value;
}
}
[TestMethod]
[HostType("VS IDE")]
public void PackageLoadTest()
{
UIThreadInvoker.Invoke((ThreadInvoker)delegate()
{
//Get the Shell Service
IVsShell shellService = VsIdeTestHostContext.ServiceProvider.GetService(typeof(SVsShell)) as IVsShell;
Assert.IsNotNull(shellService);
//Validate package load
IVsPackage package;
Guid packageGuid = new Guid(VitaliiGanzha.VSPackageInstall.GuidList.guidVSPackageInstallPkgString);
Assert.IsTrue(0 == shellService.LoadPackage(ref packageGuid, out package));
Assert.IsNotNull(package, "Package failed to load");
});
}
}
}

View File

@ -0,0 +1,109 @@
using System;
using System.Text;
using System.Collections.Generic;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.VsSDK.IntegrationTestLibrary;
using Microsoft.VSSDK.Tools.VsIdeTesting;
using EnvDTE;
using System.IO;
namespace VSPackageInstall_IntegrationTests.IntegrationTests
{
[TestClass]
public class CPPProjectTests
{
#region fields
private delegate void ThreadInvoker();
private TestContext _testContext;
#endregion
#region properties
/// <summary>
///Gets or sets the test context which provides
///information about and functionality for the current test run.
///</summary>
public TestContext TestContext
{
get { return _testContext; }
set { _testContext = value; }
}
#endregion
#region ctors
public CPPProjectTests()
{
}
#endregion
#region Additional test attributes
//
// You can use the following additional attributes as you write your tests:
//
// Use ClassInitialize to run code before running the first test in the class
// [ClassInitialize()]
// public static void MyClassInitialize(TestContext testContext) { }
//
// Use ClassCleanup to run code after all tests in a class have run
// [ClassCleanup()]
// public static void MyClassCleanup() { }
//
// Use TestInitialize to run code before running each test
// [TestInitialize()]
// public void MyTestInitialize() { }
//
// Use TestCleanup to run code after each test has run
// [TestCleanup()]
// public void MyTestCleanup() { }
//
#endregion
[HostType("VS IDE")]
[TestMethod]
public void CPPWinformsApplication()
{
UIThreadInvoker.Invoke((ThreadInvoker)delegate()
{
//Solution and project creation parameters
string solutionName = "CPPWinApp";
string projectName = "CPPWinApp";
//Template parameters
string projectType = "{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}";
string projectTemplateName = Path.Combine("vcNet", "mc++appwiz.vsz");
string itemTemplateName = "newc++file.cpp";
string newFileName = "Test.cpp";
DTE dte = (DTE)VsIdeTestHostContext.ServiceProvider.GetService(typeof(DTE));
TestUtils testUtils = new TestUtils();
testUtils.CreateEmptySolution(TestContext.TestDir, solutionName);
Assert.AreEqual<int>(0, testUtils.ProjectCount());
//Add new CPP Windows application project to existing solution
string solutionDirectory = Directory.GetParent(dte.Solution.FullName).FullName;
string projectDirectory = TestUtils.GetNewDirectoryName(solutionDirectory, projectName);
string projectTemplatePath = Path.Combine(dte.Solution.get_TemplatePath(projectType), projectTemplateName);
Assert.IsTrue(File.Exists(projectTemplatePath), string.Format("Could not find template file: {0}", projectTemplatePath));
dte.Solution.AddFromTemplate(projectTemplatePath, projectDirectory, projectName, false);
//Verify that the new project has been added to the solution
Assert.AreEqual<int>(1, testUtils.ProjectCount());
//Get the project
Project project = dte.Solution.Item(1);
Assert.IsNotNull(project);
Assert.IsTrue(string.Compare(project.Name, projectName, StringComparison.InvariantCultureIgnoreCase) == 0);
//Verify Adding new code file to project
string newItemTemplatePath = Path.Combine(dte.Solution.ProjectItemsTemplatePath(projectType), itemTemplateName);
Assert.IsTrue(File.Exists(newItemTemplatePath));
ProjectItem item = project.ProjectItems.AddFromTemplate(newItemTemplatePath, newFileName);
Assert.IsNotNull(item);
});
}
}
}

View File

@ -0,0 +1,83 @@
using System;
using System.Text;
using System.Collections.Generic;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.VsSDK.IntegrationTestLibrary;
using Microsoft.VSSDK.Tools.VsIdeTesting;
namespace VSPackageInstall_IntegrationTests.IntegrationTests
{
[TestClass]
public class CSharpProjectTests
{
#region fields
private delegate void ThreadInvoker();
private TestContext _testContext;
#endregion
#region properties
/// <summary>
///Gets or sets the test context which provides
///information about and functionality for the current test run.
///</summary>
public TestContext TestContext
{
get { return _testContext; }
set { _testContext = value; }
}
#endregion
#region ctors
public CSharpProjectTests()
{
}
#endregion
#region Additional test attributes
//
// You can use the following additional attributes as you write your tests:
//
// Use ClassInitialize to run code before running the first test in the class
// [ClassInitialize()]
// public static void MyClassInitialize(TestContext testContext) { }
//
// Use ClassCleanup to run code after all tests in a class have run
// [ClassCleanup()]
// public static void MyClassCleanup() { }
//
// Use TestInitialize to run code before running each test
// [TestInitialize()]
// public void MyTestInitialize() { }
//
// Use TestCleanup to run code after each test has run
// [TestCleanup()]
// public void MyTestCleanup() { }
//
#endregion
[TestMethod]
[HostType("VS IDE")]
public void WinformsApplication()
{
UIThreadInvoker.Invoke((ThreadInvoker)delegate()
{
TestUtils testUtils = new TestUtils();
testUtils.CreateEmptySolution(TestContext.TestDir, "CSWinApp");
Assert.AreEqual<int>(0, testUtils.ProjectCount());
//Create Winforms application project
//TestUtils.CreateProjectFromTemplate("MyWindowsApp", "Windows Application", "CSharp", false);
//Assert.AreEqual<int>(1, TestUtils.ProjectCount());
//TODO Verify that we can debug launch the application
//TODO Set Break point and verify that will hit
//TODO Verify Adding new project item to project
});
}
}
}

View File

@ -0,0 +1,55 @@
using System;
using System.Text;
using System.Collections.Generic;
using Microsoft.VisualStudio.Shell.Interop;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.VSSDK.Tools.VsIdeTesting;
using EnvDTE;
using System.IO;
using Microsoft.VsSDK.IntegrationTestLibrary;
namespace VSPackageInstall_IntegrationTests.IntegrationTests
{
[TestClass]
public class SolutionTests
{
#region fields
private delegate void ThreadInvoker();
private TestContext _testContext;
#endregion
#region properties
/// <summary>
///Gets or sets the test context which provides
///information about and functionality for the current test run.
///</summary>
public TestContext TestContext
{
get { return _testContext; }
set { _testContext = value; }
}
#endregion
#region ctors
public SolutionTests()
{
}
#endregion
[TestMethod]
[HostType("VS IDE")]
public void CreateEmptySolution()
{
UIThreadInvoker.Invoke((ThreadInvoker)delegate()
{
TestUtils testUtils = new TestUtils();
testUtils.CloseCurrentSolution(__VSSLNSAVEOPTIONS.SLNSAVEOPT_NoSave);
testUtils.CreateEmptySolution(TestContext.TestDir, "EmptySolution");
});
}
}
}

View File

@ -0,0 +1,101 @@
using System;
using System.Text;
using System.Collections.Generic;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.VsSDK.IntegrationTestLibrary;
using Microsoft.VSSDK.Tools.VsIdeTesting;
using EnvDTE;
namespace VSPackageInstall_IntegrationTests.IntegrationTests
{
[TestClass]
public class VisualBasicProjectTests
{
#region fields
private delegate void ThreadInvoker();
private TestContext _testContext;
#endregion
#region properties
/// <summary>
///Gets or sets the test context which provides
///information about and functionality for the current test run.
///</summary>
public TestContext TestContext
{
get { return _testContext; }
set { _testContext = value; }
}
#endregion
#region ctors
public VisualBasicProjectTests()
{
}
#endregion
#region Additional test attributes
//
// You can use the following additional attributes as you write your tests:
//
// Use ClassInitialize to run code before running the first test in the class
// [ClassInitialize()]
// public static void MyClassInitialize(TestContext testContext) { }
//
// Use ClassCleanup to run code after all tests in a class have run
// [ClassCleanup()]
// public static void MyClassCleanup() { }
//
// Use TestInitialize to run code before running each test
// [TestInitialize()]
// public void MyTestInitialize() { }
//
// Use TestCleanup to run code after each test has run
// [TestCleanup()]
// public void MyTestCleanup() { }
//
#endregion
[HostType("VS IDE")]
[TestMethod]
public void VBWinformsApplication()
{
UIThreadInvoker.Invoke((ThreadInvoker)delegate()
{
//Solution and project creation parameters
string solutionName = "VBWinApp";
string projectName = "VBWinApp";
//Template parameters
string language = "VisualBasic";
string projectTemplateName = "WindowsApplication.Zip";
string itemTemplateName = "CodeFile.zip";
string newFileName = "Test.vb";
DTE dte = (DTE)VsIdeTestHostContext.ServiceProvider.GetService(typeof(DTE));
TestUtils testUtils = new TestUtils();
testUtils.CreateEmptySolution(TestContext.TestDir, solutionName);
Assert.AreEqual<int>(0, testUtils.ProjectCount());
//Add new Windows application project to existing solution
testUtils.CreateProjectFromTemplate(projectName, projectTemplateName, language, false);
//Verify that the new project has been added to the solution
Assert.AreEqual<int>(1, testUtils.ProjectCount());
//Get the project
Project project = dte.Solution.Item(1);
Assert.IsNotNull(project);
Assert.IsTrue(string.Compare(project.Name, projectName, StringComparison.InvariantCultureIgnoreCase) == 0);
//Verify Adding new code file to project
ProjectItem newCodeFileItem = testUtils.AddNewItemFromVsTemplate(project.ProjectItems, itemTemplateName, language, newFileName);
Assert.IsNotNull(newCodeFileItem, "Could not create new project item");
});
}
}
}

View File

@ -0,0 +1,56 @@
using System;
using System.ComponentModel.Design;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.VisualStudio.OLE.Interop;
using Microsoft.VisualStudio.Shell.Interop;
using Microsoft.VisualStudio.Shell;
using Microsoft.VsSDK.IntegrationTestLibrary;
using Microsoft.VSSDK.Tools.VsIdeTesting;
namespace VSPackageInstall_IntegrationTests
{
[TestClass()]
public class ToolWindowTest
{
private delegate void ThreadInvoker();
private TestContext testContextInstance;
/// <summary>
///Gets or sets the test context which provides
///information about and functionality for the current test run.
///</summary>
public TestContext TestContext
{
get
{
return testContextInstance;
}
set
{
testContextInstance = value;
}
}
/// <summary>
///A test for showing the toolwindow
///</summary>
[TestMethod()]
[HostType("VS IDE")]
public void ShowToolWindow()
{
UIThreadInvoker.Invoke((ThreadInvoker)delegate()
{
CommandID toolWindowCmd = new CommandID(VitaliiGanzha.VSPackageInstall.GuidList.guidVSPackageInstallCmdSet, (int)VitaliiGanzha.VSPackageInstall.PkgCmdIDList.cmdidVsDingWnd);
TestUtils testUtils = new TestUtils();
testUtils.ExecuteCommand(toolWindowCmd);
Assert.IsTrue(testUtils.CanFindToolwindow(new Guid(VitaliiGanzha.VSPackageInstall.GuidList.guidToolWindowPersistanceString)));
});
}
}
}

View File

@ -0,0 +1,91 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{77A542CC-52C0-4387-B57B-63AF5F597EA1}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>VSPackageInstall_IntegrationTests</RootNamespace>
<AssemblyName>VSPackageInstall_IntegrationTests</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<ProjectTypeGuids>{3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup>
<AssemblyOriginatorKeyFile>Key.snk</AssemblyOriginatorKeyFile>
</PropertyGroup>
<PropertyGroup>
<SignAssembly>true</SignAssembly>
</PropertyGroup>
<ItemGroup>
<Reference Include="envdte" />
<Reference Include="envdte80" />
<Reference Include="Microsoft.VisualStudio.OLE.Interop" />
<Reference Include="Microsoft.VisualStudio.Shell.Interop" />
<Reference Include="Microsoft.VisualStudio.Shell.Interop.8.0" />
<Reference Include="Microsoft.VisualStudio.Shell.Interop.9.0" />
<Reference Include="Microsoft.VisualStudio.Shell.Interop.10.0" />
<Reference Include="Microsoft.VisualStudio.Shell.Interop.11.0">
<EmbedInteropTypes>true</EmbedInteropTypes>
</Reference>
<Reference Include="Microsoft.VisualStudio.Shell.12.0" />
<Reference Include="Microsoft.VisualStudio.QualityTools.UnitTestFramework" />
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="Microsoft.VSSDK.TestHostFramework" />
</ItemGroup>
<ItemGroup>
<!--<Compile Include="Properties\AssemblyInfo.cs" />-->
<!---->
<Compile Include="MenuItemTest.cs" />
<!---->
<!---->
<Compile Include="ToolWindowTest.cs" />
<!---->
<!---->
<Compile Include="PackageTest.cs" />
<Compile Include="IntegrationTest Library\DialogboxPurger.cs" />
<Compile Include="IntegrationTest Library\NativeMethods.cs" />
<Compile Include="IntegrationTest Library\Utils.cs" />
<Compile Include="SignOff-Tests\CPPProjectTests.cs" />
<Compile Include="SignOff-Tests\CSharpProjectTests.cs" />
<Compile Include="SignOff-Tests\SolutionTests.cs" />
<Compile Include="SignOff-Tests\VBProjectTests.cs" />
</ItemGroup>
<ItemGroup>
<None Include="Key.snk" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\VSPackageInstall.csproj">
<Project>{20191D13-7CC1-4F9B-9CB8-42F22ACE4CA6}</Project>
<Name>VSPackageInstall</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

Binary file not shown.

View File

@ -0,0 +1,80 @@
/***************************************************************************
Copyright (c) Microsoft Corporation. All rights reserved.
This code is licensed under the Visual Studio SDK license terms.
THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
***************************************************************************/
using System;
using System.Collections;
using System.Text;
using System.Reflection;
using System.ComponentModel.Design;
using Microsoft.VsSDK.UnitTestLibrary;
using Microsoft.VisualStudio.Shell.Interop;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.VisualStudio.Shell;
using VitaliiGanzha.VSPackageInstall;
namespace VSPackageInstall_UnitTests.MenuItemTests
{
[TestClass()]
public class MenuItemTest
{
/// <summary>
/// Verify that a new menu command object gets added to the OleMenuCommandService.
/// This action takes place In the Initialize method of the Package object
/// </summary>
[TestMethod]
public void InitializeMenuCommand()
{
// Create the package
IVsPackage package = new VSPackageInstallPackage() as IVsPackage;
Assert.IsNotNull(package, "The object does not implement IVsPackage");
// Create a basic service provider
OleServiceProvider serviceProvider = OleServiceProvider.CreateOleServiceProviderWithBasicServices();
// Site the package
Assert.AreEqual(0, package.SetSite(serviceProvider), "SetSite did not return S_OK");
//Verify that the menu command can be found
CommandID menuCommandID = new CommandID(VitaliiGanzha.VSPackageInstall.GuidList.guidVSPackageInstallCmdSet, (int)VitaliiGanzha.VSPackageInstall.PkgCmdIDList.cmdidVsDing);
System.Reflection.MethodInfo info = typeof(Package).GetMethod("GetService", BindingFlags.Instance | BindingFlags.NonPublic);
Assert.IsNotNull(info);
OleMenuCommandService mcs = info.Invoke(package, new object[] { (typeof(IMenuCommandService)) }) as OleMenuCommandService;
Assert.IsNotNull(mcs.FindCommand(menuCommandID));
}
[TestMethod]
public void MenuItemCallback()
{
// Create the package
IVsPackage package = new VSPackageInstallPackage() as IVsPackage;
Assert.IsNotNull(package, "The object does not implement IVsPackage");
// Create a basic service provider
OleServiceProvider serviceProvider = OleServiceProvider.CreateOleServiceProviderWithBasicServices();
// Create a UIShell service mock and proffer the service so that it can called from the MenuItemCallback method
BaseMock uishellMock = UIShellServiceMock.GetUiShellInstance();
serviceProvider.AddService(typeof(SVsUIShell), uishellMock, true);
// Site the package
Assert.AreEqual(0, package.SetSite(serviceProvider), "SetSite did not return S_OK");
//Invoke private method on package class and observe that the method does not throw
System.Reflection.MethodInfo info = package.GetType().GetMethod("MenuItemCallback", BindingFlags.Instance | BindingFlags.NonPublic);
Assert.IsNotNull(info, "Failed to get the private method MenuItemCallback throug refplection");
info.Invoke(package, new object[] { null, null });
//Clean up services
serviceProvider.RemoveService(typeof(SVsUIShell));
}
}
}

View File

@ -0,0 +1,76 @@
/***************************************************************************
Copyright (c) Microsoft Corporation. All rights reserved.
This code is licensed under the Visual Studio SDK license terms.
THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
***************************************************************************/
using System;
using Microsoft.VisualStudio;
using Microsoft.VisualStudio.Shell.Interop;
using Microsoft.VsSDK.UnitTestLibrary;
namespace VSPackageInstall_UnitTests
{
static class UIShellServiceMock
{
private static GenericMockFactory uiShellFactory;
#region UiShell Getters
/// <summary>
/// Returns an IVsUiShell that does not implement any methods
/// </summary>
/// <returns></returns>
internal static BaseMock GetUiShellInstance()
{
if (uiShellFactory == null)
{
uiShellFactory = new GenericMockFactory("UiShell", new Type[] { typeof(IVsUIShell), typeof(IVsUIShellOpenDocument) });
}
BaseMock uiShell = uiShellFactory.GetInstance();
return uiShell;
}
/// <summary>
/// Get an IVsUiShell that implements SetWaitCursor, SaveDocDataToFile, ShowMessageBox
/// </summary>
/// <returns>uishell mock</returns>
internal static BaseMock GetUiShellInstance0()
{
BaseMock uiShell = GetUiShellInstance();
string name = string.Format("{0}.{1}", typeof(IVsUIShell).FullName, "SetWaitCursor");
uiShell.AddMethodCallback(name, new EventHandler<CallbackArgs>(SetWaitCursorCallBack));
name = string.Format("{0}.{1}", typeof(IVsUIShell).FullName, "SaveDocDataToFile");
uiShell.AddMethodCallback(name, new EventHandler<CallbackArgs>(SaveDocDataToFileCallBack));
name = string.Format("{0}.{1}", typeof(IVsUIShell).FullName, "ShowMessageBox");
uiShell.AddMethodCallback(name, new EventHandler<CallbackArgs>(ShowMessageBoxCallBack));
return uiShell;
}
#endregion
#region Callbacks
private static void SetWaitCursorCallBack(object caller, CallbackArgs arguments)
{
arguments.ReturnValue = VSConstants.S_OK;
}
private static void SaveDocDataToFileCallBack(object caller, CallbackArgs arguments)
{
arguments.ReturnValue = VSConstants.S_OK;
}
private static void ShowMessageBoxCallBack(object caller, CallbackArgs arguments)
{
arguments.ReturnValue = VSConstants.S_OK;
arguments.SetParameter(10, (int)System.Windows.Forms.DialogResult.Yes);
}
#endregion
}
}

View File

@ -0,0 +1,58 @@
/***************************************************************************
Copyright (c) Microsoft Corporation. All rights reserved.
This code is licensed under the Visual Studio SDK license terms.
THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
***************************************************************************/
using System;
using System.Collections;
using System.Text;
using System.Reflection;
using Microsoft.VsSDK.UnitTestLibrary;
using Microsoft.VisualStudio.Shell.Interop;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.VSSDK.Tools.VsIdeTesting;
using VitaliiGanzha.VSPackageInstall;
namespace VSPackageInstall_UnitTests.MyToolWindowTest
{
/// <summary>
///This is a test class for MyToolWindowTest and is intended
///to contain all MyToolWindowTest Unit Tests
///</summary>
[TestClass()]
public class MyToolWindowTest
{
/// <summary>
///MyToolWindow Constructor test
///</summary>
[TestMethod()]
public void MyToolWindowConstructorTest()
{
MyToolWindow target = new MyToolWindow();
Assert.IsNotNull(target, "Failed to create an instance of MyToolWindow");
MethodInfo method = target.GetType().GetMethod("get_Content", BindingFlags.Public | BindingFlags.Instance);
Assert.IsNotNull(method.Invoke(target, null), "MyControl object was not instantiated");
}
/// <summary>
///Verify the Content property is valid.
///</summary>
[TestMethod()]
public void WindowPropertyTest()
{
MyToolWindow target = new MyToolWindow();
Assert.IsNotNull(target.Content, "Content property was null");
}
}
}

View File

@ -0,0 +1,77 @@
/***************************************************************************
Copyright (c) Microsoft Corporation. All rights reserved.
This code is licensed under the Visual Studio SDK license terms.
THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
***************************************************************************/
using System;
using System.Collections;
using System.Text;
using System.Reflection;
using Microsoft.VsSDK.UnitTestLibrary;
using Microsoft.VisualStudio.Shell.Interop;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.VSSDK.Tools.VsIdeTesting;
using VitaliiGanzha.VSPackageInstall;
namespace VSPackageInstall_UnitTests.MyToolWindowTest
{
[TestClass()]
public class ShowToolWindowTest
{
[TestMethod()]
public void ValidateToolWindowShown()
{
IVsPackage package = new VSPackageInstallPackage() as IVsPackage;
// Create a basic service provider
OleServiceProvider serviceProvider = OleServiceProvider.CreateOleServiceProviderWithBasicServices();
//Add uishell service that knows how to create a toolwindow
BaseMock uiShellService = UIShellServiceMock.GetUiShellInstanceCreateToolWin();
serviceProvider.AddService(typeof(SVsUIShell), uiShellService, false);
// Site the package
Assert.AreEqual(0, package.SetSite(serviceProvider), "SetSite did not return S_OK");
MethodInfo method = typeof(VSPackageInstallPackage).GetMethod("ShowToolWindow", BindingFlags.NonPublic | BindingFlags.Instance);
object result = method.Invoke(package, new object[] { null, null });
}
[TestMethod()]
[ExpectedException(typeof(InvalidOperationException), "Did not throw expected exception when windowframe object was null")]
public void ShowToolwindowNegativeTest()
{
IVsPackage package = new VSPackageInstallPackage() as IVsPackage;
// Create a basic service provider
OleServiceProvider serviceProvider = OleServiceProvider.CreateOleServiceProviderWithBasicServices();
//Add uishell service that knows how to create a toolwindow
BaseMock uiShellService = UIShellServiceMock.GetUiShellInstanceCreateToolWinReturnsNull();
serviceProvider.AddService(typeof(SVsUIShell), uiShellService, false);
// Site the package
Assert.AreEqual(0, package.SetSite(serviceProvider), "SetSite did not return S_OK");
MethodInfo method = typeof(VSPackageInstallPackage).GetMethod("ShowToolWindow", BindingFlags.NonPublic | BindingFlags.Instance);
//Invoke thows TargetInvocationException, but we want it's inner Exception thrown by ShowToolWindow, InvalidOperationException.
try
{
object result = method.Invoke(package, new object[] { null, null });
}
catch (Exception e)
{
throw e.InnerException;
}
}
}
}

View File

@ -0,0 +1,84 @@
/***************************************************************************
Copyright (c) Microsoft Corporation. All rights reserved.
This code is licensed under the Visual Studio SDK license terms.
THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
***************************************************************************/
using System;
using Microsoft.VisualStudio;
using Microsoft.VisualStudio.Shell.Interop;
using Microsoft.VsSDK.UnitTestLibrary;
namespace VSPackageInstall_UnitTests.MyToolWindowTest
{
static class UIShellServiceMock
{
private static GenericMockFactory uiShellFactory;
#region UiShell Getters
/// <summary>
/// Returns an IVsUiShell that does not implement any methods
/// </summary>
/// <returns></returns>
internal static BaseMock GetUiShellInstance()
{
if (uiShellFactory == null)
{
uiShellFactory = new GenericMockFactory("UiShell", new Type[] { typeof(IVsUIShell), typeof(IVsUIShellOpenDocument) });
}
BaseMock uiShell = uiShellFactory.GetInstance();
return uiShell;
}
/// <summary>
/// Get an IVsUiShell that implement CreateToolWindow
/// </summary>
/// <returns>uishell mock</returns>
internal static BaseMock GetUiShellInstanceCreateToolWin()
{
BaseMock uiShell = GetUiShellInstance();
string name = string.Format("{0}.{1}", typeof(IVsUIShell).FullName, "CreateToolWindow");
uiShell.AddMethodCallback(name, new EventHandler<CallbackArgs>(CreateToolWindowCallBack));
return uiShell;
}
/// <summary>
/// Get an IVsUiShell that implement CreateToolWindow (negative test)
/// </summary>
/// <returns>uishell mock</returns>
internal static BaseMock GetUiShellInstanceCreateToolWinReturnsNull()
{
BaseMock uiShell = GetUiShellInstance();
string name = string.Format("{0}.{1}", typeof(IVsUIShell).FullName, "CreateToolWindow");
uiShell.AddMethodCallback(name, new EventHandler<CallbackArgs>(CreateToolWindowNegativeTestCallBack));
return uiShell;
}
#endregion
#region Callbacks
private static void CreateToolWindowCallBack(object caller, CallbackArgs arguments)
{
arguments.ReturnValue = VSConstants.S_OK;
// Create the output mock object for the frame
IVsWindowFrame frame = WindowFrameMock.GetBaseFrame();
arguments.SetParameter(9, frame);
}
private static void CreateToolWindowNegativeTestCallBack(object caller, CallbackArgs arguments)
{
arguments.ReturnValue = VSConstants.S_OK;
//set the windowframe object to null
arguments.SetParameter(9, null);
}
#endregion
}
}

View File

@ -0,0 +1,39 @@
/***************************************************************************
Copyright (c) Microsoft Corporation. All rights reserved.
This code is licensed under the Visual Studio SDK license terms.
THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
***************************************************************************/
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.VsSDK.UnitTestLibrary;
using Microsoft.VisualStudio;
using Microsoft.VisualStudio.Shell.Interop;
namespace VSPackageInstall_UnitTests.MyToolWindowTest
{
class WindowFrameMock
{
const string propertiesName = "properties";
private static GenericMockFactory frameFactory = null;
/// <summary>
/// Return a IVsWindowFrame without any special implementation
/// </summary>
/// <returns></returns>
internal static IVsWindowFrame GetBaseFrame()
{
if (frameFactory == null)
frameFactory = new GenericMockFactory("WindowFrame", new Type[] { typeof(IVsWindowFrame), typeof(IVsWindowFrame2) });
IVsWindowFrame frame = (IVsWindowFrame)frameFactory.GetInstance();
return frame;
}
}
}

View File

@ -0,0 +1,56 @@
/***************************************************************************
Copyright (c) Microsoft Corporation. All rights reserved.
This code is licensed under the Visual Studio SDK license terms.
THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
***************************************************************************/
using System;
using System.Collections;
using System.Text;
using System.Reflection;
using Microsoft.VsSDK.UnitTestLibrary;
using Microsoft.VisualStudio.Shell.Interop;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using VitaliiGanzha.VSPackageInstall;
namespace VSPackageInstall_UnitTests
{
[TestClass()]
public class PackageTest
{
[TestMethod()]
public void CreateInstance()
{
VSPackageInstallPackage package = new VSPackageInstallPackage();
}
[TestMethod()]
public void IsIVsPackage()
{
VSPackageInstallPackage package = new VSPackageInstallPackage();
Assert.IsNotNull(package as IVsPackage, "The object does not implement IVsPackage");
}
[TestMethod()]
public void SetSite()
{
// Create the package
IVsPackage package = new VSPackageInstallPackage() as IVsPackage;
Assert.IsNotNull(package, "The object does not implement IVsPackage");
// Create a basic service provider
OleServiceProvider serviceProvider = OleServiceProvider.CreateOleServiceProviderWithBasicServices();
// Site the package
Assert.AreEqual(0, package.SetSite(serviceProvider), "SetSite did not return S_OK");
// Unsite the package
Assert.AreEqual(0, package.SetSite(null), "SetSite(null) did not return S_OK");
}
}
}

View File

@ -0,0 +1,84 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="12.0">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{E620FC0C-6208-4216-9899-47DF43578E4C}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>VSPackageInstall_UnitTests</RootNamespace>
<AssemblyName>VSPackageInstall_UnitTests</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<ProjectTypeGuids>{3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath Condition="'$(OutputPath)'==''">bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath Condition="'$(OutputPath)'==''">bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup>
<AssemblyOriginatorKeyFile>Key.snk</AssemblyOriginatorKeyFile>
</PropertyGroup>
<PropertyGroup>
<SignAssembly>true</SignAssembly>
</PropertyGroup>
<ItemGroup>
<Reference Include="Microsoft.VisualStudio.OLE.Interop" />
<Reference Include="Microsoft.VisualStudio.Shell.Interop" />
<Reference Include="Microsoft.VisualStudio.Shell.Interop.8.0" />
<Reference Include="Microsoft.VisualStudio.Shell.Interop.9.0" />
<Reference Include="Microsoft.VisualStudio.Shell.Interop.10.0" />
<Reference Include="Microsoft.VisualStudio.Shell.Interop.11.0">
<EmbedInteropTypes>true</EmbedInteropTypes>
</Reference>
<Reference Include="Microsoft.VisualStudio.Shell.12.0" />
<Reference Include="Microsoft.VisualStudio.Shell.Immutable.10.0" />
<Reference Include="Microsoft.VisualStudio.Shell.Immutable.11.0" />
<!---->
<Reference Include="Microsoft.VisualStudio.QualityTools.UnitTestFramework" />
<Reference Include="Microsoft.VSSDK.UnitTestLibrary" />
<Reference Include="Microsoft.VSSDK.TestHostFramework" />
<Reference Include="System" />
<Reference Include="System.Data" />
<Reference Include="System.Design" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="PackageTest.cs" />
<!---->
<Compile Include="MenuItemTests\MenuItemCallback.cs" />
<Compile Include="MenuItemTests\UIShellServiceMock.cs" />
<!---->
<!---->
<Compile Include="MyToolWindowTest\MyToolWindow.cs" />
<Compile Include="MyToolWindowTest\ShowToolWindow.cs" />
<Compile Include="MyToolWindowTest\WindowFrameMock.cs" />
<Compile Include="MyToolWindowTest\UIShellServiceMock.cs" />
<!---->
<!---->
</ItemGroup>
<ItemGroup>
<None Include="Key.snk" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\VSPackageInstall.csproj">
<Project>{20191D13-7CC1-4F9B-9CB8-42F22ACE4CA6}</Project>
<Name>VSPackageInstall</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
</Project>

View File

@ -0,0 +1,18 @@
<?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">
<Metadata>
<Identity Id="a527a9c1-ec2f-46a0-a6e3-371859c5845b" Version="1.0" Language="en-US" Publisher="Vitalii Ganzha" />
<DisplayName>VSPackageInstall</DisplayName>
<Description>Visual Studio sound notifications</Description>
</Metadata>
<Installation InstalledByMsi="false">
<InstallationTarget Id="Microsoft.VisualStudio.Pro" Version="[12.0]" />
</Installation>
<Dependencies>
<Dependency Id="Microsoft.Framework.NDP" DisplayName="Microsoft .NET Framework" d:Source="Manual" Version="[4.5,)" />
<Dependency Id="Microsoft.VisualStudio.MPF.12.0" DisplayName="Visual Studio MPF 12.0" d:Source="Installed" Version="[12.0]" />
</Dependencies>
<Assets>
<Asset Type="Microsoft.VisualStudio.VsPackage" d:Source="Project" d:ProjectName="%CurrentProject%" Path="|%CurrentProject%;PkgdefProjectOutputGroup|" />
</Assets>
</PackageManifest>

46
VsDingExtension.sln Normal file
View File

@ -0,0 +1,46 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2013
VisualStudioVersion = 12.0.21005.1
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VsDingExtension", "VsDingExtension\VsDingExtension.csproj", "{54C786E5-FD14-4036-92AE-E9F25B71534B}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VSPackageInstall", "VSPackageInstall\VSPackageInstall.csproj", "{20191D13-7CC1-4F9B-9CB8-42F22ACE4CA6}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VSPackageInstall_IntegrationTests", "VSPackageInstall\VSPackageInstall_IntegrationTests\VSPackageInstall_IntegrationTests.csproj", "{77A542CC-52C0-4387-B57B-63AF5F597EA1}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{5BD9D4DB-8683-4698-8D24-01EE7306F73A}"
ProjectSection(SolutionItems) = preProject
IntegrationTests.testsettings = IntegrationTests.testsettings
UnitTests.testsettings = UnitTests.testsettings
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VSPackageInstall_UnitTests", "VSPackageInstall\VSPackageInstall_UnitTests\VSPackageInstall_UnitTests.csproj", "{E620FC0C-6208-4216-9899-47DF43578E4C}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{54C786E5-FD14-4036-92AE-E9F25B71534B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{54C786E5-FD14-4036-92AE-E9F25B71534B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{54C786E5-FD14-4036-92AE-E9F25B71534B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{54C786E5-FD14-4036-92AE-E9F25B71534B}.Release|Any CPU.Build.0 = Release|Any CPU
{20191D13-7CC1-4F9B-9CB8-42F22ACE4CA6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{20191D13-7CC1-4F9B-9CB8-42F22ACE4CA6}.Debug|Any CPU.Build.0 = Debug|Any CPU
{20191D13-7CC1-4F9B-9CB8-42F22ACE4CA6}.Release|Any CPU.ActiveCfg = Release|Any CPU
{20191D13-7CC1-4F9B-9CB8-42F22ACE4CA6}.Release|Any CPU.Build.0 = Release|Any CPU
{77A542CC-52C0-4387-B57B-63AF5F597EA1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{77A542CC-52C0-4387-B57B-63AF5F597EA1}.Debug|Any CPU.Build.0 = Debug|Any CPU
{77A542CC-52C0-4387-B57B-63AF5F597EA1}.Release|Any CPU.ActiveCfg = Release|Any CPU
{77A542CC-52C0-4387-B57B-63AF5F597EA1}.Release|Any CPU.Build.0 = Release|Any CPU
{E620FC0C-6208-4216-9899-47DF43578E4C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E620FC0C-6208-4216-9899-47DF43578E4C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E620FC0C-6208-4216-9899-47DF43578E4C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E620FC0C-6208-4216-9899-47DF43578E4C}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal