Commit 30219022 302190229046be38f993758941863f0033d25516 by Christian Gerdes

- Implemented issue #2 Initialize of VSIX now automatically installs the recorde…

…r plugin on first launch into the users WebTestPlugins folder. Tested in Exp and working.
- Launching of Exp on F5 is now checked in (csproj.user file) and no longer ignored.
1 parent d3013cb5
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
3 3
4 # User-specific files 4 # User-specific files
5 *.suo 5 *.suo
6 *.user 6 # *.user
7 *.sln.docstates 7 *.sln.docstates
8 8
9 # Build results 9 # Build results
......
1 //------------------------------------------------------------------------------
2 // <copyright file="InfoCommand.cs" company="Company">
3 // Copyright (c) Company. All rights reserved.
4 // </copyright>
5 //------------------------------------------------------------------------------
6
7 using System;
8 using System.ComponentModel.Design;
9 using System.Globalization;
10 using Microsoft.VisualStudio.Shell;
11 using Microsoft.VisualStudio.Shell.Interop;
12
13 namespace WebTest.WebServive.Plugin
14 {
15 /// <summary>
16 /// Command handler
17 /// </summary>
18 internal sealed class InfoCommand
19 {
20 /// <summary>
21 /// Command ID.
22 /// </summary>
23 public const int CommandId = 0x0100;
24
25 /// <summary>
26 /// Command menu group (command set GUID).
27 /// </summary>
28 public static readonly Guid CommandSet = new Guid("dabd9d62-5ee8-4639-a7d5-71485c06eeca");
29
30 /// <summary>
31 /// VS Package that provides this command, not null.
32 /// </summary>
33 private readonly Package package;
34
35 /// <summary>
36 /// Initializes a new instance of the <see cref="InfoCommand"/> class.
37 /// Adds our command handlers for menu (commands must exist in the command table file)
38 /// </summary>
39 /// <param name="package">Owner package, not null.</param>
40 private InfoCommand(Package package)
41 {
42 if (package == null)
43 {
44 throw new ArgumentNullException("package");
45 }
46
47 this.package = package;
48
49 OleMenuCommandService commandService = this.ServiceProvider.GetService(typeof(IMenuCommandService)) as OleMenuCommandService;
50 if (commandService != null)
51 {
52 var menuCommandID = new CommandID(CommandSet, CommandId);
53 var menuItem = new MenuCommand(this.MenuItemCallback, menuCommandID);
54 commandService.AddCommand(menuItem);
55 }
56 }
57
58 /// <summary>
59 /// Gets the instance of the command.
60 /// </summary>
61 public static InfoCommand Instance
62 {
63 get;
64 private set;
65 }
66
67 /// <summary>
68 /// Gets the service provider from the owner package.
69 /// </summary>
70 private IServiceProvider ServiceProvider
71 {
72 get
73 {
74 return this.package;
75 }
76 }
77
78 /// <summary>
79 /// Initializes the singleton instance of the command.
80 /// </summary>
81 /// <param name="package">Owner package, not null.</param>
82 public static void Initialize(Package package)
83 {
84 Instance = new InfoCommand(package);
85 }
86
87 /// <summary>
88 /// This function is the callback used to execute the command when the menu item is clicked.
89 /// See the constructor to see how the menu item is associated with this function using
90 /// OleMenuCommandService service and MenuCommand class.
91 /// </summary>
92 /// <param name="sender">Event sender.</param>
93 /// <param name="e">Event args.</param>
94 private void MenuItemCallback(object sender, EventArgs e)
95 {
96 string message = string.Format(CultureInfo.CurrentCulture, "Inside {0}.MenuItemCallback()", this.GetType().FullName);
97 string title = "InfoCommand";
98
99 // Show a message box to prove we were here
100 VsShellUtilities.ShowMessageBox(
101 this.ServiceProvider,
102 message,
103 title,
104 OLEMSGICON.OLEMSGICON_INFO,
105 OLEMSGBUTTON.OLEMSGBUTTON_OK,
106 OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST);
107 }
108 }
109 }
...@@ -51,6 +51,7 @@ ...@@ -51,6 +51,7 @@
51 <WarningLevel>4</WarningLevel> 51 <WarningLevel>4</WarningLevel>
52 </PropertyGroup> 52 </PropertyGroup>
53 <ItemGroup> 53 <ItemGroup>
54 <Compile Include="InfoCommand.cs" />
54 <Compile Include="Properties\AssemblyInfo.cs" /> 55 <Compile Include="Properties\AssemblyInfo.cs" />
55 <Compile Include="WebServiceVSPackage.cs" /> 56 <Compile Include="WebServiceVSPackage.cs" />
56 </ItemGroup> 57 </ItemGroup>
...@@ -63,8 +64,12 @@ ...@@ -63,8 +64,12 @@
63 </ItemGroup> 64 </ItemGroup>
64 <ItemGroup> 65 <ItemGroup>
65 <Content Include="index.html" /> 66 <Content Include="index.html" />
67 <Content Include="Resources\InfoCommand.png" />
66 <Content Include="Resources\WebServiceVSPackage.ico" /> 68 <Content Include="Resources\WebServiceVSPackage.ico" />
67 <Content Include="stylesheet.css" /> 69 <Content Include="stylesheet.css" />
70 <VSCTCompile Include="WebServiceVSPackage.vsct">
71 <ResourceName>Menus.ctmenu</ResourceName>
72 </VSCTCompile>
68 </ItemGroup> 73 </ItemGroup>
69 <ItemGroup> 74 <ItemGroup>
70 <Reference Include="EnvDTE, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"> 75 <Reference Include="EnvDTE, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
...@@ -80,9 +85,8 @@ ...@@ -80,9 +85,8 @@
80 <EmbedInteropTypes>False</EmbedInteropTypes> 85 <EmbedInteropTypes>False</EmbedInteropTypes>
81 </Reference> 86 </Reference>
82 <Reference Include="Extensibility, Version=7.0.3300.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"> 87 <Reference Include="Extensibility, Version=7.0.3300.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
83 <EmbedInteropTypes>True</EmbedInteropTypes> 88 <EmbedInteropTypes>False</EmbedInteropTypes>
84 </Reference> 89 </Reference>
85 <Reference Include="Microsoft.Build.Framework" />
86 <Reference Include="Microsoft.CSharp" /> 90 <Reference Include="Microsoft.CSharp" />
87 <Reference Include="Microsoft.VisualStudio.CommandBars, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"> 91 <Reference Include="Microsoft.VisualStudio.CommandBars, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
88 <EmbedInteropTypes>False</EmbedInteropTypes> 92 <EmbedInteropTypes>False</EmbedInteropTypes>
......
1 <?xml version="1.0" encoding="utf-8"?>
2 <Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
3 <PropertyGroup>
4 <ProjectView>ProjectFiles</ProjectView>
5 </PropertyGroup>
6 <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|AnyCPU'">
7 <StartAction>Program</StartAction>
8 <StartProgram>C:\Program Files %28x86%29\Microsoft Visual Studio 14.0\Common7\IDE\devenv.exe</StartProgram>
9 <StartArguments>/rootsuffix Exp</StartArguments>
10 </PropertyGroup>
11 </Project>
...\ No newline at end of file ...\ No newline at end of file
...@@ -18,6 +18,9 @@ using Microsoft.Win32; ...@@ -18,6 +18,9 @@ using Microsoft.Win32;
18 using EnvDTE; 18 using EnvDTE;
19 using EnvDTE80; 19 using EnvDTE80;
20 using WebTest.WebService.Plugin.ResultTab; 20 using WebTest.WebService.Plugin.ResultTab;
21 using Microsoft.VisualStudio.Settings;
22 using Microsoft.VisualStudio.Shell.Settings;
23 using System.IO;
21 24
22 namespace WebTest.WebServive.Plugin 25 namespace WebTest.WebServive.Plugin
23 { 26 {
...@@ -43,6 +46,7 @@ namespace WebTest.WebServive.Plugin ...@@ -43,6 +46,7 @@ namespace WebTest.WebServive.Plugin
43 [Guid(WebServiceVSPackage.PackageGuidString)] 46 [Guid(WebServiceVSPackage.PackageGuidString)]
44 [SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1650:ElementDocumentationMustBeSpelledCorrectly", Justification = "pkgdef, VS and vsixmanifest are valid VS terms")] 47 [SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1650:ElementDocumentationMustBeSpelledCorrectly", Justification = "pkgdef, VS and vsixmanifest are valid VS terms")]
45 [ProvideAutoLoad(UIContextGuids80.SolutionExists)] 48 [ProvideAutoLoad(UIContextGuids80.SolutionExists)]
49 [ProvideMenuResource("Menus.ctmenu", 1)]
46 public sealed class WebServiceVSPackage : Package 50 public sealed class WebServiceVSPackage : Package
47 { 51 {
48 /// <summary> 52 /// <summary>
...@@ -69,11 +73,15 @@ namespace WebTest.WebServive.Plugin ...@@ -69,11 +73,15 @@ namespace WebTest.WebServive.Plugin
69 /// </summary> 73 /// </summary>
70 protected override void Initialize() 74 protected override void Initialize()
71 { 75 {
76 // check setup
77 checkSetup();
78
72 base.Initialize(); 79 base.Initialize();
73 DTE2 dte = (DTE2)GetService(typeof(DTE)); 80 DTE2 dte = (DTE2)GetService(typeof(DTE));
74 81
75 _wsp_connect = new WebTest.WebService.Plugin.ResultTab.Connect(); 82 _wsp_connect = new WebTest.WebService.Plugin.ResultTab.Connect();
76 _wsp_connect.OnConnection(dte, Extensibility.ext_ConnectMode.ext_cm_Startup, null, ref _arr); 83 _wsp_connect.OnConnection(dte, Extensibility.ext_ConnectMode.ext_cm_Startup, null, ref _arr);
84 WebTest.WebServive.Plugin.InfoCommand.Initialize(this);
77 85
78 } 86 }
79 87
...@@ -86,6 +94,65 @@ namespace WebTest.WebServive.Plugin ...@@ -86,6 +94,65 @@ namespace WebTest.WebServive.Plugin
86 base.Dispose(disposing); 94 base.Dispose(disposing);
87 } 95 }
88 96
97 bool checkSetup()
98 {
99 RegistryKey rk = Registry.CurrentUser.OpenSubKey("SOFTWARE\\WebServicePlugin");
100 bool installOK = false;
101 if(rk == null)
102 {
103 // Registry key not found, i.e. we did not install the dll's before
104 installOK = false;
105 } else
106 {
107 // Registry key found, check if we are installed
108 Object regInstalled = rk.GetValue("INSTALLED");
109 if (regInstalled != null)
110 {
111 Int32 val = (Int32)regInstalled;
112 if (val == 1) installOK = true;
113 else installOK = false;
114 } else
115 {
116 installOK = false;
117 }
118 }
119
120 // Install if we need to install, and show info message when done
121 if(installOK == false)
122 {
123 string messageLoc = new Uri(typeof(WebService.Plugin.MessageEditors.XmlMessageEditor).Assembly.CodeBase).LocalPath;
124 string runtimeLoc = new Uri(typeof(WebService.Plugin.Runtime.WebServicePlugin).Assembly.CodeBase).LocalPath;
125
126 // Check if the old runtime was found in PublicAssemblies (old version installed there)
127 if (runtimeLoc.Contains("PublicAssemblies"))
128 {
129 // CONFLICT
130 VsShellUtilities.ShowMessageBox(this, "Previous version of the runtime dll was found in the PublicAssemblies folder. This version will conflict with this new version of the plugin. Please remove it and restart Visual Studio.\n\n Path to the DLL: " + runtimeLoc,
131 "Conflicting previous version", OLEMSGICON.OLEMSGICON_CRITICAL, OLEMSGBUTTON.OLEMSGBUTTON_OK, OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST);
132 return false;
133 }
134 else
135 {
136 // OK to proceed
137 // Copy message editor plugins and recorder plugin to users webtest dir
138 ShellSettingsManager sm = new ShellSettingsManager(this);
139 string pluginPath = sm.GetApplicationDataFolder(ApplicationDataFolder.Documents) + @"\WebTestPlugins\";
140 Directory.CreateDirectory(pluginPath);
141 pluginPath += Path.GetFileName(messageLoc);
142 File.Copy(messageLoc, pluginPath, true);
143
144 //Update the registry
145 RegistryKey wrk = Registry.CurrentUser.CreateSubKey("SOFTWARE\\WebServicePlugin");
146 wrk.SetValue("INSTALLED", 1, RegistryValueKind.DWord);
147
148 //Tell the user
149 VsShellUtilities.ShowMessageBox(this, "Recorder plugin copied to: " + pluginPath, "Plugin files installed", OLEMSGICON.OLEMSGICON_INFO, OLEMSGBUTTON.OLEMSGBUTTON_OK, OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST);
150 }
151 }
152
153 return installOK;
154 }
155
89 #endregion 156 #endregion
90 Connect _wsp_connect = null; 157 Connect _wsp_connect = null;
91 Array _arr = new object[0]; 158 Array _arr = new object[0];
......
1 <?xml version="1.0" encoding="utf-8"?>
2 <CommandTable xmlns="http://schemas.microsoft.com/VisualStudio/2005-10-18/CommandTable" xmlns:xs="http://www.w3.org/2001/XMLSchema">
3
4 <!-- This is the file that defines the actual layout and type of the commands.
5 It is divided in different sections (e.g. command definition, command
6 placement, ...), with each defining a specific set of properties.
7 See the comment before each section for more details about how to
8 use it. -->
9
10 <!-- The VSCT compiler (the tool that translates this file into the binary
11 format that VisualStudio will consume) has the ability to run a preprocessor
12 on the vsct file; this preprocessor is (usually) the C++ preprocessor, so
13 it is possible to define includes and macros with the same syntax used
14 in C++ files. Using this ability of the compiler here, we include some files
15 defining some of the constants that we will use inside the file. -->
16
17 <!--This is the file that defines the IDs for all the commands exposed by VisualStudio. -->
18 <Extern href="stdidcmd.h"/>
19
20 <!--This header contains the command ids for the menus provided by the shell. -->
21 <Extern href="vsshlids.h"/>
22
23 <!--The Commands section is where commands, menus, and menu groups are defined.
24 This section uses a Guid to identify the package that provides the command defined inside it. -->
25 <Commands package="guidWebServiceVSPackage">
26 <!-- Inside this section we have different sub-sections: one for the menus, another
27 for the menu groups, one for the buttons (the actual commands), one for the combos
28 and the last one for the bitmaps used. Each element is identified by a command id that
29 is a unique pair of guid and numeric identifier; the guid part of the identifier is usually
30 called "command set" and is used to group different command inside a logically related
31 group; your package should define its own command set in order to avoid collisions
32 with command ids defined by other packages. -->
33
34 <!-- In this section you can define new menu groups. A menu group is a container for
35 other menus or buttons (commands); from a visual point of view you can see the
36 group as the part of a menu contained between two lines. The parent of a group
37 must be a menu. -->
38 <Groups>
39 <Group guid="guidWebServiceVSPackageCmdSet" id="MyMenuGroup" priority="0x0600">
40 <Parent guid="guidSHLMainMenu" id="IDM_VS_MENU_TOOLS"/>
41 </Group>
42 </Groups>
43
44 <!--Buttons section. -->
45 <!--This section defines the elements the user can interact with, like a menu command or a button
46 or combo box in a toolbar. -->
47 <Buttons>
48 <!--To define a menu group you have to specify its ID, the parent menu and its display priority.
49 The command is visible and enabled by default. If you need to change the visibility, status, etc, you can use
50 the CommandFlag node.
51 You can add more than one CommandFlag node e.g.:
52 <CommandFlag>DefaultInvisible</CommandFlag>
53 <CommandFlag>DynamicVisibility</CommandFlag>
54 If you do not want an image next to your command, remove the Icon node /> -->
55 <Button guid="guidWebServiceVSPackageCmdSet" id="InfoCommandId" priority="0x0100" type="Button">
56 <Parent guid="guidWebServiceVSPackageCmdSet" id="MyMenuGroup" />
57 <Icon guid="guidImages" id="bmpPic1" />
58 <Strings>
59 <ButtonText>Invoke InfoCommand</ButtonText>
60 </Strings>
61 </Button>
62 </Buttons>
63
64 <!--The bitmaps section is used to define the bitmaps that are used for the commands.-->
65 <Bitmaps>
66 <!-- The bitmap id is defined in a way that is a little bit different from the others:
67 the declaration starts with a guid for the bitmap strip, then there is the resource id of the
68 bitmap strip containing the bitmaps and then there are the numeric ids of the elements used
69 inside a button definition. An important aspect of this declaration is that the element id
70 must be the actual index (1-based) of the bitmap inside the bitmap strip. -->
71 <Bitmap guid="guidImages" href="Resources\InfoCommand.png" usedList="bmpPic1, bmpPic2, bmpPicSearch, bmpPicX, bmpPicArrows, bmpPicStrikethrough"/>
72 </Bitmaps>
73 </Commands>
74
75 <Symbols>
76 <!-- This is the package guid. -->
77 <GuidSymbol name="guidWebServiceVSPackage" value="{7e15e6a8-3708-4be9-92f4-92218254a23d}" />
78
79 <!-- This is the guid used to group the menu commands together -->
80 <GuidSymbol name="guidWebServiceVSPackageCmdSet" value="{dabd9d62-5ee8-4639-a7d5-71485c06eeca}">
81 <IDSymbol name="MyMenuGroup" value="0x1020" />
82 <IDSymbol name="InfoCommandId" value="0x0100" />
83 </GuidSymbol>
84
85 <GuidSymbol name="guidImages" value="{fe1ce9bc-93c0-4c17-bbb5-6107d6492e08}" >
86 <IDSymbol name="bmpPic1" value="1" />
87 <IDSymbol name="bmpPic2" value="2" />
88 <IDSymbol name="bmpPicSearch" value="3" />
89 <IDSymbol name="bmpPicX" value="4" />
90 <IDSymbol name="bmpPicArrows" value="5" />
91 <IDSymbol name="bmpPicStrikethrough" value="6" />
92 </GuidSymbol>
93 </Symbols>
94 </CommandTable>