diff options
| author | Roy Ben-Shabat <Roy@Twine-s.com> | 2018-05-24 19:35:16 +0300 |
|---|---|---|
| committer | Roy Ben-Shabat <Roy@Twine-s.com> | 2018-05-24 19:35:16 +0300 |
| commit | 3b9b17a00716128ed9f68728c31714f753b8e9ea (patch) | |
| tree | 626699296ceb7ea5119e664f99554b53db31cde9 /Software/Visual_Studio/VSIX/Tango.BuildExtensions | |
| parent | 5fd370643691a312e1266f138982d784f0f9ebb1 (diff) | |
| download | Tango-3b9b17a00716128ed9f68728c31714f753b8e9ea.tar.gz Tango-3b9b17a00716128ed9f68728c31714f753b8e9ea.zip | |
Implemented Remote Debugging for panel PC as VS command using PsiExec!
Started investigating the Surface SDK controls.
Diffstat (limited to 'Software/Visual_Studio/VSIX/Tango.BuildExtensions')
13 files changed, 1007 insertions, 243 deletions
diff --git a/Software/Visual_Studio/VSIX/Tango.BuildExtensions/BuildForm.Designer.cs b/Software/Visual_Studio/VSIX/Tango.BuildExtensions/BuildForm.Designer.cs index 4b95a83b0..5f7c82c65 100644 --- a/Software/Visual_Studio/VSIX/Tango.BuildExtensions/BuildForm.Designer.cs +++ b/Software/Visual_Studio/VSIX/Tango.BuildExtensions/BuildForm.Designer.cs @@ -187,7 +187,7 @@ this.label1.Padding = new System.Windows.Forms.Padding(5, 0, 0, 0); this.label1.Size = new System.Drawing.Size(594, 29); this.label1.TabIndex = 0; - this.label1.Text = "Tango Initializer"; + this.label1.Text = "Tango Build Engine"; this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; // // BuildForm @@ -206,7 +206,7 @@ this.ShowIcon = false; this.ShowInTaskbar = false; this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; - this.Text = "Tango Initializer"; + this.Text = "Tango Build Engine"; this.TopMost = true; this.panel1.ResumeLayout(false); this.panel1.PerformLayout(); diff --git a/Software/Visual_Studio/VSIX/Tango.BuildExtensions/ProgressForm.Designer.cs b/Software/Visual_Studio/VSIX/Tango.BuildExtensions/ProgressForm.Designer.cs index fd70df334..7b9493b08 100644 --- a/Software/Visual_Studio/VSIX/Tango.BuildExtensions/ProgressForm.Designer.cs +++ b/Software/Visual_Studio/VSIX/Tango.BuildExtensions/ProgressForm.Designer.cs @@ -47,7 +47,7 @@ this.label1.Padding = new System.Windows.Forms.Padding(5, 0, 0, 0); this.label1.Size = new System.Drawing.Size(483, 29); this.label1.TabIndex = 0; - this.label1.Text = "Tango Initializer"; + this.label1.Text = "Tango Build Extensions"; this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; this.label1.UseWaitCursor = true; // diff --git a/Software/Visual_Studio/VSIX/Tango.BuildExtensions/PsExec.exe b/Software/Visual_Studio/VSIX/Tango.BuildExtensions/PsExec.exe Binary files differnew file mode 100644 index 000000000..446a8df23 --- /dev/null +++ b/Software/Visual_Studio/VSIX/Tango.BuildExtensions/PsExec.exe diff --git a/Software/Visual_Studio/VSIX/Tango.BuildExtensions/RemoteDebugCommand.cs b/Software/Visual_Studio/VSIX/Tango.BuildExtensions/RemoteDebugCommand.cs new file mode 100644 index 000000000..d4f072635 --- /dev/null +++ b/Software/Visual_Studio/VSIX/Tango.BuildExtensions/RemoteDebugCommand.cs @@ -0,0 +1,169 @@ +//------------------------------------------------------------------------------ +// <copyright file="RemoteDebugCommand.cs" company="Company"> +// Copyright (c) Company. All rights reserved. +// </copyright> +//------------------------------------------------------------------------------ + +using System; +using System.ComponentModel.Design; +using System.Globalization; +using Microsoft.VisualStudio.Shell; +using Microsoft.VisualStudio.Shell.Interop; +using System.Linq; +using System.IO; +using System.Diagnostics; + +namespace Tango.BuildExtensions +{ + /// <summary> + /// Command handler + /// </summary> + internal sealed class RemoteDebugCommand : VSIXBase + { + private const string SHARED_PATH = @"\\twine01\data\RemoteDebugging"; + + /// <summary> + /// Command ID. + /// </summary> + public const int CommandId = 4129; + + /// <summary> + /// Command menu group (command set GUID). + /// </summary> + public static readonly Guid CommandSet = new Guid("c03a7b01-8109-4ec5-8f90-858bed027e5d"); + + /// <summary> + /// VS Package that provides this command, not null. + /// </summary> + private readonly Package package; + + /// <summary> + /// Initializes a new instance of the <see cref="RemoteDebugCommand"/> class. + /// Adds our command handlers for menu (commands must exist in the command table file) + /// </summary> + /// <param name="package">Owner package, not null.</param> + private RemoteDebugCommand(Package package) : base(package) + { + if (package == null) + { + throw new ArgumentNullException("package"); + } + + this.package = package; + + OleMenuCommandService commandService = this.ServiceProvider.GetService(typeof(IMenuCommandService)) as OleMenuCommandService; + if (commandService != null) + { + var menuCommandID = new CommandID(CommandSet, CommandId); + var menuItem = new MenuCommand(this.MenuItemCallback, menuCommandID); + commandService.AddCommand(menuItem); + } + } + + /// <summary> + /// Gets the instance of the command. + /// </summary> + public static RemoteDebugCommand Instance + { + get; + private set; + } + + /// <summary> + /// Gets the service provider from the owner package. + /// </summary> + private IServiceProvider ServiceProvider + { + get + { + return this.package; + } + } + + /// <summary> + /// Initializes the singleton instance of the command. + /// </summary> + /// <param name="package">Owner package, not null.</param> + public static void Initialize(Package package) + { + Instance = new RemoteDebugCommand(package); + } + + // %ifnot% $toolWindow$ + /// <summary> + /// This function is the callback used to execute the command when the menu item is clicked. + /// See the constructor to see how the menu item is associated with this function using + /// OleMenuCommandService service and MenuCommand class. + /// </summary> + /// <param name="sender">Event sender.</param> + /// <param name="e">Event args.</param> + private void MenuItemCallback(object sender, EventArgs e) + { + RunRemote(); + } + + private void RunRemote() + { + try + { + String projectName = DTE.Solution.Properties.Item("StartupProject").Value.ToString(); + + RemoteDebugForm dlg = new RemoteDebugForm(projectName); + + if (dlg.ShowDialog() == System.Windows.Forms.DialogResult.OK) + { + System.Threading.Tasks.Task.Factory.StartNew(() => + { + OpenProgressForm(); + + SetProgressText("Building " + projectName + "..."); + + var project = GetSolutionProjects().SingleOrDefault(x => x.Name == projectName); + + String filePath = GetProjectOutputFilePath(project); + String folder = Path.GetDirectoryName(filePath); + String fileName = Path.GetFileName(filePath); + String remoteFolder = Path.Combine(SHARED_PATH, projectName); + String remoteFilePath = Path.Combine(remoteFolder, fileName); + + DTE.Solution.SolutionBuild.BuildProject("Debug", project.FullName, true); + + Directory.CreateDirectory(remoteFolder); + + CopyDirectory(folder, remoteFolder, true, (file) => + { + SetProgressText("Copying to " + file + "..."); + }); + + String PsExecPath = GetFullPathToContentFile("PsExec.exe"); + + SetProgressText("Executing remote process..."); + + Process p = new Process(); + p.StartInfo.FileName = PsExecPath; + p.StartInfo.UseShellExecute = false; + p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden; + p.StartInfo.CreateNoWindow = true; + p.EnableRaisingEvents = true; + p.StartInfo.RedirectStandardError = true; + p.StartInfo.RedirectStandardOutput = false; + p.ErrorDataReceived += (x, e) => + { + SetProgressText("The process will start shortly, please wait..."); + Wait(20000); + CloseProgressForm(); + }; + p.StartInfo.Arguments = String.Format("-u {0} -p {1} -i {2} \"{3}\" -accepteula", dlg.UserName, dlg.Password, dlg.HostName, remoteFilePath); + p.Start(); + p.BeginErrorReadLine(); + }); + } + } + catch (Exception ex) + { + CloseProgressForm(); + ShowMessage(ex.Message); + } + } + } +} diff --git a/Software/Visual_Studio/VSIX/Tango.BuildExtensions/RemoteDebugForm.Designer.cs b/Software/Visual_Studio/VSIX/Tango.BuildExtensions/RemoteDebugForm.Designer.cs new file mode 100644 index 000000000..bfbc8c683 --- /dev/null +++ b/Software/Visual_Studio/VSIX/Tango.BuildExtensions/RemoteDebugForm.Designer.cs @@ -0,0 +1,256 @@ +namespace Tango.BuildExtensions +{ + partial class RemoteDebugForm + { + /// <summary> + /// Required designer variable. + /// </summary> + private System.ComponentModel.IContainer components = null; + + /// <summary> + /// Clean up any resources being used. + /// </summary> + /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param> + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// <summary> + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// </summary> + private void InitializeComponent() + { + this.panel1 = new System.Windows.Forms.Panel(); + this.label5 = new System.Windows.Forms.Label(); + this.txtPass = new System.Windows.Forms.TextBox(); + this.label4 = new System.Windows.Forms.Label(); + this.txtUserName = new System.Windows.Forms.TextBox(); + this.label3 = new System.Windows.Forms.Label(); + this.txtProjectName = new System.Windows.Forms.Label(); + this.txtHostName = new System.Windows.Forms.TextBox(); + this.btnCancel = new System.Windows.Forms.Button(); + this.btnOK = new System.Windows.Forms.Button(); + this.pictureBox1 = new System.Windows.Forms.PictureBox(); + this.label2 = new System.Windows.Forms.Label(); + this.label1 = new System.Windows.Forms.Label(); + this.panel1.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit(); + this.SuspendLayout(); + // + // panel1 + // + this.panel1.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; + this.panel1.Controls.Add(this.label5); + this.panel1.Controls.Add(this.txtPass); + this.panel1.Controls.Add(this.label4); + this.panel1.Controls.Add(this.txtUserName); + this.panel1.Controls.Add(this.label3); + this.panel1.Controls.Add(this.txtProjectName); + this.panel1.Controls.Add(this.txtHostName); + this.panel1.Controls.Add(this.btnCancel); + this.panel1.Controls.Add(this.btnOK); + this.panel1.Controls.Add(this.pictureBox1); + this.panel1.Controls.Add(this.label2); + this.panel1.Controls.Add(this.label1); + this.panel1.Dock = System.Windows.Forms.DockStyle.Fill; + this.panel1.Location = new System.Drawing.Point(0, 0); + this.panel1.Name = "panel1"; + this.panel1.Size = new System.Drawing.Size(561, 309); + this.panel1.TabIndex = 2; + // + // label5 + // + this.label5.AutoSize = true; + this.label5.Cursor = System.Windows.Forms.Cursors.Arrow; + this.label5.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.label5.Location = new System.Drawing.Point(255, 145); + this.label5.Name = "label5"; + this.label5.Size = new System.Drawing.Size(68, 16); + this.label5.TabIndex = 18; + this.label5.Text = "Password"; + // + // txtPass + // + this.txtPass.BackColor = System.Drawing.Color.Black; + this.txtPass.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; + this.txtPass.ForeColor = System.Drawing.Color.White; + this.txtPass.Location = new System.Drawing.Point(258, 167); + this.txtPass.Name = "txtPass"; + this.txtPass.Size = new System.Drawing.Size(170, 20); + this.txtPass.TabIndex = 17; + this.txtPass.Text = "Aa123456"; + this.txtPass.UseSystemPasswordChar = true; + // + // label4 + // + this.label4.AutoSize = true; + this.label4.Cursor = System.Windows.Forms.Cursors.Arrow; + this.label4.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.label4.Location = new System.Drawing.Point(98, 145); + this.label4.Name = "label4"; + this.label4.Size = new System.Drawing.Size(77, 16); + this.label4.TabIndex = 16; + this.label4.Text = "User Name"; + // + // txtUserName + // + this.txtUserName.BackColor = System.Drawing.Color.Black; + this.txtUserName.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; + this.txtUserName.ForeColor = System.Drawing.Color.White; + this.txtUserName.Location = new System.Drawing.Point(101, 167); + this.txtUserName.Name = "txtUserName"; + this.txtUserName.Size = new System.Drawing.Size(148, 20); + this.txtUserName.TabIndex = 15; + this.txtUserName.Text = "panel-pc"; + // + // label3 + // + this.label3.AutoSize = true; + this.label3.Cursor = System.Windows.Forms.Cursors.Arrow; + this.label3.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.label3.Location = new System.Drawing.Point(98, 81); + this.label3.Name = "label3"; + this.label3.Size = new System.Drawing.Size(76, 16); + this.label3.TabIndex = 14; + this.label3.Text = "Host Name"; + // + // txtProjectName + // + this.txtProjectName.AutoSize = true; + this.txtProjectName.Cursor = System.Windows.Forms.Cursors.Arrow; + this.txtProjectName.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.txtProjectName.Location = new System.Drawing.Point(255, 45); + this.txtProjectName.Name = "txtProjectName"; + this.txtProjectName.Size = new System.Drawing.Size(87, 16); + this.txtProjectName.TabIndex = 13; + this.txtProjectName.Text = "Project name"; + // + // txtHostName + // + this.txtHostName.BackColor = System.Drawing.Color.Black; + this.txtHostName.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; + this.txtHostName.ForeColor = System.Drawing.Color.White; + this.txtHostName.Location = new System.Drawing.Point(101, 100); + this.txtHostName.Name = "txtHostName"; + this.txtHostName.Size = new System.Drawing.Size(327, 20); + this.txtHostName.TabIndex = 12; + this.txtHostName.Text = "\\\\PANEL-PC"; + // + // btnCancel + // + this.btnCancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.btnCancel.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(40)))), ((int)(((byte)(40)))), ((int)(((byte)(40))))); + this.btnCancel.Cursor = System.Windows.Forms.Cursors.Arrow; + this.btnCancel.FlatAppearance.BorderSize = 0; + this.btnCancel.FlatAppearance.MouseDownBackColor = System.Drawing.Color.FromArgb(((int)(((byte)(15)))), ((int)(((byte)(15)))), ((int)(((byte)(15))))); + this.btnCancel.FlatAppearance.MouseOverBackColor = System.Drawing.Color.FromArgb(((int)(((byte)(60)))), ((int)(((byte)(60)))), ((int)(((byte)(60))))); + this.btnCancel.FlatStyle = System.Windows.Forms.FlatStyle.Flat; + this.btnCancel.Location = new System.Drawing.Point(314, 254); + this.btnCancel.Name = "btnCancel"; + this.btnCancel.Size = new System.Drawing.Size(114, 42); + this.btnCancel.TabIndex = 11; + this.btnCancel.Text = "CANCEL"; + this.btnCancel.UseVisualStyleBackColor = false; + // + // btnOK + // + this.btnOK.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.btnOK.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(40)))), ((int)(((byte)(40)))), ((int)(((byte)(40))))); + this.btnOK.Cursor = System.Windows.Forms.Cursors.Arrow; + this.btnOK.FlatAppearance.BorderSize = 0; + this.btnOK.FlatAppearance.MouseDownBackColor = System.Drawing.Color.FromArgb(((int)(((byte)(15)))), ((int)(((byte)(15)))), ((int)(((byte)(15))))); + this.btnOK.FlatAppearance.MouseOverBackColor = System.Drawing.Color.FromArgb(((int)(((byte)(60)))), ((int)(((byte)(60)))), ((int)(((byte)(60))))); + this.btnOK.FlatStyle = System.Windows.Forms.FlatStyle.Flat; + this.btnOK.Location = new System.Drawing.Point(434, 254); + this.btnOK.Name = "btnOK"; + this.btnOK.Size = new System.Drawing.Size(114, 42); + this.btnOK.TabIndex = 10; + this.btnOK.Text = "RUN"; + this.btnOK.UseVisualStyleBackColor = false; + // + // pictureBox1 + // + this.pictureBox1.Cursor = System.Windows.Forms.Cursors.Arrow; + this.pictureBox1.Image = global::Tango.BuildExtensions.Properties.Resources.machine_trans_small; + this.pictureBox1.Location = new System.Drawing.Point(20, 45); + this.pictureBox1.Name = "pictureBox1"; + this.pictureBox1.Size = new System.Drawing.Size(63, 68); + this.pictureBox1.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage; + this.pictureBox1.TabIndex = 4; + this.pictureBox1.TabStop = false; + // + // label2 + // + this.label2.AutoSize = true; + this.label2.Cursor = System.Windows.Forms.Cursors.Arrow; + this.label2.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.label2.Location = new System.Drawing.Point(98, 45); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size(151, 16); + this.label2.TabIndex = 1; + this.label2.Text = "Remote Debug Project: "; + // + // label1 + // + this.label1.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(40)))), ((int)(((byte)(40)))), ((int)(((byte)(40))))); + this.label1.Cursor = System.Windows.Forms.Cursors.Arrow; + this.label1.Dock = System.Windows.Forms.DockStyle.Top; + this.label1.Location = new System.Drawing.Point(0, 0); + this.label1.Margin = new System.Windows.Forms.Padding(0); + this.label1.Name = "label1"; + this.label1.Padding = new System.Windows.Forms.Padding(5, 0, 0, 0); + this.label1.Size = new System.Drawing.Size(559, 29); + this.label1.TabIndex = 0; + this.label1.Text = "Run On Remote Machine"; + this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; + // + // RemoteDebugForm + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(20)))), ((int)(((byte)(20)))), ((int)(((byte)(20))))); + this.ClientSize = new System.Drawing.Size(561, 309); + this.ControlBox = false; + this.Controls.Add(this.panel1); + this.ForeColor = System.Drawing.Color.Gainsboro; + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None; + this.MaximizeBox = false; + this.MinimizeBox = false; + this.Name = "RemoteDebugForm"; + this.ShowIcon = false; + this.ShowInTaskbar = false; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; + this.Text = "Tango Initializer"; + this.TopMost = true; + this.panel1.ResumeLayout(false); + this.panel1.PerformLayout(); + ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit(); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.Panel panel1; + private System.Windows.Forms.Label label1; + private System.Windows.Forms.Label label2; + private System.Windows.Forms.PictureBox pictureBox1; + private System.Windows.Forms.Button btnOK; + private System.Windows.Forms.Button btnCancel; + private System.Windows.Forms.TextBox txtHostName; + private System.Windows.Forms.Label label3; + private System.Windows.Forms.Label txtProjectName; + private System.Windows.Forms.Label label5; + private System.Windows.Forms.TextBox txtPass; + private System.Windows.Forms.Label label4; + private System.Windows.Forms.TextBox txtUserName; + } +}
\ No newline at end of file diff --git a/Software/Visual_Studio/VSIX/Tango.BuildExtensions/RemoteDebugForm.cs b/Software/Visual_Studio/VSIX/Tango.BuildExtensions/RemoteDebugForm.cs new file mode 100644 index 000000000..a59a138e0 --- /dev/null +++ b/Software/Visual_Studio/VSIX/Tango.BuildExtensions/RemoteDebugForm.cs @@ -0,0 +1,44 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; + +namespace Tango.BuildExtensions +{ + public partial class RemoteDebugForm : Form + { + public String HostName { get; set; } + public String UserName { get; set; } + public String Password { get; set; } + + public RemoteDebugForm(String projectName) + { + InitializeComponent(); + + txtProjectName.Text = projectName; + + btnOK.Click += BtnOK_Click; + btnCancel.Click += BtnCancel_Click; + } + + private void BtnCancel_Click(object sender, EventArgs e) + { + DialogResult = DialogResult.Cancel; + Close(); + } + + private void BtnOK_Click(object sender, EventArgs e) + { + HostName = txtHostName.Text; + UserName = txtUserName.Text; + Password = txtPass.Text; + DialogResult = DialogResult.OK; + Close(); + } + } +} diff --git a/Software/Visual_Studio/VSIX/Tango.BuildExtensions/RemoteDebugForm.resx b/Software/Visual_Studio/VSIX/Tango.BuildExtensions/RemoteDebugForm.resx new file mode 100644 index 000000000..1af7de150 --- /dev/null +++ b/Software/Visual_Studio/VSIX/Tango.BuildExtensions/RemoteDebugForm.resx @@ -0,0 +1,120 @@ +<?xml version="1.0" encoding="utf-8"?> +<root> + <!-- + Microsoft ResX Schema + + Version 2.0 + + The primary goals of this format is to allow a simple XML format + that is mostly human readable. The generation and parsing of the + various data types are done through the TypeConverter classes + associated with the data types. + + Example: + + ... ado.net/XML headers & schema ... + <resheader name="resmimetype">text/microsoft-resx</resheader> + <resheader name="version">2.0</resheader> + <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader> + <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader> + <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data> + <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data> + <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64"> + <value>[base64 mime encoded serialized .NET Framework object]</value> + </data> + <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64"> + <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value> + <comment>This is a comment</comment> + </data> + + There are any number of "resheader" rows that contain simple + name/value pairs. + + Each data row contains a name, and value. The row also contains a + type or mimetype. Type corresponds to a .NET class that support + text/value conversion through the TypeConverter architecture. + Classes that don't support this are serialized and stored with the + mimetype set. + + The mimetype is used for serialized objects, and tells the + ResXResourceReader how to depersist the object. This is currently not + extensible. For a given mimetype the value must be set accordingly: + + Note - application/x-microsoft.net.object.binary.base64 is the format + that the ResXResourceWriter will generate, however the reader can + read any of the formats listed below. + + mimetype: application/x-microsoft.net.object.binary.base64 + value : The object must be serialized with + : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter + : and then encoded with base64 encoding. + + mimetype: application/x-microsoft.net.object.soap.base64 + value : The object must be serialized with + : System.Runtime.Serialization.Formatters.Soap.SoapFormatter + : and then encoded with base64 encoding. + + mimetype: application/x-microsoft.net.object.bytearray.base64 + value : The object must be serialized into a byte array + : using a System.ComponentModel.TypeConverter + : and then encoded with base64 encoding. + --> + <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"> + <xsd:import namespace="http://www.w3.org/XML/1998/namespace" /> + <xsd:element name="root" msdata:IsDataSet="true"> + <xsd:complexType> + <xsd:choice maxOccurs="unbounded"> + <xsd:element name="metadata"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="value" type="xsd:string" minOccurs="0" /> + </xsd:sequence> + <xsd:attribute name="name" use="required" type="xsd:string" /> + <xsd:attribute name="type" type="xsd:string" /> + <xsd:attribute name="mimetype" type="xsd:string" /> + <xsd:attribute ref="xml:space" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="assembly"> + <xsd:complexType> + <xsd:attribute name="alias" type="xsd:string" /> + <xsd:attribute name="name" type="xsd:string" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="data"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> + <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" /> + </xsd:sequence> + <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" /> + <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" /> + <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" /> + <xsd:attribute ref="xml:space" /> + </xsd:complexType> + </xsd:element> + <xsd:element name="resheader"> + <xsd:complexType> + <xsd:sequence> + <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> + </xsd:sequence> + <xsd:attribute name="name" type="xsd:string" use="required" /> + </xsd:complexType> + </xsd:element> + </xsd:choice> + </xsd:complexType> + </xsd:element> + </xsd:schema> + <resheader name="resmimetype"> + <value>text/microsoft-resx</value> + </resheader> + <resheader name="version"> + <value>2.0</value> + </resheader> + <resheader name="reader"> + <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> + </resheader> + <resheader name="writer"> + <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> + </resheader> +</root>
\ No newline at end of file diff --git a/Software/Visual_Studio/VSIX/Tango.BuildExtensions/Resources/RemoteDebugCommand.png b/Software/Visual_Studio/VSIX/Tango.BuildExtensions/Resources/RemoteDebugCommand.png Binary files differnew file mode 100644 index 000000000..b22d975cb --- /dev/null +++ b/Software/Visual_Studio/VSIX/Tango.BuildExtensions/Resources/RemoteDebugCommand.png diff --git a/Software/Visual_Studio/VSIX/Tango.BuildExtensions/Tango.BuildExtensions.csproj b/Software/Visual_Studio/VSIX/Tango.BuildExtensions/Tango.BuildExtensions.csproj index b5b5ed45e..86c9bd2b8 100644 --- a/Software/Visual_Studio/VSIX/Tango.BuildExtensions/Tango.BuildExtensions.csproj +++ b/Software/Visual_Studio/VSIX/Tango.BuildExtensions/Tango.BuildExtensions.csproj @@ -7,6 +7,21 @@ <NuGetPackageImportStamp> </NuGetPackageImportStamp> <UseCodebase>true</UseCodebase> + <PublishUrl>publish\</PublishUrl> + <Install>true</Install> + <InstallFrom>Disk</InstallFrom> + <UpdateEnabled>false</UpdateEnabled> + <UpdateMode>Foreground</UpdateMode> + <UpdateInterval>7</UpdateInterval> + <UpdateIntervalUnits>Days</UpdateIntervalUnits> + <UpdatePeriodically>false</UpdatePeriodically> + <UpdateRequired>false</UpdateRequired> + <MapFileExtensions>true</MapFileExtensions> + <ApplicationRevision>0</ApplicationRevision> + <ApplicationVersion>1.0.0.%2a</ApplicationVersion> + <IsWebBootstrapper>false</IsWebBootstrapper> + <UseApplicationTrust>false</UseApplicationTrust> + <BootstrapperEnabled>true</BootstrapperEnabled> </PropertyGroup> <PropertyGroup> <SignAssembly>true</SignAssembly> @@ -69,8 +84,16 @@ <DesignTime>True</DesignTime> <DependentUpon>Resources.resx</DependentUpon> </Compile> + <Compile Include="RemoteDebugCommand.cs" /> + <Compile Include="RemoteDebugForm.cs"> + <SubType>Form</SubType> + </Compile> + <Compile Include="RemoteDebugForm.Designer.cs"> + <DependentUpon>RemoteDebugForm.cs</DependentUpon> + </Compile> <Compile Include="TangoBuildCommand.cs" /> <Compile Include="TangoBuildCommandPackage.cs" /> + <Compile Include="VSIXBase.cs" /> <Compile Include="VSPackage.Designer.cs"> <AutoGen>True</AutoGen> <DesignTime>True</DesignTime> @@ -87,6 +110,9 @@ </ItemGroup> <ItemGroup> <Content Include="index.html" /> + <Content Include="PsExec.exe"> + <IncludeInVSIX>true</IncludeInVSIX> + </Content> <Content Include="Resources\BuildTangoCommand.png" /> <Content Include="Resources\BuildTangoCommandPackage.ico" /> <VSCTCompile Include="TangoBuildCommandPackage.vsct"> @@ -94,6 +120,7 @@ </VSCTCompile> <None Include="Resources\machine-trans-small.png" /> <None Include="Resources\machine-trans-16x16.png" /> + <Content Include="Resources\RemoteDebugCommand.png" /> <Content Include="Resources\TangoBuildCommand.png" /> <Content Include="Resources\TangoBuildCommandPackage.ico" /> <Content Include="stylesheet.css" /> @@ -212,6 +239,9 @@ <Generator>ResXFileCodeGenerator</Generator> <LastGenOutput>Resources.Designer.cs</LastGenOutput> </EmbeddedResource> + <EmbeddedResource Include="RemoteDebugForm.resx"> + <DependentUpon>RemoteDebugForm.cs</DependentUpon> + </EmbeddedResource> <EmbeddedResource Include="VSPackage.resx"> <MergeWithCTO>true</MergeWithCTO> <ManifestResourceName>VSPackage</ManifestResourceName> @@ -223,6 +253,18 @@ <Analyzer Include="..\..\packages\Microsoft.VisualStudio.SDK.Analyzers.15.7.7\analyzers\cs\Microsoft.VisualStudio.SDK.Analyzers.dll" /> <Analyzer Include="..\..\packages\Microsoft.VisualStudio.Threading.Analyzers.15.7.18\analyzers\cs\Microsoft.VisualStudio.Threading.Analyzers.dll" /> </ItemGroup> + <ItemGroup> + <BootstrapperPackage Include=".NETFramework,Version=v4.6"> + <Visible>False</Visible> + <ProductName>Microsoft .NET Framework 4.6 %28x86 and x64%29</ProductName> + <Install>true</Install> + </BootstrapperPackage> + <BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1"> + <Visible>False</Visible> + <ProductName>.NET Framework 3.5 SP1</ProductName> + <Install>false</Install> + </BootstrapperPackage> + </ItemGroup> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <Import Project="$(VSToolsPath)\VSSDK\Microsoft.VsSDK.targets" Condition="'$(VSToolsPath)' != ''" /> <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild"> diff --git a/Software/Visual_Studio/VSIX/Tango.BuildExtensions/TangoBuildCommand.cs b/Software/Visual_Studio/VSIX/Tango.BuildExtensions/TangoBuildCommand.cs index 36506e5b0..f2fb09c36 100644 --- a/Software/Visual_Studio/VSIX/Tango.BuildExtensions/TangoBuildCommand.cs +++ b/Software/Visual_Studio/VSIX/Tango.BuildExtensions/TangoBuildCommand.cs @@ -27,9 +27,8 @@ namespace Tango.BuildExtensions /// <summary> /// Command handler /// </summary> - internal sealed class TangoBuildCommand + internal sealed class TangoBuildCommand : VSIXBase { - private DTE2 _dte; private IList<Project> _projects; private SelectForm _form; private TestStack.White.Application _application; @@ -66,7 +65,7 @@ namespace Tango.BuildExtensions /// Adds our command handlers for menu (commands must exist in the command table file) /// </summary> /// <param name="package">Owner package, not null.</param> - private TangoBuildCommand(Package package) + private TangoBuildCommand(Package package) : base(package) { if (package == null) { @@ -138,9 +137,9 @@ namespace Tango.BuildExtensions System.Threading.Tasks.Task.Factory.StartNew(() => { - _projects = Projects().ToList(); + _projects = GetSolutionProjects().ToList(); - String vsWindowTitle = _dte.DTE.MainWindow.Caption; + String vsWindowTitle = DTE.DTE.MainWindow.Caption; _vsProcess = System.Diagnostics.Process.GetProcesses().ToList().SingleOrDefault(x => x.MainWindowTitle == vsWindowTitle); _application = TestStack.White.Application.Attach(_vsProcess); _window = _application.GetWindow(vsWindowTitle); @@ -170,7 +169,7 @@ namespace Tango.BuildExtensions BuildSolution(); } - SetStatusText("Done!"); + SetProgressText("Done!"); Wait(1000); CloseProgressForm(); } @@ -193,41 +192,41 @@ namespace Tango.BuildExtensions var projectItems = project.ProjectItems.OfType<ProjectItem>().ToList(); - SetStatusText("Locating " + edmxModelName + " scheme..."); + SetProgressText("Locating " + edmxModelName + " scheme..."); - var items = GetProjectItemsDeep(project); + var items = GetProjectItems(project); - var edmx = GetProjectItemsDeep(project).SingleOrDefault(x => x.Name == edmxModelName); + var edmx = GetProjectItems(project).SingleOrDefault(x => x.Name == edmxModelName); if (edmx == null) { throw new NullReferenceException("Could not locate " + edmxModelName + "!"); } - SetStatusText("Expanding diagram..."); + SetProgressText("Expanding diagram..."); edmx.ExpandView(); - SetStatusText("Opening edmx diagram window..."); + SetProgressText("Opening edmx diagram window..."); Window win = edmx.Open(EnvDTE.Constants.vsViewKindPrimary); win.Visible = true; - SetStatusText("Waiting for edmx diagram window..."); + SetProgressText("Waiting for edmx diagram window..."); _window.WaitTill(() => _window.Get(SearchCriteria.ByText(edmxModelName + " [Diagram1]")) != null); - SetStatusText("Cleaning up edmx scheme..."); + SetProgressText("Cleaning up edmx scheme..."); - _dte.MainWindow.Activate(); - _dte.ExecuteCommand("Edit.SelectAll"); + DTE.MainWindow.Activate(); + DTE.ExecuteCommand("Edit.SelectAll"); Keyboard.Instance.PressSpecialKey(KeyboardInput.SpecialKeys.DELETE); WaitForWindowOpen("Delete Unmapped Tables and Views").PressKey(KeyboardInput.SpecialKeys.RETURN); WaitForWindowClose("Delete Unmapped Tables and Views"); _window.WaitWhileBusy(); - SetStatusText("Reinitializing edmx scheme..."); + SetProgressText("Reinitializing edmx scheme..."); var window = WindowInfo.GetWindow(edmxModelName + " [Diagram1]*"); window.SetActive(); @@ -258,13 +257,13 @@ namespace Tango.BuildExtensions updateWindow.PressKey(KeyboardInput.SpecialKeys.RETURN); - SetStatusText("Generating edmx scheme..."); + SetProgressText("Generating edmx scheme..."); WaitForWindowClose("Update Wizard"); _window.WaitWhileBusy(); - SetStatusText("Saving changes..."); + SetProgressText("Saving changes..."); win.Close(vsSaveChanges.vsSaveChangesYes); @@ -272,18 +271,18 @@ namespace Tango.BuildExtensions foreach (var template in edmx.ProjectItems.OfType<ProjectItem>().Where(x => x.Name.EndsWith(".tt"))) { - SetStatusText("Running custom tool for " + template.Name + "..."); + SetProgressText("Running custom tool for " + template.Name + "..."); (template.Object as VSProjectItem).RunCustomTool(); _window.WaitWhileBusy(); } _window.WaitWhileBusy(); - SetStatusText("Building project " + dalProjectName + "..."); + SetProgressText("Building project " + dalProjectName + "..."); - _dte.Solution.SolutionBuild.BuildProject("Debug", project.FullName, true); + DTE.Solution.SolutionBuild.BuildProject("Debug", project.FullName, true); - if (_dte.Solution.SolutionBuild.LastBuildInfo > 0) + if (DTE.Solution.SolutionBuild.LastBuildInfo > 0) { throw new ExternalException(dalProjectName + " failed to build!"); } @@ -298,15 +297,15 @@ namespace Tango.BuildExtensions throw new NullReferenceException("Could not locate project " + observablesGeneratorProjectName); } - SetStatusText("Building project " + observablesGeneratorProjectName + "..."); + SetProgressText("Building project " + observablesGeneratorProjectName + "..."); - _dte.Solution.SolutionBuild.BuildProject("Debug", project.FullName, true); + DTE.Solution.SolutionBuild.BuildProject("Debug", project.FullName, true); - _dte.Solution.Properties.Item("StartupProject").Value = observablesGeneratorProjectName; + DTE.Solution.Properties.Item("StartupProject").Value = observablesGeneratorProjectName; - SetStatusText("Executing observables generator..."); + SetProgressText("Executing observables generator..."); - _dte.ExecuteCommand("Debug.Start"); + DTE.ExecuteCommand("Debug.Start"); WaitForWindowOpen("Tango Observables Generator"); @@ -319,7 +318,7 @@ namespace Tango.BuildExtensions throw new NullReferenceException("Could not locate project " + observablesProjectName); } - SetStatusText("Updating " + observablesProjectName + "..."); + SetProgressText("Updating " + observablesProjectName + "..."); foreach (var file in Directory.GetFiles(Path.GetDirectoryName(observablesProject.FileName), "*.cs", SearchOption.AllDirectories)) { @@ -327,17 +326,17 @@ namespace Tango.BuildExtensions if (parentFolderName != "Debug" && parentFolderName != "Release" && parentFolderName != "obj") { - SetStatusText("Adding/Updating file " + Path.GetFileName(file) + "..."); + SetProgressText("Adding/Updating file " + Path.GetFileName(file) + "..."); observablesProject.ProjectItems.AddFromFile(file); Wait(10); } } - SetStatusText("Building project " + observablesProjectName + "..."); + SetProgressText("Building project " + observablesProjectName + "..."); - _dte.Solution.SolutionBuild.BuildProject("Debug", observablesProject.FullName, true); + DTE.Solution.SolutionBuild.BuildProject("Debug", observablesProject.FullName, true); - if (_dte.Solution.SolutionBuild.LastBuildInfo > 0) + if (DTE.Solution.SolutionBuild.LastBuildInfo > 0) { throw new ExternalException(observablesProjectName + " failed to build!"); } @@ -352,15 +351,15 @@ namespace Tango.BuildExtensions throw new NullReferenceException("Could not locate project " + pmrGeneratorProjectName); } - SetStatusText("Building project " + pmrGeneratorProjectName + "..."); + SetProgressText("Building project " + pmrGeneratorProjectName + "..."); - _dte.Solution.SolutionBuild.BuildProject("Debug", project.FullName, true); + DTE.Solution.SolutionBuild.BuildProject("Debug", project.FullName, true); - _dte.Solution.Properties.Item("StartupProject").Value = pmrGeneratorProjectName; + DTE.Solution.Properties.Item("StartupProject").Value = pmrGeneratorProjectName; - SetStatusText("Executing PMR generator..."); + SetProgressText("Executing PMR generator..."); - _dte.ExecuteCommand("Debug.Start"); + DTE.ExecuteCommand("Debug.Start"); WaitForWindowOpen("Tango PMR Generator"); @@ -376,20 +375,20 @@ namespace Tango.BuildExtensions throw new NullReferenceException("Could not locate project " + protoCliProjectName); } - SetStatusText("Building project " + protoCliProjectName + "..."); + SetProgressText("Building project " + protoCliProjectName + "..."); - _dte.Solution.SolutionBuild.BuildProject("Debug", protoProject.FullName, true); + DTE.Solution.SolutionBuild.BuildProject("Debug", protoProject.FullName, true); - if (_dte.Solution.SolutionBuild.LastBuildInfo > 0) + if (DTE.Solution.SolutionBuild.LastBuildInfo > 0) { throw new ExternalException(protoCliProjectName + " failed to build!"); } - _dte.Solution.Properties.Item("StartupProject").Value = protoCliProjectName; + DTE.Solution.Properties.Item("StartupProject").Value = protoCliProjectName; - SetStatusText("Executing Tango Proto Compiler..."); + SetProgressText("Executing Tango Proto Compiler..."); - _dte.ExecuteCommand("Debug.Start"); + DTE.ExecuteCommand("Debug.Start"); WaitForWindowOpen("Tango Protobuf Compiler"); @@ -403,7 +402,7 @@ namespace Tango.BuildExtensions throw new NullReferenceException("Could not locate project " + pmrProjectName); } - SetStatusText("Updating " + pmrProjectName + "..."); + SetProgressText("Updating " + pmrProjectName + "..."); foreach (var file in Directory.GetFiles(Path.GetDirectoryName(project.FileName), "*.cs", SearchOption.AllDirectories)) { @@ -411,17 +410,17 @@ namespace Tango.BuildExtensions if (parentFolderName != "Debug" && parentFolderName != "Release" && parentFolderName != "obj") { - SetStatusText("Adding/Updating file " + Path.GetFileName(file) + "..."); + SetProgressText("Adding/Updating file " + Path.GetFileName(file) + "..."); project.ProjectItems.AddFromFile(file); Wait(10); } } - SetStatusText("Building project " + pmrProjectName + "..."); + SetProgressText("Building project " + pmrProjectName + "..."); - _dte.Solution.SolutionBuild.BuildProject("Debug", project.FullName, true); + DTE.Solution.SolutionBuild.BuildProject("Debug", project.FullName, true); - if (_dte.Solution.SolutionBuild.LastBuildInfo > 0) + if (DTE.Solution.SolutionBuild.LastBuildInfo > 0) { throw new ExternalException(pmrProjectName + " failed to build!"); } @@ -429,198 +428,15 @@ namespace Tango.BuildExtensions private void BuildSolution() { - SetStatusText("Building solution..."); - _dte.Solution.SolutionBuild.Build(true); + SetProgressText("Building solution..."); + DTE.Solution.SolutionBuild.Build(true); - if (_dte.Solution.SolutionBuild.LastBuildInfo > 0) + if (DTE.Solution.SolutionBuild.LastBuildInfo > 0) { throw new ExternalException("Error building solution!"); } } #endregion - - #region Solution & Projects - - public DTE2 GetActiveIDE() - { - // Get an instance of currently running Visual Studio IDE. - DTE2 dte2 = Package.GetGlobalService(typeof(DTE)) as DTE2; - _dte = dte2; - return dte2; - } - - public IList<Project> Projects() - { - Projects projects = GetActiveIDE().Solution.Projects; - List<Project> list = new List<Project>(); - var item = projects.GetEnumerator(); - while (item.MoveNext()) - { - var project = item.Current as Project; - if (project == null) - { - continue; - } - - if (project.Kind == ProjectKinds.vsProjectKindSolutionFolder) - { - list.AddRange(GetSolutionFolderProjects(project)); - } - else - { - list.Add(project); - } - } - - return list; - } - - private IEnumerable<Project> GetSolutionFolderProjects(Project solutionFolder) - { - List<Project> list = new List<Project>(); - for (var i = 1; i <= solutionFolder.ProjectItems.Count; i++) - { - var subProject = solutionFolder.ProjectItems.Item(i).SubProject; - if (subProject == null) - { - continue; - } - - // If this is another solution folder, do a recursive call, otherwise add - if (subProject.Kind == ProjectKinds.vsProjectKindSolutionFolder) - { - list.AddRange(GetSolutionFolderProjects(subProject)); - } - else - { - list.Add(subProject); - } - } - return list; - } - - private List<ProjectItem> GetProjectItemsDeep(Project project) - { - List<ProjectItem> results = new List<ProjectItem>(); - FillProjectItems(project.ProjectItems.OfType<ProjectItem>().ToList(), results); - return results; - } - - private void FillProjectItems(List<ProjectItem> rootItems, List<ProjectItem> results) - { - foreach (var item in rootItems) - { - results.Add(item); - - if (item.ProjectItems.Count > 0) - { - FillProjectItems(item.ProjectItems.OfType<ProjectItem>().ToList(), results); - } - } - } - - #endregion - - #region Notifications - - private void WriteToConsole(String text) - { - // Get the output window - var outputWindow = Package.GetGlobalService(typeof(SVsOutputWindow)) as IVsOutputWindow; - - // Ensure that the desired pane is visible - var paneGuid = Microsoft.VisualStudio.VSConstants.OutputWindowPaneGuid.GeneralPane_guid; - IVsOutputWindowPane pane; - outputWindow.CreatePane(paneGuid, "General", 1, 0); - outputWindow.GetPane(paneGuid, out pane); - - // Output the message - pane.OutputString(text + Environment.NewLine); - } - - private void ShowMessage(String text) - { - // Show a message box to prove we were here - - VsShellUtilities.ShowMessageBox( - ServiceProvider, - text, - "Tango Initializer", - OLEMSGICON.OLEMSGICON_INFO, - OLEMSGBUTTON.OLEMSGBUTTON_OK, - OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST); - } - - #endregion - - #region Windows API - - private WindowInfo WaitForWindowOpen(String title) - { - WindowInfo window = null; - - do - { - window = WindowInfo.GetAllWindows().SelectMany(x => x.Children).FirstOrDefault(x => x.Caption == title); - } while (window == null); - - return window; - } - - private void WaitForWindowClose(String title) - { - while (WindowInfo.GetAllWindows().SelectMany(x => x.Children).ToList().Exists(x => x.Caption == title)) - { - System.Threading.Thread.Sleep(100); - } - } - - #endregion - - #region Threading - - private void Wait(int milli) - { - System.Threading.Thread.Sleep(milli); - } - - #endregion - - #region Status Form - - private void OpenProgressForm() - { - System.Threading.Thread thread = new System.Threading.Thread(() => - { - _form = new SelectForm(); - var handle = _form.Handle; - _form.ShowDialog(); - }); - - thread.SetApartmentState(System.Threading.ApartmentState.STA); - thread.Start(); - - while (_form == null || !_form.IsHandleCreated) { } - } - - private void SetStatusText(String text) - { - _form.Invoke(new Action(() => - { - _form.SetStatus(text); - })); - } - - private void CloseProgressForm() - { - _form.Invoke(new Action(() => - { - _form.Close(); - _form = null; - })); - } - - #endregion } } diff --git a/Software/Visual_Studio/VSIX/Tango.BuildExtensions/TangoBuildCommandPackage.cs b/Software/Visual_Studio/VSIX/Tango.BuildExtensions/TangoBuildCommandPackage.cs index f31bb8193..9a99b527c 100644 --- a/Software/Visual_Studio/VSIX/Tango.BuildExtensions/TangoBuildCommandPackage.cs +++ b/Software/Visual_Studio/VSIX/Tango.BuildExtensions/TangoBuildCommandPackage.cs @@ -68,6 +68,7 @@ namespace Tango.BuildExtensions { TangoBuildCommand.Initialize(this); base.Initialize(); + Tango.BuildExtensions.RemoteDebugCommand.Initialize(this); } #endregion diff --git a/Software/Visual_Studio/VSIX/Tango.BuildExtensions/TangoBuildCommandPackage.vsct b/Software/Visual_Studio/VSIX/Tango.BuildExtensions/TangoBuildCommandPackage.vsct index 06eec602e..b454037e0 100644 --- a/Software/Visual_Studio/VSIX/Tango.BuildExtensions/TangoBuildCommandPackage.vsct +++ b/Software/Visual_Studio/VSIX/Tango.BuildExtensions/TangoBuildCommandPackage.vsct @@ -15,10 +15,10 @@ defining some of the constants that we will use inside the file. --> <!--This is the file that defines the IDs for all the commands exposed by VisualStudio. --> - <Extern href="stdidcmd.h"/> + <Extern href="stdidcmd.h" /> <!--This header contains the command ids for the menus provided by the shell. --> - <Extern href="vsshlids.h"/> + <Extern href="vsshlids.h" /> <!--The Commands section is where commands, menus, and menu groups are defined. This section uses a Guid to identify the package that provides the command defined inside it. --> @@ -37,7 +37,7 @@ must be a menu. --> <Groups> <Group guid="guidTangoBuildCommandPackageCmdSet" id="MyMenuGroup" priority="0x0600"> - <Parent guid="guidSHLMainMenu" id="IDM_VS_MENU_TOOLS"/> + <Parent guid="guidSHLMainMenu" id="IDM_VS_MENU_TOOLS" /> </Group> </Groups> @@ -59,6 +59,13 @@ <ButtonText>Tango Build Engine</ButtonText> </Strings> </Button> + <Button guid="guidTangoBuildCommandPackageCmdSet" id="cmdidRemoteDebugCommand" priority="0x0100" type="Button"> + <Parent guid="guidTangoBuildCommandPackageCmdSet" id="MyMenuGroup" /> + <Icon guid="guidImages1" id="bmpPic1" /> + <Strings> + <ButtonText>Run On Remote Machine</ButtonText> + </Strings> + </Button> </Buttons> <!--The bitmaps section is used to define the bitmaps that are used for the commands.--> @@ -68,8 +75,9 @@ bitmap strip containing the bitmaps and then there are the numeric ids of the elements used inside a button definition. An important aspect of this declaration is that the element id must be the actual index (1-based) of the bitmap inside the bitmap strip. --> - <Bitmap guid="guidImages" href="Resources\TangoBuildCommand.png" usedList="bmpPic1, bmpPic2, bmpPicSearch, bmpPicX, bmpPicArrows, bmpPicStrikethrough"/> - <Bitmap guid="guidMyImages" href="Resources\machine-trans-16x16.png" usedList="machine"/> + <Bitmap guid="guidImages" href="Resources\TangoBuildCommand.png" usedList="bmpPic1, bmpPic2, bmpPicSearch, bmpPicX, bmpPicArrows, bmpPicStrikethrough" /> + <Bitmap guid="guidMyImages" href="Resources\machine-trans-16x16.png" usedList="machine" /> + <Bitmap guid="guidImages1" href="Resources\RemoteDebugCommand.png" usedList="bmpPic1, bmpPic2, bmpPicSearch, bmpPicX, bmpPicArrows, bmpPicStrikethrough" /> </Bitmaps> </Commands> @@ -81,13 +89,23 @@ <GuidSymbol name="guidTangoBuildCommandPackageCmdSet" value="{c03a7b01-8109-4ec5-8f90-858bed027e5d}"> <IDSymbol name="MyMenuGroup" value="0x1020" /> <IDSymbol name="TangoBuildCommandId" value="0x0100" /> + <IDSymbol value="4129" name="cmdidRemoteDebugCommand" /> </GuidSymbol> <GuidSymbol name="guidMyImages" value="{d52f5c81-cc63-4c7c-8513-231caf50db11}"> <IDSymbol name="machine" value="1" /> </GuidSymbol> - <GuidSymbol name="guidImages" value="{735a16c4-95ad-41f9-9342-ac321265d383}" > + <GuidSymbol name="guidImages" value="{735a16c4-95ad-41f9-9342-ac321265d383}"> + <IDSymbol name="bmpPic1" value="1" /> + <IDSymbol name="bmpPic2" value="2" /> + <IDSymbol name="bmpPicSearch" value="3" /> + <IDSymbol name="bmpPicX" value="4" /> + <IDSymbol name="bmpPicArrows" value="5" /> + <IDSymbol name="bmpPicStrikethrough" value="6" /> + </GuidSymbol> + + <GuidSymbol value="{aac52784-fa61-4a71-8649-e9b1d5f25c07}" name="guidImages1"> <IDSymbol name="bmpPic1" value="1" /> <IDSymbol name="bmpPic2" value="2" /> <IDSymbol name="bmpPicSearch" value="3" /> diff --git a/Software/Visual_Studio/VSIX/Tango.BuildExtensions/VSIXBase.cs b/Software/Visual_Studio/VSIX/Tango.BuildExtensions/VSIXBase.cs new file mode 100644 index 000000000..068268298 --- /dev/null +++ b/Software/Visual_Studio/VSIX/Tango.BuildExtensions/VSIXBase.cs @@ -0,0 +1,298 @@ +using System; +using System.ComponentModel.Design; +using System.Globalization; +using Microsoft.VisualStudio.Shell; +using Microsoft.VisualStudio.Shell.Interop; +using System.Collections.Generic; +using EnvDTE; +using EnvDTE80; +using Microsoft.VisualStudio; +using System.Linq; +using TestStack.White.UIItems.Finders; +using TestStack.White.InputDevices; +using TestStack.White.UIItems; +using VSLangProj; +using System.Runtime.InteropServices; +using TestStack.White.WindowsAPI; +using System.IO; + +namespace Tango.BuildExtensions +{ + public class VSIXBase + { + private SelectForm _form; + + public IServiceProvider BaseServiceProvider { get; private set; } + + public DTE2 DTE { get; private set; } + + public VSIXBase(IServiceProvider serviceProvider) + { + BaseServiceProvider = serviceProvider; + DTE = GetActiveIDE(); + } + + #region Solution & Projects + + private DTE2 GetActiveIDE() + { + // Get an instance of currently running Visual Studio IDE. + DTE2 dte2 = Package.GetGlobalService(typeof(DTE)) as DTE2; + return dte2; + } + + public IList<Project> GetSolutionProjects() + { + Projects projects = GetActiveIDE().Solution.Projects; + List<Project> list = new List<Project>(); + var item = projects.GetEnumerator(); + while (item.MoveNext()) + { + var project = item.Current as Project; + if (project == null) + { + continue; + } + + if (project.Kind == ProjectKinds.vsProjectKindSolutionFolder) + { + list.AddRange(GetSolutionFolderProjects(project)); + } + else + { + list.Add(project); + } + } + + return list; + } + + private IEnumerable<Project> GetSolutionFolderProjects(Project solutionFolder) + { + List<Project> list = new List<Project>(); + for (var i = 1; i <= solutionFolder.ProjectItems.Count; i++) + { + var subProject = solutionFolder.ProjectItems.Item(i).SubProject; + if (subProject == null) + { + continue; + } + + // If this is another solution folder, do a recursive call, otherwise add + if (subProject.Kind == ProjectKinds.vsProjectKindSolutionFolder) + { + list.AddRange(GetSolutionFolderProjects(subProject)); + } + else + { + list.Add(subProject); + } + } + return list; + } + + public List<ProjectItem> GetProjectItems(Project project) + { + List<ProjectItem> results = new List<ProjectItem>(); + FillProjectItems(project.ProjectItems.OfType<ProjectItem>().ToList(), results); + return results; + } + + private void FillProjectItems(List<ProjectItem> rootItems, List<ProjectItem> results) + { + foreach (var item in rootItems) + { + results.Add(item); + + if (item.ProjectItems.Count > 0) + { + FillProjectItems(item.ProjectItems.OfType<ProjectItem>().ToList(), results); + } + } + } + + protected String GetProjectOutputFilePath(EnvDTE.Project vsProject) + { + string fullPath = vsProject.Properties.Item("FullPath").Value.ToString(); + + string outputPath = vsProject.ConfigurationManager.ActiveConfiguration.Properties.Item("OutputPath").Value.ToString(); + + string outputDir = Path.Combine(fullPath, outputPath); + + string outputFileName = vsProject.Properties.Item("OutputFileName").Value.ToString(); + + string assemblyPath = Path.Combine(outputDir, outputFileName); + + return assemblyPath; + } + + #endregion + + #region Notifications + + public void WriteToConsole(String text) + { + // Get the output window + var outputWindow = Package.GetGlobalService(typeof(SVsOutputWindow)) as IVsOutputWindow; + + // Ensure that the desired pane is visible + var paneGuid = Microsoft.VisualStudio.VSConstants.OutputWindowPaneGuid.GeneralPane_guid; + IVsOutputWindowPane pane; + outputWindow.CreatePane(paneGuid, "General", 1, 0); + outputWindow.GetPane(paneGuid, out pane); + + // Output the message + pane.OutputString(text + Environment.NewLine); + } + + public void ShowMessage(String text) + { + // Show a message box to prove we were here + + VsShellUtilities.ShowMessageBox( + BaseServiceProvider, + text, + "Tango Initializer", + OLEMSGICON.OLEMSGICON_INFO, + OLEMSGBUTTON.OLEMSGBUTTON_OK, + OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST); + } + + #endregion + + #region Windows API + + protected WindowInfo WaitForWindowOpen(String title) + { + WindowInfo window = null; + + do + { + window = WindowInfo.GetAllWindows().SelectMany(x => x.Children).FirstOrDefault(x => x.Caption == title); + } while (window == null); + + return window; + } + + protected void WaitForWindowClose(String title) + { + while (WindowInfo.GetAllWindows().SelectMany(x => x.Children).ToList().Exists(x => x.Caption == title)) + { + System.Threading.Thread.Sleep(100); + } + } + + #endregion + + #region Threading + + protected void Wait(int milli) + { + System.Threading.Thread.Sleep(milli); + } + + #endregion + + #region Status Form + + protected void OpenProgressForm() + { + System.Threading.Thread thread = new System.Threading.Thread(() => + { + _form = new SelectForm(); + var handle = _form.Handle; + _form.ShowDialog(); + }); + + thread.SetApartmentState(System.Threading.ApartmentState.STA); + thread.Start(); + + while (_form == null || !_form.IsHandleCreated) { } + } + + protected void SetProgressText(String text) + { + if (_form != null) + { + _form.Invoke(new Action(() => + { + _form.SetStatus(text); + })); + } + } + + protected void CloseProgressForm() + { + if (_form != null) + { + _form.Invoke(new Action(() => + { + _form.Close(); + _form = null; + })); + } + } + + #endregion + + #region Content + + protected string GetFullPathToContentFile(String fileName) + { + return Path.Combine(Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().CodeBase), fileName).Replace("file:\\", ""); + } + + #endregion + + #region IO + + /// <summary> + /// Copies the specified directory source path to the specified destination. + /// </summary> + /// <param name="sourcePath">The source path.</param> + /// <param name="destinationPath">The destination path.</param> + /// <param name="copySubDirs">if set to <c>true</c> will copy sub directories.</param> + /// <exception cref="DirectoryNotFoundException">Source directory does not exist or could not be found: " + /// + sourcePath</exception> + protected void CopyDirectory(string sourcePath, string destinationPath, bool copySubDirs, Action<String> progress = null) + { + // Get the subdirectories for the specified directory. + DirectoryInfo dir = new DirectoryInfo(sourcePath); + + if (!dir.Exists) + { + throw new DirectoryNotFoundException( + "Source directory does not exist or could not be found: " + + sourcePath); + } + + DirectoryInfo[] dirs = dir.GetDirectories(); + // If the destination directory doesn't exist, create it. + if (!Directory.Exists(destinationPath)) + { + Directory.CreateDirectory(destinationPath); + } + + // Get the files in the directory and copy them to the new location. + FileInfo[] files = dir.GetFiles(); + foreach (FileInfo file in files) + { + string temppath = Path.Combine(destinationPath, file.Name); + progress?.Invoke(temppath); + file.CopyTo(temppath, true); + } + + // If copying subdirectories, copy them and their contents to new location. + if (copySubDirs) + { + foreach (DirectoryInfo subdir in dirs) + { + string temppath = Path.Combine(destinationPath, subdir.Name); + CopyDirectory(subdir.FullName, temppath, copySubDirs); + } + } + } + + #endregion + } +} |
