├── .gitattributes
├── .gitignore
├── IntegrationTests.testsettings
├── License.txt
├── README.md
├── Screenshot.png
├── SmartPaster2013.sln
├── SmartPaster2013
├── GlobalSuppressions.cs
├── Guids.cs
├── Key.snk
├── PkgCmdID.cs
├── Properties
│ └── AssemblyInfo.cs
├── ReplaceForm.Designer.cs
├── ReplaceForm.cs
├── ReplaceForm.resx
├── Resources.Designer.cs
├── Resources.resx
├── Resources
│ ├── Images.png
│ ├── Package.ico
│ └── Paste_6520.png
├── SmartFormatter.cs
├── SmartPaster.cs
├── SmartPaster2013.csproj
├── SmartPaster2013.vsct
├── SmartPaster2013Package.cs
├── SmartPaster2013_IntegrationTests
│ ├── IntegrationTest Library
│ │ ├── DialogboxPurger.cs
│ │ ├── NativeMethods.cs
│ │ └── Utils.cs
│ ├── Key.snk
│ ├── MenuItemTest.cs
│ ├── PackageTest.cs
│ ├── SignOff-Tests
│ │ ├── CPPProjectTests.cs
│ │ ├── CSharpProjectTests.cs
│ │ ├── SolutionTests.cs
│ │ └── VBProjectTests.cs
│ └── SmartPaster2013_IntegrationTests.csproj
├── SmartPaster2013_UnitTests
│ ├── Key.snk
│ ├── MenuItemTests
│ │ ├── MenuItemCallback.cs
│ │ └── UIShellServiceMock.cs
│ ├── PackageTest.cs
│ ├── Scratchpad.vb
│ ├── SmartFormatterTests.cs
│ ├── SmartPaster2013_UnitTests.csproj
│ ├── app.config
│ └── packages.config
├── VSPackage.resx
├── app.config
├── packages.config
└── source.extension.vsixmanifest
└── UnitTests.testsettings
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
3 |
4 | # Custom for Visual Studio
5 | *.cs diff=csharp
6 | *.sln merge=union
7 | *.csproj merge=union
8 | *.vbproj merge=union
9 | *.fsproj merge=union
10 | *.dbproj merge=union
11 |
12 | # Standard to msysgit
13 | *.doc diff=astextplain
14 | *.DOC diff=astextplain
15 | *.docx diff=astextplain
16 | *.DOCX diff=astextplain
17 | *.dot diff=astextplain
18 | *.DOT diff=astextplain
19 | *.pdf diff=astextplain
20 | *.PDF diff=astextplain
21 | *.rtf diff=astextplain
22 | *.RTF diff=astextplain
23 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | #################
2 | ## Eclipse
3 | #################
4 |
5 | *.pydevproject
6 | .project
7 | .metadata
8 | bin/
9 | tmp/
10 | *.tmp
11 | *.bak
12 | *.swp
13 | *~.nib
14 | local.properties
15 | .classpath
16 | .settings/
17 | .loadpath
18 |
19 | # External tool builders
20 | .externalToolBuilders/
21 |
22 | # Locally stored "Eclipse launch configurations"
23 | *.launch
24 |
25 | # CDT-specific
26 | .cproject
27 |
28 | # PDT-specific
29 | .buildpath
30 |
31 |
32 | #################
33 | ## Visual Studio
34 | #################
35 |
36 | ## Ignore Visual Studio temporary files, build results, and
37 | ## files generated by popular Visual Studio add-ons.
38 |
39 | # User-specific files
40 | *.suo
41 | *.user
42 | *.sln.docstates
43 |
44 | # Build results
45 |
46 | [Dd]ebug/
47 | [Rr]elease/
48 | x64/
49 | build/
50 | [Bb]in/
51 | [Oo]bj/
52 | .vs/
53 |
54 | # MSTest test Results
55 | [Tt]est[Rr]esult*/
56 | [Bb]uild[Ll]og.*
57 |
58 | *_i.c
59 | *_p.c
60 | *.ilk
61 | *.meta
62 | *.obj
63 | *.pch
64 | *.pdb
65 | *.pgc
66 | *.pgd
67 | *.rsp
68 | *.sbr
69 | *.tlb
70 | *.tli
71 | *.tlh
72 | *.tmp
73 | *.tmp_proj
74 | *.log
75 | *.vspscc
76 | *.vssscc
77 | .builds
78 | *.pidb
79 | *.log
80 | *.scc
81 |
82 | # Visual C++ cache files
83 | ipch/
84 | *.aps
85 | *.ncb
86 | *.opensdf
87 | *.sdf
88 | *.cachefile
89 |
90 | # Visual Studio profiler
91 | *.psess
92 | *.vsp
93 | *.vspx
94 |
95 | # Guidance Automation Toolkit
96 | *.gpState
97 |
98 | # ReSharper is a .NET coding add-in
99 | _ReSharper*/
100 | *.[Rr]e[Ss]harper
101 |
102 | # TeamCity is a build add-in
103 | _TeamCity*
104 |
105 | # DotCover is a Code Coverage Tool
106 | *.dotCover
107 |
108 | # NCrunch
109 | *.ncrunch*
110 | .*crunch*.local.xml
111 |
112 | # Installshield output folder
113 | [Ee]xpress/
114 |
115 | # DocProject is a documentation generator add-in
116 | DocProject/buildhelp/
117 | DocProject/Help/*.HxT
118 | DocProject/Help/*.HxC
119 | DocProject/Help/*.hhc
120 | DocProject/Help/*.hhk
121 | DocProject/Help/*.hhp
122 | DocProject/Help/Html2
123 | DocProject/Help/html
124 |
125 | # Click-Once directory
126 | publish/
127 |
128 | # Publish Web Output
129 | *.Publish.xml
130 | *.pubxml
131 |
132 | # NuGet Packages Directory
133 | ## TODO: If you have NuGet Package Restore enabled, uncomment the next line
134 | packages/
135 |
136 | # Windows Azure Build Output
137 | csx
138 | *.build.csdef
139 |
140 | # Windows Store app package directory
141 | AppPackages/
142 |
143 | # Others
144 | sql/
145 | *.Cache
146 | ClientBin/
147 | [Ss]tyle[Cc]op.*
148 | ~$*
149 | *~
150 | *.dbmdl
151 | *.[Pp]ublish.xml
152 | *.pfx
153 | *.publishsettings
154 |
155 | # RIA/Silverlight projects
156 | Generated_Code/
157 |
158 | # Backup & report files from converting an old project file to a newer
159 | # Visual Studio version. Backup files are not needed, because we have git ;-)
160 | _UpgradeReport_Files/
161 | Backup*/
162 | UpgradeLog*.XML
163 | UpgradeLog*.htm
164 |
165 | # SQL Server files
166 | App_Data/*.mdf
167 | App_Data/*.ldf
168 |
169 | #############
170 | ## Windows detritus
171 | #############
172 |
173 | # Windows image file caches
174 | Thumbs.db
175 | ehthumbs.db
176 |
177 | # Folder config file
178 | Desktop.ini
179 |
180 | # Recycle Bin used on file shares
181 | $RECYCLE.BIN/
182 |
183 | # Mac crap
184 | .DS_Store
185 |
186 |
187 | #############
188 | ## Python
189 | #############
190 |
191 | *.py[co]
192 |
193 | # Packages
194 | *.egg
195 | *.egg-info
196 | dist/
197 | build/
198 | eggs/
199 | parts/
200 | var/
201 | sdist/
202 | develop-eggs/
203 | .installed.cfg
204 |
205 | # Installer logs
206 | pip-log.txt
207 |
208 | # Unit test / coverage reports
209 | .coverage
210 | .tox
211 |
212 | #Translations
213 | *.mo
214 |
215 | #Mr Developer
216 | .mr.developer.cfg
217 |
--------------------------------------------------------------------------------
/IntegrationTests.testsettings:
--------------------------------------------------------------------------------
1 |
2 |
7 | This test run configuration uses the VS IDE host type in the test run.
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/License.txt:
--------------------------------------------------------------------------------
1 |
2 | The MIT License (MIT)
3 |
4 | Copyright (c) 2013 Martin J Willey
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining a copy
7 | of this software and associated documentation files (the "Software"), to deal
8 | in the Software without restriction, including without limitation the rights
9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | copies of the Software, and to permit persons to whom the Software is
11 | furnished to do so, subject to the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be included in all
14 | copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | SOFTWARE.
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # SmartPaster 2013/2015/2017/2019
2 |
3 | A port of Alex Papadimoulis' Smart Paster for Visual Studio 2013, 2015 and 2017.
4 | (via SmartPaster 2010 for Visual Studio 2010 and 2012: https://smartpaster2010.codeplex.com/)
5 |
6 | For VS 2022, see https://github.com/martinjw/SmartPaster (marketplace: https://marketplace.visualstudio.com/items?itemName=martinw.SmartPaster )
7 |
8 | A "Paste As" right-click option that allows clipboard text to be:
9 |
10 | * Paste as Comment
11 | * Paste as Literal String (regular string literal)
12 | * Paste as @String (in C#, verbatim string; in VB, CData or VB14 multi-line strings depending on version)
13 | * Paste as StringBuilder
14 | * Paste as Byte Array
15 |
16 | On Visual Studio Gallery:
17 | http://visualstudiogallery.msdn.microsoft.com/0611a238-7405-4d5f-ace0-5b3d5cf325e0
18 |
19 | v1.1 adds Unicode, VS2015 support, both regular and verbatim strings.
20 | v1.2 adds Paste as Byte Array, C++ support (thanks to leg0)
21 | v1.3 adds VS2017 support, renamed to SmartPaster2017
22 |
23 | 
24 |
25 | SmartPaster 2010 Codeplex version (VS2010, VS2012):
26 | https://smartpaster2010.codeplex.com/
27 |
28 | ## Credits
29 |
30 | The original SmartPaster (for VS 2003/2005/2008) by Alex Papadimoulis is here: http://weblogs.asp.net/alex_papadimoulis/archive/2004/05/25/Smart-Paster-1.1-Add-In---StringBuilder-and-Better-C_2300_-Handling.aspx
31 | The original source code is here: http://code.google.com/p/smartpaster/
32 |
--------------------------------------------------------------------------------
/Screenshot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/martinjw/SmartPaster2013/a65224953b746cf4de4634d38750b068cd2658b4/Screenshot.png
--------------------------------------------------------------------------------
/SmartPaster2013.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 15
4 | VisualStudioVersion = 15.0.26206.0
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SmartPaster2013", "SmartPaster2013\SmartPaster2013.csproj", "{E4C30299-C9D8-4860-BBB0-02F5887D3ED2}"
7 | EndProject
8 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{2DC34759-FCD8-4627-B701-48F17B531123}"
9 | ProjectSection(SolutionItems) = preProject
10 | IntegrationTests.testsettings = IntegrationTests.testsettings
11 | License.txt = License.txt
12 | UnitTests.testsettings = UnitTests.testsettings
13 | EndProjectSection
14 | EndProject
15 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SmartPaster2013_UnitTests", "SmartPaster2013\SmartPaster2013_UnitTests\SmartPaster2013_UnitTests.csproj", "{B8D186B6-3465-4F1D-8157-04367BE5C9ED}"
16 | EndProject
17 | Global
18 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
19 | Debug|Any CPU = Debug|Any CPU
20 | Release|Any CPU = Release|Any CPU
21 | EndGlobalSection
22 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
23 | {E4C30299-C9D8-4860-BBB0-02F5887D3ED2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
24 | {E4C30299-C9D8-4860-BBB0-02F5887D3ED2}.Debug|Any CPU.Build.0 = Debug|Any CPU
25 | {E4C30299-C9D8-4860-BBB0-02F5887D3ED2}.Release|Any CPU.ActiveCfg = Release|Any CPU
26 | {E4C30299-C9D8-4860-BBB0-02F5887D3ED2}.Release|Any CPU.Build.0 = Release|Any CPU
27 | {B8D186B6-3465-4F1D-8157-04367BE5C9ED}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
28 | {B8D186B6-3465-4F1D-8157-04367BE5C9ED}.Debug|Any CPU.Build.0 = Debug|Any CPU
29 | {B8D186B6-3465-4F1D-8157-04367BE5C9ED}.Release|Any CPU.ActiveCfg = Release|Any CPU
30 | {B8D186B6-3465-4F1D-8157-04367BE5C9ED}.Release|Any CPU.Build.0 = Release|Any CPU
31 | EndGlobalSection
32 | GlobalSection(SolutionProperties) = preSolution
33 | HideSolutionNode = FALSE
34 | EndGlobalSection
35 | EndGlobal
36 |
--------------------------------------------------------------------------------
/SmartPaster2013/GlobalSuppressions.cs:
--------------------------------------------------------------------------------
1 | // This file is used by Code Analysis to maintain SuppressMessage
2 | // attributes that are applied to this project. Project-level
3 | // suppressions either have no target or are given a specific target
4 | // and scoped to a namespace, type, member, etc.
5 | //
6 | // To add a suppression to this file, right-click the message in the
7 | // Error List, point to "Suppress Message(s)", and click "In Project
8 | // Suppression File". You do not need to add suppressions to this
9 | // file manually.
10 |
11 | [assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1017:MarkAssembliesWithComVisible")]
12 |
--------------------------------------------------------------------------------
/SmartPaster2013/Guids.cs:
--------------------------------------------------------------------------------
1 | // Guids.cs
2 | // MUST match guids.h
3 | using System;
4 |
5 | namespace SmartPaster2013
6 | {
7 | static class GuidList
8 | {
9 | public const string guidSmartPaster2013PkgString = "233fade6-f9e1-4a0d-8784-089004c574fc";
10 | public const string guidSmartPaster2013CmdSetString = "1dba502a-a6ce-4857-a13e-d9936e61ec66";
11 |
12 | public static readonly Guid guidSmartPaster2013CmdSet = new Guid(guidSmartPaster2013CmdSetString);
13 | };
14 | }
--------------------------------------------------------------------------------
/SmartPaster2013/Key.snk:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/martinjw/SmartPaster2013/a65224953b746cf4de4634d38750b068cd2658b4/SmartPaster2013/Key.snk
--------------------------------------------------------------------------------
/SmartPaster2013/PkgCmdID.cs:
--------------------------------------------------------------------------------
1 | // PkgCmdID.cs
2 | // MUST match PkgCmdID.h
3 | using System;
4 |
5 | namespace SmartPaster2013
6 | {
7 | static class PkgCmdIDList
8 | {
9 | public const uint cmdidPasteAsComment = 0x100;
10 | public const uint cmdidPasteAsString = 0x101;
11 | public const uint cmdidPasteAsVerbatimString = 0x102;
12 | public const uint cmdidPasteAsStringBuilder = 0x103;
13 | public const uint cmdidPasteAsBytes = 0x104;
14 | public const uint cmdidPasteWithReplace = 0x105;
15 |
16 | };
17 | }
--------------------------------------------------------------------------------
/SmartPaster2013/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Reflection;
3 | using System.Resources;
4 | using System.Runtime.CompilerServices;
5 | using System.Runtime.InteropServices;
6 |
7 | // General Information about an assembly is controlled through the following
8 | // set of attributes. Change these attribute values to modify the information
9 | // associated with an assembly.
10 | [assembly: AssemblyTitle("SmartPaster2017")]
11 | [assembly: AssemblyDescription("")]
12 | [assembly: AssemblyConfiguration("")]
13 | [assembly: AssemblyCompany("Martin Willey")]
14 | [assembly: AssemblyProduct("SmartPaster2017")]
15 | [assembly: AssemblyCopyright("")]
16 | [assembly: AssemblyTrademark("")]
17 | [assembly: AssemblyCulture("")]
18 | [assembly: ComVisible(false)]
19 | [assembly: CLSCompliant(false)]
20 | [assembly: NeutralResourcesLanguage("en-US")]
21 |
22 | // Version information for an assembly consists of the following four values:
23 | //
24 | // Major Version
25 | // Minor Version
26 | // Build Number
27 | // Revision
28 | //
29 | // You can specify all the values or you can default the Revision and Build Numbers
30 | // by using the '*' as shown below:
31 |
32 | [assembly: AssemblyVersion("1.5.0.0")]
33 | [assembly: AssemblyFileVersion("1.5.0.0")]
34 |
35 | [assembly: InternalsVisibleTo("SmartPaster2013_IntegrationTests, PublicKey=002400000480000094000000060200000024000052534131000400000100010027ba1044a9cff13efea75ee0f830422b00274a6f7d38ac224c0c5a2ef11ae373b6102a0a17c561292c645a2aebb9266ff3c89d30faa7757315e7702647910625157e8b5c648522d5b206b841b9d2d4ae9ea904527ddeff74b4a498181c51c635e7d76310157c327aee3dfae846720c8c161b2bc551707e4f3de7fb6f92e7f1ca")]
36 | [assembly: InternalsVisibleTo("SmartPaster2013_UnitTests, PublicKey=002400000480000094000000060200000024000052534131000400000100010027ba1044a9cff13efea75ee0f830422b00274a6f7d38ac224c0c5a2ef11ae373b6102a0a17c561292c645a2aebb9266ff3c89d30faa7757315e7702647910625157e8b5c648522d5b206b841b9d2d4ae9ea904527ddeff74b4a498181c51c635e7d76310157c327aee3dfae846720c8c161b2bc551707e4f3de7fb6f92e7f1ca")]
37 |
--------------------------------------------------------------------------------
/SmartPaster2013/ReplaceForm.Designer.cs:
--------------------------------------------------------------------------------
1 | namespace SmartPaster2013
2 | {
3 | partial class ReplaceForm
4 | {
5 | ///
6 | /// Required designer variable.
7 | ///
8 | private System.ComponentModel.IContainer components = null;
9 |
10 | ///
11 | /// Clean up any resources being used.
12 | ///
13 | /// true if managed resources should be disposed; otherwise, false.
14 | protected override void Dispose(bool disposing)
15 | {
16 | if (disposing && (components != null))
17 | {
18 | components.Dispose();
19 | }
20 | base.Dispose(disposing);
21 | }
22 |
23 | #region Windows Form Designer generated code
24 |
25 | ///
26 | /// Required method for Designer support - do not modify
27 | /// the contents of this method with the code editor.
28 | ///
29 | private void InitializeComponent()
30 | {
31 | this.findTextBox = new System.Windows.Forms.TextBox();
32 | this.replaceWithTextBox = new System.Windows.Forms.TextBox();
33 | this.FindLabel = new System.Windows.Forms.Label();
34 | this.ReplaceWithLabel = new System.Windows.Forms.Label();
35 | this.pasteButton = new System.Windows.Forms.Button();
36 | this.SuspendLayout();
37 | //
38 | // findTextBox
39 | //
40 | this.findTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
41 | | System.Windows.Forms.AnchorStyles.Right)));
42 | this.findTextBox.Location = new System.Drawing.Point(82, 11);
43 | this.findTextBox.Margin = new System.Windows.Forms.Padding(2, 2, 2, 2);
44 | this.findTextBox.Name = "findTextBox";
45 | this.findTextBox.Size = new System.Drawing.Size(345, 20);
46 | this.findTextBox.TabIndex = 0;
47 | //
48 | // replaceWithTextBox
49 | //
50 | this.replaceWithTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
51 | | System.Windows.Forms.AnchorStyles.Right)));
52 | this.replaceWithTextBox.Location = new System.Drawing.Point(82, 33);
53 | this.replaceWithTextBox.Margin = new System.Windows.Forms.Padding(2, 2, 2, 2);
54 | this.replaceWithTextBox.Name = "replaceWithTextBox";
55 | this.replaceWithTextBox.Size = new System.Drawing.Size(345, 20);
56 | this.replaceWithTextBox.TabIndex = 1;
57 | //
58 | // FindLabel
59 | //
60 | this.FindLabel.AutoSize = true;
61 | this.FindLabel.Location = new System.Drawing.Point(9, 13);
62 | this.FindLabel.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
63 | this.FindLabel.Name = "FindLabel";
64 | this.FindLabel.Size = new System.Drawing.Size(30, 13);
65 | this.FindLabel.TabIndex = 2;
66 | this.FindLabel.Text = "Find:";
67 | //
68 | // ReplaceWithLabel
69 | //
70 | this.ReplaceWithLabel.AutoSize = true;
71 | this.ReplaceWithLabel.Location = new System.Drawing.Point(9, 37);
72 | this.ReplaceWithLabel.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
73 | this.ReplaceWithLabel.Name = "ReplaceWithLabel";
74 | this.ReplaceWithLabel.Size = new System.Drawing.Size(72, 13);
75 | this.ReplaceWithLabel.TabIndex = 3;
76 | this.ReplaceWithLabel.Text = "Replace with:";
77 | //
78 | // pasteButton
79 | //
80 | this.pasteButton.Location = new System.Drawing.Point(82, 57);
81 | this.pasteButton.Margin = new System.Windows.Forms.Padding(2, 2, 2, 2);
82 | this.pasteButton.Name = "pasteButton";
83 | this.pasteButton.Size = new System.Drawing.Size(345, 19);
84 | this.pasteButton.TabIndex = 4;
85 | this.pasteButton.Text = "Paste";
86 | this.pasteButton.UseVisualStyleBackColor = true;
87 | this.pasteButton.Click += new System.EventHandler(this.pasteButton_Click);
88 | //
89 | // ReplaceForm
90 | //
91 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
92 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
93 | this.ClientSize = new System.Drawing.Size(436, 82);
94 | this.Controls.Add(this.pasteButton);
95 | this.Controls.Add(this.ReplaceWithLabel);
96 | this.Controls.Add(this.FindLabel);
97 | this.Controls.Add(this.replaceWithTextBox);
98 | this.Controls.Add(this.findTextBox);
99 | this.Margin = new System.Windows.Forms.Padding(2, 2, 2, 2);
100 | this.Name = "ReplaceForm";
101 | this.Text = "Find/Replace in paste text";
102 | this.ResumeLayout(false);
103 | this.PerformLayout();
104 |
105 | }
106 |
107 | #endregion
108 |
109 | private System.Windows.Forms.TextBox findTextBox;
110 | private System.Windows.Forms.TextBox replaceWithTextBox;
111 | private System.Windows.Forms.Label FindLabel;
112 | private System.Windows.Forms.Label ReplaceWithLabel;
113 | private System.Windows.Forms.Button pasteButton;
114 | }
115 | }
--------------------------------------------------------------------------------
/SmartPaster2013/ReplaceForm.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.ComponentModel;
4 | using System.Data;
5 | using System.Drawing;
6 | using System.Linq;
7 | using System.Text;
8 | using System.Threading.Tasks;
9 | using System.Windows.Forms;
10 |
11 | namespace SmartPaster2013
12 | {
13 | public partial class ReplaceForm : Form
14 | {
15 | public ReplaceForm()
16 | {
17 | InitializeComponent();
18 | }
19 |
20 | private void pasteButton_Click(object sender, EventArgs e)
21 | {
22 | this.DialogResult = DialogResult.OK;
23 | }
24 |
25 | public string TextToReplace
26 | => this.findTextBox.Text;
27 |
28 | public string ReplaceText
29 | => this.replaceWithTextBox.Text;
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/SmartPaster2013/ReplaceForm.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
--------------------------------------------------------------------------------
/SmartPaster2013/Resources.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated by a tool.
4 | // Runtime Version:4.0.30319.42000
5 | //
6 | // Changes to this file may cause incorrect behavior and will be lost if
7 | // the code is regenerated.
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace SmartPaster2013 {
12 | using System;
13 |
14 |
15 | ///
16 | /// A strongly-typed resource class, for looking up localized strings, etc.
17 | ///
18 | // This class was auto-generated by the StronglyTypedResourceBuilder
19 | // class via a tool like ResGen or Visual Studio.
20 | // To add or remove a member, edit your .ResX file then rerun ResGen
21 | // with the /str option, or rebuild your VS project.
22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
25 | internal class Resources {
26 |
27 | private static global::System.Resources.ResourceManager resourceMan;
28 |
29 | private static global::System.Globalization.CultureInfo resourceCulture;
30 |
31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
32 | internal Resources() {
33 | }
34 |
35 | ///
36 | /// Returns the cached ResourceManager instance used by this class.
37 | ///
38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
39 | internal static global::System.Resources.ResourceManager ResourceManager {
40 | get {
41 | if (object.ReferenceEquals(resourceMan, null)) {
42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("SmartPaster2013.Resources", typeof(Resources).Assembly);
43 | resourceMan = temp;
44 | }
45 | return resourceMan;
46 | }
47 | }
48 |
49 | ///
50 | /// Overrides the current thread's CurrentUICulture property for all
51 | /// resource lookups using this strongly typed resource class.
52 | ///
53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
54 | internal static global::System.Globalization.CultureInfo Culture {
55 | get {
56 | return resourceCulture;
57 | }
58 | set {
59 | resourceCulture = value;
60 | }
61 | }
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/SmartPaster2013/Resources.resx:
--------------------------------------------------------------------------------
1 |
2 |
11 |
12 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 | text/microsoft-resx
119 |
120 |
121 | 2.0
122 |
123 |
124 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
125 |
126 |
127 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
128 |
129 |
--------------------------------------------------------------------------------
/SmartPaster2013/Resources/Images.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/martinjw/SmartPaster2013/a65224953b746cf4de4634d38750b068cd2658b4/SmartPaster2013/Resources/Images.png
--------------------------------------------------------------------------------
/SmartPaster2013/Resources/Package.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/martinjw/SmartPaster2013/a65224953b746cf4de4634d38750b068cd2658b4/SmartPaster2013/Resources/Package.ico
--------------------------------------------------------------------------------
/SmartPaster2013/Resources/Paste_6520.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/martinjw/SmartPaster2013/a65224953b746cf4de4634d38750b068cd2658b4/SmartPaster2013/Resources/Paste_6520.png
--------------------------------------------------------------------------------
/SmartPaster2013/SmartFormatter.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.IO;
3 | using System.Linq;
4 | using System.Text;
5 |
6 | namespace SmartPaster2013
7 | {
8 | public static class SmartFormatter
9 | {
10 | private const string Quote = "\"";
11 |
12 | ///
13 | /// Stringinizes text passed to it for use in C#
14 | ///
15 | /// Text to be Stringinized
16 | /// C# Stringinized text
17 | public static string StringinizeInCs(string txt)
18 | {
19 | //sb to work with
20 | var sb = new StringBuilder(txt);
21 |
22 | //escape appropriately
23 | //escape the quotes with ""
24 | sb.Replace(Quote, Quote + Quote);
25 |
26 | //insert " at beginning and end
27 | sb.Insert(0, "@" + Quote);
28 | sb.Append(Quote);
29 | return sb.ToString();
30 | }
31 |
32 | ///
33 | /// Literallies the text in C#.
34 | ///
35 | /// Literally, the text to be literallized.
36 | ///
37 | public static string LiterallyInCs(string txt)
38 | {
39 | //escape appropriately
40 | //escape the quotes with ""
41 | txt = txt.Trim() //ignore leading and trailing blank lines
42 | .Replace("\\", "\\\\") //escape backslashes
43 | .Replace(Quote, "\\\"") //escape quotes
44 | .Replace("\t", "\\t") //escape tabs
45 | .Replace("\r", "\\r") //cr
46 | .Replace("\n", "\\n") //lf
47 | //.Replace("\"\" + ", "") //"" +
48 | .Replace("\\r\\n", "\" + Environment.NewLine + \r\n\"") //escaped crlf to Env.NewLine
49 | ;
50 |
51 | return Quote + txt + Quote;
52 | }
53 |
54 | public static string LiterallyInCxx(string txt)
55 | {
56 | var lines = from line in txt.Split(new string[] { "\r\n", "\n" }, StringSplitOptions.None)
57 | select "\"" + line
58 | .Replace("\\", "\\\\")
59 | .Replace("\"", "\\\"")
60 | .Replace("\t", @"\t")
61 | + "\"";
62 | return String.Join("\r\n", lines);
63 | }
64 |
65 | ///
66 | /// Stringinizes the text in vb (VB14 verbatim).
67 | ///
68 | /// The text.
69 | ///
70 | public static string StringinizeInVb(string txt)
71 | {
72 | //double-up internal quotes
73 | txt = txt.Replace(Quote, Quote + Quote);
74 |
75 | //vb14 (vs2015+) supports verbatim strings
76 | return Quote + txt + Quote;
77 | }
78 |
79 | ///
80 | /// Literal VB (actually in C#, wat...).
81 | ///
82 | /// The text.
83 | ///
84 | public static string LiterallyInVb(string txt)
85 | {
86 | //double-up internal quotes
87 | txt = txt.Replace(Quote, Quote + Quote);
88 | txt = txt.Trim() //ignore leading and trailing blank lines
89 | .Replace(Quote, Quote + Quote) //escape quotes
90 | .Replace("\t", "\" & vbTab & \"") //explicit Tabs
91 | .Replace("\r", "\" & vbCr & \"") //cr
92 | .Replace("\n", "\" & vbLf & \"") //lf
93 | .Replace("\" & vbCr & \"\" & vbLf & \"", "\" & vbCrLf & _\r\n\"") //escaped cr + lf to CrLf + vb line continuation
94 | .Replace("\"\" & ", ""); //"" &
95 |
96 | return Quote + txt + Quote;
97 | }
98 |
99 | public static string CDataizeInVb(string txt)
100 | {
101 | const string cdataStart = ".Value";
104 | var sb = new StringBuilder();
105 |
106 | sb.AppendLine(cdataStart);
107 | sb.AppendLine(txt);
108 | sb.AppendLine(cdataEnd);
109 |
110 | //add the dec statement
111 | sb.Insert(0, "Dim s As String = " + Environment.NewLine);
112 |
113 | //and return
114 | return sb.ToString();
115 | }
116 |
117 | ///
118 | /// Commentizes text passed to it for use in C#
119 | ///
120 | /// Text to be Stringinized
121 | /// C# Commentized text
122 | public static string CommentizeInCs(string txt)
123 | {
124 | const string cmtChar = "//";
125 |
126 | var sb = new StringBuilder(txt.Length);
127 |
128 | //process the passed string (txt), one line at a time
129 | //the original was horrible WTF code
130 | using (var reader = new StringReader(txt))
131 | {
132 | string line;
133 | while ((line = reader.ReadLine()) != null)
134 | {
135 | sb.AppendLine(cmtChar + line);
136 | }
137 | }
138 |
139 | return sb.ToString();
140 | }
141 |
142 | public static string CommentizeInVb(string txt)
143 | {
144 | const string cmtChar = "'";
145 |
146 | var sb = new StringBuilder(txt.Length);
147 |
148 | //process the passed string (txt), one line at a time
149 | using (var reader = new StringReader(txt))
150 | {
151 | string line;
152 | while ((line = reader.ReadLine()) != null)
153 | {
154 | sb.AppendLine(cmtChar + line);
155 | }
156 | }
157 |
158 | return sb.ToString();
159 | }
160 |
161 | public static string CommentizeInXml(string txt)
162 | {
163 | //we don't need to escape < or >, just --
164 | return string.Concat("");
165 | }
166 |
167 | public static string StringbuilderizeInCs(string txt, string sbName)
168 | {
169 | //sb to work with
170 | var sb = new StringBuilder(txt);
171 |
172 | //escape \,", and {}
173 | sb.Replace(Quote, Quote + Quote);
174 |
175 | //process the passed string (txt), one line at a time
176 |
177 | //dump the stringbuilder into a temp string
178 | string fullString = sb.ToString();
179 | sb.Clear(); //lovely .net 4 - sb.Remove(0, sb.Length);
180 |
181 | //the original was horrible
182 | using (var reader = new StringReader(fullString))
183 | {
184 | string line;
185 | while ((line = reader.ReadLine()) != null)
186 | {
187 | sb.Append(sbName + ".AppendLine(");
188 | sb.Append("@" + Quote);
189 | sb.Append(line);
190 | sb.AppendLine(Quote + ");");
191 | }
192 | }
193 |
194 | //TODO: Better '@"" + ' replacement to not cover inside strings
195 | sb.Replace("@" + Quote + Quote + " + ", "");
196 |
197 | //add the dec statement
198 | sb.Insert(0, "var " + sbName + " = new System.Text.StringBuilder(" + txt.Length + ");" + Environment.NewLine);
199 |
200 | //and return
201 | return sb.ToString();
202 | }
203 |
204 | public static string StringbuilderizeInVb(string txt, string sbName)
205 | {
206 | //sb to work with
207 | var sb = new StringBuilder(txt);
208 |
209 | //escape
210 | sb.Replace(Quote, Quote + Quote);
211 |
212 | //dump the stringbuilder into a temp string
213 | var fullString = sb.ToString();
214 | sb.Clear();
215 |
216 | //read it line by line
217 | using (var reader = new StringReader(fullString))
218 | {
219 | string line;
220 | while ((line = reader.ReadLine()) != null)
221 | {
222 | sb.Append(sbName + ".AppendLine(");
223 | sb.Append(Quote);
224 | sb.Append(line);
225 | sb.Append(Quote);
226 | sb.AppendLine(")");
227 | }
228 | }
229 |
230 | //add the dec statement
231 | sb.Insert(0, "Dim " + sbName + " As New System.Text.StringBuilder(" + txt.Length + ")" + Environment.NewLine);
232 |
233 | //and return
234 | return sb.ToString();
235 | }
236 |
237 | }
238 | }
239 |
--------------------------------------------------------------------------------
/SmartPaster2013/SmartPaster.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Windows.Forms; //clipboard
3 | using EnvDTE;
4 | using EnvDTE80;
5 | using System.Text;
6 |
7 | namespace SmartPaster2013
8 | {
9 | ///
10 | /// Class responsible for doing the pasting/manipulating of clipdata.
11 | ///
12 | internal sealed class SmartPaster
13 | {
14 | ///
15 | /// Convient property to retrieve the clipboard text from the clipboard
16 | ///
17 | private static string ClipboardText
18 | {
19 | get
20 | {
21 | IDataObject iData = Clipboard.GetDataObject();
22 | if (iData == null) return string.Empty;
23 | //is it Unicode? Then we use that
24 | if (iData.GetDataPresent(DataFormats.UnicodeText))
25 | return Convert.ToString(iData.GetData(DataFormats.UnicodeText));
26 | //otherwise ANSI
27 | if (iData.GetDataPresent(DataFormats.Text))
28 | return Convert.ToString(iData.GetData(DataFormats.Text));
29 | return string.Empty;
30 | }
31 | }
32 |
33 |
34 | ///
35 | /// Inserts text at current cursor location in the application
36 | ///
37 | /// application with activewindow
38 | /// text to insert
39 | private static void Paste(DTE2 application, string text)
40 | {
41 | //get the text document
42 | var txt = (TextDocument)application.ActiveDocument.Object("TextDocument");
43 |
44 | //get an edit point
45 | EditPoint ep = txt.Selection.ActivePoint.CreateEditPoint();
46 |
47 | //get a start point
48 | EditPoint sp = txt.Selection.ActivePoint.CreateEditPoint();
49 |
50 | //open the undo context
51 | bool isOpen = application.UndoContext.IsOpen;
52 | if (!isOpen)
53 | application.UndoContext.Open("SmartPaster");
54 |
55 | //clear the selection
56 | if (!txt.Selection.IsEmpty)
57 | txt.Selection.Delete();
58 |
59 | //insert the text
60 | //ep.Insert(Indent(text, ep.LineCharOffset))
61 | ep.Insert(text);
62 |
63 | //smart format
64 | sp.SmartFormat(ep);
65 |
66 | //close the context
67 | if (!isOpen)
68 | application.UndoContext.Close();
69 | }
70 |
71 | private static bool IsXml(DTE2 application)
72 | {
73 | var caption = application.ActiveWindow.Caption;
74 | foreach (var ext in new [] { ".xml", ".xsd", ".config", ".xaml"})
75 | {
76 | if (caption.EndsWith(ext, StringComparison.OrdinalIgnoreCase))
77 | return true;
78 | }
79 | return false;
80 | }
81 | private static bool IsVb(DTE2 application)
82 | {
83 | return application.ActiveWindow.Caption.EndsWith(".vb", StringComparison.OrdinalIgnoreCase);
84 | }
85 | private static bool IsCs(DTE2 application)
86 | {
87 | return application.ActiveWindow.Caption.EndsWith(".cs", StringComparison.OrdinalIgnoreCase);
88 | }
89 |
90 | private static bool IsCxx(DTE2 application)
91 | {
92 | return application.ActiveDocument.Language == "C/C++";
93 | }
94 | #region "Paste As ..."
95 |
96 | ///
97 | /// Public method to paste and format clipboard text as string the cursor
98 | /// location for the configured or active window's langage .
99 | ///
100 | /// application to insert
101 | public void PasteAsString(DTE2 application)
102 | {
103 | string text;
104 | if (IsVb(application))
105 | text = SmartFormatter.LiterallyInVb(ClipboardText);
106 | else if (IsCs(application))
107 | text = SmartFormatter.LiterallyInCs(ClipboardText);
108 | else if (IsCxx(application))
109 | text = SmartFormatter.LiterallyInCxx(ClipboardText);
110 | else
111 | text = ClipboardText;
112 | Paste(application, text);
113 | }
114 |
115 | public void PasteAsBytes(DTE2 application)
116 | {
117 | if (IsCxx(application) || IsCs(application))
118 | {
119 | var sb = new StringBuilder();
120 | var count = 0;
121 | foreach (var ch in ClipboardText)
122 | {
123 | sb.AppendFormat("0x{0:x2}, ", (int)ch);
124 | if (++count == 16)
125 | {
126 | count = 0;
127 | sb.AppendLine();
128 | }
129 | }
130 | Paste(application, sb.ToString());
131 | }
132 | }
133 |
134 | ///
135 | /// Pastes as verbatim string.
136 | ///
137 | /// The application.
138 | public void PasteAsVerbatimString(DTE2 application)
139 | {
140 | if (IsVb(application))
141 | {
142 | //vb14 has verbatim strings, otherwise do the CData trick
143 | int version;
144 | var appVersion = application.Version;
145 | var p = appVersion.IndexOf('.'); //12.0 in VS2013, but MSDN says dp is optional
146 | if (p > 0) appVersion = appVersion.Substring(0, p);
147 |
148 | int.TryParse(appVersion, out version);
149 |
150 | Paste(application,
151 | version < 14
152 | ? SmartFormatter.CDataizeInVb(ClipboardText)
153 | : SmartFormatter.StringinizeInVb(ClipboardText));
154 | return;
155 | }
156 | //c#
157 | Paste(application, SmartFormatter.StringinizeInCs(ClipboardText));
158 | }
159 |
160 |
161 | ///
162 | /// Public method to paste and format clipboard text as comment the cursor
163 | /// location for the configured or active window's langage .
164 | ///
165 | /// application to insert
166 | public void PasteAsComment(DTE2 application)
167 | {
168 | string text;
169 | if (IsVb(application))
170 | {
171 | text = SmartFormatter.CommentizeInVb(ClipboardText);
172 | }
173 | else if (IsXml(application))
174 | {
175 | text = SmartFormatter.CommentizeInXml(ClipboardText);
176 | }
177 | else
178 | {
179 | text = SmartFormatter.CommentizeInCs(ClipboardText);
180 | }
181 | Paste(application, text);
182 | }
183 |
184 |
185 | ///
186 | /// Public method to paste format clipboard text into a specified region
187 | ///
188 | /// application to insert
189 | public void PasteAsRegion(DTE2 application)
190 | {
191 | //get the region name
192 | const string region = "myRegion";
193 |
194 | //it's so simple, we really don't need a function
195 | string csRegionized = "#region " + region + Environment.NewLine + ClipboardText + Environment.NewLine + "#endregion";
196 |
197 | //and paste
198 | Paste(application, csRegionized);
199 | }
200 |
201 | ///
202 | /// Public method to paste and format clipboard text as stringbuilder the cursor
203 | /// location for the configured or active window's langage .
204 | ///
205 | /// application to insert
206 | public void PasteAsStringBuilder(DTE2 application)
207 | {
208 | const string stringbuilder = "sb";
209 | Paste(application, IsVb(application) ?
210 | SmartFormatter.StringbuilderizeInVb(ClipboardText, stringbuilder) :
211 | SmartFormatter.StringbuilderizeInCs(ClipboardText, stringbuilder));
212 | }
213 |
214 | public void PasteWithReplace(DTE2 application)
215 | {
216 | using (var replaceForm = new ReplaceForm())
217 | {
218 | if (replaceForm.ShowDialog() == DialogResult.OK)
219 | {
220 | var src = replaceForm.TextToReplace;
221 | var dst = replaceForm.ReplaceText;
222 | var txt = ClipboardText.Replace(src, dst);
223 | Paste(application, txt);
224 | }
225 | }
226 | }
227 |
228 | #endregion
229 | }
230 | }
231 |
--------------------------------------------------------------------------------
/SmartPaster2013/SmartPaster2013.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | 15.0
6 | 12.0
7 | $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)
8 |
9 |
10 |
11 |
12 | 12.0
13 | publish\
14 | true
15 | Disk
16 | false
17 | Foreground
18 | 7
19 | Days
20 | false
21 | false
22 | true
23 | 0
24 | 1.0.0.%2a
25 | false
26 | false
27 | true
28 |
29 |
30 |
31 |
32 |
33 |
34 | Debug
35 | AnyCPU
36 | 2.0
37 | {E4C30299-C9D8-4860-BBB0-02F5887D3ED2}
38 | {82b43b9b-a64c-4715-b499-d71e9ca2bd60};{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
39 | Library
40 | Properties
41 | SmartPaster2013
42 | SmartPaster2019
43 | True
44 | Key.snk
45 | v4.6
46 |
47 |
48 | true
49 | full
50 | false
51 | bin\Debug\
52 | DEBUG;TRACE
53 | prompt
54 | 4
55 | True
56 |
57 |
58 | pdbonly
59 | true
60 | bin\Release\
61 | TRACE
62 | prompt
63 | 4
64 | true
65 |
66 |
67 |
68 | False
69 | False
70 |
71 |
72 | False
73 | False
74 |
75 |
76 | False
77 | False
78 |
79 |
80 | False
81 | False
82 |
83 |
84 | ..\packages\Microsoft.VisualStudio.CoreUtility.15.0.26201\lib\net45\Microsoft.VisualStudio.CoreUtility.dll
85 | True
86 |
87 |
88 | ..\packages\Microsoft.VisualStudio.Imaging.14.3.25407\lib\net45\Microsoft.VisualStudio.Imaging.dll
89 | True
90 |
91 |
92 | ..\packages\Microsoft.VisualStudio.OLE.Interop.7.10.6070\lib\Microsoft.VisualStudio.OLE.Interop.dll
93 | True
94 |
95 |
96 | ..\packages\Microsoft.VisualStudio.Shell.14.0.14.3.25407\lib\Microsoft.VisualStudio.Shell.14.0.dll
97 | True
98 |
99 |
100 | ..\packages\Microsoft.VisualStudio.Shell.Framework.15.0.26201\lib\net45\Microsoft.VisualStudio.Shell.Framework.dll
101 | True
102 |
103 |
104 | ..\packages\Microsoft.VisualStudio.Shell.Immutable.10.0.10.0.30319\lib\net40\Microsoft.VisualStudio.Shell.Immutable.10.0.dll
105 | True
106 |
107 |
108 | ..\packages\Microsoft.VisualStudio.Shell.Immutable.11.0.11.0.50727\lib\net45\Microsoft.VisualStudio.Shell.Immutable.11.0.dll
109 | True
110 |
111 |
112 | ..\packages\Microsoft.VisualStudio.Shell.Immutable.12.0.12.0.21003\lib\net45\Microsoft.VisualStudio.Shell.Immutable.12.0.dll
113 | True
114 |
115 |
116 | ..\packages\Microsoft.VisualStudio.Shell.Immutable.14.0.14.3.25407\lib\net45\Microsoft.VisualStudio.Shell.Immutable.14.0.dll
117 | True
118 |
119 |
120 | ..\packages\Microsoft.VisualStudio.Shell.Interop.7.10.6071\lib\Microsoft.VisualStudio.Shell.Interop.dll
121 | True
122 |
123 |
124 | ..\packages\Microsoft.VisualStudio.Shell.Interop.8.0.8.0.50727\lib\Microsoft.VisualStudio.Shell.Interop.8.0.dll
125 | True
126 |
127 |
128 | ..\packages\Microsoft.VisualStudio.Shell.Interop.9.0.9.0.30729\lib\Microsoft.VisualStudio.Shell.Interop.9.0.dll
129 | True
130 |
131 |
132 | ..\packages\Microsoft.VisualStudio.TextManager.Interop.7.10.6070\lib\Microsoft.VisualStudio.TextManager.Interop.dll
133 | True
134 |
135 |
136 | ..\packages\Microsoft.VisualStudio.TextManager.Interop.8.0.8.0.50727\lib\Microsoft.VisualStudio.TextManager.Interop.8.0.dll
137 | True
138 |
139 |
140 | ..\packages\Microsoft.VisualStudio.Threading.14.1.111\lib\net45\Microsoft.VisualStudio.Threading.dll
141 | True
142 |
143 |
144 | ..\packages\Microsoft.VisualStudio.Utilities.15.0.26201\lib\net45\Microsoft.VisualStudio.Utilities.dll
145 | True
146 |
147 |
148 | ..\packages\Microsoft.VisualStudio.Validation.14.1.111\lib\net45\Microsoft.VisualStudio.Validation.dll
149 | True
150 |
151 |
152 | False
153 | False
154 |
155 |
156 | False
157 | False
158 |
159 |
160 |
161 |
162 | true
163 |
164 |
165 | true
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 | Form
179 |
180 |
181 | ReplaceForm.cs
182 |
183 |
184 | True
185 | True
186 | Resources.resx
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 | ReplaceForm.cs
198 |
199 |
200 | ResXFileCodeGenerator
201 | Resources.Designer.cs
202 | Designer
203 |
204 |
205 | true
206 | VSPackage
207 |
208 |
209 |
210 |
211 |
212 |
213 | Designer
214 |
215 |
216 |
217 |
218 |
219 |
220 |
221 | Menus.ctmenu
222 | Designer
223 |
224 |
225 |
226 |
227 |
228 |
229 |
230 | License.txt
231 | true
232 |
233 |
234 | Always
235 | true
236 |
237 |
238 |
239 |
240 |
241 | False
242 | .NET Framework 3.5 SP1
243 | false
244 |
245 |
246 |
247 | true
248 |
249 |
250 |
251 |
252 |
259 |
260 |
--------------------------------------------------------------------------------
/SmartPaster2013/SmartPaster2013.vsct:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
10 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
28 |
29 |
41 |
42 |
50 |
51 |
52 |
53 |
54 |
55 |
58 |
59 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
71 |
72 |
79 |
80 |
87 |
94 |
101 |
108 |
115 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
--------------------------------------------------------------------------------
/SmartPaster2013/SmartPaster2013Package.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Diagnostics;
3 | using System.Globalization;
4 | using System.Runtime.InteropServices;
5 | using System.ComponentModel.Design;
6 | using Microsoft.VisualStudio.Shell;
7 | using EnvDTE;
8 | using EnvDTE80;
9 |
10 | namespace SmartPaster2013
11 | {
12 | ///
13 | /// This is the class that implements the package exposed by this assembly.
14 | ///
15 | /// The minimum requirement for a class to be considered a valid package for Visual Studio
16 | /// is to implement the IVsPackage interface and register itself with the shell.
17 | /// This package uses the helper classes defined inside the Managed Package Framework (MPF)
18 | /// to do it: it derives from the Package class that provides the implementation of the
19 | /// IVsPackage interface and uses the registration attributes defined in the framework to
20 | /// register itself and its components with the shell.
21 | ///
22 | // This attribute tells the PkgDef creation utility (CreatePkgDef.exe) that this class is
23 | // a package.
24 | [PackageRegistration(UseManagedResourcesOnly = true)]
25 | // This attribute is used to register the information needed to show this package
26 | // in the Help/About dialog of Visual Studio.
27 | [InstalledProductRegistration("#110", "#112", "1.0", IconResourceID = 400)]
28 | // This attribute is needed to let the shell know that this package exposes some menus.
29 | [ProvideMenuResource("Menus.ctmenu", 1)]
30 | [Guid(GuidList.guidSmartPaster2013PkgString)]
31 | public sealed class SmartPaster2013Package : Package
32 | {
33 | ///
34 | /// Default constructor of the package.
35 | /// Inside this method you can place any initialization code that does not require
36 | /// any Visual Studio service because at this point the package object is created but
37 | /// not sited yet inside Visual Studio environment. The place to do all the other
38 | /// initialization is the Initialize method.
39 | ///
40 | public SmartPaster2013Package()
41 | {
42 | Debug.WriteLine(string.Format(CultureInfo.CurrentCulture, "Entering constructor for: {0}", this.ToString()));
43 | // Debug.WriteLine(string.Format(CultureInfo.CurrentCulture, "Entering constructor for: {0}", this.ToString()));
44 | }
45 |
46 |
47 |
48 | /////////////////////////////////////////////////////////////////////////////
49 | // Overridden Package Implementation
50 | #region Package Members
51 |
52 | ///
53 | /// Initialization of the package; this method is called right after the package is sited, so this is the place
54 | /// where you can put all the initialization code that rely on services provided by VisualStudio.
55 | ///
56 | protected override void Initialize()
57 | {
58 | Debug.WriteLine(string.Format(CultureInfo.CurrentCulture, "Entering Initialize() of: {0}", this.ToString()));
59 | base.Initialize();
60 |
61 |
62 | // Add our command handlers for menu (commands must exist in the .vsct file)
63 | var mcs = GetService(typeof(IMenuCommandService)) as OleMenuCommandService;
64 | if (null != mcs)
65 | {
66 | // Create the command for the menu item.
67 | var menuCommandVerbatimID = new CommandID(GuidList.guidSmartPaster2013CmdSet, (int)PkgCmdIDList.cmdidPasteAsVerbatimString);
68 | var menuItemVerbatim = new MenuCommand(CallPasteAsVerbatimString, menuCommandVerbatimID);
69 | mcs.AddCommand(menuItemVerbatim);
70 |
71 | var menuCommandStringID = new CommandID(GuidList.guidSmartPaster2013CmdSet, (int)PkgCmdIDList.cmdidPasteAsString);
72 | var menuItemString = new MenuCommand(CallPasteAsString, menuCommandStringID);
73 | mcs.AddCommand(menuItemString);
74 |
75 | var menuCommandBytesID = new CommandID(GuidList.guidSmartPaster2013CmdSet, (int)PkgCmdIDList.cmdidPasteAsBytes);
76 | var menuItemBytes = new MenuCommand(CallPasteAsBytes, menuCommandBytesID);
77 | mcs.AddCommand(menuItemBytes);
78 |
79 | var menuCommandSbID = new CommandID(GuidList.guidSmartPaster2013CmdSet, (int)PkgCmdIDList.cmdidPasteAsStringBuilder);
80 | var menuItemSb = new MenuCommand(CallPasteAsStringBuilder, menuCommandSbID);
81 | mcs.AddCommand(menuItemSb);
82 |
83 | var menuCommandID = new CommandID(GuidList.guidSmartPaster2013CmdSet, (int)PkgCmdIDList.cmdidPasteAsComment);
84 | var menuItem = new MenuCommand(CallPasteAsComment, menuCommandID);
85 | mcs.AddCommand(menuItem);
86 |
87 | var menuCommandReplaceID = new CommandID(GuidList.guidSmartPaster2013CmdSet, (int)PkgCmdIDList.cmdidPasteWithReplace);
88 | var menuItemReplace = new MenuCommand(CallPasteWithReplace, menuCommandReplaceID);
89 | mcs.AddCommand(menuItemReplace);
90 |
91 | }
92 | }
93 | #endregion
94 |
95 |
96 |
97 | ///
98 | /// This function is the callback used to execute a command when the a menu item is clicked.
99 | /// See the Initialize method to see how the menu item is associated to this function using
100 | /// the OleMenuCommandService service and the MenuCommand class.
101 | ///
102 | private void CallPasteAsComment(object sender, EventArgs e)
103 | {
104 | var dte = (DTE2)GetService(typeof(DTE));
105 | var sp = new SmartPaster();
106 | sp.PasteAsComment(dte);
107 | }
108 |
109 | private void CallPasteAsStringBuilder(object sender, EventArgs e)
110 | {
111 | var dte = (DTE2)GetService(typeof(DTE));
112 | var sp = new SmartPaster();
113 | sp.PasteAsStringBuilder(dte);
114 | }
115 |
116 | private void CallPasteAsString(object sender, EventArgs e)
117 | {
118 | var dte = (DTE2)GetService(typeof(DTE));
119 | var sp = new SmartPaster();
120 | sp.PasteAsString(dte);
121 | }
122 |
123 | private void CallPasteAsBytes(object sender, EventArgs e)
124 | {
125 | var dte = (DTE2)GetService(typeof(DTE));
126 | var sp = new SmartPaster();
127 | sp.PasteAsBytes(dte);
128 | }
129 |
130 | private void CallPasteAsVerbatimString(object sender, EventArgs e)
131 | {
132 | var dte = (DTE2)GetService(typeof(DTE));
133 | var sp = new SmartPaster();
134 | sp.PasteAsVerbatimString(dte);
135 | }
136 |
137 | private void CallPasteWithReplace(object sender, EventArgs e)
138 | {
139 | var dte = (DTE2)GetService(typeof(DTE));
140 | var sp = new SmartPaster();
141 | sp.PasteWithReplace(dte);
142 | }
143 |
144 | }
145 | }
146 |
--------------------------------------------------------------------------------
/SmartPaster2013/SmartPaster2013_IntegrationTests/IntegrationTest Library/DialogboxPurger.cs:
--------------------------------------------------------------------------------
1 |
2 | namespace Microsoft.VsSDK.IntegrationTestLibrary
3 | {
4 | using System;
5 | using System.Collections.Generic;
6 | using System.Text;
7 | using System.Runtime.InteropServices;
8 | using System.Threading;
9 | using Microsoft.VisualStudio.Shell.Interop;
10 | using Microsoft.VisualStudio.Shell;
11 |
12 | ///
13 | /// This class is responsible to close dialog boxes that pop up during different VS Calls
14 | ///
15 | internal class DialogBoxPurger : IDisposable
16 | {
17 | ///
18 | /// The default number of milliseconds to wait for the threads to signal to terminate.
19 | ///
20 | private const int DefaultMillisecondsToWait = 3500;
21 |
22 | ///
23 | /// Object used for synchronization between thread calls.
24 | ///
25 | internal static volatile object Mutex = new object();
26 |
27 | ///
28 | /// The IVsUIShell. This cannot be queried on the working thread from the service provider. Must be done in the main thread.!!
29 | ///
30 | private IVsUIShell uiShell;
31 |
32 | ///
33 | /// The button to "press" on the dialog.
34 | ///
35 | private int buttonAction;
36 |
37 | ///
38 | /// Thread signales to the calling thread that it is done.
39 | ///
40 | private bool exitThread = false;
41 |
42 | ///
43 | /// Calling thread signales to this thread to die.
44 | ///
45 | private AutoResetEvent threadDone = new AutoResetEvent(false);
46 |
47 | ///
48 | /// The queued thread started.
49 | ///
50 | private AutoResetEvent threadStarted = new AutoResetEvent(false);
51 |
52 | ///
53 | /// 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.
54 | ///
55 | private bool dialogBoxCloseResult = false;
56 |
57 | ///
58 | /// The expected text to see on the dialog box. If set the thread will continue finding the dialog box with this text.
59 | ///
60 | private string expectedDialogBoxText = String.Empty;
61 |
62 | ///
63 | /// The number of the same dialog boxes to wait for.
64 | /// This is for scenarios when two dialog boxes with the same text are popping up.
65 | ///
66 | private int numberOfDialogsToWaitFor = 1;
67 |
68 | ///
69 | /// Has the object been disposed.
70 | ///
71 | private bool isDisposed;
72 |
73 | ///
74 | /// Overloaded ctor.
75 | ///
76 | /// The botton to "press" on the dialog box.
77 | /// 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
78 | /// The expected dialog box message to check for.
79 | internal DialogBoxPurger(int buttonAction, int numberOfDialogsToWaitFor, string expectedDialogMesssage)
80 | {
81 | this.buttonAction = buttonAction;
82 | this.numberOfDialogsToWaitFor = numberOfDialogsToWaitFor;
83 | this.expectedDialogBoxText = expectedDialogMesssage;
84 | }
85 |
86 | ///
87 | /// Overloaded ctor.
88 | ///
89 | /// The botton to "press" on the dialog box.
90 | /// 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
91 | internal DialogBoxPurger(int buttonAction, int numberOfDialogsToWaitFor)
92 | {
93 | this.buttonAction = buttonAction;
94 | this.numberOfDialogsToWaitFor = numberOfDialogsToWaitFor;
95 | }
96 |
97 | ///
98 | /// Overloaded ctor.
99 | ///
100 | /// The botton to "press" on the dialog box.
101 | /// The expected dialog box message to check for.
102 | internal DialogBoxPurger(int buttonAction, string expectedDialogMesssage)
103 | {
104 | this.buttonAction = buttonAction;
105 | this.expectedDialogBoxText = expectedDialogMesssage;
106 | }
107 |
108 | ///
109 | /// Overloaded ctor.
110 | ///
111 | /// The botton to "press" on the dialog box.
112 | internal DialogBoxPurger(int buttonAction)
113 | {
114 | this.buttonAction = buttonAction;
115 | }
116 |
117 | ///
118 | #region IDisposable Members
119 |
120 | void IDisposable.Dispose()
121 | {
122 | if (this.isDisposed)
123 | {
124 | return;
125 | }
126 |
127 | this.WaitForDialogThreadToTerminate();
128 |
129 | this.isDisposed = true;
130 | }
131 |
132 | ///
133 | /// Spawns a thread that will start listening to dialog boxes.
134 | ///
135 | internal void Start()
136 | {
137 | // We ask for the uishell here since we cannot do that on the therad that we will spawn.
138 | IVsUIShell uiShell = Package.GetGlobalService(typeof(SVsUIShell)) as IVsUIShell;
139 |
140 | if (uiShell == null)
141 | {
142 | throw new InvalidOperationException("Could not get the uiShell from the serviceProvider");
143 | }
144 |
145 | this.uiShell = uiShell;
146 |
147 | System.Threading.Thread thread = new System.Threading.Thread(new ThreadStart(this.HandleDialogBoxes));
148 | thread.Start();
149 |
150 | // We should never deadlock here, hence do not use the lock. Wait to be sure that the thread started.
151 | this.threadStarted.WaitOne(3500, false);
152 | }
153 |
154 | ///
155 | /// Waits for the dialog box close thread to terminate. If the thread does not signal back within millisecondsToWait that it is shutting down,
156 | /// then it will tell to the thread to do it.
157 | ///
158 | internal bool WaitForDialogThreadToTerminate()
159 | {
160 | return this.WaitForDialogThreadToTerminate(DefaultMillisecondsToWait);
161 | }
162 |
163 | ///
164 | /// Waits for the dialog box close thread to terminate. If the thread does not signal back within millisecondsToWait that it is shutting down,
165 | /// then it will tell to the thread to do it.
166 | ///
167 | /// 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.
168 | /// The result of the dialog boxes closing
169 | internal bool WaitForDialogThreadToTerminate(int numberOfMillisecondsToWait)
170 | {
171 | bool signaled = false;
172 |
173 | // We give millisecondsToWait sec to bring up and close the dialog box.
174 | signaled = this.threadDone.WaitOne(numberOfMillisecondsToWait, false);
175 |
176 | // Kill the thread since a timeout occured.
177 | if (!signaled)
178 | {
179 | lock (Mutex)
180 | {
181 | // Set the exit thread to true. Next time the thread will kill itselfes if it sees
182 | this.exitThread = true;
183 | }
184 |
185 | // Wait for the thread to finish. We should never deadlock here.
186 | this.threadDone.WaitOne();
187 | }
188 |
189 | return this.dialogBoxCloseResult;
190 | }
191 |
192 | ///
193 | /// This is the thread method.
194 | ///
195 | private void HandleDialogBoxes()
196 | {
197 | // No synchronization numberOfDialogsToWaitFor since it is readonly
198 | IntPtr[] hwnds = new IntPtr[this.numberOfDialogsToWaitFor];
199 | bool[] dialogBoxCloseResults = new bool[this.numberOfDialogsToWaitFor];
200 |
201 | try
202 | {
203 | // Signal that we started
204 | lock (Mutex)
205 | {
206 | this.threadStarted.Set();
207 | }
208 |
209 | // 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.
210 | bool stayInLoop = true;
211 | int dialogBoxesToWaitFor = 1;
212 |
213 | while (stayInLoop)
214 | {
215 | int hwndIndex = dialogBoxesToWaitFor - 1;
216 |
217 | // We need to lock since the caller might set context to null.
218 | lock (Mutex)
219 | {
220 | if (this.exitThread)
221 | {
222 | break;
223 | }
224 |
225 | // We protect the shell too from reentrency.
226 | this.uiShell.GetDialogOwnerHwnd(out hwnds[hwndIndex]);
227 |
228 | }
229 |
230 | if (hwnds[hwndIndex] != IntPtr.Zero)
231 | {
232 | StringBuilder windowClassName = new StringBuilder(256);
233 | NativeMethods.GetClassName(hwnds[hwndIndex], windowClassName, windowClassName.Capacity);
234 |
235 | // The #32770 is the class name of a messagebox dialog.
236 | if (windowClassName.ToString().Contains("#32770"))
237 | {
238 | IntPtr unmanagedMemoryLocation = IntPtr.Zero;
239 | string dialogBoxText = String.Empty;
240 | try
241 | {
242 | unmanagedMemoryLocation = Marshal.AllocHGlobal(10 * 1024);
243 | NativeMethods.EnumChildWindows(hwnds[hwndIndex], new NativeMethods.CallBack(FindMessageBoxString), unmanagedMemoryLocation);
244 | dialogBoxText = Marshal.PtrToStringUni(unmanagedMemoryLocation);
245 | }
246 | finally
247 | {
248 | if (unmanagedMemoryLocation != IntPtr.Zero)
249 | {
250 | Marshal.FreeHGlobal(unmanagedMemoryLocation);
251 | }
252 | }
253 |
254 | lock (Mutex)
255 | {
256 |
257 | // Since this is running on the main thread be sure that we close the dialog.
258 | bool dialogCloseResult = false;
259 | if (this.buttonAction != 0)
260 | {
261 | dialogCloseResult = NativeMethods.EndDialog(hwnds[hwndIndex], this.buttonAction);
262 | }
263 |
264 | // Check if we have found the right dialog box.
265 | if (String.IsNullOrEmpty(this.expectedDialogBoxText) || (!String.IsNullOrEmpty(dialogBoxText) && String.Compare(this.expectedDialogBoxText, dialogBoxText.Trim(), StringComparison.OrdinalIgnoreCase) == 0))
266 | {
267 | dialogBoxCloseResults[hwndIndex] = dialogCloseResult;
268 | if (dialogBoxesToWaitFor++ >= this.numberOfDialogsToWaitFor)
269 | {
270 | stayInLoop = false;
271 | }
272 | }
273 | }
274 | }
275 | }
276 | }
277 | }
278 | finally
279 | {
280 | //Let the main thread run a possible close command.
281 | System.Threading.Thread.Sleep(2000);
282 |
283 | foreach (IntPtr hwnd in hwnds)
284 | {
285 | // At this point the dialog should be closed, if not attempt to close it.
286 | if (hwnd != IntPtr.Zero)
287 | {
288 | NativeMethods.SendMessage(hwnd, NativeMethods.WM_CLOSE, 0, new IntPtr(0));
289 | }
290 | }
291 |
292 | lock (Mutex)
293 | {
294 | // Be optimistic.
295 | this.dialogBoxCloseResult = true;
296 |
297 | for (int i = 0; i < dialogBoxCloseResults.Length; i++)
298 | {
299 | if (!dialogBoxCloseResults[i])
300 | {
301 | this.dialogBoxCloseResult = false;
302 | break;
303 | }
304 | }
305 |
306 | this.threadDone.Set();
307 | }
308 | }
309 | }
310 |
311 | ///
312 | /// Finds a messagebox string on a messagebox.
313 | ///
314 | /// The windows handle of the dialog
315 | /// A pointer to the memorylocation the string will be written to
316 | /// True if found.
317 | private static bool FindMessageBoxString(IntPtr hwnd, IntPtr unmanagedMemoryLocation)
318 | {
319 | StringBuilder sb = new StringBuilder(512);
320 | NativeMethods.GetClassName(hwnd, sb, sb.Capacity);
321 |
322 | if (sb.ToString().ToLower().Contains("static"))
323 | {
324 | StringBuilder windowText = new StringBuilder(2048);
325 | NativeMethods.GetWindowText(hwnd, windowText, windowText.Capacity);
326 |
327 | if (windowText.Length > 0)
328 | {
329 | IntPtr stringAsPtr = IntPtr.Zero;
330 | try
331 | {
332 | stringAsPtr = Marshal.StringToHGlobalAnsi(windowText.ToString());
333 | char[] stringAsArray = windowText.ToString().ToCharArray();
334 |
335 | // Since unicode characters are copied check if we are out of the allocated length.
336 | // If not add the end terminating zero.
337 | if ((2 * stringAsArray.Length) + 1 < 2048)
338 | {
339 | Marshal.Copy(stringAsArray, 0, unmanagedMemoryLocation, stringAsArray.Length);
340 | Marshal.WriteInt32(unmanagedMemoryLocation, 2 * stringAsArray.Length, 0);
341 | }
342 | }
343 | finally
344 | {
345 | if (stringAsPtr != IntPtr.Zero)
346 | {
347 | Marshal.FreeHGlobal(stringAsPtr);
348 | }
349 | }
350 | return false;
351 | }
352 | }
353 |
354 | return true;
355 | }
356 |
357 | #endregion
358 | }
359 | }
360 |
--------------------------------------------------------------------------------
/SmartPaster2013/SmartPaster2013_IntegrationTests/IntegrationTest Library/NativeMethods.cs:
--------------------------------------------------------------------------------
1 | /***************************************************************************
2 |
3 | Copyright (c) Microsoft Corporation. All rights reserved.
4 | This code is licensed under the Visual Studio SDK license terms.
5 | THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
6 | ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
7 | IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
8 | PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
9 |
10 | ***************************************************************************/
11 |
12 | namespace Microsoft.VsSDK.IntegrationTestLibrary
13 | {
14 | using System;
15 | using System.Collections.Generic;
16 | using System.Text;
17 | using System.Runtime.InteropServices;
18 | using System.Threading;
19 | using Microsoft.VisualStudio.Shell.Interop;
20 |
21 | ///
22 | /// Defines pinvoked utility methods and internal VS Constants
23 | ///
24 | internal static class NativeMethods
25 | {
26 | internal delegate bool CallBack(IntPtr hwnd, IntPtr lParam);
27 |
28 | // Declare two overloaded SendMessage functions
29 | [DllImport("user32.dll")]
30 | internal static extern UInt32 SendMessage(IntPtr hWnd, UInt32 Msg,
31 | UInt32 wParam, IntPtr lParam);
32 |
33 | [DllImport("user32.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto)]
34 | internal static extern bool PeekMessage([In, Out] ref Microsoft.VisualStudio.OLE.Interop.MSG msg, HandleRef hwnd, int msgMin, int msgMax, int remove);
35 |
36 | [DllImport("user32.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto)]
37 | internal static extern bool TranslateMessage([In, Out] ref Microsoft.VisualStudio.OLE.Interop.MSG msg);
38 |
39 | [DllImport("user32.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto)]
40 | internal static extern int DispatchMessage([In] ref Microsoft.VisualStudio.OLE.Interop.MSG msg);
41 |
42 | [DllImport("user32.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto)]
43 | internal static extern bool AttachThreadInput(uint idAttach, uint idAttachTo, bool attach);
44 |
45 | [DllImport("user32.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto)]
46 | internal static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);
47 |
48 | [DllImport("kernel32.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto)]
49 | internal static extern uint GetCurrentThreadId();
50 |
51 | [DllImport("user32")]
52 | internal static extern int EnumChildWindows(IntPtr hwnd, CallBack x, IntPtr y);
53 |
54 | [DllImport("user32")]
55 | internal static extern bool IsWindowVisible(IntPtr hDlg);
56 |
57 | [DllImport("user32.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto)]
58 | internal static extern IntPtr SetFocus(IntPtr hWnd);
59 |
60 | [DllImport("user32")]
61 | internal static extern int GetClassName(IntPtr hWnd,
62 | StringBuilder className,
63 | int stringLength);
64 | [DllImport("user32")]
65 | internal static extern int GetWindowText(IntPtr hWnd, StringBuilder className, int stringLength);
66 |
67 |
68 | [DllImport("user32")]
69 | internal static extern bool EndDialog(IntPtr hDlg, int result);
70 |
71 | [DllImport("Kernel32")]
72 | internal static extern long GetLastError();
73 |
74 | internal const int QS_KEY = 0x0001,
75 | QS_MOUSEMOVE = 0x0002,
76 | QS_MOUSEBUTTON = 0x0004,
77 | QS_POSTMESSAGE = 0x0008,
78 | QS_TIMER = 0x0010,
79 | QS_PAINT = 0x0020,
80 | QS_SENDMESSAGE = 0x0040,
81 | QS_HOTKEY = 0x0080,
82 | QS_ALLPOSTMESSAGE = 0x0100,
83 | QS_MOUSE = QS_MOUSEMOVE | QS_MOUSEBUTTON,
84 | QS_INPUT = QS_MOUSE | QS_KEY,
85 | QS_ALLEVENTS = QS_INPUT | QS_POSTMESSAGE | QS_TIMER | QS_PAINT | QS_HOTKEY,
86 | QS_ALLINPUT = QS_INPUT | QS_POSTMESSAGE | QS_TIMER | QS_PAINT | QS_HOTKEY | QS_SENDMESSAGE;
87 |
88 | internal const int Facility_Win32 = 7;
89 |
90 | internal const int WM_CLOSE = 0x0010;
91 |
92 | internal const int
93 | S_FALSE = 0x00000001,
94 | S_OK = 0x00000000,
95 |
96 | IDOK = 1,
97 | IDCANCEL = 2,
98 | IDABORT = 3,
99 | IDRETRY = 4,
100 | IDIGNORE = 5,
101 | IDYES = 6,
102 | IDNO = 7,
103 | IDCLOSE = 8,
104 | IDHELP = 9,
105 | IDTRYAGAIN = 10,
106 | IDCONTINUE = 11;
107 |
108 | internal static long HResultFromWin32(long error)
109 | {
110 | if (error <= 0)
111 | {
112 | return error;
113 | }
114 |
115 | return ((error & 0x0000FFFF) | (Facility_Win32 << 16) | 0x80000000);
116 | }
117 |
118 | ///
119 | /// Please use this "approved" method to compare file names.
120 | ///
121 | public static bool IsSamePath(string file1, string file2)
122 | {
123 | if (file1 == null || file1.Length == 0)
124 | {
125 | return (file2 == null || file2.Length == 0);
126 | }
127 |
128 | Uri uri1 = null;
129 | Uri uri2 = null;
130 |
131 | try
132 | {
133 | if (!Uri.TryCreate(file1, UriKind.Absolute, out uri1) || !Uri.TryCreate(file2, UriKind.Absolute, out uri2))
134 | {
135 | return false;
136 | }
137 |
138 | if (uri1 != null && uri1.IsFile && uri2 != null && uri2.IsFile)
139 | {
140 | return 0 == String.Compare(uri1.LocalPath, uri2.LocalPath, StringComparison.OrdinalIgnoreCase);
141 | }
142 |
143 | return file1 == file2;
144 | }
145 | catch (UriFormatException e)
146 | {
147 | System.Diagnostics.Trace.WriteLine("Exception " + e.Message);
148 | }
149 |
150 | return false;
151 | }
152 |
153 | }
154 | }
155 |
--------------------------------------------------------------------------------
/SmartPaster2013/SmartPaster2013_IntegrationTests/IntegrationTest Library/Utils.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.IO;
3 | using System.Text;
4 | using System.Reflection;
5 | using System.Diagnostics;
6 | using System.Collections;
7 | using System.Collections.Generic;
8 | using System.ComponentModel.Design;
9 | using System.Runtime.InteropServices;
10 | using Microsoft.VisualStudio.Shell.Interop;
11 | using Microsoft.VisualStudio.Shell;
12 | using EnvDTE;
13 | using EnvDTE80;
14 | using Microsoft.Win32;
15 | using IOleServiceProvider = Microsoft.VisualStudio.OLE.Interop.IServiceProvider;
16 | using Microsoft.VisualStudio.TestTools.UnitTesting;
17 | using Microsoft.VSSDK.Tools.VsIdeTesting;
18 | using Microsoft.VisualStudio;
19 |
20 | namespace Microsoft.VsSDK.IntegrationTestLibrary
21 | {
22 | ///
23 | ///
24 | public class TestUtils
25 | {
26 |
27 | #region Methods: Handling embedded resources
28 | ///
29 | /// Gets the embedded file identified by the resource name, and converts the
30 | /// file into a string.
31 | ///
32 | /// In VS, is DefaultNamespace.FileName?
33 | ///
34 | public static string GetEmbeddedStringResource(Assembly assembly, string resourceName)
35 | {
36 | string result = null;
37 |
38 | // Use the .NET procedure for loading a file embedded in the assembly
39 | Stream stream = assembly.GetManifestResourceStream(resourceName);
40 | if (stream != null)
41 | {
42 | // Convert bytes to string
43 | byte[] fileContentsAsBytes = new byte[stream.Length];
44 | stream.Read(fileContentsAsBytes, 0, (int)stream.Length);
45 | result = Encoding.Default.GetString(fileContentsAsBytes);
46 | }
47 | else
48 | {
49 | // Embedded resource not found - list available resources
50 | Debug.WriteLine("Unable to find the embedded resource file '" + resourceName + "'.");
51 | Debug.WriteLine(" Available resources:");
52 | foreach (string aResourceName in assembly.GetManifestResourceNames())
53 | {
54 | Debug.WriteLine(" " + aResourceName);
55 | }
56 | }
57 |
58 | return result;
59 | }
60 | ///
61 | ///
62 | ///
63 | ///
64 | ///
65 | ///
66 | ///
67 | public static void WriteEmbeddedResourceToFile(Assembly assembly, string embeddedResourceName, string fileName)
68 | {
69 | // Get file contents
70 | string fileContents = GetEmbeddedStringResource(assembly, embeddedResourceName);
71 | if (fileContents == null)
72 | throw new ApplicationException("Failed to get embedded resource '" + embeddedResourceName + "' from assembly '" + assembly.FullName);
73 |
74 | // Write to file
75 | StreamWriter sw = new StreamWriter(fileName);
76 | sw.Write(fileContents);
77 | sw.Close();
78 | }
79 |
80 | ///
81 | /// Writes an embedded resource to a file.
82 | ///
83 | /// The name of the assembly that the embedded resource is defined.
84 | /// The name of the embedded resource.
85 | /// The file to write the embedded resource's content.
86 | public static void WriteEmbeddedResourceToBinaryFile(Assembly assembly, string embeddedResourceName, string fileName)
87 | {
88 | // Get file contents
89 | Stream stream = assembly.GetManifestResourceStream(embeddedResourceName);
90 | if (stream == null)
91 | throw new InvalidOperationException("Failed to get embedded resource '" + embeddedResourceName + "' from assembly '" + assembly.FullName);
92 |
93 | // Write to file
94 | BinaryWriter sw = null;
95 | FileStream fs = null;
96 | try
97 | {
98 | byte[] fileContentsAsBytes = new byte[stream.Length];
99 | stream.Read(fileContentsAsBytes, 0, (int)stream.Length);
100 |
101 | FileMode mode = FileMode.CreateNew;
102 | if (File.Exists(fileName))
103 | {
104 | mode = FileMode.Truncate;
105 | }
106 |
107 | fs = new FileStream(fileName, mode);
108 |
109 | sw = new BinaryWriter(fs);
110 | sw.Write(fileContentsAsBytes);
111 | }
112 | finally
113 | {
114 | if (fs != null)
115 | {
116 | fs.Close();
117 | }
118 | if (sw != null)
119 | {
120 | sw.Close();
121 | }
122 | }
123 | }
124 |
125 | #endregion
126 |
127 | #region Methods: Handling temporary files and directories
128 | ///
129 | /// Returns the first available file name on the form
130 | /// [baseFileName]i.[extension]
131 | /// where [i] starts at 1 and increases until there is an available file name
132 | /// in the given directory. Also creates an empty file with that name to mark
133 | /// that file as occupied.
134 | ///
135 | /// Directory that the file should live in.
136 | ///
137 | /// may be null, in which case the .[extension] part
138 | /// is not added.
139 | /// Full file name.
140 | public static string GetNewFileName(string directory, string baseFileName, string extension)
141 | {
142 | // Get the new file name
143 | string fileName = GetNewFileOrDirectoryNameWithoutCreatingAnything(directory, baseFileName, extension);
144 |
145 | // Create an empty file to mark it as taken
146 | StreamWriter sw = new StreamWriter(fileName);
147 |
148 | sw.Write("");
149 | sw.Close();
150 | return fileName;
151 | }
152 | ///
153 | /// Returns the first available directory name on the form
154 | /// [baseDirectoryName]i
155 | /// where [i] starts at 1 and increases until there is an available directory name
156 | /// in the given directory. Also creates the directory to mark it as occupied.
157 | ///
158 | /// Directory that the file should live in.
159 | ///
160 | /// Full directory name.
161 | public static string GetNewDirectoryName(string directory, string baseDirectoryName)
162 | {
163 | // Get the new file name
164 | string directoryName = GetNewFileOrDirectoryNameWithoutCreatingAnything(directory, baseDirectoryName, null);
165 |
166 | // Create an empty directory to make it as occupied
167 | Directory.CreateDirectory(directoryName);
168 |
169 | return directoryName;
170 | }
171 |
172 | ///
173 | ///
174 | ///
175 | ///
176 | ///
177 | ///
178 | ///
179 | private static string GetNewFileOrDirectoryNameWithoutCreatingAnything(string directory, string baseFileName, string extension)
180 | {
181 | // - get a file name that we can use
182 | string fileName;
183 | int i = 1;
184 |
185 | string fullFileName = null;
186 | while (true)
187 | {
188 | // construct next file name
189 | fileName = baseFileName + i;
190 | if (extension != null)
191 | fileName += '.' + extension;
192 |
193 | // check if that file exists in the directory
194 | fullFileName = Path.Combine(directory, fileName);
195 |
196 | if (!File.Exists(fullFileName) && !Directory.Exists(fullFileName))
197 | break;
198 | else
199 | i++;
200 | }
201 |
202 | return fullFileName;
203 | }
204 | #endregion
205 |
206 | #region Methods: Handling solutions
207 | ///
208 | /// Closes the currently open solution (if any), and creates a new solution with the given name.
209 | ///
210 | /// Name of new solution.
211 | public void CreateEmptySolution(string directory, string solutionName)
212 | {
213 | CloseCurrentSolution(__VSSLNSAVEOPTIONS.SLNSAVEOPT_NoSave);
214 |
215 | string solutionDirectory = GetNewDirectoryName(directory, solutionName);
216 |
217 | // Create and force save solution
218 | IVsSolution solutionService = (IVsSolution)VsIdeTestHostContext.ServiceProvider.GetService(typeof(IVsSolution));
219 | solutionService.CreateSolution(solutionDirectory, solutionName, (uint)__VSCREATESOLUTIONFLAGS.CSF_SILENT);
220 | solutionService.SaveSolutionElement((uint)__VSSLNSAVEOPTIONS.SLNSAVEOPT_ForceSave, null, 0);
221 | DTE dte = VsIdeTestHostContext.Dte;
222 | Assert.AreEqual(solutionName + ".sln", Path.GetFileName(dte.Solution.FileName), "Newly created solution has wrong Filename");
223 | }
224 |
225 | public void CloseCurrentSolution(__VSSLNSAVEOPTIONS saveoptions)
226 | {
227 | // Get solution service
228 | IVsSolution solutionService = (IVsSolution)VsIdeTestHostContext.ServiceProvider.GetService(typeof(IVsSolution));
229 |
230 | // Close already open solution
231 | solutionService.CloseSolutionElement((uint)saveoptions, null, 0);
232 | }
233 |
234 | public void ForceSaveSolution()
235 | {
236 | // Get solution service
237 | IVsSolution solutionService = (IVsSolution)VsIdeTestHostContext.ServiceProvider.GetService(typeof(IVsSolution));
238 |
239 | // Force-save the solution
240 | solutionService.SaveSolutionElement((uint)__VSSLNSAVEOPTIONS.SLNSAVEOPT_ForceSave, null, 0);
241 | }
242 |
243 | ///
244 | /// Get current number of open project in solution
245 | ///
246 | ///
247 | public int ProjectCount()
248 | {
249 | // Get solution service
250 | IVsSolution solutionService = (IVsSolution)VsIdeTestHostContext.ServiceProvider.GetService(typeof(IVsSolution));
251 | object projectCount;
252 | solutionService.GetProperty((int)__VSPROPID.VSPROPID_ProjectCount, out projectCount);
253 | return (int)projectCount;
254 | }
255 | #endregion
256 |
257 | #region Methods: Handling projects
258 | ///
259 | /// Creates a project.
260 | ///
261 | /// Name of new project.
262 | /// Name of project template to use
263 | /// language
264 | /// New project.
265 | public void CreateProjectFromTemplate(string projectName, string templateName, string language, bool exclusive)
266 | {
267 | DTE dte = (DTE)VsIdeTestHostContext.ServiceProvider.GetService(typeof(DTE));
268 |
269 | Solution2 sol = dte.Solution as Solution2;
270 | string projectTemplate = sol.GetProjectTemplate(templateName, language);
271 |
272 | // - project name and directory
273 | string solutionDirectory = Directory.GetParent(dte.Solution.FullName).FullName;
274 | string projectDirectory = GetNewDirectoryName(solutionDirectory, projectName);
275 |
276 | dte.Solution.AddFromTemplate(projectTemplate, projectDirectory, projectName, false);
277 | }
278 | #endregion
279 |
280 | #region Methods: Handling project items
281 | ///
282 | /// Create a new item in the project
283 | ///
284 | /// the parent collection for the new item
285 | ///
286 | ///
287 | ///
288 | ///
289 | public ProjectItem AddNewItemFromVsTemplate(ProjectItems parent, string templateName, string language, string name)
290 | {
291 | if (parent == null)
292 | throw new ArgumentException("project");
293 | if (name == null)
294 | throw new ArgumentException("name");
295 |
296 | DTE dte = (DTE)VsIdeTestHostContext.ServiceProvider.GetService(typeof(DTE));
297 |
298 | Solution2 sol = dte.Solution as Solution2;
299 |
300 | string filename = sol.GetProjectItemTemplate(templateName, language);
301 |
302 | parent.AddFromTemplate(filename, name);
303 |
304 | return parent.Item(name);
305 | }
306 |
307 | ///
308 | /// Save an open document.
309 | ///
310 | /// for filebased documents this is the full path to the document
311 | public void SaveDocument(string documentMoniker)
312 | {
313 | // Get document cookie and hierarchy for the file
314 | IVsRunningDocumentTable runningDocumentTableService = (IVsRunningDocumentTable)VsIdeTestHostContext.ServiceProvider.GetService(typeof(IVsRunningDocumentTable));
315 | uint docCookie;
316 | IntPtr docData;
317 | IVsHierarchy hierarchy;
318 | uint itemId;
319 | runningDocumentTableService.FindAndLockDocument(
320 | (uint)Microsoft.VisualStudio.Shell.Interop._VSRDTFLAGS.RDT_NoLock,
321 | documentMoniker,
322 | out hierarchy,
323 | out itemId,
324 | out docData,
325 | out docCookie);
326 |
327 | // Save the document
328 | IVsSolution solutionService = (IVsSolution)VsIdeTestHostContext.ServiceProvider.GetService(typeof(IVsSolution));
329 | solutionService.SaveSolutionElement((uint)__VSSLNSAVEOPTIONS.SLNSAVEOPT_ForceSave, hierarchy, docCookie);
330 | }
331 |
332 | public void CloseInEditorWithoutSaving(string fullFileName)
333 | {
334 | // Get the RDT service
335 | IVsRunningDocumentTable runningDocumentTableService = (IVsRunningDocumentTable)VsIdeTestHostContext.ServiceProvider.GetService(typeof(IVsRunningDocumentTable));
336 | Assert.IsNotNull(runningDocumentTableService, "Failed to get the Running Document Table Service");
337 |
338 | // Get our document cookie and hierarchy for the file
339 | uint docCookie;
340 | IntPtr docData;
341 | IVsHierarchy hierarchy;
342 | uint itemId;
343 | runningDocumentTableService.FindAndLockDocument(
344 | (uint)Microsoft.VisualStudio.Shell.Interop._VSRDTFLAGS.RDT_NoLock,
345 | fullFileName,
346 | out hierarchy,
347 | out itemId,
348 | out docData,
349 | out docCookie);
350 |
351 | // Get the SolutionService
352 | IVsSolution solutionService = VsIdeTestHostContext.ServiceProvider.GetService(typeof(IVsSolution)) as IVsSolution;
353 | Assert.IsNotNull(solutionService, "Failed to get IVsSolution service");
354 |
355 | // Close the document
356 | solutionService.CloseSolutionElement(
357 | (uint)__VSSLNSAVEOPTIONS.SLNSAVEOPT_NoSave,
358 | hierarchy,
359 | docCookie);
360 | }
361 | #endregion
362 |
363 | #region Methods: Handling Toolwindows
364 | public bool CanFindToolwindow(Guid persistenceGuid)
365 | {
366 | IVsUIShell uiShellService = VsIdeTestHostContext.ServiceProvider.GetService(typeof(SVsUIShell)) as IVsUIShell;
367 | Assert.IsNotNull(uiShellService);
368 | IVsWindowFrame windowFrame;
369 | int hr = uiShellService.FindToolWindow((uint)__VSFINDTOOLWIN.FTW_fFindFirst, ref persistenceGuid, out windowFrame);
370 | Assert.IsTrue(hr == VSConstants.S_OK);
371 |
372 | return (windowFrame != null);
373 | }
374 | #endregion
375 |
376 | #region Methods: Loading packages
377 | public IVsPackage LoadPackage(Guid packageGuid)
378 | {
379 | IVsShell shellService = (IVsShell)VsIdeTestHostContext.ServiceProvider.GetService(typeof(SVsShell));
380 | IVsPackage package;
381 | shellService.LoadPackage(ref packageGuid, out package);
382 | Assert.IsNotNull(package, "Failed to load package");
383 | return package;
384 | }
385 | #endregion
386 |
387 | ///
388 | /// Executes a Command (menu item) in the given context
389 | ///
390 | public void ExecuteCommand(CommandID cmd)
391 | {
392 | object Customin = null;
393 | object Customout = null;
394 | string guidString = cmd.Guid.ToString("B").ToUpper();
395 | int cmdId = cmd.ID;
396 | DTE dte = VsIdeTestHostContext.Dte;
397 | dte.Commands.Raise(guidString, cmdId, ref Customin, ref Customout);
398 | }
399 |
400 | }
401 | }
402 |
--------------------------------------------------------------------------------
/SmartPaster2013/SmartPaster2013_IntegrationTests/Key.snk:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/martinjw/SmartPaster2013/a65224953b746cf4de4634d38750b068cd2658b4/SmartPaster2013/SmartPaster2013_IntegrationTests/Key.snk
--------------------------------------------------------------------------------
/SmartPaster2013/SmartPaster2013_IntegrationTests/MenuItemTest.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Globalization;
3 | using System.ComponentModel.Design;
4 | using Microsoft.VisualStudio.TestTools.UnitTesting;
5 | using Microsoft.VisualStudio.OLE.Interop;
6 | using Microsoft.VisualStudio.Shell.Interop;
7 | using Microsoft.VisualStudio.Shell;
8 | using Microsoft.VsSDK.IntegrationTestLibrary;
9 | using Microsoft.VSSDK.Tools.VsIdeTesting;
10 |
11 | namespace SmartPaster2013_IntegrationTests
12 | {
13 | [TestClass()]
14 | public class MenuItemTest
15 | {
16 | private delegate void ThreadInvoker();
17 |
18 | private TestContext testContextInstance;
19 |
20 | ///
21 | ///Gets or sets the test context which provides
22 | ///information about and functionality for the current test run.
23 | ///
24 | public TestContext TestContext
25 | {
26 | get
27 | {
28 | return testContextInstance;
29 | }
30 | set
31 | {
32 | testContextInstance = value;
33 | }
34 | }
35 |
36 | ///
37 | ///A test for lauching the command and closing the associated dialogbox
38 | ///
39 | [TestMethod()]
40 | [HostType("VS IDE")]
41 | public void LaunchCommand()
42 | {
43 | UIThreadInvoker.Invoke((ThreadInvoker)delegate()
44 | {
45 | CommandID menuItemCmd = new CommandID(SmartPaster2013.GuidList.guidSmartPaster2013CmdSet, (int)SmartPaster2013.PkgCmdIDList.cmdidPasteAsComment);
46 |
47 | // Create the DialogBoxListener Thread.
48 | string expectedDialogBoxText = string.Format(CultureInfo.CurrentCulture, "{0}\n\nInside {1}.MenuItemCallback()", "SmartPaster2013", "MartinWilley.SmartPaster2013.SmartPaster2013Package");
49 | DialogBoxPurger purger = new DialogBoxPurger(NativeMethods.IDOK, expectedDialogBoxText);
50 |
51 | try
52 | {
53 | purger.Start();
54 |
55 | TestUtils testUtils = new TestUtils();
56 | testUtils.ExecuteCommand(menuItemCmd);
57 | }
58 | finally
59 | {
60 | Assert.IsTrue(purger.WaitForDialogThreadToTerminate(), "The dialog box has not shown");
61 | }
62 | });
63 | }
64 |
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/SmartPaster2013/SmartPaster2013_IntegrationTests/PackageTest.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Text;
3 | using System.Collections.Generic;
4 | using System.Linq;
5 | using Microsoft.VisualStudio.TestTools.UnitTesting;
6 | using Microsoft.VSSDK.Tools.VsIdeTesting;
7 | using Microsoft.VisualStudio.Shell.Interop;
8 | using Microsoft.VisualStudio.Shell;
9 | using EnvDTE;
10 |
11 | namespace SmartPaster2013_IntegrationTests
12 | {
13 | ///
14 | /// Integration test for package validation
15 | ///
16 | [TestClass]
17 | public class PackageTest
18 | {
19 | private delegate void ThreadInvoker();
20 |
21 | private TestContext testContextInstance;
22 |
23 | ///
24 | ///Gets or sets the test context which provides
25 | ///information about and functionality for the current test run.
26 | ///
27 | public TestContext TestContext
28 | {
29 | get
30 | {
31 | return testContextInstance;
32 | }
33 | set
34 | {
35 | testContextInstance = value;
36 | }
37 | }
38 |
39 | [TestMethod]
40 | [HostType("VS IDE")]
41 | public void PackageLoadTest()
42 | {
43 | UIThreadInvoker.Invoke((ThreadInvoker)delegate()
44 | {
45 |
46 | //Get the Shell Service
47 | IVsShell shellService = VsIdeTestHostContext.ServiceProvider.GetService(typeof(SVsShell)) as IVsShell;
48 | Assert.IsNotNull(shellService);
49 |
50 | //Validate package load
51 | IVsPackage package;
52 | Guid packageGuid = new Guid(SmartPaster2013.GuidList.guidSmartPaster2013PkgString);
53 | Assert.IsTrue(0 == shellService.LoadPackage(ref packageGuid, out package));
54 | Assert.IsNotNull(package, "Package failed to load");
55 |
56 | });
57 | }
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/SmartPaster2013/SmartPaster2013_IntegrationTests/SignOff-Tests/CPPProjectTests.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Text;
3 | using System.Collections.Generic;
4 | using Microsoft.VisualStudio.TestTools.UnitTesting;
5 | using Microsoft.VsSDK.IntegrationTestLibrary;
6 | using Microsoft.VSSDK.Tools.VsIdeTesting;
7 | using EnvDTE;
8 | using System.IO;
9 |
10 | namespace SmartPaster2013_IntegrationTests.IntegrationTests
11 | {
12 | [TestClass]
13 | public class CPPProjectTests
14 | {
15 | #region fields
16 | private delegate void ThreadInvoker();
17 | private TestContext _testContext;
18 | #endregion
19 |
20 | #region properties
21 | ///
22 | ///Gets or sets the test context which provides
23 | ///information about and functionality for the current test run.
24 | ///
25 | public TestContext TestContext
26 | {
27 | get { return _testContext; }
28 | set { _testContext = value; }
29 | }
30 | #endregion
31 |
32 | #region ctors
33 | public CPPProjectTests()
34 | {
35 | }
36 | #endregion
37 |
38 | #region Additional test attributes
39 | //
40 | // You can use the following additional attributes as you write your tests:
41 | //
42 | // Use ClassInitialize to run code before running the first test in the class
43 | // [ClassInitialize()]
44 | // public static void MyClassInitialize(TestContext testContext) { }
45 | //
46 | // Use ClassCleanup to run code after all tests in a class have run
47 | // [ClassCleanup()]
48 | // public static void MyClassCleanup() { }
49 | //
50 | // Use TestInitialize to run code before running each test
51 | // [TestInitialize()]
52 | // public void MyTestInitialize() { }
53 | //
54 | // Use TestCleanup to run code after each test has run
55 | // [TestCleanup()]
56 | // public void MyTestCleanup() { }
57 | //
58 | #endregion
59 |
60 | [HostType("VS IDE")]
61 | [TestMethod]
62 | public void CPPWinformsApplication()
63 | {
64 | UIThreadInvoker.Invoke((ThreadInvoker)delegate()
65 | {
66 | //Solution and project creation parameters
67 | string solutionName = "CPPWinApp";
68 | string projectName = "CPPWinApp";
69 |
70 | //Template parameters
71 | string projectType = "{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}";
72 | string projectTemplateName = Path.Combine("vcNet", "mc++appwiz.vsz");
73 |
74 | string itemTemplateName = "newc++file.cpp";
75 | string newFileName = "Test.cpp";
76 |
77 | DTE dte = (DTE)VsIdeTestHostContext.ServiceProvider.GetService(typeof(DTE));
78 |
79 | TestUtils testUtils = new TestUtils();
80 |
81 | testUtils.CreateEmptySolution(TestContext.TestDir, solutionName);
82 | Assert.AreEqual(0, testUtils.ProjectCount());
83 |
84 | //Add new CPP Windows application project to existing solution
85 | string solutionDirectory = Directory.GetParent(dte.Solution.FullName).FullName;
86 | string projectDirectory = TestUtils.GetNewDirectoryName(solutionDirectory, projectName);
87 | string projectTemplatePath = Path.Combine(dte.Solution.get_TemplatePath(projectType), projectTemplateName);
88 | Assert.IsTrue(File.Exists(projectTemplatePath), string.Format("Could not find template file: {0}", projectTemplatePath));
89 | dte.Solution.AddFromTemplate(projectTemplatePath, projectDirectory, projectName, false);
90 |
91 | //Verify that the new project has been added to the solution
92 | Assert.AreEqual(1, testUtils.ProjectCount());
93 |
94 | //Get the project
95 | Project project = dte.Solution.Item(1);
96 | Assert.IsNotNull(project);
97 | Assert.IsTrue(string.Compare(project.Name, projectName, StringComparison.InvariantCultureIgnoreCase) == 0);
98 |
99 | //Verify Adding new code file to project
100 | string newItemTemplatePath = Path.Combine(dte.Solution.ProjectItemsTemplatePath(projectType), itemTemplateName);
101 | Assert.IsTrue(File.Exists(newItemTemplatePath));
102 | ProjectItem item = project.ProjectItems.AddFromTemplate(newItemTemplatePath, newFileName);
103 | Assert.IsNotNull(item);
104 |
105 | });
106 | }
107 |
108 | }
109 | }
110 |
--------------------------------------------------------------------------------
/SmartPaster2013/SmartPaster2013_IntegrationTests/SignOff-Tests/CSharpProjectTests.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Text;
3 | using System.Collections.Generic;
4 | using Microsoft.VisualStudio.TestTools.UnitTesting;
5 | using Microsoft.VsSDK.IntegrationTestLibrary;
6 | using Microsoft.VSSDK.Tools.VsIdeTesting;
7 |
8 | namespace SmartPaster2013_IntegrationTests.IntegrationTests
9 | {
10 | [TestClass]
11 | public class CSharpProjectTests
12 | {
13 | #region fields
14 | private delegate void ThreadInvoker();
15 | private TestContext _testContext;
16 | #endregion
17 |
18 | #region properties
19 | ///
20 | ///Gets or sets the test context which provides
21 | ///information about and functionality for the current test run.
22 | ///
23 | public TestContext TestContext
24 | {
25 | get { return _testContext; }
26 | set { _testContext = value; }
27 | }
28 | #endregion
29 |
30 | #region ctors
31 | public CSharpProjectTests()
32 | {
33 | }
34 | #endregion
35 |
36 | #region Additional test attributes
37 | //
38 | // You can use the following additional attributes as you write your tests:
39 | //
40 | // Use ClassInitialize to run code before running the first test in the class
41 | // [ClassInitialize()]
42 | // public static void MyClassInitialize(TestContext testContext) { }
43 | //
44 | // Use ClassCleanup to run code after all tests in a class have run
45 | // [ClassCleanup()]
46 | // public static void MyClassCleanup() { }
47 | //
48 | // Use TestInitialize to run code before running each test
49 | // [TestInitialize()]
50 | // public void MyTestInitialize() { }
51 | //
52 | // Use TestCleanup to run code after each test has run
53 | // [TestCleanup()]
54 | // public void MyTestCleanup() { }
55 | //
56 | #endregion
57 |
58 | [TestMethod]
59 | [HostType("VS IDE")]
60 | public void WinformsApplication()
61 | {
62 | UIThreadInvoker.Invoke((ThreadInvoker)delegate()
63 | {
64 | TestUtils testUtils = new TestUtils();
65 |
66 | testUtils.CreateEmptySolution(TestContext.TestDir, "CSWinApp");
67 | Assert.AreEqual(0, testUtils.ProjectCount());
68 |
69 | //Create Winforms application project
70 | //TestUtils.CreateProjectFromTemplate("MyWindowsApp", "Windows Application", "CSharp", false);
71 | //Assert.AreEqual(1, TestUtils.ProjectCount());
72 |
73 | //TODO Verify that we can debug launch the application
74 |
75 | //TODO Set Break point and verify that will hit
76 |
77 | //TODO Verify Adding new project item to project
78 |
79 | });
80 | }
81 |
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/SmartPaster2013/SmartPaster2013_IntegrationTests/SignOff-Tests/SolutionTests.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Text;
3 | using System.Collections.Generic;
4 | using Microsoft.VisualStudio.Shell.Interop;
5 | using Microsoft.VisualStudio.TestTools.UnitTesting;
6 | using Microsoft.VSSDK.Tools.VsIdeTesting;
7 | using EnvDTE;
8 | using System.IO;
9 | using Microsoft.VsSDK.IntegrationTestLibrary;
10 |
11 |
12 | namespace SmartPaster2013_IntegrationTests.IntegrationTests
13 | {
14 | [TestClass]
15 | public class SolutionTests
16 | {
17 | #region fields
18 | private delegate void ThreadInvoker();
19 | private TestContext _testContext;
20 | #endregion
21 |
22 | #region properties
23 | ///
24 | ///Gets or sets the test context which provides
25 | ///information about and functionality for the current test run.
26 | ///
27 | public TestContext TestContext
28 | {
29 | get { return _testContext; }
30 | set { _testContext = value; }
31 | }
32 | #endregion
33 |
34 |
35 | #region ctors
36 | public SolutionTests()
37 | {
38 | }
39 |
40 | #endregion
41 |
42 | [TestMethod]
43 | [HostType("VS IDE")]
44 | public void CreateEmptySolution()
45 | {
46 | UIThreadInvoker.Invoke((ThreadInvoker)delegate()
47 | {
48 | TestUtils testUtils = new TestUtils();
49 | testUtils.CloseCurrentSolution(__VSSLNSAVEOPTIONS.SLNSAVEOPT_NoSave);
50 | testUtils.CreateEmptySolution(TestContext.TestDir, "EmptySolution");
51 | });
52 | }
53 |
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/SmartPaster2013/SmartPaster2013_IntegrationTests/SignOff-Tests/VBProjectTests.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Text;
3 | using System.Collections.Generic;
4 | using Microsoft.VisualStudio.TestTools.UnitTesting;
5 | using Microsoft.VsSDK.IntegrationTestLibrary;
6 | using Microsoft.VSSDK.Tools.VsIdeTesting;
7 | using EnvDTE;
8 |
9 | namespace SmartPaster2013_IntegrationTests.IntegrationTests
10 | {
11 | [TestClass]
12 | public class VisualBasicProjectTests
13 | {
14 | #region fields
15 | private delegate void ThreadInvoker();
16 | private TestContext _testContext;
17 | #endregion
18 |
19 | #region properties
20 | ///
21 | ///Gets or sets the test context which provides
22 | ///information about and functionality for the current test run.
23 | ///
24 | public TestContext TestContext
25 | {
26 | get { return _testContext; }
27 | set { _testContext = value; }
28 | }
29 | #endregion
30 |
31 | #region ctors
32 | public VisualBasicProjectTests()
33 | {
34 | }
35 | #endregion
36 |
37 | #region Additional test attributes
38 | //
39 | // You can use the following additional attributes as you write your tests:
40 | //
41 | // Use ClassInitialize to run code before running the first test in the class
42 | // [ClassInitialize()]
43 | // public static void MyClassInitialize(TestContext testContext) { }
44 | //
45 | // Use ClassCleanup to run code after all tests in a class have run
46 | // [ClassCleanup()]
47 | // public static void MyClassCleanup() { }
48 | //
49 | // Use TestInitialize to run code before running each test
50 | // [TestInitialize()]
51 | // public void MyTestInitialize() { }
52 | //
53 | // Use TestCleanup to run code after each test has run
54 | // [TestCleanup()]
55 | // public void MyTestCleanup() { }
56 | //
57 | #endregion
58 |
59 | [HostType("VS IDE")]
60 | [TestMethod]
61 | public void VBWinformsApplication()
62 | {
63 | UIThreadInvoker.Invoke((ThreadInvoker)delegate()
64 | {
65 | //Solution and project creation parameters
66 | string solutionName = "VBWinApp";
67 | string projectName = "VBWinApp";
68 |
69 | //Template parameters
70 | string language = "VisualBasic";
71 | string projectTemplateName = "WindowsApplication.Zip";
72 | string itemTemplateName = "CodeFile.zip";
73 | string newFileName = "Test.vb";
74 |
75 | DTE dte = (DTE)VsIdeTestHostContext.ServiceProvider.GetService(typeof(DTE));
76 |
77 | TestUtils testUtils = new TestUtils();
78 |
79 | testUtils.CreateEmptySolution(TestContext.TestDir, solutionName);
80 | Assert.AreEqual(0, testUtils.ProjectCount());
81 |
82 | //Add new Windows application project to existing solution
83 | testUtils.CreateProjectFromTemplate(projectName, projectTemplateName, language, false);
84 |
85 | //Verify that the new project has been added to the solution
86 | Assert.AreEqual(1, testUtils.ProjectCount());
87 |
88 | //Get the project
89 | Project project = dte.Solution.Item(1);
90 | Assert.IsNotNull(project);
91 | Assert.IsTrue(string.Compare(project.Name, projectName, StringComparison.InvariantCultureIgnoreCase) == 0);
92 |
93 | //Verify Adding new code file to project
94 | ProjectItem newCodeFileItem = testUtils.AddNewItemFromVsTemplate(project.ProjectItems, itemTemplateName, language, newFileName);
95 | Assert.IsNotNull(newCodeFileItem, "Could not create new project item");
96 |
97 | });
98 | }
99 |
100 | }
101 | }
102 |
--------------------------------------------------------------------------------
/SmartPaster2013/SmartPaster2013_IntegrationTests/SmartPaster2013_IntegrationTests.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Debug
5 | AnyCPU
6 | 2.0
7 | {089197FF-F1AF-4AA3-9C8F-79D3381CB0D1}
8 | Library
9 | Properties
10 | SmartPaster2013_IntegrationTests
11 | SmartPaster2013_IntegrationTests
12 | v4.5
13 | 512
14 | {3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
15 |
16 |
17 | true
18 | full
19 | false
20 | bin\Debug\
21 | DEBUG;TRACE
22 | prompt
23 | 4
24 |
25 |
26 | pdbonly
27 | true
28 | bin\Release\
29 | TRACE
30 | prompt
31 | 4
32 |
33 |
34 | Key.snk
35 |
36 |
37 | true
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 | true
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 | {E4C30299-C9D8-4860-BBB0-02F5887D3ED2}
78 | SmartPaster2013
79 |
80 |
81 |
82 |
89 |
--------------------------------------------------------------------------------
/SmartPaster2013/SmartPaster2013_UnitTests/Key.snk:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/martinjw/SmartPaster2013/a65224953b746cf4de4634d38750b068cd2658b4/SmartPaster2013/SmartPaster2013_UnitTests/Key.snk
--------------------------------------------------------------------------------
/SmartPaster2013/SmartPaster2013_UnitTests/MenuItemTests/MenuItemCallback.cs:
--------------------------------------------------------------------------------
1 | /***************************************************************************
2 |
3 | Copyright (c) Microsoft Corporation. All rights reserved.
4 | This code is licensed under the Visual Studio SDK license terms.
5 | THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
6 | ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
7 | IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
8 | PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
9 |
10 | ***************************************************************************/
11 |
12 | using System;
13 | using System.Collections;
14 | using System.Text;
15 | using System.Reflection;
16 | using System.ComponentModel.Design;
17 | using Microsoft.VsSDK.UnitTestLibrary;
18 | using Microsoft.VisualStudio.Shell.Interop;
19 | using Microsoft.VisualStudio.TestTools.UnitTesting;
20 | using Microsoft.VisualStudio.Shell;
21 | using SmartPaster2013;
22 |
23 | namespace SmartPaster2013_UnitTests.MenuItemTests
24 | {
25 | [TestClass()]
26 | public class MenuItemTest
27 | {
28 | ///
29 | /// Verify that a new menu command object gets added to the OleMenuCommandService.
30 | /// This action takes place In the Initialize method of the Package object
31 | ///
32 | [TestMethod]
33 | public void InitializeMenuCommand()
34 | {
35 | // Create the package
36 | IVsPackage package = new SmartPaster2013Package() as IVsPackage;
37 | Assert.IsNotNull(package, "The object does not implement IVsPackage");
38 |
39 | // Create a basic service provider
40 | OleServiceProvider serviceProvider = OleServiceProvider.CreateOleServiceProviderWithBasicServices();
41 |
42 | // Site the package
43 | Assert.AreEqual(0, package.SetSite(serviceProvider), "SetSite did not return S_OK");
44 |
45 | //Verify that the menu command can be found
46 | CommandID menuCommandID = new CommandID(SmartPaster2013.GuidList.guidSmartPaster2013CmdSet, (int)SmartPaster2013.PkgCmdIDList.cmdidPasteAsComment);
47 | System.Reflection.MethodInfo info = typeof(Package).GetMethod("GetService", BindingFlags.Instance | BindingFlags.NonPublic);
48 | Assert.IsNotNull(info);
49 | OleMenuCommandService mcs = info.Invoke(package, new object[] { (typeof(IMenuCommandService)) }) as OleMenuCommandService;
50 | Assert.IsNotNull(mcs.FindCommand(menuCommandID));
51 | }
52 |
53 | //[TestMethod]
54 | //public void MenuItemCallback()
55 | //{
56 | // // Create the package
57 | // IVsPackage package = new SmartPaster2013Package() as IVsPackage;
58 | // Assert.IsNotNull(package, "The object does not implement IVsPackage");
59 |
60 | // // Create a basic service provider
61 | // OleServiceProvider serviceProvider = OleServiceProvider.CreateOleServiceProviderWithBasicServices();
62 |
63 | // // Create a UIShell service mock and proffer the service so that it can called from the MenuItemCallback method
64 | // BaseMock uishellMock = UIShellServiceMock.GetUiShellInstance();
65 | // serviceProvider.AddService(typeof(SVsUIShell), uishellMock, true);
66 |
67 | // // Site the package
68 | // Assert.AreEqual(0, package.SetSite(serviceProvider), "SetSite did not return S_OK");
69 |
70 | // //Invoke private method on package class and observe that the method does not throw
71 | // System.Reflection.MethodInfo info = package.GetType().GetMethod("MenuItemCallback", BindingFlags.Instance | BindingFlags.NonPublic);
72 | // Assert.IsNotNull(info, "Failed to get the private method MenuItemCallback throug refplection");
73 | // info.Invoke(package, new object[] { null, null });
74 |
75 | // //Clean up services
76 | // serviceProvider.RemoveService(typeof(SVsUIShell));
77 |
78 | //}
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/SmartPaster2013/SmartPaster2013_UnitTests/MenuItemTests/UIShellServiceMock.cs:
--------------------------------------------------------------------------------
1 | /***************************************************************************
2 |
3 | Copyright (c) Microsoft Corporation. All rights reserved.
4 | This code is licensed under the Visual Studio SDK license terms.
5 | THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
6 | ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
7 | IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
8 | PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
9 |
10 | ***************************************************************************/
11 |
12 | using System;
13 | using Microsoft.VisualStudio;
14 | using Microsoft.VisualStudio.Shell.Interop;
15 | using Microsoft.VsSDK.UnitTestLibrary;
16 |
17 | namespace SmartPaster2013_UnitTests
18 | {
19 | static class UIShellServiceMock
20 | {
21 | private static GenericMockFactory uiShellFactory;
22 |
23 | #region UiShell Getters
24 | ///
25 | /// Returns an IVsUiShell that does not implement any methods
26 | ///
27 | ///
28 | internal static BaseMock GetUiShellInstance()
29 | {
30 | if (uiShellFactory == null)
31 | {
32 | uiShellFactory = new GenericMockFactory("UiShell", new Type[] { typeof(IVsUIShell), typeof(IVsUIShellOpenDocument) });
33 | }
34 | BaseMock uiShell = uiShellFactory.GetInstance();
35 | return uiShell;
36 | }
37 |
38 | ///
39 | /// Get an IVsUiShell that implements SetWaitCursor, SaveDocDataToFile, ShowMessageBox
40 | ///
41 | /// uishell mock
42 | internal static BaseMock GetUiShellInstance0()
43 | {
44 | BaseMock uiShell = GetUiShellInstance();
45 | string name = string.Format("{0}.{1}", typeof(IVsUIShell).FullName, "SetWaitCursor");
46 | uiShell.AddMethodCallback(name, new EventHandler(SetWaitCursorCallBack));
47 |
48 | name = string.Format("{0}.{1}", typeof(IVsUIShell).FullName, "SaveDocDataToFile");
49 | uiShell.AddMethodCallback(name, new EventHandler(SaveDocDataToFileCallBack));
50 |
51 | name = string.Format("{0}.{1}", typeof(IVsUIShell).FullName, "ShowMessageBox");
52 | uiShell.AddMethodCallback(name, new EventHandler(ShowMessageBoxCallBack));
53 | return uiShell;
54 | }
55 | #endregion
56 |
57 | #region Callbacks
58 | private static void SetWaitCursorCallBack(object caller, CallbackArgs arguments)
59 | {
60 | arguments.ReturnValue = VSConstants.S_OK;
61 | }
62 |
63 | private static void SaveDocDataToFileCallBack(object caller, CallbackArgs arguments)
64 | {
65 | arguments.ReturnValue = VSConstants.S_OK;
66 | }
67 |
68 | private static void ShowMessageBoxCallBack(object caller, CallbackArgs arguments)
69 | {
70 | arguments.ReturnValue = VSConstants.S_OK;
71 | arguments.SetParameter(10, (int)System.Windows.Forms.DialogResult.Yes);
72 | }
73 |
74 | #endregion
75 | }
76 | }
--------------------------------------------------------------------------------
/SmartPaster2013/SmartPaster2013_UnitTests/PackageTest.cs:
--------------------------------------------------------------------------------
1 | /***************************************************************************
2 |
3 | Copyright (c) Microsoft Corporation. All rights reserved.
4 | This code is licensed under the Visual Studio SDK license terms.
5 | THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
6 | ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
7 | IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
8 | PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
9 |
10 | ***************************************************************************/
11 |
12 | using System;
13 | using System.Collections;
14 | using System.Text;
15 | using System.Reflection;
16 | using Microsoft.VsSDK.UnitTestLibrary;
17 | using Microsoft.VisualStudio.Shell.Interop;
18 | using Microsoft.VisualStudio.TestTools.UnitTesting;
19 | using SmartPaster2013;
20 |
21 | namespace SmartPaster2013_UnitTests
22 | {
23 | [TestClass()]
24 | public class PackageTest
25 | {
26 | [TestMethod()]
27 | public void CreateInstance()
28 | {
29 | SmartPaster2013Package package = new SmartPaster2013Package();
30 | }
31 |
32 | [TestMethod()]
33 | public void IsIVsPackage()
34 | {
35 | SmartPaster2013Package package = new SmartPaster2013Package();
36 | Assert.IsNotNull(package as IVsPackage, "The object does not implement IVsPackage");
37 | }
38 |
39 | [TestMethod()]
40 | public void SetSite()
41 | {
42 | // Create the package
43 | IVsPackage package = new SmartPaster2013Package() as IVsPackage;
44 | Assert.IsNotNull(package, "The object does not implement IVsPackage");
45 |
46 | // Create a basic service provider
47 | OleServiceProvider serviceProvider = OleServiceProvider.CreateOleServiceProviderWithBasicServices();
48 |
49 | // Site the package
50 | Assert.AreEqual(0, package.SetSite(serviceProvider), "SetSite did not return S_OK");
51 |
52 | // Unsite the package
53 | Assert.AreEqual(0, package.SetSite(null), "SetSite(null) did not return S_OK");
54 | }
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/SmartPaster2013/SmartPaster2013_UnitTests/Scratchpad.vb:
--------------------------------------------------------------------------------
1 |
2 | '我给你一本书 。
3 | 'This has a tab and " quotes but this \t is not an escape
4 |
5 |
6 | 'Not a real VB class, just a file with BuildAction None and a vb extension so we can test SmartPaster
7 | Public Class ScratchPad
8 |
9 | Public Function GetValue(ByVal id As Integer) As String
10 | Dim a = "'我给你一本书 。" & Environment.NewLine & _
11 | "'This has a tab and "" quotes but this \t is not an escape"
12 | Dim s As String =
13 | .Value
17 | ''我给你一本书 。
18 | ''This has a tab and " quotes but this \t is not an escape
19 | Dim sb As New System.Text.StringBuilder(73)
20 | sb.AppendLine("'我给你一本书 。")
21 | sb.AppendLine("'This has a tab and "" quotes but this \t is not an escape")
22 |
23 |
24 | Return "value"
25 | End Function
26 |
27 | Public Sub Void(ByVal value As String)
28 |
29 | End Sub
30 |
31 | End Class
--------------------------------------------------------------------------------
/SmartPaster2013/SmartPaster2013_UnitTests/SmartFormatterTests.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Microsoft.VisualStudio.TestTools.UnitTesting;
3 | using SmartPaster2013;
4 |
5 | namespace SmartPaster2013_UnitTests
6 | {
7 | [TestClass]
8 | public class SmartFormatterTests
9 | {
10 | /*
11 | 我给你一本书 。
12 | This has a tab and " quotes but this \t is not an escape
13 | */
14 | //我给你一本书 。
15 | //This has a tab and " quotes but this \t is not an escape
16 |
17 | private const string Original = "我给你一本书 。\r\nThis has a \t tab and \" quotes but this \\t is not an escape";
18 |
19 | [TestMethod]
20 | public void TestVerbatimStringCs()
21 | {
22 | var result = SmartFormatter.StringinizeInCs(Original);
23 |
24 | //should look like this
25 | var s = @"我给你一本书 。
26 | This has a tab and "" quotes but this \t is not an escape";
27 |
28 | //The line break is included, the double-quotes are doubled
29 | //In verbatim, tabs can't be escaped, so it's just included as a raw tab
30 | //a VS reformat may convert the tab to spaces
31 | Assert.AreEqual(@"@""我给你一本书 。
32 | This has a " + "\t tab and \"\" quotes but this \\t is not an escape\"", result);
33 | }
34 |
35 | [TestMethod]
36 | public void TestLiteralStringCs()
37 | {
38 | var result = SmartFormatter.LiterallyInCs(Original);
39 |
40 | //should look like this
41 | var s = "我给你一本书 。" + Environment.NewLine +
42 | "This has a tab and \" quotes but this \t is not an escape";
43 |
44 | //Tab and quote is escaped, line is turned into NewLine
45 | Assert.AreEqual(@"""我给你一本书 。"" + Environment.NewLine +
46 | ""This has a \t tab and \"" quotes but this \\t is not an escape""", result);
47 | }
48 |
49 | [TestMethod]
50 | public void TestLiteralStringCsPath()
51 | {
52 | var path = @"C:\x\y\x";
53 | var result = SmartFormatter.LiterallyInCs(path);
54 | Assert.AreEqual("\"C:\\\\x\\\\y\\\\x\"", result);
55 | }
56 |
57 | [TestMethod]
58 | public void TestLiteralStringCxxPath()
59 | {
60 | var path = @"C:\x\y\x";
61 | var result = SmartFormatter.LiterallyInCxx(path);
62 | Assert.AreEqual("\"C:\\\\x\\\\y\\\\x\"", result);
63 | }
64 |
65 | [TestMethod]
66 | public void TestLiteralStringWithEmptyLinesCs()
67 | {
68 | var result = SmartFormatter.LiterallyInCs(@"
69 | 1
70 |
71 | 2
72 | ");
73 |
74 | //should look like this
75 | var s = "1" + Environment.NewLine +
76 | Environment.NewLine +
77 | "2";
78 |
79 | //Tab and quote is escaped, line is turned into NewLine
80 | Assert.AreEqual("\"1\" + Environment.NewLine + \r\n\"\" + Environment.NewLine + \r\n\"2\"", result);
81 | }
82 |
83 | [TestMethod]
84 | public void TestLiteralWithLineBreak()
85 | {
86 | var s = @"select ""Id"", ""max"", ""Prefs""
87 | from rs.""table"";";
88 | var result = SmartFormatter.LiterallyInCs(s);
89 |
90 | Assert.AreEqual(
91 | "\"select \\\"Id\\\", \\\"max\\\", \\\"Prefs\\\"\" + Environment.NewLine + \r\n\" from rs.\\\"table\\\";\"", result);
92 | }
93 |
94 |
95 | [TestMethod]
96 | public void TestVerbatimStringVb()
97 | {
98 | var result = SmartFormatter.StringinizeInVb(Original);
99 |
100 | //Verbatim in VB 14. Double quoted, otherwise unchanged.
101 | Assert.AreEqual("\"我给你一本书 。\r\nThis has a \t tab and \"\" quotes but this \\t is not an escape\"", result);
102 | }
103 |
104 |
105 | [TestMethod]
106 | public void TestLiteralStringVb()
107 | {
108 | var result = SmartFormatter.LiterallyInVb(Original);
109 |
110 | //No verbatim in VB up to 14, so we just use literals with vbCrLf and line continuation
111 | Assert.AreEqual("\"我给你一本书 。\" & vbCrLf & _\r\n\"This has a \" & vbTab & \" tab and \"\"\"\" quotes but this \\t is not an escape\"", result);
112 | }
113 |
114 |
115 | [TestMethod]
116 | public void TestLiteralStringWithEmptyLinesVb()
117 | {
118 | var result = SmartFormatter.LiterallyInVb(@"
119 | 1
120 |
121 | 2
122 | ");
123 |
124 | //No verbatim in VB up to 14, so we just use literals with vbCrLf and line continuation
125 | //Arguably tab could be vbTab
126 | //You could use xml literals...
127 | Assert.AreEqual("\"1\" & vbCrLf & _\r\nvbCrLf & _\r\n\"2\"", result);
128 | }
129 |
130 |
131 | [TestMethod]
132 | public void TestCommentCs()
133 | {
134 | var result = SmartFormatter.CommentizeInCs(Original);
135 |
136 | //should look like this
137 | //我给你一本书 。
138 | //This has a tab and " quotes but this \t is not an escape
139 |
140 | //don't double quotes, just use line comment prefix
141 | //there's a trailing line break too
142 | Assert.AreEqual(@"//我给你一本书 。
143 | //This has a " + "\t tab and \" quotes but this \\t is not an escape\r\n", result);
144 | }
145 |
146 | [TestMethod]
147 | public void TestCommentVb()
148 | {
149 | var result = SmartFormatter.CommentizeInVb(Original);
150 |
151 | //don't double quotes, just use line comment prefix
152 | //there's a trailing line break too
153 | Assert.AreEqual(@"'我给你一本书 。
154 | 'This has a " + "\t tab and \" quotes but this \\t is not an escape\r\n", result);
155 | }
156 |
157 | [TestMethod]
158 | public void TestStringBuilderCs()
159 | {
160 | var result = SmartFormatter.StringbuilderizeInCs(Original, "sb");
161 |
162 | //should look like this
163 | var sb = new System.Text.StringBuilder(68);
164 | sb.AppendLine(@"我给你一本书 。");
165 | sb.AppendLine(@"This has a tab and "" quotes but this \t is not an escape");
166 |
167 | //the single " becomes doubled, which becomes 4 here
168 | Assert.AreEqual(@"var sb = new System.Text.StringBuilder(68);
169 | sb.AppendLine(@""我给你一本书 。"");
170 | sb.AppendLine(@""This has a tab and """" quotes but this \t is not an escape"");
171 | ", result);
172 | }
173 |
174 |
175 | [TestMethod]
176 | public void TestStringBuilderVb()
177 | {
178 | var result = SmartFormatter.StringbuilderizeInVb(Original, "sb");
179 |
180 | //the single " becomes doubled, which becomes 4 here
181 | Assert.AreEqual(@"Dim sb As New System.Text.StringBuilder(68)
182 | sb.AppendLine(""我给你一本书 。"")
183 | sb.AppendLine(""This has a tab and """" quotes but this \t is not an escape"")
184 | ", result);
185 | }
186 |
187 |
188 | }
189 | }
190 |
--------------------------------------------------------------------------------
/SmartPaster2013/SmartPaster2013_UnitTests/SmartPaster2013_UnitTests.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Debug
5 | AnyCPU
6 | 2.0
7 | {B8D186B6-3465-4F1D-8157-04367BE5C9ED}
8 | Library
9 | Properties
10 | SmartPaster2013_UnitTests
11 | SmartPaster2013_UnitTests
12 | v4.6
13 | {3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
14 |
15 |
16 |
17 | true
18 | full
19 | false
20 | bin\Debug\
21 | DEBUG;TRACE
22 | prompt
23 | 4
24 |
25 |
26 | pdbonly
27 | true
28 | bin\Release\
29 | TRACE
30 | prompt
31 | 4
32 |
33 |
34 | Key.snk
35 |
36 |
37 | true
38 |
39 |
40 |
41 | ..\..\packages\Microsoft.VisualStudio.Imaging.14.3.25407\lib\net45\Microsoft.VisualStudio.Imaging.dll
42 | True
43 |
44 |
45 | ..\..\packages\Microsoft.VisualStudio.OLE.Interop.7.10.6070\lib\Microsoft.VisualStudio.OLE.Interop.dll
46 | True
47 |
48 |
49 | ..\..\packages\Microsoft.VisualStudio.Shell.14.0.14.3.25407\lib\Microsoft.VisualStudio.Shell.14.0.dll
50 | True
51 |
52 |
53 | ..\..\packages\Microsoft.VisualStudio.Shell.Immutable.10.0.10.0.30319\lib\net40\Microsoft.VisualStudio.Shell.Immutable.10.0.dll
54 | True
55 |
56 |
57 | ..\..\packages\Microsoft.VisualStudio.Shell.Immutable.11.0.11.0.50727\lib\net45\Microsoft.VisualStudio.Shell.Immutable.11.0.dll
58 | True
59 |
60 |
61 | ..\..\packages\Microsoft.VisualStudio.Shell.Immutable.12.0.12.0.21003\lib\net45\Microsoft.VisualStudio.Shell.Immutable.12.0.dll
62 | True
63 |
64 |
65 | ..\..\packages\Microsoft.VisualStudio.Shell.Immutable.14.0.14.3.25407\lib\net45\Microsoft.VisualStudio.Shell.Immutable.14.0.dll
66 | True
67 |
68 |
69 | ..\..\packages\Microsoft.VisualStudio.Shell.Interop.7.10.6071\lib\Microsoft.VisualStudio.Shell.Interop.dll
70 | True
71 |
72 |
73 | ..\..\packages\Microsoft.VisualStudio.Shell.Interop.8.0.8.0.50727\lib\Microsoft.VisualStudio.Shell.Interop.8.0.dll
74 | True
75 |
76 |
77 |
78 | true
79 |
80 |
81 |
82 |
83 | ..\..\packages\Microsoft.VisualStudio.Shell.Interop.9.0.9.0.30729\lib\Microsoft.VisualStudio.Shell.Interop.9.0.dll
84 | True
85 |
86 |
87 | ..\..\packages\Microsoft.VisualStudio.TextManager.Interop.7.10.6070\lib\Microsoft.VisualStudio.TextManager.Interop.dll
88 | True
89 |
90 |
91 | ..\..\packages\Microsoft.VisualStudio.TextManager.Interop.8.0.8.0.50727\lib\Microsoft.VisualStudio.TextManager.Interop.8.0.dll
92 | True
93 |
94 |
95 | ..\..\packages\Microsoft.VisualStudio.Threading.14.1.111\lib\net45\Microsoft.VisualStudio.Threading.dll
96 | True
97 |
98 |
99 | ..\..\packages\Microsoft.VisualStudio.Utilities.14.3.25407\lib\net45\Microsoft.VisualStudio.Utilities.dll
100 | True
101 |
102 |
103 | ..\..\packages\Microsoft.VisualStudio.Validation.14.1.111\lib\net45\Microsoft.VisualStudio.Validation.dll
104 | True
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 | {E4C30299-C9D8-4860-BBB0-02F5887D3ED2}
132 | SmartPaster2013
133 |
134 |
135 |
136 |
--------------------------------------------------------------------------------
/SmartPaster2013/SmartPaster2013_UnitTests/app.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/SmartPaster2013/SmartPaster2013_UnitTests/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/SmartPaster2013/VSPackage.resx:
--------------------------------------------------------------------------------
1 |
2 |
12 |
13 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 | text/microsoft-resx
120 |
121 |
122 | 2.0
123 |
124 |
125 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
126 |
127 |
128 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
129 |
130 |
131 |
132 | SmartPaster2013
133 |
134 |
135 | Paste clipboard into comments or string builder
136 |
137 |
138 | Resources\Package.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
139 |
140 |
--------------------------------------------------------------------------------
/SmartPaster2013/app.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/SmartPaster2013/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/SmartPaster2013/source.extension.vsixmanifest:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SmartPaster2019
6 | Paste clipboard into comments or strings in C#, VB, C++
7 | https://github.com/martinjw/SmartPaster2013
8 | License.txt
9 | Resources/Package.ico
10 | PasteAs Verbatim StringBuilder Comment
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/UnitTests.testsettings:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 | This test run configuration is used for running the unit tests
9 |
10 |
--------------------------------------------------------------------------------