diff --git a/BismNormalizer/AlmToolkit/AlmToolkit.csproj b/BismNormalizer/AlmToolkit/AlmToolkit.csproj index ca87ab2..a0a9ec4 100644 --- a/BismNormalizer/AlmToolkit/AlmToolkit.csproj +++ b/BismNormalizer/AlmToolkit/AlmToolkit.csproj @@ -42,6 +42,9 @@ app.manifest + + BismNorm.ico + ..\packages\Microsoft.AnalysisServices.retail.amd64.18.0.5\lib\net45\Microsoft.AnalysisServices.dll @@ -155,6 +158,7 @@ + Always diff --git a/BismNormalizer/AlmToolkit/Images/BismNormalizerLogo.ico b/BismNormalizer/AlmToolkit/BismNorm.ico similarity index 100% rename from BismNormalizer/AlmToolkit/Images/BismNormalizerLogo.ico rename to BismNormalizer/AlmToolkit/BismNorm.ico diff --git a/BismNormalizer/AlmToolkit/ComparisonForm.Designer.cs b/BismNormalizer/AlmToolkit/ComparisonForm.Designer.cs index dfdabf5..02cb244 100644 --- a/BismNormalizer/AlmToolkit/ComparisonForm.Designer.cs +++ b/BismNormalizer/AlmToolkit/ComparisonForm.Designer.cs @@ -86,22 +86,21 @@ this.StatusBarComparsion.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { this.toolStripStatusLabel1, this.toolStripProgressBar1}); - this.StatusBarComparsion.Location = new System.Drawing.Point(0, 564); + this.StatusBarComparsion.Location = new System.Drawing.Point(0, 810); this.StatusBarComparsion.Name = "StatusBarComparsion"; - this.StatusBarComparsion.Padding = new System.Windows.Forms.Padding(1, 0, 19, 0); - this.StatusBarComparsion.Size = new System.Drawing.Size(1100, 22); + this.StatusBarComparsion.Size = new System.Drawing.Size(1176, 22); this.StatusBarComparsion.TabIndex = 48; this.StatusBarComparsion.Text = "Comparison Status"; // // toolStripStatusLabel1 // this.toolStripStatusLabel1.Name = "toolStripStatusLabel1"; - this.toolStripStatusLabel1.Size = new System.Drawing.Size(0, 12); + this.toolStripStatusLabel1.Size = new System.Drawing.Size(0, 17); // // toolStripProgressBar1 // this.toolStripProgressBar1.Name = "toolStripProgressBar1"; - this.toolStripProgressBar1.Size = new System.Drawing.Size(133, 12); + this.toolStripProgressBar1.Size = new System.Drawing.Size(100, 16); this.toolStripProgressBar1.Visible = false; // // tabHome @@ -329,7 +328,7 @@ this.pnlRibbon.Location = new System.Drawing.Point(0, 0); this.pnlRibbon.Margin = new System.Windows.Forms.Padding(1); this.pnlRibbon.Name = "pnlRibbon"; - this.pnlRibbon.Size = new System.Drawing.Size(1100, 142); + this.pnlRibbon.Size = new System.Drawing.Size(1176, 115); this.pnlRibbon.TabIndex = 49; // // maqSoftwareLogo @@ -338,10 +337,10 @@ this.maqSoftwareLogo.BackColor = System.Drawing.Color.White; this.maqSoftwareLogo.Cursor = System.Windows.Forms.Cursors.Hand; this.maqSoftwareLogo.Image = ((System.Drawing.Image)(resources.GetObject("maqSoftwareLogo.Image"))); - this.maqSoftwareLogo.Location = new System.Drawing.Point(681, 39); + this.maqSoftwareLogo.Location = new System.Drawing.Point(862, 32); this.maqSoftwareLogo.Margin = new System.Windows.Forms.Padding(1); this.maqSoftwareLogo.Name = "maqSoftwareLogo"; - this.maqSoftwareLogo.Size = new System.Drawing.Size(217, 62); + this.maqSoftwareLogo.Size = new System.Drawing.Size(163, 50); this.maqSoftwareLogo.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage; this.maqSoftwareLogo.TabIndex = 3; this.maqSoftwareLogo.TabStop = false; @@ -351,10 +350,10 @@ // this.powerBiLogo.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); this.powerBiLogo.Image = ((System.Drawing.Image)(resources.GetObject("powerBiLogo.Image"))); - this.powerBiLogo.Location = new System.Drawing.Point(895, 34); + this.powerBiLogo.Location = new System.Drawing.Point(1022, 28); this.powerBiLogo.Margin = new System.Windows.Forms.Padding(1); this.powerBiLogo.Name = "powerBiLogo"; - this.powerBiLogo.Size = new System.Drawing.Size(199, 71); + this.powerBiLogo.Size = new System.Drawing.Size(149, 58); this.powerBiLogo.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage; this.powerBiLogo.TabIndex = 2; this.powerBiLogo.TabStop = false; @@ -382,7 +381,7 @@ this.ribbonMain.OrbStyle = System.Windows.Forms.RibbonOrbStyle.Office_2013; this.ribbonMain.OrbText = "File"; this.ribbonMain.RibbonTabFont = new System.Drawing.Font("Trebuchet MS", 9F); - this.ribbonMain.Size = new System.Drawing.Size(1100, 111); + this.ribbonMain.Size = new System.Drawing.Size(1176, 90); this.ribbonMain.TabIndex = 1; this.ribbonMain.Tabs.Add(this.tabHome); this.ribbonMain.Tabs.Add(this.tabHelp); @@ -434,10 +433,9 @@ this.pnlHeader.BackColor = System.Drawing.SystemColors.HighlightText; this.pnlHeader.Controls.Add(this.spltSourceTarget); this.pnlHeader.Dock = System.Windows.Forms.DockStyle.Top; - this.pnlHeader.Location = new System.Drawing.Point(0, 142); - this.pnlHeader.Margin = new System.Windows.Forms.Padding(4); + this.pnlHeader.Location = new System.Drawing.Point(0, 115); this.pnlHeader.Name = "pnlHeader"; - this.pnlHeader.Size = new System.Drawing.Size(1100, 41); + this.pnlHeader.Size = new System.Drawing.Size(1176, 33); this.pnlHeader.TabIndex = 50; // // spltSourceTarget @@ -445,7 +443,6 @@ this.spltSourceTarget.Dock = System.Windows.Forms.DockStyle.Fill; this.spltSourceTarget.IsSplitterFixed = true; this.spltSourceTarget.Location = new System.Drawing.Point(0, 0); - this.spltSourceTarget.Margin = new System.Windows.Forms.Padding(4); this.spltSourceTarget.Name = "spltSourceTarget"; // // spltSourceTarget.Panel1 @@ -459,18 +456,16 @@ this.spltSourceTarget.Panel2.Controls.Add(this.txtTarget); this.spltSourceTarget.Panel2.Controls.Add(this.label2); this.spltSourceTarget.Panel2.RightToLeft = System.Windows.Forms.RightToLeft.No; - this.spltSourceTarget.Size = new System.Drawing.Size(1100, 41); - this.spltSourceTarget.SplitterDistance = 557; - this.spltSourceTarget.SplitterWidth = 5; + this.spltSourceTarget.Size = new System.Drawing.Size(1176, 33); + this.spltSourceTarget.SplitterDistance = 594; this.spltSourceTarget.TabIndex = 45; // // label1 // this.label1.AutoSize = true; - this.label1.Location = new System.Drawing.Point(3, 10); - this.label1.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); + this.label1.Location = new System.Drawing.Point(2, 8); this.label1.Name = "label1"; - this.label1.Size = new System.Drawing.Size(51, 16); + this.label1.Size = new System.Drawing.Size(41, 13); this.label1.TabIndex = 39; this.label1.Text = "Source"; // @@ -480,10 +475,9 @@ | System.Windows.Forms.AnchorStyles.Right))); this.txtSource.BackColor = System.Drawing.SystemColors.HighlightText; this.txtSource.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; - this.txtSource.Location = new System.Drawing.Point(65, 7); - this.txtSource.Margin = new System.Windows.Forms.Padding(4); + this.txtSource.Location = new System.Drawing.Point(49, 6); this.txtSource.Name = "txtSource"; - this.txtSource.Size = new System.Drawing.Size(439, 22); + this.txtSource.Size = new System.Drawing.Size(476, 20); this.txtSource.TabIndex = 41; // // txtTarget @@ -492,10 +486,9 @@ | System.Windows.Forms.AnchorStyles.Right))); this.txtTarget.BackColor = System.Drawing.SystemColors.HighlightText; this.txtTarget.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; - this.txtTarget.Location = new System.Drawing.Point(60, 7); - this.txtTarget.Margin = new System.Windows.Forms.Padding(4); + this.txtTarget.Location = new System.Drawing.Point(45, 6); this.txtTarget.Name = "txtTarget"; - this.txtTarget.Size = new System.Drawing.Size(437, 22); + this.txtTarget.Size = new System.Drawing.Size(451, 20); this.txtTarget.TabIndex = 42; // // label2 @@ -503,28 +496,25 @@ this.label2.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); this.label2.AutoSize = true; - this.label2.Location = new System.Drawing.Point(4, 10); - this.label2.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); + this.label2.Location = new System.Drawing.Point(3, 8); this.label2.Name = "label2"; - this.label2.Size = new System.Drawing.Size(48, 16); + this.label2.Size = new System.Drawing.Size(38, 13); this.label2.TabIndex = 40; this.label2.Text = "Target"; // // ComparisonForm // - this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 16F); + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(1100, 586); + this.ClientSize = new System.Drawing.Size(1176, 832); this.Controls.Add(this.pnlHeader); this.Controls.Add(this.StatusBarComparsion); this.Controls.Add(this.pnlRibbon); this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); this.KeyPreview = true; - this.Margin = new System.Windows.Forms.Padding(4); - this.MinimumSize = new System.Drawing.Size(1017, 583); + this.MinimumSize = new System.Drawing.Size(767, 481); this.Name = "ComparisonForm"; this.Text = "ALM Toolkit for Power BI"; - this.WindowState = System.Windows.Forms.FormWindowState.Maximized; this.Load += new System.EventHandler(this.ComparisonForm_Load); this.Shown += new System.EventHandler(this.ComparisonForm_Shown); this.StatusBarComparsion.ResumeLayout(false); diff --git a/BismNormalizer/AlmToolkit/ComparisonForm.cs b/BismNormalizer/AlmToolkit/ComparisonForm.cs index f2a08ca..0255939 100644 --- a/BismNormalizer/AlmToolkit/ComparisonForm.cs +++ b/BismNormalizer/AlmToolkit/ComparisonForm.cs @@ -338,7 +338,7 @@ namespace AlmToolkit private void SetAutoComplete() { - if (!_comparisonInfo.ConnectionInfoSource.UseProject && !_comparisonInfo.ConnectionInfoSource.UseBimFile) + if (!_comparisonInfo.ConnectionInfoSource.UseProject && !_comparisonInfo.ConnectionInfoSource.UseDesktop && !_comparisonInfo.ConnectionInfoSource.UseBimFile) { if (Settings.Default.SourceServerAutoCompleteEntries.IndexOf(_comparisonInfo.ConnectionInfoSource.ServerName + "|") > -1) { @@ -354,7 +354,7 @@ namespace AlmToolkit GetFromAutoCompleteSource(); } - if (!_comparisonInfo.ConnectionInfoTarget.UseProject && !_comparisonInfo.ConnectionInfoTarget.UseBimFile) + if (!_comparisonInfo.ConnectionInfoTarget.UseProject && !_comparisonInfo.ConnectionInfoTarget.UseDesktop && !_comparisonInfo.ConnectionInfoTarget.UseBimFile) { if (Settings.Default.TargetServerAutoCompleteEntries.IndexOf(_comparisonInfo.ConnectionInfoTarget.ServerName + "|") > -1) { @@ -377,8 +377,32 @@ namespace AlmToolkit private void PopulateSourceTargetTextBoxes() { - txtSource.Text = _comparisonInfo.ConnectionInfoSource.ServerName + ";" + _comparisonInfo.ConnectionInfoSource.DatabaseName; - txtTarget.Text = _comparisonInfo.ConnectionInfoTarget.ServerName + ";" + _comparisonInfo.ConnectionInfoTarget.DatabaseName; + if (_comparisonInfo.ConnectionInfoSource.UseDesktop) + { + txtSource.Text = "PBI Desktop/SSDT: " + _comparisonInfo.ConnectionInfoSource.DesktopName; + } + else if (_comparisonInfo.ConnectionInfoSource.UseBimFile) + { + txtSource.Text = "File: " + _comparisonInfo.ConnectionInfoSource.BimFile; + } + else + { + txtSource.Text = "Database: " + _comparisonInfo.ConnectionInfoSource.ServerName + ";" + _comparisonInfo.ConnectionInfoSource.DatabaseName; + } + + if (_comparisonInfo.ConnectionInfoTarget.UseDesktop) + { + txtTarget.Text = "PBI Desktop/SSDT: " + _comparisonInfo.ConnectionInfoTarget.DesktopName; + } + else if (_comparisonInfo.ConnectionInfoTarget.UseBimFile) + { + txtTarget.Text = "File: " + _comparisonInfo.ConnectionInfoTarget.BimFile; + } + else + { + txtTarget.Text = "Database: " + _comparisonInfo.ConnectionInfoTarget.ServerName + ";" + _comparisonInfo.ConnectionInfoTarget.DatabaseName; + } + } private void btnGenerateScript_Click(object sender, EventArgs e) @@ -742,6 +766,8 @@ namespace AlmToolkit { try { + CleanUpConnectionInfo(); + _fileName = fileName; XmlSerializer writer = new XmlSerializer(typeof(ComparisonInfo)); StreamWriter file = new System.IO.StreamWriter(fileName); @@ -755,6 +781,21 @@ namespace AlmToolkit } } + private void CleanUpConnectionInfo() + { + if (_comparisonInfo.ConnectionInfoSource.UseDesktop) + { + _comparisonInfo.ConnectionInfoSource.ServerName = null; + _comparisonInfo.ConnectionInfoSource.DatabaseName = null; + } + + if (_comparisonInfo.ConnectionInfoTarget.UseDesktop) + { + _comparisonInfo.ConnectionInfoTarget.ServerName = null; + _comparisonInfo.ConnectionInfoTarget.DatabaseName = null; + } + } + private void mnuOpen_Click(object sender, EventArgs e) { try diff --git a/BismNormalizer/AlmToolkit/ComparisonForm.resx b/BismNormalizer/AlmToolkit/ComparisonForm.resx index da1c8c5..cdef54f 100644 --- a/BismNormalizer/AlmToolkit/ComparisonForm.resx +++ b/BismNormalizer/AlmToolkit/ComparisonForm.resx @@ -181,6 +181,44 @@ iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAh NwAAITcBM1ifegAAABNJREFUOE9jGAWjYBSMAjBgYAAABBAAAadEfGMAAAAASUVORK5CYII= + + + + + iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAYAAAA7MK6iAAAABGdBTUEAALGPC/xhBQAAAmBJREFUSEvt + l01oE0EUx3P0Ll6868FLRb0J4k1a8CCIF0E8KNGDqAepbWw+JQULhsSCJmjcqBgxLUo3myYtfiRNN9m2 + pmpiZUvTZm0Sk2pBxXOfb9bd0NCdkO7iIeAffvDmzc77zyyzu7OmjpKQEc5leWElOy1MCWnhkJL+t8ql + c7sFfmZDmJ7hkTVkXukyLqfTedDhcJxHzAQmyAzh6jbQEFRSr1NFfirza3OOtF0u10V1nM1mO+N2u3cp + ZVvLbrcfDQQCP0dHRiESichwLAfjY/G2UMcQYlwMfD5fCWvuUMrThTO1kQHr39abWBKXQFwQWyIVpS3j + PB7PDzTer5Sni2asl843Xiwta+Zp6DZO52fhU3FRji89vAkX7tsbfe2g2zj4agQOO0/DldAgdN8yg1Qu + Q7X8FZ4yYWD8jzSZy74zbkzwciE45bsKq5VKI5efz1MpFUuN6zp/c22XzjNeWZWgVqvLsT/xDC4z7kZf + O+g2Hnzhh54hM9ie34EuywnIFHJy/u1kEia4SU3Ehb+PnyHjen0Nzt7tgwMDJyEnFuQceZwS0QkqZGcb + NjbKf2OqWhk/fvMS7JFhzT4auo2HY0+gP3wbwikW9vUeh+RHQc7Lr8f3BU3I5jNsXKlWoQc/DnuudUNi + LiXnSGHmXogKn8wYNyYsf5Fg9vOHply7dPbm0sN2jC3x8bhmET3g8fY7ntO7lPJ04eyOBB8Ef7NjLNCI + stEmuCi3BXLXCF6vt4aH+p1K+dayWq3HcOW9BJzIdQLGfSrY7idgbCFgfEMF2wMEjK0E/JvYq5TdJJPp + D5oiqINNnQHQAAAAAElFTkSuQmCC + + + + + iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAYAAAA7MK6iAAAABGdBTUEAALGPC/xhBQAAAmBJREFUSEvt + l01oE0EUx3P0Ll6868FLRb0J4k1a8CCIF0E8KNGDqAepbWw+JQULhsSCJmjcqBgxLUo3myYtfiRNN9m2 + pmpiZUvTZm0Sk2pBxXOfb9bd0NCdkO7iIeAffvDmzc77zyyzu7OmjpKQEc5leWElOy1MCWnhkJL+t8ql + c7sFfmZDmJ7hkTVkXukyLqfTedDhcJxHzAQmyAzh6jbQEFRSr1NFfirza3OOtF0u10V1nM1mO+N2u3cp + ZVvLbrcfDQQCP0dHRiESichwLAfjY/G2UMcQYlwMfD5fCWvuUMrThTO1kQHr39abWBKXQFwQWyIVpS3j + PB7PDzTer5Sni2asl843Xiwta+Zp6DZO52fhU3FRji89vAkX7tsbfe2g2zj4agQOO0/DldAgdN8yg1Qu + Q7X8FZ4yYWD8jzSZy74zbkzwciE45bsKq5VKI5efz1MpFUuN6zp/c22XzjNeWZWgVqvLsT/xDC4z7kZf + O+g2Hnzhh54hM9ie34EuywnIFHJy/u1kEia4SU3Ehb+PnyHjen0Nzt7tgwMDJyEnFuQceZwS0QkqZGcb + NjbKf2OqWhk/fvMS7JFhzT4auo2HY0+gP3wbwikW9vUeh+RHQc7Lr8f3BU3I5jNsXKlWoQc/DnuudUNi + LiXnSGHmXogKn8wYNyYsf5Fg9vOHply7dPbm0sN2jC3x8bhmET3g8fY7ntO7lPJ04eyOBB8Ef7NjLNCI + stEmuCi3BXLXCF6vt4aH+p1K+dayWq3HcOW9BJzIdQLGfSrY7idgbCFgfEMF2wMEjK0E/JvYq5TdJJPp + D5oiqINNnQHQAAAAAElFTkSuQmCC + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAh + NwAAITcBM1ifegAAABNJREFUOE9jGAWjYBSMAjBgYAAABBAAAadEfGMAAAAASUVORK5CYII= @@ -343,44 +381,6 @@ iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAh NwAAITcBM1ifegAAABNJREFUOE9jGAWjYBSMAjBgYAAABBAAAadEfGMAAAAASUVORK5CYII= - - - - - iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAYAAAA7MK6iAAAABGdBTUEAALGPC/xhBQAAAmBJREFUSEvt - l01oE0EUx3P0Ll6868FLRb0J4k1a8CCIF0E8KNGDqAepbWw+JQULhsSCJmjcqBgxLUo3myYtfiRNN9m2 - pmpiZUvTZm0Sk2pBxXOfb9bd0NCdkO7iIeAffvDmzc77zyyzu7OmjpKQEc5leWElOy1MCWnhkJL+t8ql - c7sFfmZDmJ7hkTVkXukyLqfTedDhcJxHzAQmyAzh6jbQEFRSr1NFfirza3OOtF0u10V1nM1mO+N2u3cp - ZVvLbrcfDQQCP0dHRiESichwLAfjY/G2UMcQYlwMfD5fCWvuUMrThTO1kQHr39abWBKXQFwQWyIVpS3j - PB7PDzTer5Sni2asl843Xiwta+Zp6DZO52fhU3FRji89vAkX7tsbfe2g2zj4agQOO0/DldAgdN8yg1Qu - Q7X8FZ4yYWD8jzSZy74zbkzwciE45bsKq5VKI5efz1MpFUuN6zp/c22XzjNeWZWgVqvLsT/xDC4z7kZf - O+g2Hnzhh54hM9ie34EuywnIFHJy/u1kEia4SU3Ehb+PnyHjen0Nzt7tgwMDJyEnFuQceZwS0QkqZGcb - NjbKf2OqWhk/fvMS7JFhzT4auo2HY0+gP3wbwikW9vUeh+RHQc7Lr8f3BU3I5jNsXKlWoQc/DnuudUNi - LiXnSGHmXogKn8wYNyYsf5Fg9vOHply7dPbm0sN2jC3x8bhmET3g8fY7ntO7lPJ04eyOBB8Ef7NjLNCI - stEmuCi3BXLXCF6vt4aH+p1K+dayWq3HcOW9BJzIdQLGfSrY7idgbCFgfEMF2wMEjK0E/JvYq5TdJJPp - D5oiqINNnQHQAAAAAElFTkSuQmCC - - - - - iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAYAAAA7MK6iAAAABGdBTUEAALGPC/xhBQAAAmBJREFUSEvt - l01oE0EUx3P0Ll6868FLRb0J4k1a8CCIF0E8KNGDqAepbWw+JQULhsSCJmjcqBgxLUo3myYtfiRNN9m2 - pmpiZUvTZm0Sk2pBxXOfb9bd0NCdkO7iIeAffvDmzc77zyyzu7OmjpKQEc5leWElOy1MCWnhkJL+t8ql - c7sFfmZDmJ7hkTVkXukyLqfTedDhcJxHzAQmyAzh6jbQEFRSr1NFfirza3OOtF0u10V1nM1mO+N2u3cp - ZVvLbrcfDQQCP0dHRiESichwLAfjY/G2UMcQYlwMfD5fCWvuUMrThTO1kQHr39abWBKXQFwQWyIVpS3j - PB7PDzTer5Sni2asl843Xiwta+Zp6DZO52fhU3FRji89vAkX7tsbfe2g2zj4agQOO0/DldAgdN8yg1Qu - Q7X8FZ4yYWD8jzSZy74zbkzwciE45bsKq5VKI5efz1MpFUuN6zp/c22XzjNeWZWgVqvLsT/xDC4z7kZf - O+g2Hnzhh54hM9ie34EuywnIFHJy/u1kEia4SU3Ehb+PnyHjen0Nzt7tgwMDJyEnFuQceZwS0QkqZGcb - NjbKf2OqWhk/fvMS7JFhzT4auo2HY0+gP3wbwikW9vUeh+RHQc7Lr8f3BU3I5jNsXKlWoQc/DnuudUNi - LiXnSGHmXogKn8wYNyYsf5Fg9vOHply7dPbm0sN2jC3x8bhmET3g8fY7ntO7lPJ04eyOBB8Ef7NjLNCI - stEmuCi3BXLXCF6vt4aH+p1K+dayWq3HcOW9BJzIdQLGfSrY7idgbCFgfEMF2wMEjK0E/JvYq5TdJJPp - D5oiqINNnQHQAAAAAElFTkSuQmCC - - - - - iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAh - NwAAITcBM1ifegAAABNJREFUOE9jGAWjYBSMAjBgYAAABBAAAadEfGMAAAAASUVORK5CYII= diff --git a/BismNormalizer/AlmToolkit/Images/BismNorm.ico b/BismNormalizer/AlmToolkit/Images/BismNorm.ico new file mode 100644 index 0000000..523c7aa Binary files /dev/null and b/BismNormalizer/AlmToolkit/Images/BismNorm.ico differ diff --git a/BismNormalizer/AlmToolkit/Images/PBIReportServer.png b/BismNormalizer/AlmToolkit/Images/PBIReportServer.png new file mode 100644 index 0000000..78898e0 Binary files /dev/null and b/BismNormalizer/AlmToolkit/Images/PBIReportServer.png differ diff --git a/BismNormalizer/AlmToolkit/Images/devenv.png b/BismNormalizer/AlmToolkit/Images/devenv.png new file mode 100644 index 0000000..22b714b Binary files /dev/null and b/BismNormalizer/AlmToolkit/Images/devenv.png differ diff --git a/BismNormalizer/AlmToolkit/Images/powerBI2.png b/BismNormalizer/AlmToolkit/Images/powerBI2.png new file mode 100644 index 0000000..63dab84 Binary files /dev/null and b/BismNormalizer/AlmToolkit/Images/powerBI2.png differ diff --git a/BismNormalizer/AlmToolkit/ManagedIpHelper.cs b/BismNormalizer/AlmToolkit/ManagedIpHelper.cs new file mode 100644 index 0000000..2e3c913 --- /dev/null +++ b/BismNormalizer/AlmToolkit/ManagedIpHelper.cs @@ -0,0 +1,282 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Net; +using System.Net.NetworkInformation; +using System.Runtime.InteropServices; + +namespace AlmToolkit +{ + + + #region Managed IP Helper API + + public class TcpTable : IEnumerable + { + #region Private Fields + + private IEnumerable tcpRows; + + #endregion + + #region Constructors + + public TcpTable(IEnumerable tcpRows) + { + this.tcpRows = tcpRows; + } + + #endregion + + #region Public Properties + + public IEnumerable Rows + { + get { return this.tcpRows; } + } + + #endregion + + #region IEnumerable Members + + public IEnumerator GetEnumerator() + { + return this.tcpRows.GetEnumerator(); + } + + #endregion + + #region IEnumerable Members + + IEnumerator IEnumerable.GetEnumerator() + { + return this.tcpRows.GetEnumerator(); + } + + #endregion + } + + public class TcpRow + { + #region Private Fields + + private IPEndPoint localEndPoint; + private IPEndPoint remoteEndPoint; + private TcpState state; + private int processId; + + #endregion + + #region Constructors + + public TcpRow(IpHelper.TcpRow tcpRow) + { + this.state = tcpRow.state; + this.processId = tcpRow.owningPid; + + int localPort = (tcpRow.localPort1 << 8) + (tcpRow.localPort2) + (tcpRow.localPort3 << 24) + (tcpRow.localPort4 << 16); + long localAddress = tcpRow.localAddr; + this.localEndPoint = new IPEndPoint(localAddress, localPort); + + int remotePort = (tcpRow.remotePort1 << 8) + (tcpRow.remotePort2) + (tcpRow.remotePort3 << 24) + (tcpRow.remotePort4 << 16); + long remoteAddress = tcpRow.remoteAddr; + this.remoteEndPoint = new IPEndPoint(remoteAddress, remotePort); + } + + #endregion + + #region Public Properties + + public IPEndPoint LocalEndPoint + { + get { return this.localEndPoint; } + } + + public IPEndPoint RemoteEndPoint + { + get { return this.remoteEndPoint; } + } + + public TcpState State + { + get { return this.state; } + } + + public int ProcessId + { + get { return this.processId; } + } + + #endregion + } + + public static class ManagedIpHelper + { + #region Public Methods + + public static TcpTable GetExtendedTcpTable(bool sorted) + { + List tcpRows = new List(); + + IntPtr tcpTable = IntPtr.Zero; + int tcpTableLength = 0; + + if (IpHelper.GetExtendedTcpTable(tcpTable, ref tcpTableLength, sorted, IpHelper.AfInet, IpHelper.TcpTableType.OwnerPidAll, 0) != 0) + { + try + { + tcpTable = Marshal.AllocHGlobal(tcpTableLength); + if (IpHelper.GetExtendedTcpTable(tcpTable, ref tcpTableLength, true, IpHelper.AfInet, IpHelper.TcpTableType.OwnerPidAll, 0) == 0) + { + IpHelper.TcpTable table = (IpHelper.TcpTable)Marshal.PtrToStructure(tcpTable, typeof(IpHelper.TcpTable)); + + IntPtr rowPtr = (IntPtr)((long)tcpTable + Marshal.SizeOf(table.length)); + for (int i = 0; i < table.length; ++i) + { + tcpRows.Add(new TcpRow((IpHelper.TcpRow)Marshal.PtrToStructure(rowPtr, typeof(IpHelper.TcpRow)))); + rowPtr = (IntPtr)((long)rowPtr + Marshal.SizeOf(typeof(IpHelper.TcpRow))); + } + } + } + finally + { + if (tcpTable != IntPtr.Zero) + { + Marshal.FreeHGlobal(tcpTable); + } + } + } + + return new TcpTable(tcpRows); + } + + public static Dictionary GetExtendedTcpDictionary() + { + Dictionary tcpRows = new Dictionary(); + + IntPtr tcpTable = IntPtr.Zero; + int tcpTableLength = 0; + + if (IpHelper.GetExtendedTcpTable(tcpTable, ref tcpTableLength, false, IpHelper.AfInet, IpHelper.TcpTableType.OwnerPidAll, 0) != 0) + { + try + { + tcpTable = Marshal.AllocHGlobal(tcpTableLength); + if (IpHelper.GetExtendedTcpTable(tcpTable, ref tcpTableLength, true, IpHelper.AfInet, IpHelper.TcpTableType.OwnerPidAll, 0) == 0) + { + IpHelper.TcpTable table = (IpHelper.TcpTable)Marshal.PtrToStructure(tcpTable, typeof(IpHelper.TcpTable)); + + IntPtr rowPtr = (IntPtr)((long)tcpTable + Marshal.SizeOf(table.length)); + for (int i = 0; i < table.length; ++i) + { + TcpRow row = new TcpRow((IpHelper.TcpRow)Marshal.PtrToStructure(rowPtr, typeof(IpHelper.TcpRow))); + // HACK: only add first row that is in a Listening state + if (row.State == TcpState.Listen) + { + if (!tcpRows.Keys.Contains(row.ProcessId)) + tcpRows.Add(row.ProcessId, row); + } + rowPtr = (IntPtr)((long)rowPtr + Marshal.SizeOf(typeof(IpHelper.TcpRow))); + } + } + } + finally + { + if (tcpTable != IntPtr.Zero) + { + Marshal.FreeHGlobal(tcpTable); + } + } + } + + return tcpRows; + } + + + #endregion + } + + #endregion + + #region P/Invoke IP Helper API + + /// + /// + /// + public static class IpHelper + { + #region Public Fields + + public const string DllName = "iphlpapi.dll"; + public const int AfInet = 2; + + #endregion + + #region Public Methods + + /// + /// + /// + [DllImport(IpHelper.DllName, SetLastError = true)] + public static extern uint GetExtendedTcpTable(IntPtr tcpTable, ref int tcpTableLength, bool sort, int ipVersion, TcpTableType tcpTableType, int reserved); + + #endregion + + #region Public Enums + + /// + /// + /// + public enum TcpTableType + { + BasicListener, + BasicConnections, + BasicAll, + OwnerPidListener, + OwnerPidConnections, + OwnerPidAll, + OwnerModuleListener, + OwnerModuleConnections, + OwnerModuleAll, + } + + #endregion + + #region Public Structs + + /// + /// + /// + [StructLayout(LayoutKind.Sequential)] + public struct TcpTable + { + public uint length; + public TcpRow row; + } + + /// + /// + /// + [StructLayout(LayoutKind.Sequential)] + public struct TcpRow + { + public TcpState state; + public uint localAddr; + public byte localPort1; + public byte localPort2; + public byte localPort3; + public byte localPort4; + public uint remoteAddr; + public byte remotePort1; + public byte remotePort2; + public byte remotePort3; + public byte remotePort4; + public int owningPid; + } + + #endregion + + #endregion + } +} diff --git a/BismNormalizer/AlmToolkit/PowerBIHelper.cs b/BismNormalizer/AlmToolkit/PowerBIHelper.cs new file mode 100644 index 0000000..8384ba7 --- /dev/null +++ b/BismNormalizer/AlmToolkit/PowerBIHelper.cs @@ -0,0 +1,122 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +//using Serilog; +using System.Security.Principal; + +namespace AlmToolkit +{ + public enum EmbeddedSSASIcon + { + PowerBI, + Devenv, + PowerBIReportServer, + Loading + } + public class PowerBIInstance + { + public PowerBIInstance(string name, int port, EmbeddedSSASIcon icon) + { + Port = port; + Icon = icon; + try + { + var dashPos = name.LastIndexOf(" - "); + if (dashPos >= 0) + { Name = name.Substring(0, dashPos); } // Strip "Power BI Designer" or "Power BI Desktop" off the end of the string + else + { + //Log.Warning("{class} {method} {message} {dashPos}", "PowerBIInstance", "ctor", $"Unable to find ' - ' in Power BI title '{name}'", dashPos); + Name = name; + } + } + catch (Exception ex) + { + //Log.Error("{class} {method} {message} {stacktrace}", "PowerBIInstance", "ctor", ex.Message, ex.StackTrace); + Name = name; + } + } + public int Port { get; private set; } + public string Name { get; private set; } + + public EmbeddedSSASIcon Icon { get; private set; } + } + + public class PowerBIHelper + { + + public static List GetLocalInstances() + { + List _instances = new List(); + + _instances.Clear(); + + var dict = ManagedIpHelper.GetExtendedTcpDictionary(); + foreach (var proc in Process.GetProcessesByName("msmdsrv")) + { + int _port = 0; + EmbeddedSSASIcon _icon = EmbeddedSSASIcon.PowerBI; + var parent = proc.GetParent(); + + // exit here if the parent == "services" then this is a SSAS instance + if (parent.ProcessName.Equals("services", StringComparison.OrdinalIgnoreCase)) continue; + + // exit here if the parent == "RSHostingService" then this is a SSAS instance + if (parent.ProcessName.Equals("RSHostingService", StringComparison.OrdinalIgnoreCase)) + { + // only show PBI Report Server if we are running as admin + // otherwise we won't have any access to the models + if (IsAdministrator()) + _icon = EmbeddedSSASIcon.PowerBIReportServer; + else + continue; + } + + // if the process was launched from Visual Studio change the icon + if (parent.ProcessName.Equals("devenv", StringComparison.OrdinalIgnoreCase)) _icon = EmbeddedSSASIcon.Devenv; + + // get the window title so that we can parse out the file name + var parentTitle = parent.MainWindowTitle; + if (parentTitle.Length == 0) + { + // for minimized windows we need to use some Win32 api calls to get the title + //parentTitle = WindowTitle.GetWindowTitleTimeout( parent.Id, 300); + parentTitle = WindowTitle.GetWindowTitle(parent.Id); + } + + // try and get the tcp port from the Win32 TcpTable API + try + { + TcpRow tcpRow = null; + dict.TryGetValue(proc.Id, out tcpRow); + if (tcpRow != null) + { + _port = tcpRow.LocalEndPoint.Port; + _instances.Add(new PowerBIInstance(parentTitle, _port, _icon)); + //Log.Debug("{class} {method} PowerBI found on port: {port}", "PowerBIHelper", "Refresh", _port); + } + else + { + //Log.Debug("{class} {method} PowerBI port not found for process: {processName} PID: {pid}", "PowerBIHelper", "Refresh", proc.ProcessName, proc.Id); + } + + } + catch (Exception ex) + { + //Log.Error("{class} {Method} {Error} {StackTrace}", "PowerBIHelper", "Refresh", ex.Message, ex.StackTrace); + } + + } + return _instances; + } + + public static bool IsAdministrator() + { + WindowsIdentity identity = WindowsIdentity.GetCurrent(); + WindowsPrincipal principal = new WindowsPrincipal(identity); + return principal.IsInRole(WindowsBuiltInRole.Administrator); + } + + + } +} diff --git a/BismNormalizer/AlmToolkit/ProcessExtensions.cs b/BismNormalizer/AlmToolkit/ProcessExtensions.cs new file mode 100644 index 0000000..8057c5d --- /dev/null +++ b/BismNormalizer/AlmToolkit/ProcessExtensions.cs @@ -0,0 +1,31 @@ +using System.Diagnostics; +using System.Linq; +using System.Management; + +namespace AlmToolkit +{ + public static class ProcessExtensions + { + public static Process GetParent(this Process process) + { + try + { + using (var query = new ManagementObjectSearcher( + "SELECT ParentProcessId " + + "FROM Win32_Process " + + "WHERE ProcessId=" + process.Id)) + { + return query + .Get() + .OfType() + .Select(p => Process.GetProcessById((int)(uint)p["ParentProcessId"])) + .FirstOrDefault(); + } + } + catch + { + return null; + } + } + } +} diff --git a/BismNormalizer/AlmToolkit/WindowTitle.cs b/BismNormalizer/AlmToolkit/WindowTitle.cs new file mode 100644 index 0000000..15de05a --- /dev/null +++ b/BismNormalizer/AlmToolkit/WindowTitle.cs @@ -0,0 +1,161 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Runtime.InteropServices; +using System.Text; +using System.Threading.Tasks; + +namespace AlmToolkit +{ + public class WindowTitle + { + + + //static void Main(string[] args) + //{ + // var p = Process.GetProcessById(3484); + // var h = p.MainWindowHandle; + + // string s = GetWindowTextTimeout(h, 100 /*msec*/); + + //} + + + + #region PInvoke calls to get the window title of a minimize window + + delegate bool EnumThreadDelegate(IntPtr hWnd, IntPtr lParam); + + [DllImport("user32.dll")] + static extern bool IsWindowVisible(IntPtr hWnd); + + + [DllImport("user32.dll")] + static extern bool EnumThreadWindows(int dwThreadId, EnumThreadDelegate lpfn, + IntPtr lParam); + + [DllImport("User32.dll", SetLastError = true)] + public unsafe static extern int SendMessageTimeout( + IntPtr hWnd, + uint uMsg, + uint wParam, + StringBuilder lParam, + uint fuFlags, + uint uTimeout, + void* lpdwResult); + + [DllImport("user32.dll", CharSet = CharSet.Auto)] + static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, int wParam, + StringBuilder lParam); + + [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)] + static extern int GetWindowTextLength(IntPtr hWnd); + + [DllImport("User32.dll", SetLastError = true, CharSet = CharSet.Auto)] + static extern long GetWindowText(IntPtr hwnd, StringBuilder lpString, long cch); + + const int WM_GETTEXT = 0x000D; + const int WM_GETTEXTLENGTH = 0x000E; + + #endregion + + + private static IEnumerable EnumerateProcessWindowHandles(int processId) + { + var handles = new List(); + + foreach (ProcessThread thread in Process.GetProcessById(processId).Threads) + EnumThreadWindows(thread.Id, + (hWnd, lParam) => { handles.Add(hWnd); return true; }, IntPtr.Zero); + + return handles; + } + + + public static string GetWindowTitle(int procId) + { + foreach (var handle in EnumerateProcessWindowHandles(procId)) + { + StringBuilder message = new StringBuilder(1000); + if (IsWindowVisible(handle)) + { + //SendMessage(handle, WM_GETTEXT, message.Capacity, message); + //if (message.Length > 0) return message.ToString(); + return GetCaptionOfWindow(handle); + } + + } + return ""; + } + + /* ====================================== */ + + public static string GetWindowTitleTimeout(int procId, uint timeout) + { + string title = ""; + foreach (var handle in EnumerateProcessWindowHandles(procId)) + { + try + { + // if there is an issue with the window handle we just + // ignore it and skip to the next one in the collection + title = GetWindowTextTimeout(handle, timeout); + } + catch + { + title = ""; + } + if (title.Length > 0) return title; + } + return title; + } + + + private static unsafe string GetWindowTextTimeout(IntPtr hWnd, uint timeout) + { + int length; + if (SendMessageTimeout(hWnd, WM_GETTEXTLENGTH, 0, null, 2, timeout, &length) == 0) + { + return null; + } + if (length == 0) + { + return null; + } + + StringBuilder sb = new StringBuilder(length + 1); // leave room for null-terminator + if (SendMessageTimeout(hWnd, WM_GETTEXT, (uint)sb.Capacity, sb, 2, timeout, null) == 0) + { + return null; + } + + return sb.ToString(); + } + + private static string GetCaptionOfWindow(IntPtr hwnd) + { + string caption = ""; + StringBuilder windowText = null; + try + { + int max_length = GetWindowTextLength(hwnd); + windowText = new StringBuilder("", max_length + 5); + GetWindowText(hwnd, windowText, max_length + 2); + + if (!String.IsNullOrEmpty(windowText.ToString()) && !String.IsNullOrWhiteSpace(windowText.ToString())) + caption = windowText.ToString(); + } + catch (Exception ex) + { + caption = ex.Message; + } + finally + { + windowText = null; + } + return caption; + } + + } +} diff --git a/BismNormalizer/BismNormalizer/BismNormalizer.csproj b/BismNormalizer/BismNormalizer/BismNormalizer.csproj index 3196f54..5a3276a 100644 --- a/BismNormalizer/BismNormalizer/BismNormalizer.csproj +++ b/BismNormalizer/BismNormalizer/BismNormalizer.csproj @@ -62,6 +62,7 @@ true + true true @@ -73,6 +74,7 @@ 4 true true + true @@ -248,6 +250,10 @@ Connections.cs + + + + Form diff --git a/BismNormalizer/BismNormalizer/TabularCompare/ComparisonFactory.cs b/BismNormalizer/BismNormalizer/TabularCompare/ComparisonFactory.cs index 30d0b45..68f9c26 100644 --- a/BismNormalizer/BismNormalizer/TabularCompare/ComparisonFactory.cs +++ b/BismNormalizer/BismNormalizer/TabularCompare/ComparisonFactory.cs @@ -73,6 +73,18 @@ namespace BismNormalizer.TabularCompare #region Data-source versions check + //Check not working with Desktop and not V3 + if (comparisonInfo.ConnectionInfoSource.ServerName != null && comparisonInfo.ConnectionInfoSource.ServerMode == ServerMode.SharePoint && !_supportedDataSourceVersions.Contains(comparisonInfo.SourceDataSourceVersion)) + { + string message = $"The source is a Power BI Desktop dataset with default data-source version of {comparisonInfo.SourceDataSourceVersion}, which is not supported for comparison. Please ensure you're using the latest version of Power BI Desktop and if necessary enable the preview feature."; + throw new ConnectionException(message); + } + if (comparisonInfo.ConnectionInfoTarget.ServerName != null && comparisonInfo.ConnectionInfoTarget.ServerMode == ServerMode.SharePoint && !_supportedDataSourceVersions.Contains(comparisonInfo.TargetDataSourceVersion)) + { + string message = $"The target is a Power BI Desktop dataset with default data-source version of {comparisonInfo.TargetDataSourceVersion}, which is not supported for comparison. Please ensure you're using the latest version of Power BI Desktop and if necessary enable the preview feature."; + throw new ConnectionException(message); + } + //If Power BI, check the default datasource version //Source bool sourceDataSourceVersionRequiresUpgrade = false; @@ -107,7 +119,7 @@ namespace BismNormalizer.TabularCompare } else if (targetDataSourceVersionRequiresUpgrade) { - string message = $"The target is a Power BI datasets with default data-source version of {comparisonInfo.TargetDataSourceVersion}, which is not supported for comparison."; + string message = $"The target is a Power BI dataset with default data-source version of {comparisonInfo.TargetDataSourceVersion}, which is not supported for comparison."; if (comparisonInfo.Interactive && System.Windows.Forms.MessageBox.Show( message += $"\nDo you want to upgrade it to {_supportedDataSourceVersions[0]} and allow the comparison?\n\nNOTE: this is a irreversible operation and you may not be able to download the PBIX file(s) to Power BI Desktop. You should only do this if you have the original PBIX as a backup.", comparisonInfo.AppName, System.Windows.Forms.MessageBoxButtons.YesNo, System.Windows.Forms.MessageBoxIcon.Question) != System.Windows.Forms.DialogResult.Yes) { diff --git a/BismNormalizer/BismNormalizer/TabularCompare/ConnectionInfo.cs b/BismNormalizer/BismNormalizer/TabularCompare/ConnectionInfo.cs index 3d0a937..12767f0 100644 --- a/BismNormalizer/BismNormalizer/TabularCompare/ConnectionInfo.cs +++ b/BismNormalizer/BismNormalizer/TabularCompare/ConnectionInfo.cs @@ -19,15 +19,18 @@ namespace BismNormalizer.TabularCompare { #region Private Variables - private bool _useProject = false; + private bool _useProject = false; //Missed the boat to have an enum would break backwards compat with .bism file private bool _useBimFile = false; + private bool _useDesktop = false; private string _bimFile; + private string _desktopName; private string _serverName; private string _databaseName; private string _projectName; private string _projectFile; private int _compatibilityLevel; private string _dataSourceVersion; + private ServerMode _serverMode; private bool _directQuery; private string _ssdtBimFile; private EnvDTE.Project _project; @@ -62,12 +65,33 @@ namespace BismNormalizer.TabularCompare { //To late to do an enum would break backwards compat _useBimFile = false; + _useDesktop = false; _bimFile = null; } _useProject = value; } } + /// + /// A Boolean specifying whether the connection represents a Power BI Desktop or SSDT workspace AS instance. + /// + [XmlIgnore()] + public bool UseDesktop + { + get { return _useDesktop; } + set + { + if (value) + { + //To late to do an enum would break backwards compat + _useProject = false; + _useBimFile = false; + _bimFile = null; + } + _useDesktop = value; + } + } + /// /// A Boolean specifying whether the connection represents a BIM file. /// @@ -87,6 +111,16 @@ namespace BismNormalizer.TabularCompare } } + /// + /// Name of the PBIX or SSDT project to which workspace AS instance connected. + /// + [XmlIgnore()] + public string DesktopName + { + get { return _desktopName; } + set { _desktopName = value; } + } + /// /// Name of the server on which the tabular model resides. /// @@ -154,6 +188,12 @@ namespace BismNormalizer.TabularCompare [XmlIgnore()] public string DataSourceVersion => _dataSourceVersion; + /// + /// Server mode of the connection. + /// + [XmlIgnore()] + public ServerMode ServerMode => _serverMode; + /// /// A Boolean specifying whether the tabular model for the connection is running in DirectQuery mode. /// @@ -508,7 +548,20 @@ namespace BismNormalizer.TabularCompare throw new ConnectionException($"Analysis Server {this.ServerName} is not running in Tabular mode"); } - Database amoDatabase = amoServer.Databases.FindByName(this.DatabaseName); + Database amoDatabase = null; + if (this.DatabaseName == "" && this.ServerName.ToUpper().StartsWith("localhost:".ToUpper())) + { + //PBI Desktop doesn't have db name yet + if (amoServer.Databases.Count > 0) + { + amoDatabase = amoServer.Databases[0]; + this.DatabaseName = amoDatabase.Name; + } + } + else + { + amoDatabase = amoServer.Databases.FindByName(this.DatabaseName); + } if (amoDatabase == null) { if (!this.UseProject) @@ -644,6 +697,7 @@ $@"{{ _compatibilityLevel = amoDatabase.CompatibilityLevel; _dataSourceVersion = amoDatabase.Model.DefaultPowerBIDataSourceVersion.ToString(); + _serverMode = amoServer.ServerMode; _directQuery = ((amoDatabase.Model != null && amoDatabase.Model.DefaultMode == Microsoft.AnalysisServices.Tabular.ModeType.DirectQuery) || amoDatabase.DirectQueryMode == DirectQueryMode.DirectQuery || amoDatabase.DirectQueryMode == DirectQueryMode.InMemoryWithDirectQuery || amoDatabase.DirectQueryMode == DirectQueryMode.DirectQueryWithInMemory); } diff --git a/BismNormalizer/BismNormalizer/TabularCompare/UI/ConnectionsAlmt.Designer.cs b/BismNormalizer/BismNormalizer/TabularCompare/UI/ConnectionsAlmt.Designer.cs index 516e157..286e448 100644 --- a/BismNormalizer/BismNormalizer/TabularCompare/UI/ConnectionsAlmt.Designer.cs +++ b/BismNormalizer/BismNormalizer/TabularCompare/UI/ConnectionsAlmt.Designer.cs @@ -32,25 +32,47 @@ this.cboSourceServer = new System.Windows.Forms.ComboBox(); this.label2 = new System.Windows.Forms.Label(); this.label1 = new System.Windows.Forms.Label(); - this.pnlSourceDb = new System.Windows.Forms.Panel(); + this.pnlSourceDataset = new System.Windows.Forms.Panel(); this.grpSource = new System.Windows.Forms.GroupBox(); + this.pnlSourceFile = new System.Windows.Forms.Panel(); + this.btnSourceFileOpen = new System.Windows.Forms.Button(); + this.txtSourceFile = new System.Windows.Forms.TextBox(); + this.pnlSourceDesktop = new System.Windows.Forms.Panel(); + this.cboSourceDesktop = new System.Windows.Forms.ComboBox(); + this.rdoSourceFile = new System.Windows.Forms.RadioButton(); + this.rdoSourceDesktop = new System.Windows.Forms.RadioButton(); + this.rdoSourceDataset = new System.Windows.Forms.RadioButton(); + this.label5 = new System.Windows.Forms.Label(); this.btnOK = new System.Windows.Forms.Button(); this.btnCancel = new System.Windows.Forms.Button(); this.btnSwitch = new System.Windows.Forms.Button(); this.panel2 = new System.Windows.Forms.Panel(); this.panel1 = new System.Windows.Forms.Panel(); this.grpTarget = new System.Windows.Forms.GroupBox(); + this.pnlTargetFile = new System.Windows.Forms.Panel(); + this.btnTargetFileOpen = new System.Windows.Forms.Button(); + this.txtTargetFile = new System.Windows.Forms.TextBox(); + this.rdoTargetFile = new System.Windows.Forms.RadioButton(); + this.pnlTargetDesktop = new System.Windows.Forms.Panel(); + this.cboTargetDesktop = new System.Windows.Forms.ComboBox(); + this.rdoTargetDesktop = new System.Windows.Forms.RadioButton(); + this.rdoTargetDataset = new System.Windows.Forms.RadioButton(); + this.label6 = new System.Windows.Forms.Label(); this.label3 = new System.Windows.Forms.Label(); this.label4 = new System.Windows.Forms.Label(); - this.pnlTargetDb = new System.Windows.Forms.Panel(); + this.pnlTargetDataset = new System.Windows.Forms.Panel(); this.cboTargetServer = new System.Windows.Forms.ComboBox(); this.cboTargetDatabase = new System.Windows.Forms.ComboBox(); - this.pnlSourceDb.SuspendLayout(); + this.pnlSourceDataset.SuspendLayout(); this.grpSource.SuspendLayout(); + this.pnlSourceFile.SuspendLayout(); + this.pnlSourceDesktop.SuspendLayout(); this.panel2.SuspendLayout(); this.panel1.SuspendLayout(); this.grpTarget.SuspendLayout(); - this.pnlTargetDb.SuspendLayout(); + this.pnlTargetFile.SuspendLayout(); + this.pnlTargetDesktop.SuspendLayout(); + this.pnlTargetDataset.SuspendLayout(); this.SuspendLayout(); // // cboSourceDatabase @@ -59,11 +81,10 @@ | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); this.cboSourceDatabase.FormattingEnabled = true; - this.cboSourceDatabase.Location = new System.Drawing.Point(26, 87); - this.cboSourceDatabase.Margin = new System.Windows.Forms.Padding(7); + this.cboSourceDatabase.Location = new System.Drawing.Point(11, 39); this.cboSourceDatabase.MaxDropDownItems = 11; this.cboSourceDatabase.Name = "cboSourceDatabase"; - this.cboSourceDatabase.Size = new System.Drawing.Size(858, 37); + this.cboSourceDatabase.Size = new System.Drawing.Size(396, 21); this.cboSourceDatabase.TabIndex = 2; this.cboSourceDatabase.Enter += new System.EventHandler(this.cboSourceDatabase_Enter); // @@ -73,69 +94,174 @@ | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); this.cboSourceServer.FormattingEnabled = true; - this.cboSourceServer.Location = new System.Drawing.Point(26, 16); - this.cboSourceServer.Margin = new System.Windows.Forms.Padding(7); + this.cboSourceServer.Location = new System.Drawing.Point(11, 7); this.cboSourceServer.MaxDropDownItems = 11; this.cboSourceServer.Name = "cboSourceServer"; - this.cboSourceServer.Size = new System.Drawing.Size(858, 37); + this.cboSourceServer.Size = new System.Drawing.Size(396, 21); this.cboSourceServer.TabIndex = 1; this.cboSourceServer.TextChanged += new System.EventHandler(this.cboSourceServer_TextChanged); // // label2 // this.label2.AutoSize = true; - this.label2.Location = new System.Drawing.Point(18, 154); - this.label2.Margin = new System.Windows.Forms.Padding(7, 0, 7, 0); + this.label2.Location = new System.Drawing.Point(33, 99); this.label2.Name = "label2"; - this.label2.Size = new System.Drawing.Size(94, 29); + this.label2.Size = new System.Drawing.Size(44, 13); this.label2.TabIndex = 2; this.label2.Text = "Dataset"; // // label1 // this.label1.AutoSize = true; - this.label1.Location = new System.Drawing.Point(14, 83); - this.label1.Margin = new System.Windows.Forms.Padding(7, 0, 7, 0); + this.label1.Location = new System.Drawing.Point(33, 67); this.label1.Name = "label1"; - this.label1.Size = new System.Drawing.Size(134, 29); + this.label1.Size = new System.Drawing.Size(62, 13); this.label1.TabIndex = 1; this.label1.Text = "Workspace"; // - // pnlSourceDb + // pnlSourceDataset // - this.pnlSourceDb.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + this.pnlSourceDataset.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); - this.pnlSourceDb.Controls.Add(this.cboSourceServer); - this.pnlSourceDb.Controls.Add(this.cboSourceDatabase); - this.pnlSourceDb.Location = new System.Drawing.Point(147, 60); - this.pnlSourceDb.Margin = new System.Windows.Forms.Padding(7); - this.pnlSourceDb.Name = "pnlSourceDb"; - this.pnlSourceDb.Size = new System.Drawing.Size(910, 147); - this.pnlSourceDb.TabIndex = 1; + this.pnlSourceDataset.Controls.Add(this.cboSourceServer); + this.pnlSourceDataset.Controls.Add(this.cboSourceDatabase); + this.pnlSourceDataset.Location = new System.Drawing.Point(100, 57); + this.pnlSourceDataset.Name = "pnlSourceDataset"; + this.pnlSourceDataset.Size = new System.Drawing.Size(416, 66); + this.pnlSourceDataset.TabIndex = 1; // // grpSource // + this.grpSource.Controls.Add(this.pnlSourceFile); + this.grpSource.Controls.Add(this.pnlSourceDesktop); + this.grpSource.Controls.Add(this.rdoSourceFile); + this.grpSource.Controls.Add(this.rdoSourceDesktop); + this.grpSource.Controls.Add(this.rdoSourceDataset); + this.grpSource.Controls.Add(this.label5); this.grpSource.Controls.Add(this.label1); this.grpSource.Controls.Add(this.label2); - this.grpSource.Controls.Add(this.pnlSourceDb); + this.grpSource.Controls.Add(this.pnlSourceDataset); this.grpSource.Dock = System.Windows.Forms.DockStyle.Top; + this.grpSource.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); this.grpSource.Location = new System.Drawing.Point(0, 0); - this.grpSource.Margin = new System.Windows.Forms.Padding(7); this.grpSource.Name = "grpSource"; - this.grpSource.Padding = new System.Windows.Forms.Padding(7); - this.grpSource.Size = new System.Drawing.Size(1069, 263); + this.grpSource.Size = new System.Drawing.Size(522, 211); this.grpSource.TabIndex = 16; this.grpSource.TabStop = false; - this.grpSource.Text = "Source"; + // + // pnlSourceFile + // + this.pnlSourceFile.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.pnlSourceFile.Controls.Add(this.btnSourceFileOpen); + this.pnlSourceFile.Controls.Add(this.txtSourceFile); + this.pnlSourceFile.Enabled = false; + this.pnlSourceFile.Location = new System.Drawing.Point(100, 166); + this.pnlSourceFile.Name = "pnlSourceFile"; + this.pnlSourceFile.Size = new System.Drawing.Size(416, 31); + this.pnlSourceFile.TabIndex = 21; + // + // btnSourceFileOpen + // + this.btnSourceFileOpen.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Right))); + this.btnSourceFileOpen.Location = new System.Drawing.Point(380, 7); + this.btnSourceFileOpen.Margin = new System.Windows.Forms.Padding(2); + this.btnSourceFileOpen.Name = "btnSourceFileOpen"; + this.btnSourceFileOpen.Size = new System.Drawing.Size(27, 20); + this.btnSourceFileOpen.TabIndex = 1; + this.btnSourceFileOpen.Text = "..."; + this.btnSourceFileOpen.UseVisualStyleBackColor = true; + this.btnSourceFileOpen.Click += new System.EventHandler(this.btnSourceFileOpen_Click); + // + // txtSourceFile + // + this.txtSourceFile.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.txtSourceFile.Location = new System.Drawing.Point(11, 7); + this.txtSourceFile.Margin = new System.Windows.Forms.Padding(2); + this.txtSourceFile.Name = "txtSourceFile"; + this.txtSourceFile.Size = new System.Drawing.Size(365, 20); + this.txtSourceFile.TabIndex = 0; + // + // pnlSourceDesktop + // + this.pnlSourceDesktop.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.pnlSourceDesktop.Controls.Add(this.cboSourceDesktop); + this.pnlSourceDesktop.Enabled = false; + this.pnlSourceDesktop.Location = new System.Drawing.Point(172, 129); + this.pnlSourceDesktop.Name = "pnlSourceDesktop"; + this.pnlSourceDesktop.Size = new System.Drawing.Size(344, 31); + this.pnlSourceDesktop.TabIndex = 19; + // + // cboSourceDesktop + // + this.cboSourceDesktop.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.cboSourceDesktop.DisplayMember = "Name"; + this.cboSourceDesktop.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; + this.cboSourceDesktop.FormattingEnabled = true; + this.cboSourceDesktop.Location = new System.Drawing.Point(11, 8); + this.cboSourceDesktop.MaxDropDownItems = 11; + this.cboSourceDesktop.Name = "cboSourceDesktop"; + this.cboSourceDesktop.Size = new System.Drawing.Size(324, 21); + this.cboSourceDesktop.TabIndex = 9; + // + // rdoSourceFile + // + this.rdoSourceFile.AutoSize = true; + this.rdoSourceFile.Location = new System.Drawing.Point(15, 174); + this.rdoSourceFile.Name = "rdoSourceFile"; + this.rdoSourceFile.Size = new System.Drawing.Size(41, 17); + this.rdoSourceFile.TabIndex = 11; + this.rdoSourceFile.Text = "File"; + this.rdoSourceFile.UseVisualStyleBackColor = true; + this.rdoSourceFile.CheckedChanged += new System.EventHandler(this.rdoSourceFile_CheckedChanged); + // + // rdoSourceDesktop + // + this.rdoSourceDesktop.AutoSize = true; + this.rdoSourceDesktop.Location = new System.Drawing.Point(15, 138); + this.rdoSourceDesktop.Name = "rdoSourceDesktop"; + this.rdoSourceDesktop.Size = new System.Drawing.Size(151, 17); + this.rdoSourceDesktop.TabIndex = 5; + this.rdoSourceDesktop.Text = "Power BI Desktop / SSDT"; + this.rdoSourceDesktop.UseVisualStyleBackColor = true; + this.rdoSourceDesktop.CheckedChanged += new System.EventHandler(this.rdoSourceDesktop_CheckedChanged); + // + // rdoSourceDataset + // + this.rdoSourceDataset.AutoSize = true; + this.rdoSourceDataset.Checked = true; + this.rdoSourceDataset.Location = new System.Drawing.Point(15, 34); + this.rdoSourceDataset.Name = "rdoSourceDataset"; + this.rdoSourceDataset.Size = new System.Drawing.Size(62, 17); + this.rdoSourceDataset.TabIndex = 4; + this.rdoSourceDataset.TabStop = true; + this.rdoSourceDataset.Text = "Dataset"; + this.rdoSourceDataset.UseVisualStyleBackColor = true; + this.rdoSourceDataset.CheckedChanged += new System.EventHandler(this.rdoSourceDataset_CheckedChanged); + // + // label5 + // + this.label5.AutoSize = true; + this.label5.Font = new System.Drawing.Font("Microsoft Sans Serif", 10F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.label5.Location = new System.Drawing.Point(12, 9); + this.label5.Name = "label5"; + this.label5.Size = new System.Drawing.Size(59, 17); + this.label5.TabIndex = 3; + this.label5.Text = "Source"; // // btnOK // this.btnOK.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); this.btnOK.DialogResult = System.Windows.Forms.DialogResult.OK; - this.btnOK.Location = new System.Drawing.Point(696, 23); - this.btnOK.Margin = new System.Windows.Forms.Padding(7); + this.btnOK.Location = new System.Drawing.Point(362, 10); this.btnOK.Name = "btnOK"; - this.btnOK.Size = new System.Drawing.Size(161, 51); + this.btnOK.Size = new System.Drawing.Size(69, 23); this.btnOK.TabIndex = 6; this.btnOK.Text = "OK"; this.btnOK.UseVisualStyleBackColor = true; @@ -145,10 +271,9 @@ // this.btnCancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); this.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel; - this.btnCancel.Location = new System.Drawing.Point(871, 23); - this.btnCancel.Margin = new System.Windows.Forms.Padding(7); + this.btnCancel.Location = new System.Drawing.Point(437, 10); this.btnCancel.Name = "btnCancel"; - this.btnCancel.Size = new System.Drawing.Size(166, 51); + this.btnCancel.Size = new System.Drawing.Size(71, 23); this.btnCancel.TabIndex = 7; this.btnCancel.Text = "Cancel"; this.btnCancel.UseVisualStyleBackColor = true; @@ -157,10 +282,9 @@ // this.btnSwitch.BackgroundImage = global::BismNormalizer.Resources.ButtonSwitch; this.btnSwitch.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Center; - this.btnSwitch.Location = new System.Drawing.Point(467, 6); - this.btnSwitch.Margin = new System.Windows.Forms.Padding(7); + this.btnSwitch.Location = new System.Drawing.Point(236, 3); this.btnSwitch.Name = "btnSwitch"; - this.btnSwitch.Size = new System.Drawing.Size(130, 71); + this.btnSwitch.Size = new System.Drawing.Size(56, 32); this.btnSwitch.TabIndex = 3; this.btnSwitch.UseVisualStyleBackColor = true; this.btnSwitch.Click += new System.EventHandler(this.btnSwitch_Click); @@ -170,66 +294,174 @@ this.panel2.Controls.Add(this.btnCancel); this.panel2.Controls.Add(this.btnOK); this.panel2.Dock = System.Windows.Forms.DockStyle.Bottom; - this.panel2.Location = new System.Drawing.Point(0, 627); + this.panel2.Location = new System.Drawing.Point(0, 473); + this.panel2.Margin = new System.Windows.Forms.Padding(1); this.panel2.Name = "panel2"; - this.panel2.Size = new System.Drawing.Size(1069, 100); + this.panel2.Size = new System.Drawing.Size(522, 45); this.panel2.TabIndex = 22; // // panel1 // this.panel1.Controls.Add(this.btnSwitch); this.panel1.Dock = System.Windows.Forms.DockStyle.Top; - this.panel1.Location = new System.Drawing.Point(0, 263); + this.panel1.Location = new System.Drawing.Point(0, 211); + this.panel1.Margin = new System.Windows.Forms.Padding(1); this.panel1.Name = "panel1"; - this.panel1.Size = new System.Drawing.Size(1069, 84); + this.panel1.Size = new System.Drawing.Size(522, 38); this.panel1.TabIndex = 25; // // grpTarget // + this.grpTarget.Controls.Add(this.pnlTargetFile); + this.grpTarget.Controls.Add(this.rdoTargetFile); + this.grpTarget.Controls.Add(this.pnlTargetDesktop); + this.grpTarget.Controls.Add(this.rdoTargetDesktop); + this.grpTarget.Controls.Add(this.rdoTargetDataset); + this.grpTarget.Controls.Add(this.label6); this.grpTarget.Controls.Add(this.label3); this.grpTarget.Controls.Add(this.label4); - this.grpTarget.Controls.Add(this.pnlTargetDb); + this.grpTarget.Controls.Add(this.pnlTargetDataset); this.grpTarget.Dock = System.Windows.Forms.DockStyle.Top; - this.grpTarget.Location = new System.Drawing.Point(0, 347); - this.grpTarget.Margin = new System.Windows.Forms.Padding(7); + this.grpTarget.Location = new System.Drawing.Point(0, 249); this.grpTarget.Name = "grpTarget"; - this.grpTarget.Padding = new System.Windows.Forms.Padding(7); - this.grpTarget.Size = new System.Drawing.Size(1069, 268); + this.grpTarget.Size = new System.Drawing.Size(522, 218); this.grpTarget.TabIndex = 26; this.grpTarget.TabStop = false; - this.grpTarget.Text = "Target"; + // + // pnlTargetFile + // + this.pnlTargetFile.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.pnlTargetFile.Controls.Add(this.btnTargetFileOpen); + this.pnlTargetFile.Controls.Add(this.txtTargetFile); + this.pnlTargetFile.Enabled = false; + this.pnlTargetFile.Location = new System.Drawing.Point(100, 173); + this.pnlTargetFile.Name = "pnlTargetFile"; + this.pnlTargetFile.Size = new System.Drawing.Size(416, 31); + this.pnlTargetFile.TabIndex = 21; + // + // btnTargetFileOpen + // + this.btnTargetFileOpen.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Right))); + this.btnTargetFileOpen.Location = new System.Drawing.Point(380, 3); + this.btnTargetFileOpen.Margin = new System.Windows.Forms.Padding(2); + this.btnTargetFileOpen.Name = "btnTargetFileOpen"; + this.btnTargetFileOpen.Size = new System.Drawing.Size(27, 20); + this.btnTargetFileOpen.TabIndex = 2; + this.btnTargetFileOpen.Text = "..."; + this.btnTargetFileOpen.UseVisualStyleBackColor = true; + this.btnTargetFileOpen.Click += new System.EventHandler(this.btnTargetFileOpen_Click); + // + // txtTargetFile + // + this.txtTargetFile.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.txtTargetFile.Location = new System.Drawing.Point(11, 3); + this.txtTargetFile.Margin = new System.Windows.Forms.Padding(2); + this.txtTargetFile.Name = "txtTargetFile"; + this.txtTargetFile.Size = new System.Drawing.Size(365, 20); + this.txtTargetFile.TabIndex = 1; + // + // rdoTargetFile + // + this.rdoTargetFile.AutoSize = true; + this.rdoTargetFile.Location = new System.Drawing.Point(15, 178); + this.rdoTargetFile.Name = "rdoTargetFile"; + this.rdoTargetFile.Size = new System.Drawing.Size(41, 17); + this.rdoTargetFile.TabIndex = 20; + this.rdoTargetFile.Text = "File"; + this.rdoTargetFile.UseVisualStyleBackColor = true; + this.rdoTargetFile.CheckedChanged += new System.EventHandler(this.rdoTargetFile_CheckedChanged); + // + // pnlTargetDesktop + // + this.pnlTargetDesktop.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.pnlTargetDesktop.Controls.Add(this.cboTargetDesktop); + this.pnlTargetDesktop.Enabled = false; + this.pnlTargetDesktop.Location = new System.Drawing.Point(172, 132); + this.pnlTargetDesktop.Name = "pnlTargetDesktop"; + this.pnlTargetDesktop.Size = new System.Drawing.Size(344, 31); + this.pnlTargetDesktop.TabIndex = 19; + // + // cboTargetDesktop + // + this.cboTargetDesktop.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.cboTargetDesktop.DisplayMember = "Name"; + this.cboTargetDesktop.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; + this.cboTargetDesktop.FormattingEnabled = true; + this.cboTargetDesktop.Location = new System.Drawing.Point(10, 8); + this.cboTargetDesktop.MaxDropDownItems = 11; + this.cboTargetDesktop.Name = "cboTargetDesktop"; + this.cboTargetDesktop.Size = new System.Drawing.Size(325, 21); + this.cboTargetDesktop.TabIndex = 9; + // + // rdoTargetDesktop + // + this.rdoTargetDesktop.AutoSize = true; + this.rdoTargetDesktop.Location = new System.Drawing.Point(15, 141); + this.rdoTargetDesktop.Name = "rdoTargetDesktop"; + this.rdoTargetDesktop.Size = new System.Drawing.Size(151, 17); + this.rdoTargetDesktop.TabIndex = 18; + this.rdoTargetDesktop.Text = "Power BI Desktop / SSDT"; + this.rdoTargetDesktop.UseVisualStyleBackColor = true; + this.rdoTargetDesktop.CheckedChanged += new System.EventHandler(this.rdoTargetDesktop_CheckedChanged); + // + // rdoTargetDataset + // + this.rdoTargetDataset.AutoSize = true; + this.rdoTargetDataset.Checked = true; + this.rdoTargetDataset.Location = new System.Drawing.Point(15, 37); + this.rdoTargetDataset.Name = "rdoTargetDataset"; + this.rdoTargetDataset.Size = new System.Drawing.Size(62, 17); + this.rdoTargetDataset.TabIndex = 17; + this.rdoTargetDataset.TabStop = true; + this.rdoTargetDataset.Text = "Dataset"; + this.rdoTargetDataset.UseVisualStyleBackColor = true; + this.rdoTargetDataset.CheckedChanged += new System.EventHandler(this.rdoTargetDataset_CheckedChanged); + // + // label6 + // + this.label6.AutoSize = true; + this.label6.Font = new System.Drawing.Font("Microsoft Sans Serif", 10F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.label6.Location = new System.Drawing.Point(12, 9); + this.label6.Name = "label6"; + this.label6.Size = new System.Drawing.Size(56, 17); + this.label6.TabIndex = 16; + this.label6.Text = "Target"; // // label3 // this.label3.AutoSize = true; - this.label3.Location = new System.Drawing.Point(15, 83); - this.label3.Margin = new System.Windows.Forms.Padding(7, 0, 7, 0); + this.label3.Location = new System.Drawing.Point(33, 70); this.label3.Name = "label3"; - this.label3.Size = new System.Drawing.Size(134, 29); + this.label3.Size = new System.Drawing.Size(62, 13); this.label3.TabIndex = 4; this.label3.Text = "Workspace"; // // label4 // this.label4.AutoSize = true; - this.label4.Location = new System.Drawing.Point(15, 154); - this.label4.Margin = new System.Windows.Forms.Padding(7, 0, 7, 0); + this.label4.Location = new System.Drawing.Point(33, 102); this.label4.Name = "label4"; - this.label4.Size = new System.Drawing.Size(94, 29); + this.label4.Size = new System.Drawing.Size(44, 13); this.label4.TabIndex = 5; this.label4.Text = "Dataset"; // - // pnlTargetDb + // pnlTargetDataset // - this.pnlTargetDb.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + this.pnlTargetDataset.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); - this.pnlTargetDb.Controls.Add(this.cboTargetServer); - this.pnlTargetDb.Controls.Add(this.cboTargetDatabase); - this.pnlTargetDb.Location = new System.Drawing.Point(144, 60); - this.pnlTargetDb.Margin = new System.Windows.Forms.Padding(7); - this.pnlTargetDb.Name = "pnlTargetDb"; - this.pnlTargetDb.Size = new System.Drawing.Size(911, 147); - this.pnlTargetDb.TabIndex = 15; + this.pnlTargetDataset.Controls.Add(this.cboTargetServer); + this.pnlTargetDataset.Controls.Add(this.cboTargetDatabase); + this.pnlTargetDataset.Location = new System.Drawing.Point(100, 60); + this.pnlTargetDataset.Name = "pnlTargetDataset"; + this.pnlTargetDataset.Size = new System.Drawing.Size(416, 66); + this.pnlTargetDataset.TabIndex = 15; // // cboTargetServer // @@ -237,11 +469,10 @@ | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); this.cboTargetServer.FormattingEnabled = true; - this.cboTargetServer.Location = new System.Drawing.Point(26, 16); - this.cboTargetServer.Margin = new System.Windows.Forms.Padding(7); + this.cboTargetServer.Location = new System.Drawing.Point(11, 7); this.cboTargetServer.MaxDropDownItems = 11; this.cboTargetServer.Name = "cboTargetServer"; - this.cboTargetServer.Size = new System.Drawing.Size(862, 37); + this.cboTargetServer.Size = new System.Drawing.Size(396, 21); this.cboTargetServer.TabIndex = 4; this.cboTargetServer.TextChanged += new System.EventHandler(this.cboTargetServer_TextChanged); // @@ -251,42 +482,46 @@ | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); this.cboTargetDatabase.FormattingEnabled = true; - this.cboTargetDatabase.Location = new System.Drawing.Point(26, 87); - this.cboTargetDatabase.Margin = new System.Windows.Forms.Padding(7); + this.cboTargetDatabase.Location = new System.Drawing.Point(11, 39); this.cboTargetDatabase.MaxDropDownItems = 11; this.cboTargetDatabase.Name = "cboTargetDatabase"; - this.cboTargetDatabase.Size = new System.Drawing.Size(862, 37); + this.cboTargetDatabase.Size = new System.Drawing.Size(396, 21); this.cboTargetDatabase.TabIndex = 5; this.cboTargetDatabase.Enter += new System.EventHandler(this.cboTargetDatabase_Enter); // - // Connections + // ConnectionsAlmt // this.AcceptButton = this.btnOK; - this.AutoScaleDimensions = new System.Drawing.SizeF(14F, 29F); + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.CancelButton = this.btnCancel; - this.ClientSize = new System.Drawing.Size(1069, 727); + this.ClientSize = new System.Drawing.Size(522, 518); this.Controls.Add(this.grpTarget); this.Controls.Add(this.panel1); this.Controls.Add(this.panel2); this.Controls.Add(this.grpSource); this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; - this.Margin = new System.Windows.Forms.Padding(7); this.MaximizeBox = false; this.MinimizeBox = false; - this.Name = "Connections"; + this.Name = "ConnectionsAlmt"; this.ShowIcon = false; this.ShowInTaskbar = false; this.Text = "Connections"; this.Load += new System.EventHandler(this.Connections_Load); - this.pnlSourceDb.ResumeLayout(false); + this.pnlSourceDataset.ResumeLayout(false); this.grpSource.ResumeLayout(false); this.grpSource.PerformLayout(); + this.pnlSourceFile.ResumeLayout(false); + this.pnlSourceFile.PerformLayout(); + this.pnlSourceDesktop.ResumeLayout(false); this.panel2.ResumeLayout(false); this.panel1.ResumeLayout(false); this.grpTarget.ResumeLayout(false); this.grpTarget.PerformLayout(); - this.pnlTargetDb.ResumeLayout(false); + this.pnlTargetFile.ResumeLayout(false); + this.pnlTargetFile.PerformLayout(); + this.pnlTargetDesktop.ResumeLayout(false); + this.pnlTargetDataset.ResumeLayout(false); this.ResumeLayout(false); } @@ -297,7 +532,7 @@ private System.Windows.Forms.ComboBox cboSourceServer; private System.Windows.Forms.Label label2; private System.Windows.Forms.Label label1; - private System.Windows.Forms.Panel pnlSourceDb; + private System.Windows.Forms.Panel pnlSourceDataset; private System.Windows.Forms.GroupBox grpSource; private System.Windows.Forms.Button btnOK; private System.Windows.Forms.Button btnCancel; @@ -307,8 +542,26 @@ private System.Windows.Forms.GroupBox grpTarget; private System.Windows.Forms.Label label3; private System.Windows.Forms.Label label4; - private System.Windows.Forms.Panel pnlTargetDb; + private System.Windows.Forms.Panel pnlTargetDataset; private System.Windows.Forms.ComboBox cboTargetServer; private System.Windows.Forms.ComboBox cboTargetDatabase; + private System.Windows.Forms.Label label5; + private System.Windows.Forms.RadioButton rdoSourceDataset; + private System.Windows.Forms.RadioButton rdoSourceDesktop; + private System.Windows.Forms.RadioButton rdoTargetDesktop; + private System.Windows.Forms.RadioButton rdoTargetDataset; + private System.Windows.Forms.Label label6; + private System.Windows.Forms.RadioButton rdoSourceFile; + private System.Windows.Forms.Panel pnlSourceDesktop; + private System.Windows.Forms.ComboBox cboSourceDesktop; + private System.Windows.Forms.RadioButton rdoTargetFile; + private System.Windows.Forms.Panel pnlTargetDesktop; + private System.Windows.Forms.ComboBox cboTargetDesktop; + private System.Windows.Forms.Panel pnlTargetFile; + private System.Windows.Forms.Button btnTargetFileOpen; + private System.Windows.Forms.TextBox txtTargetFile; + private System.Windows.Forms.Panel pnlSourceFile; + private System.Windows.Forms.Button btnSourceFileOpen; + private System.Windows.Forms.TextBox txtSourceFile; } } \ No newline at end of file diff --git a/BismNormalizer/BismNormalizer/TabularCompare/UI/ConnectionsAlmt.cs b/BismNormalizer/BismNormalizer/TabularCompare/UI/ConnectionsAlmt.cs index ab9a8a6..4dc83ff 100644 --- a/BismNormalizer/BismNormalizer/TabularCompare/UI/ConnectionsAlmt.cs +++ b/BismNormalizer/BismNormalizer/TabularCompare/UI/ConnectionsAlmt.cs @@ -4,15 +4,22 @@ using System.Collections.Generic; using System.Windows.Forms; using Microsoft.AnalysisServices; using System.Drawing; +using BismNormalizer.TabularCompare.UI.DesktopInstances; +using System.Linq.Expressions; namespace BismNormalizer.TabularCompare.UI { public partial class ConnectionsAlmt : Form { + #region Private members + private ComparisonInfo _comparisonInfo; private float _dpiScaleFactor; private bool _sourceDatabaseBound = false; private bool _targetDatabaseBound = false; + private List _powerBIInstances = new List(); + + #endregion public ConnectionsAlmt() { @@ -21,7 +28,14 @@ namespace BismNormalizer.TabularCompare.UI private void Connections_Load(object sender, EventArgs e) { - this.Width = Convert.ToInt32(this.Width * 1.3); + //Settings.Default.SourceServerAutoCompleteEntries = "localhost|"; + //Settings.Default.TargetServerAutoCompleteEntries = "localhost|"; + //Settings.Default.SourceCatalog = ""; + //Settings.Default.TargetCatalog = ""; + //Settings.Default.Save(); + + + //this.Width = Convert.ToInt32(this.Width * 1.3); if (_dpiScaleFactor > 1) { @@ -62,87 +76,149 @@ namespace BismNormalizer.TabularCompare.UI cboSourceDatabase.Text = Settings.Default.SourceCatalog; cboTargetDatabase.Text = Settings.Default.TargetCatalog; - bool boundTargetDatabase = false; - BindSourceConnectionInfo(); - BindTargetConnectionInfo(out boundTargetDatabase); + cboSourceDesktop.Items.Clear(); + cboTargetDesktop.Items.Clear(); + + BindingSource desktopBindingSource = new BindingSource(); + BindingSource desktopBindingTarget = new BindingSource(); + _powerBIInstances.Clear(); + try + { + _powerBIInstances = PowerBIHelper.GetLocalInstances(); + } + catch { } + + if (_powerBIInstances.Count > 1) + { + desktopBindingSource.DataSource = _powerBIInstances; + desktopBindingTarget.DataSource = _powerBIInstances; + + cboSourceDesktop.DataSource = desktopBindingSource; + cboSourceDesktop.ValueMember = "Port"; + cboSourceDesktop.DisplayMember = "Name"; + + cboTargetDesktop.DataSource = desktopBindingTarget; + cboTargetDesktop.ValueMember = "Port"; + cboTargetDesktop.DisplayMember = "Name"; + + BindSourceConnectionInfo(); + BindTargetConnectionInfo(); + } } private bool BindSourceConnectionInfo() { - bool returnVal = false; + bool boundSuccessfully = false; if (_comparisonInfo?.ConnectionInfoSource != null) { - if (!String.IsNullOrEmpty(_comparisonInfo.ConnectionInfoSource.ServerName) && !String.IsNullOrEmpty(_comparisonInfo.ConnectionInfoSource.DatabaseName)) + if (_comparisonInfo.ConnectionInfoSource.UseBimFile) { + rdoSourceFile.Checked = true; + + pnlSourceDataset.Enabled = false; + pnlSourceDesktop.Enabled = false; + pnlSourceFile.Enabled = true; + + txtSourceFile.Text = _comparisonInfo.ConnectionInfoSource.BimFile; + + boundSuccessfully = true; + } + else if (_comparisonInfo.ConnectionInfoSource.UseDesktop) + { + rdoSourceDesktop.Checked = true; + + pnlSourceDataset.Enabled = false; + pnlSourceDesktop.Enabled = true; + pnlSourceFile.Enabled = false; + + int portFromConnectionInfo = -1; + if (_comparisonInfo.ConnectionInfoSource.ServerName != null && + int.TryParse(_comparisonInfo.ConnectionInfoSource.ServerName.ToUpper().Replace("localhost:".ToUpper(), ""), out portFromConnectionInfo)) + { + for (int i = 0; i < ((BindingSource)cboSourceDesktop.DataSource).Count; i++) + { + if (((PowerBIInstance)((BindingSource)cboSourceDesktop.DataSource)[i]).Port == portFromConnectionInfo) + { + cboSourceDesktop.SelectedIndex = i; + break; + } + } + } + boundSuccessfully = true; + } + else if (!String.IsNullOrEmpty(_comparisonInfo.ConnectionInfoSource.ServerName) && !String.IsNullOrEmpty(_comparisonInfo.ConnectionInfoSource.DatabaseName)) + { + rdoSourceDataset.Checked = true; + + pnlSourceDataset.Enabled = true; + pnlSourceDesktop.Enabled = false; + pnlSourceFile.Enabled = false; + cboSourceServer.Text = _comparisonInfo.ConnectionInfoSource.ServerName; cboSourceDatabase.Text = _comparisonInfo.ConnectionInfoSource.DatabaseName; - returnVal = true; + boundSuccessfully = true; } } - return returnVal; + return boundSuccessfully; } - private bool BindTargetConnectionInfo(out bool boundTargetDatabase) + private bool BindTargetConnectionInfo() { - bool returnVal = false; - boundTargetDatabase = false; + bool boundSuccessfully = false; if (_comparisonInfo?.ConnectionInfoTarget != null) { - if (!String.IsNullOrEmpty(_comparisonInfo.ConnectionInfoTarget.ServerName) && !String.IsNullOrEmpty(_comparisonInfo.ConnectionInfoTarget.DatabaseName)) + if (_comparisonInfo.ConnectionInfoTarget.UseBimFile) { + pnlTargetDataset.Enabled = false; + pnlTargetDesktop.Enabled = false; + rdoTargetFile.Checked = true; + pnlTargetFile.Enabled = true; + txtTargetFile.Text = _comparisonInfo.ConnectionInfoTarget.BimFile; + + boundSuccessfully = true; + } + else if (_comparisonInfo.ConnectionInfoTarget.UseDesktop) + { + rdoTargetDesktop.Checked = true; + + pnlTargetDataset.Enabled = false; + pnlTargetDesktop.Enabled = true; + pnlTargetFile.Enabled = false; + + int portFromConnectionInfo = -1; + if (_comparisonInfo.ConnectionInfoTarget.ServerName != null && + int.TryParse(_comparisonInfo.ConnectionInfoTarget.ServerName.ToUpper().Replace("localhost:".ToUpper(), ""), out portFromConnectionInfo)) + { + for (int i = 0; i < ((BindingSource)cboTargetDesktop.DataSource).Count; i++) + { + if (((PowerBIInstance)((BindingSource)cboTargetDesktop.DataSource)[i]).Port == portFromConnectionInfo) + { + cboTargetDesktop.SelectedIndex = i; + break; + } + } + } + boundSuccessfully = true; + } + else if (!String.IsNullOrEmpty(_comparisonInfo.ConnectionInfoTarget.ServerName) && !String.IsNullOrEmpty(_comparisonInfo.ConnectionInfoTarget.DatabaseName)) + { + rdoTargetDataset.Checked = true; + pnlTargetDataset.Enabled = true; + pnlTargetDesktop.Enabled = false; + pnlTargetFile.Enabled = false; + cboTargetServer.Text = _comparisonInfo.ConnectionInfoTarget.ServerName; cboTargetDatabase.Text = _comparisonInfo.ConnectionInfoTarget.DatabaseName; - boundTargetDatabase = true; - returnVal = true; + boundSuccessfully = true; } } - return returnVal; - } - - private static void IterateProject(SortedList projects, EnvDTE.Project project, string derivedProjectName = "") - { - if (project.ProjectItems != null) //if project is unloaded, its ProjectItems==null - { - derivedProjectName = AppendProjectName(project, derivedProjectName); - if (project.FileName.EndsWith(".smproj")) - { - projects.Add(derivedProjectName, project); - } - else if (project.Kind == "{66A26720-8FB5-11D2-AA7E-00C04F688DDE}") - { - foreach (EnvDTE.ProjectItem projectItem in project.ProjectItems) - { - if (projectItem.SubProject != null) - { - IterateProject(projects, projectItem.SubProject, derivedProjectName); - } - } - } - } - } - - private static string AppendProjectName(EnvDTE.Project project, string derivedProjectName) - { - if (derivedProjectName != "") - { - derivedProjectName += "\\"; - } - derivedProjectName += project.Name; - - return derivedProjectName; - } - - EnvDTE80.DTE2 _dte; //EnvDTE._DTE _dte; - public EnvDTE80.DTE2 Dte // EnvDTE._DTE DTE - { - get { return _dte; } - set { _dte = value; } + return boundSuccessfully; } public ComparisonInfo ComparisonInfo @@ -157,33 +233,152 @@ namespace BismNormalizer.TabularCompare.UI set { _dpiScaleFactor = value; } } + private void rdoSourceDataset_CheckedChanged(object sender, EventArgs e) + { + pnlSourceDataset.Enabled = true; + pnlSourceDesktop.Enabled = false; + pnlSourceFile.Enabled = false; + cboSourceServer.Focus(); + } + private void rdoSourceDesktop_CheckedChanged(object sender, EventArgs e) + { + pnlSourceDataset.Enabled = false; + pnlSourceDesktop.Enabled = true; + pnlSourceFile.Enabled = false; + cboSourceDesktop.Focus(); + } + private void rdoSourceFile_CheckedChanged(object sender, EventArgs e) + { + pnlSourceDataset.Enabled = false; + pnlSourceDesktop.Enabled = false; + pnlSourceFile.Enabled = true; + btnSourceFileOpen.Focus(); + } + private void rdoTargetDataset_CheckedChanged(object sender, EventArgs e) + { + pnlTargetDataset.Enabled = true; + pnlTargetDesktop.Enabled = false; + pnlTargetFile.Enabled = false; + cboTargetServer.Focus(); + } + private void rdoTargetDesktop_CheckedChanged(object sender, EventArgs e) + { + pnlTargetDataset.Enabled = false; + pnlTargetDesktop.Enabled = true; + pnlTargetFile.Enabled = false; + cboTargetDesktop.Focus(); + } + private void rdoTargetFile_CheckedChanged(object sender, EventArgs e) + { + pnlTargetDataset.Enabled = false; + pnlTargetDesktop.Enabled = false; + pnlTargetFile.Enabled = true; + btnTargetFileOpen.Focus(); + } + private void btnOK_Click(object sender, EventArgs e) { - _comparisonInfo.ConnectionInfoSource.UseProject = false; - _comparisonInfo.ConnectionInfoSource.ServerName = cboSourceServer.Text; - _comparisonInfo.ConnectionInfoSource.DatabaseName = cboSourceDatabase.Text; - _comparisonInfo.ConnectionInfoSource.ProjectName = null; - _comparisonInfo.ConnectionInfoSource.ProjectFile = null; + if (rdoSourceDesktop.Checked) + { + _comparisonInfo.ConnectionInfoSource.UseProject = false; + _comparisonInfo.ConnectionInfoSource.UseBimFile = false; + _comparisonInfo.ConnectionInfoSource.UseDesktop = true; + _comparisonInfo.ConnectionInfoSource.ServerName = "localhost:" + cboSourceDesktop.SelectedValue.ToString(); + _comparisonInfo.ConnectionInfoSource.DatabaseName = ""; //For Desktop/SSDT don't have DB name but get first when connect + _comparisonInfo.ConnectionInfoSource.DesktopName = cboSourceDesktop.Text; + _comparisonInfo.ConnectionInfoSource.ProjectName = null; + _comparisonInfo.ConnectionInfoSource.ProjectFile = null; + _comparisonInfo.ConnectionInfoSource.BimFile = null; + } + else if (rdoSourceFile.Checked) + { + _comparisonInfo.ConnectionInfoSource.UseProject = false; + _comparisonInfo.ConnectionInfoSource.UseBimFile = true; + _comparisonInfo.ConnectionInfoSource.UseDesktop = false; + _comparisonInfo.ConnectionInfoSource.BimFile = txtSourceFile.Text; + _comparisonInfo.ConnectionInfoSource.DesktopName = null; + _comparisonInfo.ConnectionInfoSource.ProjectName = null; + _comparisonInfo.ConnectionInfoSource.ProjectFile = null; + } + else + { + _comparisonInfo.ConnectionInfoSource.UseProject = false; + _comparisonInfo.ConnectionInfoSource.UseBimFile = false; + _comparisonInfo.ConnectionInfoSource.UseDesktop = false; + _comparisonInfo.ConnectionInfoSource.ServerName = cboSourceServer.Text; + _comparisonInfo.ConnectionInfoSource.DatabaseName = cboSourceDatabase.Text; + _comparisonInfo.ConnectionInfoSource.DesktopName = null; + _comparisonInfo.ConnectionInfoSource.ProjectName = null; + _comparisonInfo.ConnectionInfoSource.ProjectFile = null; + _comparisonInfo.ConnectionInfoSource.BimFile = null; + } - _comparisonInfo.ConnectionInfoTarget.UseProject = false; - _comparisonInfo.ConnectionInfoTarget.ServerName = cboTargetServer.Text; - _comparisonInfo.ConnectionInfoTarget.DatabaseName = cboTargetDatabase.Text; - _comparisonInfo.ConnectionInfoTarget.ProjectName = null; - _comparisonInfo.ConnectionInfoTarget.ProjectFile = null; + if (rdoTargetDesktop.Checked) + { + _comparisonInfo.ConnectionInfoTarget.UseProject = false; + _comparisonInfo.ConnectionInfoTarget.UseBimFile = false; + _comparisonInfo.ConnectionInfoTarget.UseDesktop = true; + _comparisonInfo.ConnectionInfoTarget.ServerName = "localhost:" + cboTargetDesktop.SelectedValue.ToString(); + _comparisonInfo.ConnectionInfoTarget.DatabaseName = ""; //For Desktop/SSDT don't have DB name but get first when connect + _comparisonInfo.ConnectionInfoTarget.DesktopName = cboTargetDesktop.Text; + _comparisonInfo.ConnectionInfoTarget.ProjectName = null; + _comparisonInfo.ConnectionInfoTarget.ProjectFile = null; + _comparisonInfo.ConnectionInfoTarget.BimFile = null; + } + else if (rdoTargetFile.Checked) + { + _comparisonInfo.ConnectionInfoTarget.UseProject = false; + _comparisonInfo.ConnectionInfoTarget.UseBimFile = true; + _comparisonInfo.ConnectionInfoTarget.UseDesktop = false; + _comparisonInfo.ConnectionInfoTarget.BimFile = txtTargetFile.Text; + _comparisonInfo.ConnectionInfoTarget.DesktopName = null; + _comparisonInfo.ConnectionInfoTarget.ProjectName = null; + _comparisonInfo.ConnectionInfoTarget.ProjectFile = null; + } + else + { + _comparisonInfo.ConnectionInfoTarget.UseProject = false; + _comparisonInfo.ConnectionInfoTarget.UseBimFile = false; + _comparisonInfo.ConnectionInfoTarget.UseDesktop = false; + _comparisonInfo.ConnectionInfoTarget.ServerName = cboTargetServer.Text; + _comparisonInfo.ConnectionInfoTarget.DatabaseName = cboTargetDatabase.Text; + _comparisonInfo.ConnectionInfoTarget.DesktopName = null; + _comparisonInfo.ConnectionInfoTarget.ProjectName = null; + _comparisonInfo.ConnectionInfoTarget.ProjectFile = null; + _comparisonInfo.ConnectionInfoTarget.BimFile = null; + } } private void btnSwitch_Click(object sender, EventArgs e) { ConnectionInfo infoSourceTemp = new ConnectionInfo(); - + infoSourceTemp.UseProject = rdoSourceDesktop.Checked; + infoSourceTemp.UseBimFile = rdoSourceFile.Checked; + infoSourceTemp.ProjectName = cboSourceDesktop.Text; + //infoSourceTemp.Project = (PowerBIInstance)cboSourceDesktop.SelectedValue; + int portSourceTemp = (int)cboSourceDesktop.SelectedValue; //Fudge start infoSourceTemp.ServerName = cboSourceServer.Text; infoSourceTemp.DatabaseName = cboSourceDatabase.Text; + infoSourceTemp.BimFile = txtSourceFile.Text; + rdoSourceDesktop.Checked = rdoTargetDesktop.Checked; + rdoSourceFile.Checked = rdoTargetFile.Checked; + rdoSourceDataset.Checked = rdoTargetDataset.Checked; + cboSourceDesktop.Text = cboTargetDesktop.Text; + cboSourceDesktop.SelectedValue = cboTargetDesktop.SelectedValue; cboSourceServer.Text = cboTargetServer.Text; cboSourceDatabase.Text = cboTargetDatabase.Text; + txtSourceFile.Text = txtTargetFile.Text; + rdoTargetDesktop.Checked = infoSourceTemp.UseProject; + rdoTargetFile.Checked = infoSourceTemp.UseBimFile; + rdoTargetDataset.Checked = (!infoSourceTemp.UseProject && !infoSourceTemp.UseBimFile); + cboTargetDesktop.Text = infoSourceTemp.ProjectName; + //cboTargetDesktop.SelectedValue = infoSourceTemp.Project; + cboTargetDesktop.SelectedValue = portSourceTemp; //Fudge end cboTargetServer.Text = infoSourceTemp.ServerName; cboTargetDatabase.Text = infoSourceTemp.DatabaseName; + txtTargetFile.Text = infoSourceTemp.BimFile; } private void cboSourceServer_TextChanged(object sender, EventArgs e) @@ -214,6 +409,35 @@ namespace BismNormalizer.TabularCompare.UI } } + private void btnSourceFileOpen_Click(object sender, EventArgs e) + { + OpenFileDialog ofd = OpenBimFileDialog(); + if (ofd.ShowDialog() == DialogResult.OK) + { + txtSourceFile.Text = ofd.FileName; + Settings.Default.LastBimFileLocation = ofd.FileName; + } + } + + private void btnTargetFileOpen_Click(object sender, EventArgs e) + { + OpenFileDialog ofd = OpenBimFileDialog(); + if (ofd.ShowDialog() == DialogResult.OK) + { + txtTargetFile.Text = ofd.FileName; + Settings.Default.LastBimFileLocation = ofd.FileName; + } + } + + private OpenFileDialog OpenBimFileDialog() + { + OpenFileDialog ofd = new OpenFileDialog(); + ofd.InitialDirectory = (String.IsNullOrEmpty(Settings.Default.LastBimFileLocation) ? Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) : Settings.Default.LastBimFileLocation); + ofd.Filter = "BIM Files (.bim)|*.bim|All files (*.*)|*.*"; + ofd.Title = "Open"; + return ofd; + } + private void BindDatabaseList(string serverName, ComboBox cboCatalog) { try @@ -239,5 +463,6 @@ namespace BismNormalizer.TabularCompare.UI cboCatalog.DataSource = null; } } + } } diff --git a/BismNormalizer/BismNormalizer/TabularCompare/UI/DesktopInstances/ManagedIpHelper.cs b/BismNormalizer/BismNormalizer/TabularCompare/UI/DesktopInstances/ManagedIpHelper.cs new file mode 100644 index 0000000..3bf88fb --- /dev/null +++ b/BismNormalizer/BismNormalizer/TabularCompare/UI/DesktopInstances/ManagedIpHelper.cs @@ -0,0 +1,282 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Net; +using System.Net.NetworkInformation; +using System.Runtime.InteropServices; + +namespace BismNormalizer.TabularCompare.UI.DesktopInstances +{ + + + #region Managed IP Helper API + + public class TcpTable : IEnumerable + { + #region Private Fields + + private IEnumerable tcpRows; + + #endregion + + #region Constructors + + public TcpTable(IEnumerable tcpRows) + { + this.tcpRows = tcpRows; + } + + #endregion + + #region Public Properties + + public IEnumerable Rows + { + get { return this.tcpRows; } + } + + #endregion + + #region IEnumerable Members + + public IEnumerator GetEnumerator() + { + return this.tcpRows.GetEnumerator(); + } + + #endregion + + #region IEnumerable Members + + IEnumerator IEnumerable.GetEnumerator() + { + return this.tcpRows.GetEnumerator(); + } + + #endregion + } + + public class TcpRow + { + #region Private Fields + + private IPEndPoint localEndPoint; + private IPEndPoint remoteEndPoint; + private TcpState state; + private int processId; + + #endregion + + #region Constructors + + public TcpRow(IpHelper.TcpRow tcpRow) + { + this.state = tcpRow.state; + this.processId = tcpRow.owningPid; + + int localPort = (tcpRow.localPort1 << 8) + (tcpRow.localPort2) + (tcpRow.localPort3 << 24) + (tcpRow.localPort4 << 16); + long localAddress = tcpRow.localAddr; + this.localEndPoint = new IPEndPoint(localAddress, localPort); + + int remotePort = (tcpRow.remotePort1 << 8) + (tcpRow.remotePort2) + (tcpRow.remotePort3 << 24) + (tcpRow.remotePort4 << 16); + long remoteAddress = tcpRow.remoteAddr; + this.remoteEndPoint = new IPEndPoint(remoteAddress, remotePort); + } + + #endregion + + #region Public Properties + + public IPEndPoint LocalEndPoint + { + get { return this.localEndPoint; } + } + + public IPEndPoint RemoteEndPoint + { + get { return this.remoteEndPoint; } + } + + public TcpState State + { + get { return this.state; } + } + + public int ProcessId + { + get { return this.processId; } + } + + #endregion + } + + public static class ManagedIpHelper + { + #region Public Methods + + public static TcpTable GetExtendedTcpTable(bool sorted) + { + List tcpRows = new List(); + + IntPtr tcpTable = IntPtr.Zero; + int tcpTableLength = 0; + + if (IpHelper.GetExtendedTcpTable(tcpTable, ref tcpTableLength, sorted, IpHelper.AfInet, IpHelper.TcpTableType.OwnerPidAll, 0) != 0) + { + try + { + tcpTable = Marshal.AllocHGlobal(tcpTableLength); + if (IpHelper.GetExtendedTcpTable(tcpTable, ref tcpTableLength, true, IpHelper.AfInet, IpHelper.TcpTableType.OwnerPidAll, 0) == 0) + { + IpHelper.TcpTable table = (IpHelper.TcpTable)Marshal.PtrToStructure(tcpTable, typeof(IpHelper.TcpTable)); + + IntPtr rowPtr = (IntPtr)((long)tcpTable + Marshal.SizeOf(table.length)); + for (int i = 0; i < table.length; ++i) + { + tcpRows.Add(new TcpRow((IpHelper.TcpRow)Marshal.PtrToStructure(rowPtr, typeof(IpHelper.TcpRow)))); + rowPtr = (IntPtr)((long)rowPtr + Marshal.SizeOf(typeof(IpHelper.TcpRow))); + } + } + } + finally + { + if (tcpTable != IntPtr.Zero) + { + Marshal.FreeHGlobal(tcpTable); + } + } + } + + return new TcpTable(tcpRows); + } + + public static Dictionary GetExtendedTcpDictionary() + { + Dictionary tcpRows = new Dictionary(); + + IntPtr tcpTable = IntPtr.Zero; + int tcpTableLength = 0; + + if (IpHelper.GetExtendedTcpTable(tcpTable, ref tcpTableLength, false, IpHelper.AfInet, IpHelper.TcpTableType.OwnerPidAll, 0) != 0) + { + try + { + tcpTable = Marshal.AllocHGlobal(tcpTableLength); + if (IpHelper.GetExtendedTcpTable(tcpTable, ref tcpTableLength, true, IpHelper.AfInet, IpHelper.TcpTableType.OwnerPidAll, 0) == 0) + { + IpHelper.TcpTable table = (IpHelper.TcpTable)Marshal.PtrToStructure(tcpTable, typeof(IpHelper.TcpTable)); + + IntPtr rowPtr = (IntPtr)((long)tcpTable + Marshal.SizeOf(table.length)); + for (int i = 0; i < table.length; ++i) + { + TcpRow row = new TcpRow((IpHelper.TcpRow)Marshal.PtrToStructure(rowPtr, typeof(IpHelper.TcpRow))); + // HACK: only add first row that is in a Listening state + if (row.State == TcpState.Listen) + { + if (!tcpRows.Keys.Contains(row.ProcessId)) + tcpRows.Add(row.ProcessId, row); + } + rowPtr = (IntPtr)((long)rowPtr + Marshal.SizeOf(typeof(IpHelper.TcpRow))); + } + } + } + finally + { + if (tcpTable != IntPtr.Zero) + { + Marshal.FreeHGlobal(tcpTable); + } + } + } + + return tcpRows; + } + + + #endregion + } + + #endregion + + #region P/Invoke IP Helper API + + /// + /// + /// + public static class IpHelper + { + #region Public Fields + + public const string DllName = "iphlpapi.dll"; + public const int AfInet = 2; + + #endregion + + #region Public Methods + + /// + /// + /// + [DllImport(IpHelper.DllName, SetLastError = true)] + public static extern uint GetExtendedTcpTable(IntPtr tcpTable, ref int tcpTableLength, bool sort, int ipVersion, TcpTableType tcpTableType, int reserved); + + #endregion + + #region Public Enums + + /// + /// + /// + public enum TcpTableType + { + BasicListener, + BasicConnections, + BasicAll, + OwnerPidListener, + OwnerPidConnections, + OwnerPidAll, + OwnerModuleListener, + OwnerModuleConnections, + OwnerModuleAll, + } + + #endregion + + #region Public Structs + + /// + /// + /// + [StructLayout(LayoutKind.Sequential)] + public struct TcpTable + { + public uint length; + public TcpRow row; + } + + /// + /// + /// + [StructLayout(LayoutKind.Sequential)] + public struct TcpRow + { + public TcpState state; + public uint localAddr; + public byte localPort1; + public byte localPort2; + public byte localPort3; + public byte localPort4; + public uint remoteAddr; + public byte remotePort1; + public byte remotePort2; + public byte remotePort3; + public byte remotePort4; + public int owningPid; + } + + #endregion + + #endregion + } +} diff --git a/BismNormalizer/BismNormalizer/TabularCompare/UI/DesktopInstances/PowerBIHelper.cs b/BismNormalizer/BismNormalizer/TabularCompare/UI/DesktopInstances/PowerBIHelper.cs new file mode 100644 index 0000000..552e221 --- /dev/null +++ b/BismNormalizer/BismNormalizer/TabularCompare/UI/DesktopInstances/PowerBIHelper.cs @@ -0,0 +1,110 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +//using Serilog; +using System.Security.Principal; + +namespace BismNormalizer.TabularCompare.UI.DesktopInstances +{ + public enum EmbeddedSSASIcon + { + PowerBI, + Devenv, + PowerBIReportServer, + Loading + } + public class PowerBIInstance + { + public PowerBIInstance(string name, int port, EmbeddedSSASIcon icon) + { + var dashPos = name.LastIndexOf(" - "); + if (dashPos >= 0) + { Name = name.Substring(0, dashPos); } // Strip "Power BI Designer" or "Power BI Desktop" off the end of the string + + Port = port; + Icon = icon; + } + public string Name { get; private set; } + public int Port { get; private set; } + + public EmbeddedSSASIcon Icon { get; private set; } + } + + public class PowerBIHelper + { + + public static List GetLocalInstances() + { + List _instances = new List(); + + _instances.Clear(); + + var dict = ManagedIpHelper.GetExtendedTcpDictionary(); + foreach (var proc in Process.GetProcessesByName("msmdsrv")) + { + int _port = 0; + EmbeddedSSASIcon _icon = EmbeddedSSASIcon.PowerBI; + var parent = proc.GetParent(); + + // exit here if the parent == "services" then this is a SSAS instance + if (parent.ProcessName.Equals("services", StringComparison.OrdinalIgnoreCase)) continue; + + // exit here if the parent == "RSHostingService" then this is a SSAS instance + if (parent.ProcessName.Equals("RSHostingService", StringComparison.OrdinalIgnoreCase)) + { + // only show PBI Report Server if we are running as admin + // otherwise we won't have any access to the models + if (IsAdministrator()) + _icon = EmbeddedSSASIcon.PowerBIReportServer; + else + continue; + } + + // if the process was launched from Visual Studio change the icon + if (parent.ProcessName.Equals("devenv", StringComparison.OrdinalIgnoreCase)) _icon = EmbeddedSSASIcon.Devenv; + + // get the window title so that we can parse out the file name + var parentTitle = parent.MainWindowTitle; + if (parentTitle.Length == 0) + { + // for minimized windows we need to use some Win32 api calls to get the title + //parentTitle = WindowTitle.GetWindowTitleTimeout( parent.Id, 300); + parentTitle = WindowTitle.GetWindowTitle(parent.Id); + } + + // try and get the tcp port from the Win32 TcpTable API + //try + //{ + TcpRow tcpRow = null; + dict.TryGetValue(proc.Id, out tcpRow); + if (tcpRow != null) + { + _port = tcpRow.LocalEndPoint.Port; + _instances.Add(new PowerBIInstance(parentTitle, _port, _icon)); + //Log.Debug("{class} {method} PowerBI found on port: {port}", "PowerBIHelper", "Refresh", _port); + } + // else + // { + // //Log.Debug("{class} {method} PowerBI port not found for process: {processName} PID: {pid}", "PowerBIHelper", "Refresh", proc.ProcessName, proc.Id); + // } + + //} + //catch (Exception ex) + //{ + // //Log.Error("{class} {Method} {Error} {StackTrace}", "PowerBIHelper", "Refresh", ex.Message, ex.StackTrace); + //} + + } + return _instances; + } + + public static bool IsAdministrator() + { + WindowsIdentity identity = WindowsIdentity.GetCurrent(); + WindowsPrincipal principal = new WindowsPrincipal(identity); + return principal.IsInRole(WindowsBuiltInRole.Administrator); + } + + + } +} diff --git a/BismNormalizer/BismNormalizer/TabularCompare/UI/DesktopInstances/ProcessExtensions.cs b/BismNormalizer/BismNormalizer/TabularCompare/UI/DesktopInstances/ProcessExtensions.cs new file mode 100644 index 0000000..8b14a55 --- /dev/null +++ b/BismNormalizer/BismNormalizer/TabularCompare/UI/DesktopInstances/ProcessExtensions.cs @@ -0,0 +1,31 @@ +using System.Diagnostics; +using System.Linq; +using System.Management; + +namespace BismNormalizer.TabularCompare.UI.DesktopInstances +{ + public static class ProcessExtensions + { + public static Process GetParent(this Process process) + { + try + { + using (var query = new ManagementObjectSearcher( + "SELECT ParentProcessId " + + "FROM Win32_Process " + + "WHERE ProcessId=" + process.Id)) + { + return query + .Get() + .OfType() + .Select(p => Process.GetProcessById((int)(uint)p["ParentProcessId"])) + .FirstOrDefault(); + } + } + catch + { + return null; + } + } + } +} diff --git a/BismNormalizer/BismNormalizer/TabularCompare/UI/DesktopInstances/WindowTitle.cs b/BismNormalizer/BismNormalizer/TabularCompare/UI/DesktopInstances/WindowTitle.cs new file mode 100644 index 0000000..83c1797 --- /dev/null +++ b/BismNormalizer/BismNormalizer/TabularCompare/UI/DesktopInstances/WindowTitle.cs @@ -0,0 +1,161 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Runtime.InteropServices; +using System.Text; +using System.Threading.Tasks; + +namespace BismNormalizer.TabularCompare.UI.DesktopInstances +{ + public class WindowTitle + { + + + //static void Main(string[] args) + //{ + // var p = Process.GetProcessById(3484); + // var h = p.MainWindowHandle; + + // string s = GetWindowTextTimeout(h, 100 /*msec*/); + + //} + + + + #region PInvoke calls to get the window title of a minimize window + + delegate bool EnumThreadDelegate(IntPtr hWnd, IntPtr lParam); + + [DllImport("user32.dll")] + static extern bool IsWindowVisible(IntPtr hWnd); + + + [DllImport("user32.dll")] + static extern bool EnumThreadWindows(int dwThreadId, EnumThreadDelegate lpfn, + IntPtr lParam); + + [DllImport("User32.dll", SetLastError = true)] + public unsafe static extern int SendMessageTimeout( + IntPtr hWnd, + uint uMsg, + uint wParam, + StringBuilder lParam, + uint fuFlags, + uint uTimeout, + void* lpdwResult); + + [DllImport("user32.dll", CharSet = CharSet.Auto)] + static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, int wParam, + StringBuilder lParam); + + [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)] + static extern int GetWindowTextLength(IntPtr hWnd); + + [DllImport("User32.dll", SetLastError = true, CharSet = CharSet.Auto)] + static extern long GetWindowText(IntPtr hwnd, StringBuilder lpString, long cch); + + const int WM_GETTEXT = 0x000D; + const int WM_GETTEXTLENGTH = 0x000E; + + #endregion + + + private static IEnumerable EnumerateProcessWindowHandles(int processId) + { + var handles = new List(); + + foreach (ProcessThread thread in Process.GetProcessById(processId).Threads) + EnumThreadWindows(thread.Id, + (hWnd, lParam) => { handles.Add(hWnd); return true; }, IntPtr.Zero); + + return handles; + } + + + public static string GetWindowTitle(int procId) + { + foreach (var handle in EnumerateProcessWindowHandles(procId)) + { + StringBuilder message = new StringBuilder(1000); + if (IsWindowVisible(handle)) + { + //SendMessage(handle, WM_GETTEXT, message.Capacity, message); + //if (message.Length > 0) return message.ToString(); + return GetCaptionOfWindow(handle); + } + + } + return ""; + } + + /* ====================================== */ + + public static string GetWindowTitleTimeout(int procId, uint timeout) + { + string title = ""; + foreach (var handle in EnumerateProcessWindowHandles(procId)) + { + try + { + // if there is an issue with the window handle we just + // ignore it and skip to the next one in the collection + title = GetWindowTextTimeout(handle, timeout); + } + catch + { + title = ""; + } + if (title.Length > 0) return title; + } + return title; + } + + + private static unsafe string GetWindowTextTimeout(IntPtr hWnd, uint timeout) + { + int length; + if (SendMessageTimeout(hWnd, WM_GETTEXTLENGTH, 0, null, 2, timeout, &length) == 0) + { + return null; + } + if (length == 0) + { + return null; + } + + StringBuilder sb = new StringBuilder(length + 1); // leave room for null-terminator + if (SendMessageTimeout(hWnd, WM_GETTEXT, (uint)sb.Capacity, sb, 2, timeout, null) == 0) + { + return null; + } + + return sb.ToString(); + } + + private static string GetCaptionOfWindow(IntPtr hwnd) + { + string caption = ""; + StringBuilder windowText = null; + try + { + int max_length = GetWindowTextLength(hwnd); + windowText = new StringBuilder("", max_length + 5); + GetWindowText(hwnd, windowText, max_length + 2); + + if (!String.IsNullOrEmpty(windowText.ToString()) && !String.IsNullOrWhiteSpace(windowText.ToString())) + caption = windowText.ToString(); + } + catch (Exception ex) + { + caption = ex.Message; + } + finally + { + windowText = null; + } + return caption; + } + + } +}