diff --git a/JumpListUtil/FodyWeavers.xml b/JumpListUtil/FodyWeavers.xml new file mode 100755 index 0000000..f00ec6d --- /dev/null +++ b/JumpListUtil/FodyWeavers.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/JumpListUtil/FodyWeavers.xml b/JumpListUtil/FodyWeavers.xml new file mode 100755 index 0000000..f00ec6d --- /dev/null +++ b/JumpListUtil/FodyWeavers.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/JumpListUtil/JumpListUtil.csproj b/JumpListUtil/JumpListUtil.csproj index 378d940..d722456 100755 --- a/JumpListUtil/JumpListUtil.csproj +++ b/JumpListUtil/JumpListUtil.csproj @@ -1,5 +1,6 @@  + Debug @@ -27,6 +28,8 @@ false false true + + AnyCPU @@ -70,6 +73,9 @@ true + + ..\packages\Costura.Fody.4.1.0\lib\net40\Costura.dll + ..\packages\Microsoft.Bcl.AsyncInterfaces.1.1.0\lib\net461\Microsoft.Bcl.AsyncInterfaces.dll @@ -159,5 +165,16 @@ false + + + + + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + \ No newline at end of file diff --git a/JumpListUtil/FodyWeavers.xml b/JumpListUtil/FodyWeavers.xml new file mode 100755 index 0000000..f00ec6d --- /dev/null +++ b/JumpListUtil/FodyWeavers.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/JumpListUtil/JumpListUtil.csproj b/JumpListUtil/JumpListUtil.csproj index 378d940..d722456 100755 --- a/JumpListUtil/JumpListUtil.csproj +++ b/JumpListUtil/JumpListUtil.csproj @@ -1,5 +1,6 @@  + Debug @@ -27,6 +28,8 @@ false false true + + AnyCPU @@ -70,6 +73,9 @@ true + + ..\packages\Costura.Fody.4.1.0\lib\net40\Costura.dll + ..\packages\Microsoft.Bcl.AsyncInterfaces.1.1.0\lib\net461\Microsoft.Bcl.AsyncInterfaces.dll @@ -159,5 +165,16 @@ false + + + + + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + \ No newline at end of file diff --git a/JumpListUtil/packages.config b/JumpListUtil/packages.config index abb0b89..2d77df4 100755 --- a/JumpListUtil/packages.config +++ b/JumpListUtil/packages.config @@ -1,5 +1,7 @@  + + diff --git a/JumpListUtil/FodyWeavers.xml b/JumpListUtil/FodyWeavers.xml new file mode 100755 index 0000000..f00ec6d --- /dev/null +++ b/JumpListUtil/FodyWeavers.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/JumpListUtil/JumpListUtil.csproj b/JumpListUtil/JumpListUtil.csproj index 378d940..d722456 100755 --- a/JumpListUtil/JumpListUtil.csproj +++ b/JumpListUtil/JumpListUtil.csproj @@ -1,5 +1,6 @@  + Debug @@ -27,6 +28,8 @@ false false true + + AnyCPU @@ -70,6 +73,9 @@ true + + ..\packages\Costura.Fody.4.1.0\lib\net40\Costura.dll + ..\packages\Microsoft.Bcl.AsyncInterfaces.1.1.0\lib\net461\Microsoft.Bcl.AsyncInterfaces.dll @@ -159,5 +165,16 @@ false + + + + + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + \ No newline at end of file diff --git a/JumpListUtil/packages.config b/JumpListUtil/packages.config index abb0b89..2d77df4 100755 --- a/JumpListUtil/packages.config +++ b/JumpListUtil/packages.config @@ -1,5 +1,7 @@  + + diff --git a/ShellLink.cs b/ShellLink.cs index ba4d16d..73f3e58 100755 --- a/ShellLink.cs +++ b/ShellLink.cs @@ -113,7 +113,7 @@ // No limitation to length of buffer string in the case of Unicode though. StringBuilder description = new StringBuilder(NativeValues.INFOTIPSIZE); - NativeCalls.VerifySucceeded(shellLinkW.GetArguments(description, description.Capacity)); + NativeCalls.VerifySucceeded(shellLinkW.GetDescription(description, description.Capacity)); return description.ToString(); } @@ -123,6 +123,23 @@ } } + public string WorkingDirectory + { + get + { + // No limitation to length of buffer string in the case of Unicode though. + StringBuilder workingDirectory = new StringBuilder(NativeValues.INFOTIPSIZE); + + NativeCalls.VerifySucceeded(shellLinkW.GetWorkingDirectory(workingDirectory, workingDirectory.Capacity)); + + return workingDirectory.ToString(); + } + set + { + NativeCalls.VerifySucceeded(shellLinkW.SetWorkingDirectory(value)); + } + } + public Tuple IconLocation { get diff --git a/JumpListUtil/FodyWeavers.xml b/JumpListUtil/FodyWeavers.xml new file mode 100755 index 0000000..f00ec6d --- /dev/null +++ b/JumpListUtil/FodyWeavers.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/JumpListUtil/JumpListUtil.csproj b/JumpListUtil/JumpListUtil.csproj index 378d940..d722456 100755 --- a/JumpListUtil/JumpListUtil.csproj +++ b/JumpListUtil/JumpListUtil.csproj @@ -1,5 +1,6 @@  + Debug @@ -27,6 +28,8 @@ false false true + + AnyCPU @@ -70,6 +73,9 @@ true + + ..\packages\Costura.Fody.4.1.0\lib\net40\Costura.dll + ..\packages\Microsoft.Bcl.AsyncInterfaces.1.1.0\lib\net461\Microsoft.Bcl.AsyncInterfaces.dll @@ -159,5 +165,16 @@ false + + + + + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + \ No newline at end of file diff --git a/JumpListUtil/packages.config b/JumpListUtil/packages.config index abb0b89..2d77df4 100755 --- a/JumpListUtil/packages.config +++ b/JumpListUtil/packages.config @@ -1,5 +1,7 @@  + + diff --git a/ShellLink.cs b/ShellLink.cs index ba4d16d..73f3e58 100755 --- a/ShellLink.cs +++ b/ShellLink.cs @@ -113,7 +113,7 @@ // No limitation to length of buffer string in the case of Unicode though. StringBuilder description = new StringBuilder(NativeValues.INFOTIPSIZE); - NativeCalls.VerifySucceeded(shellLinkW.GetArguments(description, description.Capacity)); + NativeCalls.VerifySucceeded(shellLinkW.GetDescription(description, description.Capacity)); return description.ToString(); } @@ -123,6 +123,23 @@ } } + public string WorkingDirectory + { + get + { + // No limitation to length of buffer string in the case of Unicode though. + StringBuilder workingDirectory = new StringBuilder(NativeValues.INFOTIPSIZE); + + NativeCalls.VerifySucceeded(shellLinkW.GetWorkingDirectory(workingDirectory, workingDirectory.Capacity)); + + return workingDirectory.ToString(); + } + set + { + NativeCalls.VerifySucceeded(shellLinkW.SetWorkingDirectory(value)); + } + } + public Tuple IconLocation { get diff --git a/ShortcutUtil/ListBoxButton.cs b/ShortcutUtil/ListBoxButton.cs index e5f6b49..82da678 100755 --- a/ShortcutUtil/ListBoxButton.cs +++ b/ShortcutUtil/ListBoxButton.cs @@ -56,11 +56,22 @@ public int? IndexOver { get; private set; } + public Action OnClick; + public ListBoxControl(T control, ListBox listBox) { Control = control; this.listBox = listBox; listBox.MouseMove += ListBoxMouseMove; + listBox.Click += ListBoxClick; + } + + private void ListBoxClick(object sender, EventArgs e) + { + if (IndexOver.HasValue && OnClick != null) + { + OnClick(IndexOver.Value); + } } public Rectangle BoundsInList(int index) diff --git a/JumpListUtil/FodyWeavers.xml b/JumpListUtil/FodyWeavers.xml new file mode 100755 index 0000000..f00ec6d --- /dev/null +++ b/JumpListUtil/FodyWeavers.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/JumpListUtil/JumpListUtil.csproj b/JumpListUtil/JumpListUtil.csproj index 378d940..d722456 100755 --- a/JumpListUtil/JumpListUtil.csproj +++ b/JumpListUtil/JumpListUtil.csproj @@ -1,5 +1,6 @@  + Debug @@ -27,6 +28,8 @@ false false true + + AnyCPU @@ -70,6 +73,9 @@ true + + ..\packages\Costura.Fody.4.1.0\lib\net40\Costura.dll + ..\packages\Microsoft.Bcl.AsyncInterfaces.1.1.0\lib\net461\Microsoft.Bcl.AsyncInterfaces.dll @@ -159,5 +165,16 @@ false + + + + + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + \ No newline at end of file diff --git a/JumpListUtil/packages.config b/JumpListUtil/packages.config index abb0b89..2d77df4 100755 --- a/JumpListUtil/packages.config +++ b/JumpListUtil/packages.config @@ -1,5 +1,7 @@  + + diff --git a/ShellLink.cs b/ShellLink.cs index ba4d16d..73f3e58 100755 --- a/ShellLink.cs +++ b/ShellLink.cs @@ -113,7 +113,7 @@ // No limitation to length of buffer string in the case of Unicode though. StringBuilder description = new StringBuilder(NativeValues.INFOTIPSIZE); - NativeCalls.VerifySucceeded(shellLinkW.GetArguments(description, description.Capacity)); + NativeCalls.VerifySucceeded(shellLinkW.GetDescription(description, description.Capacity)); return description.ToString(); } @@ -123,6 +123,23 @@ } } + public string WorkingDirectory + { + get + { + // No limitation to length of buffer string in the case of Unicode though. + StringBuilder workingDirectory = new StringBuilder(NativeValues.INFOTIPSIZE); + + NativeCalls.VerifySucceeded(shellLinkW.GetWorkingDirectory(workingDirectory, workingDirectory.Capacity)); + + return workingDirectory.ToString(); + } + set + { + NativeCalls.VerifySucceeded(shellLinkW.SetWorkingDirectory(value)); + } + } + public Tuple IconLocation { get diff --git a/ShortcutUtil/ListBoxButton.cs b/ShortcutUtil/ListBoxButton.cs index e5f6b49..82da678 100755 --- a/ShortcutUtil/ListBoxButton.cs +++ b/ShortcutUtil/ListBoxButton.cs @@ -56,11 +56,22 @@ public int? IndexOver { get; private set; } + public Action OnClick; + public ListBoxControl(T control, ListBox listBox) { Control = control; this.listBox = listBox; listBox.MouseMove += ListBoxMouseMove; + listBox.Click += ListBoxClick; + } + + private void ListBoxClick(object sender, EventArgs e) + { + if (IndexOver.HasValue && OnClick != null) + { + OnClick(IndexOver.Value); + } } public Rectangle BoundsInList(int index) diff --git a/ShortcutUtil/MainForm.Designer.cs b/ShortcutUtil/MainForm.Designer.cs index 3f482fe..dee63e1 100755 --- a/ShortcutUtil/MainForm.Designer.cs +++ b/ShortcutUtil/MainForm.Designer.cs @@ -29,12 +29,15 @@ private void InitializeComponent() { this.defaultShortcutLabel = new System.Windows.Forms.Label(); - this.entryListBox = new ListBoxEx(); + this.entryListBox = new ShortcutUtil.ListBoxEx(); this.createButton = new System.Windows.Forms.Button(); this.appUserModelIdLabel = new System.Windows.Forms.Label(); this.appButton = new System.Windows.Forms.Button(); this.hwndButton = new System.Windows.Forms.Button(); this.appUserModelIdBox = new ShortcutUtil.WatermarkTextBox(); + this.helperLocationText = new System.Windows.Forms.TextBox(); + this.helperLocationButton = new System.Windows.Forms.Button(); + this.helperLocationLabel = new System.Windows.Forms.Label(); this.SuspendLayout(); // // defaultShortcutLabel @@ -55,7 +58,7 @@ this.entryListBox.FormattingEnabled = true; this.entryListBox.Location = new System.Drawing.Point(16, 98); this.entryListBox.Name = "entryListBox"; - this.entryListBox.Size = new System.Drawing.Size(770, 355); + this.entryListBox.Size = new System.Drawing.Size(770, 316); this.entryListBox.TabIndex = 1; this.entryListBox.DrawItem += new System.Windows.Forms.DrawItemEventHandler(this.entryListBox_DrawItem); this.entryListBox.MeasureItem += new System.Windows.Forms.MeasureItemEventHandler(this.entryListBox_MeasureItem); @@ -63,12 +66,13 @@ // createButton // this.createButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); - this.createButton.Location = new System.Drawing.Point(644, 458); + this.createButton.Location = new System.Drawing.Point(642, 424); this.createButton.Name = "createButton"; this.createButton.Size = new System.Drawing.Size(144, 40); this.createButton.TabIndex = 2; - this.createButton.Text = "Create Shortcut"; + this.createButton.Text = "&Create Shortcut"; this.createButton.UseVisualStyleBackColor = true; + this.createButton.Click += new System.EventHandler(this.createButton_Click); // // appUserModelIdLabel // @@ -77,7 +81,7 @@ this.appUserModelIdLabel.Name = "appUserModelIdLabel"; this.appUserModelIdLabel.Size = new System.Drawing.Size(213, 20); this.appUserModelIdLabel.TabIndex = 3; - this.appUserModelIdLabel.Text = "Shortcut App User Model ID:"; + this.appUserModelIdLabel.Text = "&Shortcut App User Model ID:"; // // appButton // @@ -86,7 +90,7 @@ this.appButton.Name = "appButton"; this.appButton.Size = new System.Drawing.Size(74, 31); this.appButton.TabIndex = 5; - this.appButton.Text = "APP"; + this.appButton.Text = "&APP"; this.appButton.UseVisualStyleBackColor = true; this.appButton.Click += new System.EventHandler(this.appButton_Click); // @@ -98,7 +102,7 @@ this.hwndButton.Name = "hwndButton"; this.hwndButton.Size = new System.Drawing.Size(76, 31); this.hwndButton.TabIndex = 6; - this.hwndButton.Text = "HWND"; + this.hwndButton.Text = "&HWND"; this.hwndButton.UseVisualStyleBackColor = true; this.hwndButton.Click += new System.EventHandler(this.hwndButton_Click); // @@ -113,12 +117,45 @@ this.appUserModelIdBox.WaterMarkColor = System.Drawing.Color.Gray; this.appUserModelIdBox.WaterMarkText = "Enter a manual ID, or select on from a UWP App or open Window"; // + // helperLocationText + // + this.helperLocationText.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.helperLocationText.Location = new System.Drawing.Point(79, 470); + this.helperLocationText.Name = "helperLocationText"; + this.helperLocationText.Size = new System.Drawing.Size(654, 26); + this.helperLocationText.TabIndex = 7; + this.helperLocationText.TextChanged += new System.EventHandler(this.helperLocationText_TextChanged); + // + // helperLocationButton + // + this.helperLocationButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.helperLocationButton.Location = new System.Drawing.Point(739, 470); + this.helperLocationButton.Name = "helperLocationButton"; + this.helperLocationButton.Size = new System.Drawing.Size(46, 31); + this.helperLocationButton.TabIndex = 8; + this.helperLocationButton.Text = "..."; + this.helperLocationButton.UseVisualStyleBackColor = true; + this.helperLocationButton.Click += new System.EventHandler(this.helperLocationButton_Click); + // + // helperLocationLabel + // + this.helperLocationLabel.AutoSize = true; + this.helperLocationLabel.Location = new System.Drawing.Point(13, 473); + this.helperLocationLabel.Name = "helperLocationLabel"; + this.helperLocationLabel.Size = new System.Drawing.Size(60, 20); + this.helperLocationLabel.TabIndex = 9; + this.helperLocationLabel.Text = "H&elper:"; + // // MainForm // this.AcceptButton = this.createButton; this.AutoScaleDimensions = new System.Drawing.SizeF(9F, 20F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.ClientSize = new System.Drawing.Size(800, 508); + this.Controls.Add(this.helperLocationLabel); + this.Controls.Add(this.helperLocationButton); + this.Controls.Add(this.helperLocationText); this.Controls.Add(this.hwndButton); this.Controls.Add(this.appButton); this.Controls.Add(this.appUserModelIdBox); @@ -142,6 +179,9 @@ private System.Windows.Forms.Button appButton; private System.Windows.Forms.Button hwndButton; private WatermarkTextBox appUserModelIdBox; + private System.Windows.Forms.TextBox helperLocationText; + private System.Windows.Forms.Button helperLocationButton; + private System.Windows.Forms.Label helperLocationLabel; } } diff --git a/JumpListUtil/FodyWeavers.xml b/JumpListUtil/FodyWeavers.xml new file mode 100755 index 0000000..f00ec6d --- /dev/null +++ b/JumpListUtil/FodyWeavers.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/JumpListUtil/JumpListUtil.csproj b/JumpListUtil/JumpListUtil.csproj index 378d940..d722456 100755 --- a/JumpListUtil/JumpListUtil.csproj +++ b/JumpListUtil/JumpListUtil.csproj @@ -1,5 +1,6 @@  + Debug @@ -27,6 +28,8 @@ false false true + + AnyCPU @@ -70,6 +73,9 @@ true + + ..\packages\Costura.Fody.4.1.0\lib\net40\Costura.dll + ..\packages\Microsoft.Bcl.AsyncInterfaces.1.1.0\lib\net461\Microsoft.Bcl.AsyncInterfaces.dll @@ -159,5 +165,16 @@ false + + + + + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + \ No newline at end of file diff --git a/JumpListUtil/packages.config b/JumpListUtil/packages.config index abb0b89..2d77df4 100755 --- a/JumpListUtil/packages.config +++ b/JumpListUtil/packages.config @@ -1,5 +1,7 @@  + + diff --git a/ShellLink.cs b/ShellLink.cs index ba4d16d..73f3e58 100755 --- a/ShellLink.cs +++ b/ShellLink.cs @@ -113,7 +113,7 @@ // No limitation to length of buffer string in the case of Unicode though. StringBuilder description = new StringBuilder(NativeValues.INFOTIPSIZE); - NativeCalls.VerifySucceeded(shellLinkW.GetArguments(description, description.Capacity)); + NativeCalls.VerifySucceeded(shellLinkW.GetDescription(description, description.Capacity)); return description.ToString(); } @@ -123,6 +123,23 @@ } } + public string WorkingDirectory + { + get + { + // No limitation to length of buffer string in the case of Unicode though. + StringBuilder workingDirectory = new StringBuilder(NativeValues.INFOTIPSIZE); + + NativeCalls.VerifySucceeded(shellLinkW.GetWorkingDirectory(workingDirectory, workingDirectory.Capacity)); + + return workingDirectory.ToString(); + } + set + { + NativeCalls.VerifySucceeded(shellLinkW.SetWorkingDirectory(value)); + } + } + public Tuple IconLocation { get diff --git a/ShortcutUtil/ListBoxButton.cs b/ShortcutUtil/ListBoxButton.cs index e5f6b49..82da678 100755 --- a/ShortcutUtil/ListBoxButton.cs +++ b/ShortcutUtil/ListBoxButton.cs @@ -56,11 +56,22 @@ public int? IndexOver { get; private set; } + public Action OnClick; + public ListBoxControl(T control, ListBox listBox) { Control = control; this.listBox = listBox; listBox.MouseMove += ListBoxMouseMove; + listBox.Click += ListBoxClick; + } + + private void ListBoxClick(object sender, EventArgs e) + { + if (IndexOver.HasValue && OnClick != null) + { + OnClick(IndexOver.Value); + } } public Rectangle BoundsInList(int index) diff --git a/ShortcutUtil/MainForm.Designer.cs b/ShortcutUtil/MainForm.Designer.cs index 3f482fe..dee63e1 100755 --- a/ShortcutUtil/MainForm.Designer.cs +++ b/ShortcutUtil/MainForm.Designer.cs @@ -29,12 +29,15 @@ private void InitializeComponent() { this.defaultShortcutLabel = new System.Windows.Forms.Label(); - this.entryListBox = new ListBoxEx(); + this.entryListBox = new ShortcutUtil.ListBoxEx(); this.createButton = new System.Windows.Forms.Button(); this.appUserModelIdLabel = new System.Windows.Forms.Label(); this.appButton = new System.Windows.Forms.Button(); this.hwndButton = new System.Windows.Forms.Button(); this.appUserModelIdBox = new ShortcutUtil.WatermarkTextBox(); + this.helperLocationText = new System.Windows.Forms.TextBox(); + this.helperLocationButton = new System.Windows.Forms.Button(); + this.helperLocationLabel = new System.Windows.Forms.Label(); this.SuspendLayout(); // // defaultShortcutLabel @@ -55,7 +58,7 @@ this.entryListBox.FormattingEnabled = true; this.entryListBox.Location = new System.Drawing.Point(16, 98); this.entryListBox.Name = "entryListBox"; - this.entryListBox.Size = new System.Drawing.Size(770, 355); + this.entryListBox.Size = new System.Drawing.Size(770, 316); this.entryListBox.TabIndex = 1; this.entryListBox.DrawItem += new System.Windows.Forms.DrawItemEventHandler(this.entryListBox_DrawItem); this.entryListBox.MeasureItem += new System.Windows.Forms.MeasureItemEventHandler(this.entryListBox_MeasureItem); @@ -63,12 +66,13 @@ // createButton // this.createButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); - this.createButton.Location = new System.Drawing.Point(644, 458); + this.createButton.Location = new System.Drawing.Point(642, 424); this.createButton.Name = "createButton"; this.createButton.Size = new System.Drawing.Size(144, 40); this.createButton.TabIndex = 2; - this.createButton.Text = "Create Shortcut"; + this.createButton.Text = "&Create Shortcut"; this.createButton.UseVisualStyleBackColor = true; + this.createButton.Click += new System.EventHandler(this.createButton_Click); // // appUserModelIdLabel // @@ -77,7 +81,7 @@ this.appUserModelIdLabel.Name = "appUserModelIdLabel"; this.appUserModelIdLabel.Size = new System.Drawing.Size(213, 20); this.appUserModelIdLabel.TabIndex = 3; - this.appUserModelIdLabel.Text = "Shortcut App User Model ID:"; + this.appUserModelIdLabel.Text = "&Shortcut App User Model ID:"; // // appButton // @@ -86,7 +90,7 @@ this.appButton.Name = "appButton"; this.appButton.Size = new System.Drawing.Size(74, 31); this.appButton.TabIndex = 5; - this.appButton.Text = "APP"; + this.appButton.Text = "&APP"; this.appButton.UseVisualStyleBackColor = true; this.appButton.Click += new System.EventHandler(this.appButton_Click); // @@ -98,7 +102,7 @@ this.hwndButton.Name = "hwndButton"; this.hwndButton.Size = new System.Drawing.Size(76, 31); this.hwndButton.TabIndex = 6; - this.hwndButton.Text = "HWND"; + this.hwndButton.Text = "&HWND"; this.hwndButton.UseVisualStyleBackColor = true; this.hwndButton.Click += new System.EventHandler(this.hwndButton_Click); // @@ -113,12 +117,45 @@ this.appUserModelIdBox.WaterMarkColor = System.Drawing.Color.Gray; this.appUserModelIdBox.WaterMarkText = "Enter a manual ID, or select on from a UWP App or open Window"; // + // helperLocationText + // + this.helperLocationText.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.helperLocationText.Location = new System.Drawing.Point(79, 470); + this.helperLocationText.Name = "helperLocationText"; + this.helperLocationText.Size = new System.Drawing.Size(654, 26); + this.helperLocationText.TabIndex = 7; + this.helperLocationText.TextChanged += new System.EventHandler(this.helperLocationText_TextChanged); + // + // helperLocationButton + // + this.helperLocationButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.helperLocationButton.Location = new System.Drawing.Point(739, 470); + this.helperLocationButton.Name = "helperLocationButton"; + this.helperLocationButton.Size = new System.Drawing.Size(46, 31); + this.helperLocationButton.TabIndex = 8; + this.helperLocationButton.Text = "..."; + this.helperLocationButton.UseVisualStyleBackColor = true; + this.helperLocationButton.Click += new System.EventHandler(this.helperLocationButton_Click); + // + // helperLocationLabel + // + this.helperLocationLabel.AutoSize = true; + this.helperLocationLabel.Location = new System.Drawing.Point(13, 473); + this.helperLocationLabel.Name = "helperLocationLabel"; + this.helperLocationLabel.Size = new System.Drawing.Size(60, 20); + this.helperLocationLabel.TabIndex = 9; + this.helperLocationLabel.Text = "H&elper:"; + // // MainForm // this.AcceptButton = this.createButton; this.AutoScaleDimensions = new System.Drawing.SizeF(9F, 20F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.ClientSize = new System.Drawing.Size(800, 508); + this.Controls.Add(this.helperLocationLabel); + this.Controls.Add(this.helperLocationButton); + this.Controls.Add(this.helperLocationText); this.Controls.Add(this.hwndButton); this.Controls.Add(this.appButton); this.Controls.Add(this.appUserModelIdBox); @@ -142,6 +179,9 @@ private System.Windows.Forms.Button appButton; private System.Windows.Forms.Button hwndButton; private WatermarkTextBox appUserModelIdBox; + private System.Windows.Forms.TextBox helperLocationText; + private System.Windows.Forms.Button helperLocationButton; + private System.Windows.Forms.Label helperLocationLabel; } } diff --git a/ShortcutUtil/MainForm.cs b/ShortcutUtil/MainForm.cs index a336e63..2b71b0f 100755 --- a/ShortcutUtil/MainForm.cs +++ b/ShortcutUtil/MainForm.cs @@ -5,11 +5,15 @@ using System.Collections.Generic; using System.ComponentModel; using System.Data; +using System.Diagnostics; using System.Drawing; +using System.IO; using System.Linq; using System.Reflection; using System.Runtime.InteropServices; using System.Text; +using System.Text.Json; +using System.Text.RegularExpressions; using System.Threading.Tasks; using System.Windows.Forms; using Windows.ApplicationModel; @@ -43,12 +47,15 @@ private EntryListItem listLayout; + private HelperLocation helperLocation; + private bool designMode; - public MainForm(EntryList entryList, AppResolver appResolver) + public MainForm(EntryList entryList, AppResolver appResolver, HelperLocation helperLocation) { designMode = System.ComponentModel.LicenseManager.UsageMode == System.ComponentModel.LicenseUsageMode.Designtime; + this.helperLocation = helperLocation; InitializeComponent(); @@ -77,6 +84,30 @@ listLayout = new EntryListItem(entryListBox); + listLayout.TestButton.OnClick += ClickedTestButton; + + helperLocationText.Text = helperLocation.Location; + + UpdateHelperValidity(); + + } + + private void UpdateHelperValidity() + { + bool valid = helperLocation.Valid; + helperLocationText.ForeColor = valid ? SystemColors.ControlText : Color.Red; + createButton.Enabled = valid && entryList.Entries.Count > 0; + } + + private void ClickedTestButton(int index) + { + ProcessStartInfo startInfo = new ProcessStartInfo + { + + FileName = entryList.Entries[index].Target, + UseShellExecute = true + }; + Process.Start(startInfo); } private Dictionary, Icon> iconsByFileIndex = new Dictionary, Icon>(); @@ -295,5 +326,79 @@ hwndButton.Enabled = true; } + + public static string EncodeParameterArgument(string original) + { + if (string.IsNullOrEmpty(original)) + return original; + string value = Regex.Replace(original, @"(\\*)" + "\"", @"$1\$0"); + value = Regex.Replace(value, @"^(.*\s.*?)(\\*)$", "\"$1$2$2\"", RegexOptions.Singleline); + + return value; + } + + private void createButton_Click(object sender, EventArgs e) + { + if (helperLocation.Valid && entryList.Entries.Count > 0) + { + int index = entryListBox.SelectedIndex; + if (index < 0 || index >= entryList.Entries.Count) index = 0; + + SaveFileDialog sfd = new SaveFileDialog(); + sfd.InitialDirectory = Environment.CurrentDirectory; + sfd.Filter = "Shortcut (*.lnk)|*.lnk"; + sfd.Title = "Select output file"; + sfd.DefaultExt = "lnk"; + sfd.CheckPathExists = true; + sfd.CreatePrompt = false; + sfd.OverwritePrompt = true; + + DialogResult res = sfd.ShowDialog(); + + if (res == DialogResult.OK) + { + Entry selected = entryList.Entries[index]; + + ShellLink shellLink = new ShellLink(); + + shellLink.TargetPath = helperLocation.Location; + shellLink.Arguments = String.Join(" ", + new string[] + { + "-s", entryList.FilePath, "-i", "" + index, "-a", appUserModelIdBox.Text + }.Select(a => EncodeParameterArgument(a))); + shellLink.Description = selected.Description; + shellLink.IconLocation = new Tuple(selected.Icon, selected.IconIndex); + shellLink.WorkingDirectory = Path.GetDirectoryName(entryList.FilePath); + shellLink.AppUserModelID = appUserModelIdBox.Text; + + shellLink.Save(sfd.FileName); + } + } + } + + private void helperLocationText_TextChanged(object sender, EventArgs e) + { + helperLocation.Location = helperLocationText.Text; + UpdateHelperValidity(); + } + + private void helperLocationButton_Click(object sender, EventArgs e) + { + OpenFileDialog ofd = new OpenFileDialog(); + ofd.Filter = "Executables (*.exe)|*.exe"; + ofd.InitialDirectory = Path.GetDirectoryName(helperLocation.Location); + ofd.Title = "Select helper executable"; + ofd.DefaultExt = "exe"; + ofd.Multiselect = false; + ofd.CheckFileExists = true; + DialogResult result = ofd.ShowDialog(); + if (result == DialogResult.OK) + { + helperLocation.Location = ofd.FileName; + helperLocationText.Text = helperLocation.Location; + UpdateHelperValidity(); + } + } } } diff --git a/JumpListUtil/FodyWeavers.xml b/JumpListUtil/FodyWeavers.xml new file mode 100755 index 0000000..f00ec6d --- /dev/null +++ b/JumpListUtil/FodyWeavers.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/JumpListUtil/JumpListUtil.csproj b/JumpListUtil/JumpListUtil.csproj index 378d940..d722456 100755 --- a/JumpListUtil/JumpListUtil.csproj +++ b/JumpListUtil/JumpListUtil.csproj @@ -1,5 +1,6 @@  + Debug @@ -27,6 +28,8 @@ false false true + + AnyCPU @@ -70,6 +73,9 @@ true + + ..\packages\Costura.Fody.4.1.0\lib\net40\Costura.dll + ..\packages\Microsoft.Bcl.AsyncInterfaces.1.1.0\lib\net461\Microsoft.Bcl.AsyncInterfaces.dll @@ -159,5 +165,16 @@ false + + + + + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + \ No newline at end of file diff --git a/JumpListUtil/packages.config b/JumpListUtil/packages.config index abb0b89..2d77df4 100755 --- a/JumpListUtil/packages.config +++ b/JumpListUtil/packages.config @@ -1,5 +1,7 @@  + + diff --git a/ShellLink.cs b/ShellLink.cs index ba4d16d..73f3e58 100755 --- a/ShellLink.cs +++ b/ShellLink.cs @@ -113,7 +113,7 @@ // No limitation to length of buffer string in the case of Unicode though. StringBuilder description = new StringBuilder(NativeValues.INFOTIPSIZE); - NativeCalls.VerifySucceeded(shellLinkW.GetArguments(description, description.Capacity)); + NativeCalls.VerifySucceeded(shellLinkW.GetDescription(description, description.Capacity)); return description.ToString(); } @@ -123,6 +123,23 @@ } } + public string WorkingDirectory + { + get + { + // No limitation to length of buffer string in the case of Unicode though. + StringBuilder workingDirectory = new StringBuilder(NativeValues.INFOTIPSIZE); + + NativeCalls.VerifySucceeded(shellLinkW.GetWorkingDirectory(workingDirectory, workingDirectory.Capacity)); + + return workingDirectory.ToString(); + } + set + { + NativeCalls.VerifySucceeded(shellLinkW.SetWorkingDirectory(value)); + } + } + public Tuple IconLocation { get diff --git a/ShortcutUtil/ListBoxButton.cs b/ShortcutUtil/ListBoxButton.cs index e5f6b49..82da678 100755 --- a/ShortcutUtil/ListBoxButton.cs +++ b/ShortcutUtil/ListBoxButton.cs @@ -56,11 +56,22 @@ public int? IndexOver { get; private set; } + public Action OnClick; + public ListBoxControl(T control, ListBox listBox) { Control = control; this.listBox = listBox; listBox.MouseMove += ListBoxMouseMove; + listBox.Click += ListBoxClick; + } + + private void ListBoxClick(object sender, EventArgs e) + { + if (IndexOver.HasValue && OnClick != null) + { + OnClick(IndexOver.Value); + } } public Rectangle BoundsInList(int index) diff --git a/ShortcutUtil/MainForm.Designer.cs b/ShortcutUtil/MainForm.Designer.cs index 3f482fe..dee63e1 100755 --- a/ShortcutUtil/MainForm.Designer.cs +++ b/ShortcutUtil/MainForm.Designer.cs @@ -29,12 +29,15 @@ private void InitializeComponent() { this.defaultShortcutLabel = new System.Windows.Forms.Label(); - this.entryListBox = new ListBoxEx(); + this.entryListBox = new ShortcutUtil.ListBoxEx(); this.createButton = new System.Windows.Forms.Button(); this.appUserModelIdLabel = new System.Windows.Forms.Label(); this.appButton = new System.Windows.Forms.Button(); this.hwndButton = new System.Windows.Forms.Button(); this.appUserModelIdBox = new ShortcutUtil.WatermarkTextBox(); + this.helperLocationText = new System.Windows.Forms.TextBox(); + this.helperLocationButton = new System.Windows.Forms.Button(); + this.helperLocationLabel = new System.Windows.Forms.Label(); this.SuspendLayout(); // // defaultShortcutLabel @@ -55,7 +58,7 @@ this.entryListBox.FormattingEnabled = true; this.entryListBox.Location = new System.Drawing.Point(16, 98); this.entryListBox.Name = "entryListBox"; - this.entryListBox.Size = new System.Drawing.Size(770, 355); + this.entryListBox.Size = new System.Drawing.Size(770, 316); this.entryListBox.TabIndex = 1; this.entryListBox.DrawItem += new System.Windows.Forms.DrawItemEventHandler(this.entryListBox_DrawItem); this.entryListBox.MeasureItem += new System.Windows.Forms.MeasureItemEventHandler(this.entryListBox_MeasureItem); @@ -63,12 +66,13 @@ // createButton // this.createButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); - this.createButton.Location = new System.Drawing.Point(644, 458); + this.createButton.Location = new System.Drawing.Point(642, 424); this.createButton.Name = "createButton"; this.createButton.Size = new System.Drawing.Size(144, 40); this.createButton.TabIndex = 2; - this.createButton.Text = "Create Shortcut"; + this.createButton.Text = "&Create Shortcut"; this.createButton.UseVisualStyleBackColor = true; + this.createButton.Click += new System.EventHandler(this.createButton_Click); // // appUserModelIdLabel // @@ -77,7 +81,7 @@ this.appUserModelIdLabel.Name = "appUserModelIdLabel"; this.appUserModelIdLabel.Size = new System.Drawing.Size(213, 20); this.appUserModelIdLabel.TabIndex = 3; - this.appUserModelIdLabel.Text = "Shortcut App User Model ID:"; + this.appUserModelIdLabel.Text = "&Shortcut App User Model ID:"; // // appButton // @@ -86,7 +90,7 @@ this.appButton.Name = "appButton"; this.appButton.Size = new System.Drawing.Size(74, 31); this.appButton.TabIndex = 5; - this.appButton.Text = "APP"; + this.appButton.Text = "&APP"; this.appButton.UseVisualStyleBackColor = true; this.appButton.Click += new System.EventHandler(this.appButton_Click); // @@ -98,7 +102,7 @@ this.hwndButton.Name = "hwndButton"; this.hwndButton.Size = new System.Drawing.Size(76, 31); this.hwndButton.TabIndex = 6; - this.hwndButton.Text = "HWND"; + this.hwndButton.Text = "&HWND"; this.hwndButton.UseVisualStyleBackColor = true; this.hwndButton.Click += new System.EventHandler(this.hwndButton_Click); // @@ -113,12 +117,45 @@ this.appUserModelIdBox.WaterMarkColor = System.Drawing.Color.Gray; this.appUserModelIdBox.WaterMarkText = "Enter a manual ID, or select on from a UWP App or open Window"; // + // helperLocationText + // + this.helperLocationText.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.helperLocationText.Location = new System.Drawing.Point(79, 470); + this.helperLocationText.Name = "helperLocationText"; + this.helperLocationText.Size = new System.Drawing.Size(654, 26); + this.helperLocationText.TabIndex = 7; + this.helperLocationText.TextChanged += new System.EventHandler(this.helperLocationText_TextChanged); + // + // helperLocationButton + // + this.helperLocationButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.helperLocationButton.Location = new System.Drawing.Point(739, 470); + this.helperLocationButton.Name = "helperLocationButton"; + this.helperLocationButton.Size = new System.Drawing.Size(46, 31); + this.helperLocationButton.TabIndex = 8; + this.helperLocationButton.Text = "..."; + this.helperLocationButton.UseVisualStyleBackColor = true; + this.helperLocationButton.Click += new System.EventHandler(this.helperLocationButton_Click); + // + // helperLocationLabel + // + this.helperLocationLabel.AutoSize = true; + this.helperLocationLabel.Location = new System.Drawing.Point(13, 473); + this.helperLocationLabel.Name = "helperLocationLabel"; + this.helperLocationLabel.Size = new System.Drawing.Size(60, 20); + this.helperLocationLabel.TabIndex = 9; + this.helperLocationLabel.Text = "H&elper:"; + // // MainForm // this.AcceptButton = this.createButton; this.AutoScaleDimensions = new System.Drawing.SizeF(9F, 20F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.ClientSize = new System.Drawing.Size(800, 508); + this.Controls.Add(this.helperLocationLabel); + this.Controls.Add(this.helperLocationButton); + this.Controls.Add(this.helperLocationText); this.Controls.Add(this.hwndButton); this.Controls.Add(this.appButton); this.Controls.Add(this.appUserModelIdBox); @@ -142,6 +179,9 @@ private System.Windows.Forms.Button appButton; private System.Windows.Forms.Button hwndButton; private WatermarkTextBox appUserModelIdBox; + private System.Windows.Forms.TextBox helperLocationText; + private System.Windows.Forms.Button helperLocationButton; + private System.Windows.Forms.Label helperLocationLabel; } } diff --git a/ShortcutUtil/MainForm.cs b/ShortcutUtil/MainForm.cs index a336e63..2b71b0f 100755 --- a/ShortcutUtil/MainForm.cs +++ b/ShortcutUtil/MainForm.cs @@ -5,11 +5,15 @@ using System.Collections.Generic; using System.ComponentModel; using System.Data; +using System.Diagnostics; using System.Drawing; +using System.IO; using System.Linq; using System.Reflection; using System.Runtime.InteropServices; using System.Text; +using System.Text.Json; +using System.Text.RegularExpressions; using System.Threading.Tasks; using System.Windows.Forms; using Windows.ApplicationModel; @@ -43,12 +47,15 @@ private EntryListItem listLayout; + private HelperLocation helperLocation; + private bool designMode; - public MainForm(EntryList entryList, AppResolver appResolver) + public MainForm(EntryList entryList, AppResolver appResolver, HelperLocation helperLocation) { designMode = System.ComponentModel.LicenseManager.UsageMode == System.ComponentModel.LicenseUsageMode.Designtime; + this.helperLocation = helperLocation; InitializeComponent(); @@ -77,6 +84,30 @@ listLayout = new EntryListItem(entryListBox); + listLayout.TestButton.OnClick += ClickedTestButton; + + helperLocationText.Text = helperLocation.Location; + + UpdateHelperValidity(); + + } + + private void UpdateHelperValidity() + { + bool valid = helperLocation.Valid; + helperLocationText.ForeColor = valid ? SystemColors.ControlText : Color.Red; + createButton.Enabled = valid && entryList.Entries.Count > 0; + } + + private void ClickedTestButton(int index) + { + ProcessStartInfo startInfo = new ProcessStartInfo + { + + FileName = entryList.Entries[index].Target, + UseShellExecute = true + }; + Process.Start(startInfo); } private Dictionary, Icon> iconsByFileIndex = new Dictionary, Icon>(); @@ -295,5 +326,79 @@ hwndButton.Enabled = true; } + + public static string EncodeParameterArgument(string original) + { + if (string.IsNullOrEmpty(original)) + return original; + string value = Regex.Replace(original, @"(\\*)" + "\"", @"$1\$0"); + value = Regex.Replace(value, @"^(.*\s.*?)(\\*)$", "\"$1$2$2\"", RegexOptions.Singleline); + + return value; + } + + private void createButton_Click(object sender, EventArgs e) + { + if (helperLocation.Valid && entryList.Entries.Count > 0) + { + int index = entryListBox.SelectedIndex; + if (index < 0 || index >= entryList.Entries.Count) index = 0; + + SaveFileDialog sfd = new SaveFileDialog(); + sfd.InitialDirectory = Environment.CurrentDirectory; + sfd.Filter = "Shortcut (*.lnk)|*.lnk"; + sfd.Title = "Select output file"; + sfd.DefaultExt = "lnk"; + sfd.CheckPathExists = true; + sfd.CreatePrompt = false; + sfd.OverwritePrompt = true; + + DialogResult res = sfd.ShowDialog(); + + if (res == DialogResult.OK) + { + Entry selected = entryList.Entries[index]; + + ShellLink shellLink = new ShellLink(); + + shellLink.TargetPath = helperLocation.Location; + shellLink.Arguments = String.Join(" ", + new string[] + { + "-s", entryList.FilePath, "-i", "" + index, "-a", appUserModelIdBox.Text + }.Select(a => EncodeParameterArgument(a))); + shellLink.Description = selected.Description; + shellLink.IconLocation = new Tuple(selected.Icon, selected.IconIndex); + shellLink.WorkingDirectory = Path.GetDirectoryName(entryList.FilePath); + shellLink.AppUserModelID = appUserModelIdBox.Text; + + shellLink.Save(sfd.FileName); + } + } + } + + private void helperLocationText_TextChanged(object sender, EventArgs e) + { + helperLocation.Location = helperLocationText.Text; + UpdateHelperValidity(); + } + + private void helperLocationButton_Click(object sender, EventArgs e) + { + OpenFileDialog ofd = new OpenFileDialog(); + ofd.Filter = "Executables (*.exe)|*.exe"; + ofd.InitialDirectory = Path.GetDirectoryName(helperLocation.Location); + ofd.Title = "Select helper executable"; + ofd.DefaultExt = "exe"; + ofd.Multiselect = false; + ofd.CheckFileExists = true; + DialogResult result = ofd.ShowDialog(); + if (result == DialogResult.OK) + { + helperLocation.Location = ofd.FileName; + helperLocationText.Text = helperLocation.Location; + UpdateHelperValidity(); + } + } } } diff --git a/ShortcutUtil/Program.cs b/ShortcutUtil/Program.cs index a46ce5b..bc6eb5a 100755 --- a/ShortcutUtil/Program.cs +++ b/ShortcutUtil/Program.cs @@ -10,6 +10,24 @@ namespace ShortcutUtil { + public class HelperLocation + { + public string Location; + public bool Valid + { + get + { + return File.Exists(Location); + } + } + public HelperLocation(string fileName) + { + Location = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, fileName); + if (Valid) return; + + Location = Path.Combine(Environment.CurrentDirectory, fileName); + } + } static class Program { /// @@ -47,10 +65,12 @@ Environment.CurrentDirectory = Path.GetDirectoryName(Path.GetFullPath(args[1])); + HelperLocation location = new HelperLocation("JumpListUtil.exe"); + Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); - Application.Run(new MainForm(entryList, appResolver)); + Application.Run(new MainForm(entryList, appResolver, location)); } } } diff --git a/JumpListUtil/FodyWeavers.xml b/JumpListUtil/FodyWeavers.xml new file mode 100755 index 0000000..f00ec6d --- /dev/null +++ b/JumpListUtil/FodyWeavers.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/JumpListUtil/JumpListUtil.csproj b/JumpListUtil/JumpListUtil.csproj index 378d940..d722456 100755 --- a/JumpListUtil/JumpListUtil.csproj +++ b/JumpListUtil/JumpListUtil.csproj @@ -1,5 +1,6 @@  + Debug @@ -27,6 +28,8 @@ false false true + + AnyCPU @@ -70,6 +73,9 @@ true + + ..\packages\Costura.Fody.4.1.0\lib\net40\Costura.dll + ..\packages\Microsoft.Bcl.AsyncInterfaces.1.1.0\lib\net461\Microsoft.Bcl.AsyncInterfaces.dll @@ -159,5 +165,16 @@ false + + + + + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + \ No newline at end of file diff --git a/JumpListUtil/packages.config b/JumpListUtil/packages.config index abb0b89..2d77df4 100755 --- a/JumpListUtil/packages.config +++ b/JumpListUtil/packages.config @@ -1,5 +1,7 @@  + + diff --git a/ShellLink.cs b/ShellLink.cs index ba4d16d..73f3e58 100755 --- a/ShellLink.cs +++ b/ShellLink.cs @@ -113,7 +113,7 @@ // No limitation to length of buffer string in the case of Unicode though. StringBuilder description = new StringBuilder(NativeValues.INFOTIPSIZE); - NativeCalls.VerifySucceeded(shellLinkW.GetArguments(description, description.Capacity)); + NativeCalls.VerifySucceeded(shellLinkW.GetDescription(description, description.Capacity)); return description.ToString(); } @@ -123,6 +123,23 @@ } } + public string WorkingDirectory + { + get + { + // No limitation to length of buffer string in the case of Unicode though. + StringBuilder workingDirectory = new StringBuilder(NativeValues.INFOTIPSIZE); + + NativeCalls.VerifySucceeded(shellLinkW.GetWorkingDirectory(workingDirectory, workingDirectory.Capacity)); + + return workingDirectory.ToString(); + } + set + { + NativeCalls.VerifySucceeded(shellLinkW.SetWorkingDirectory(value)); + } + } + public Tuple IconLocation { get diff --git a/ShortcutUtil/ListBoxButton.cs b/ShortcutUtil/ListBoxButton.cs index e5f6b49..82da678 100755 --- a/ShortcutUtil/ListBoxButton.cs +++ b/ShortcutUtil/ListBoxButton.cs @@ -56,11 +56,22 @@ public int? IndexOver { get; private set; } + public Action OnClick; + public ListBoxControl(T control, ListBox listBox) { Control = control; this.listBox = listBox; listBox.MouseMove += ListBoxMouseMove; + listBox.Click += ListBoxClick; + } + + private void ListBoxClick(object sender, EventArgs e) + { + if (IndexOver.HasValue && OnClick != null) + { + OnClick(IndexOver.Value); + } } public Rectangle BoundsInList(int index) diff --git a/ShortcutUtil/MainForm.Designer.cs b/ShortcutUtil/MainForm.Designer.cs index 3f482fe..dee63e1 100755 --- a/ShortcutUtil/MainForm.Designer.cs +++ b/ShortcutUtil/MainForm.Designer.cs @@ -29,12 +29,15 @@ private void InitializeComponent() { this.defaultShortcutLabel = new System.Windows.Forms.Label(); - this.entryListBox = new ListBoxEx(); + this.entryListBox = new ShortcutUtil.ListBoxEx(); this.createButton = new System.Windows.Forms.Button(); this.appUserModelIdLabel = new System.Windows.Forms.Label(); this.appButton = new System.Windows.Forms.Button(); this.hwndButton = new System.Windows.Forms.Button(); this.appUserModelIdBox = new ShortcutUtil.WatermarkTextBox(); + this.helperLocationText = new System.Windows.Forms.TextBox(); + this.helperLocationButton = new System.Windows.Forms.Button(); + this.helperLocationLabel = new System.Windows.Forms.Label(); this.SuspendLayout(); // // defaultShortcutLabel @@ -55,7 +58,7 @@ this.entryListBox.FormattingEnabled = true; this.entryListBox.Location = new System.Drawing.Point(16, 98); this.entryListBox.Name = "entryListBox"; - this.entryListBox.Size = new System.Drawing.Size(770, 355); + this.entryListBox.Size = new System.Drawing.Size(770, 316); this.entryListBox.TabIndex = 1; this.entryListBox.DrawItem += new System.Windows.Forms.DrawItemEventHandler(this.entryListBox_DrawItem); this.entryListBox.MeasureItem += new System.Windows.Forms.MeasureItemEventHandler(this.entryListBox_MeasureItem); @@ -63,12 +66,13 @@ // createButton // this.createButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); - this.createButton.Location = new System.Drawing.Point(644, 458); + this.createButton.Location = new System.Drawing.Point(642, 424); this.createButton.Name = "createButton"; this.createButton.Size = new System.Drawing.Size(144, 40); this.createButton.TabIndex = 2; - this.createButton.Text = "Create Shortcut"; + this.createButton.Text = "&Create Shortcut"; this.createButton.UseVisualStyleBackColor = true; + this.createButton.Click += new System.EventHandler(this.createButton_Click); // // appUserModelIdLabel // @@ -77,7 +81,7 @@ this.appUserModelIdLabel.Name = "appUserModelIdLabel"; this.appUserModelIdLabel.Size = new System.Drawing.Size(213, 20); this.appUserModelIdLabel.TabIndex = 3; - this.appUserModelIdLabel.Text = "Shortcut App User Model ID:"; + this.appUserModelIdLabel.Text = "&Shortcut App User Model ID:"; // // appButton // @@ -86,7 +90,7 @@ this.appButton.Name = "appButton"; this.appButton.Size = new System.Drawing.Size(74, 31); this.appButton.TabIndex = 5; - this.appButton.Text = "APP"; + this.appButton.Text = "&APP"; this.appButton.UseVisualStyleBackColor = true; this.appButton.Click += new System.EventHandler(this.appButton_Click); // @@ -98,7 +102,7 @@ this.hwndButton.Name = "hwndButton"; this.hwndButton.Size = new System.Drawing.Size(76, 31); this.hwndButton.TabIndex = 6; - this.hwndButton.Text = "HWND"; + this.hwndButton.Text = "&HWND"; this.hwndButton.UseVisualStyleBackColor = true; this.hwndButton.Click += new System.EventHandler(this.hwndButton_Click); // @@ -113,12 +117,45 @@ this.appUserModelIdBox.WaterMarkColor = System.Drawing.Color.Gray; this.appUserModelIdBox.WaterMarkText = "Enter a manual ID, or select on from a UWP App or open Window"; // + // helperLocationText + // + this.helperLocationText.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.helperLocationText.Location = new System.Drawing.Point(79, 470); + this.helperLocationText.Name = "helperLocationText"; + this.helperLocationText.Size = new System.Drawing.Size(654, 26); + this.helperLocationText.TabIndex = 7; + this.helperLocationText.TextChanged += new System.EventHandler(this.helperLocationText_TextChanged); + // + // helperLocationButton + // + this.helperLocationButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.helperLocationButton.Location = new System.Drawing.Point(739, 470); + this.helperLocationButton.Name = "helperLocationButton"; + this.helperLocationButton.Size = new System.Drawing.Size(46, 31); + this.helperLocationButton.TabIndex = 8; + this.helperLocationButton.Text = "..."; + this.helperLocationButton.UseVisualStyleBackColor = true; + this.helperLocationButton.Click += new System.EventHandler(this.helperLocationButton_Click); + // + // helperLocationLabel + // + this.helperLocationLabel.AutoSize = true; + this.helperLocationLabel.Location = new System.Drawing.Point(13, 473); + this.helperLocationLabel.Name = "helperLocationLabel"; + this.helperLocationLabel.Size = new System.Drawing.Size(60, 20); + this.helperLocationLabel.TabIndex = 9; + this.helperLocationLabel.Text = "H&elper:"; + // // MainForm // this.AcceptButton = this.createButton; this.AutoScaleDimensions = new System.Drawing.SizeF(9F, 20F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.ClientSize = new System.Drawing.Size(800, 508); + this.Controls.Add(this.helperLocationLabel); + this.Controls.Add(this.helperLocationButton); + this.Controls.Add(this.helperLocationText); this.Controls.Add(this.hwndButton); this.Controls.Add(this.appButton); this.Controls.Add(this.appUserModelIdBox); @@ -142,6 +179,9 @@ private System.Windows.Forms.Button appButton; private System.Windows.Forms.Button hwndButton; private WatermarkTextBox appUserModelIdBox; + private System.Windows.Forms.TextBox helperLocationText; + private System.Windows.Forms.Button helperLocationButton; + private System.Windows.Forms.Label helperLocationLabel; } } diff --git a/ShortcutUtil/MainForm.cs b/ShortcutUtil/MainForm.cs index a336e63..2b71b0f 100755 --- a/ShortcutUtil/MainForm.cs +++ b/ShortcutUtil/MainForm.cs @@ -5,11 +5,15 @@ using System.Collections.Generic; using System.ComponentModel; using System.Data; +using System.Diagnostics; using System.Drawing; +using System.IO; using System.Linq; using System.Reflection; using System.Runtime.InteropServices; using System.Text; +using System.Text.Json; +using System.Text.RegularExpressions; using System.Threading.Tasks; using System.Windows.Forms; using Windows.ApplicationModel; @@ -43,12 +47,15 @@ private EntryListItem listLayout; + private HelperLocation helperLocation; + private bool designMode; - public MainForm(EntryList entryList, AppResolver appResolver) + public MainForm(EntryList entryList, AppResolver appResolver, HelperLocation helperLocation) { designMode = System.ComponentModel.LicenseManager.UsageMode == System.ComponentModel.LicenseUsageMode.Designtime; + this.helperLocation = helperLocation; InitializeComponent(); @@ -77,6 +84,30 @@ listLayout = new EntryListItem(entryListBox); + listLayout.TestButton.OnClick += ClickedTestButton; + + helperLocationText.Text = helperLocation.Location; + + UpdateHelperValidity(); + + } + + private void UpdateHelperValidity() + { + bool valid = helperLocation.Valid; + helperLocationText.ForeColor = valid ? SystemColors.ControlText : Color.Red; + createButton.Enabled = valid && entryList.Entries.Count > 0; + } + + private void ClickedTestButton(int index) + { + ProcessStartInfo startInfo = new ProcessStartInfo + { + + FileName = entryList.Entries[index].Target, + UseShellExecute = true + }; + Process.Start(startInfo); } private Dictionary, Icon> iconsByFileIndex = new Dictionary, Icon>(); @@ -295,5 +326,79 @@ hwndButton.Enabled = true; } + + public static string EncodeParameterArgument(string original) + { + if (string.IsNullOrEmpty(original)) + return original; + string value = Regex.Replace(original, @"(\\*)" + "\"", @"$1\$0"); + value = Regex.Replace(value, @"^(.*\s.*?)(\\*)$", "\"$1$2$2\"", RegexOptions.Singleline); + + return value; + } + + private void createButton_Click(object sender, EventArgs e) + { + if (helperLocation.Valid && entryList.Entries.Count > 0) + { + int index = entryListBox.SelectedIndex; + if (index < 0 || index >= entryList.Entries.Count) index = 0; + + SaveFileDialog sfd = new SaveFileDialog(); + sfd.InitialDirectory = Environment.CurrentDirectory; + sfd.Filter = "Shortcut (*.lnk)|*.lnk"; + sfd.Title = "Select output file"; + sfd.DefaultExt = "lnk"; + sfd.CheckPathExists = true; + sfd.CreatePrompt = false; + sfd.OverwritePrompt = true; + + DialogResult res = sfd.ShowDialog(); + + if (res == DialogResult.OK) + { + Entry selected = entryList.Entries[index]; + + ShellLink shellLink = new ShellLink(); + + shellLink.TargetPath = helperLocation.Location; + shellLink.Arguments = String.Join(" ", + new string[] + { + "-s", entryList.FilePath, "-i", "" + index, "-a", appUserModelIdBox.Text + }.Select(a => EncodeParameterArgument(a))); + shellLink.Description = selected.Description; + shellLink.IconLocation = new Tuple(selected.Icon, selected.IconIndex); + shellLink.WorkingDirectory = Path.GetDirectoryName(entryList.FilePath); + shellLink.AppUserModelID = appUserModelIdBox.Text; + + shellLink.Save(sfd.FileName); + } + } + } + + private void helperLocationText_TextChanged(object sender, EventArgs e) + { + helperLocation.Location = helperLocationText.Text; + UpdateHelperValidity(); + } + + private void helperLocationButton_Click(object sender, EventArgs e) + { + OpenFileDialog ofd = new OpenFileDialog(); + ofd.Filter = "Executables (*.exe)|*.exe"; + ofd.InitialDirectory = Path.GetDirectoryName(helperLocation.Location); + ofd.Title = "Select helper executable"; + ofd.DefaultExt = "exe"; + ofd.Multiselect = false; + ofd.CheckFileExists = true; + DialogResult result = ofd.ShowDialog(); + if (result == DialogResult.OK) + { + helperLocation.Location = ofd.FileName; + helperLocationText.Text = helperLocation.Location; + UpdateHelperValidity(); + } + } } } diff --git a/ShortcutUtil/Program.cs b/ShortcutUtil/Program.cs index a46ce5b..bc6eb5a 100755 --- a/ShortcutUtil/Program.cs +++ b/ShortcutUtil/Program.cs @@ -10,6 +10,24 @@ namespace ShortcutUtil { + public class HelperLocation + { + public string Location; + public bool Valid + { + get + { + return File.Exists(Location); + } + } + public HelperLocation(string fileName) + { + Location = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, fileName); + if (Valid) return; + + Location = Path.Combine(Environment.CurrentDirectory, fileName); + } + } static class Program { /// @@ -47,10 +65,12 @@ Environment.CurrentDirectory = Path.GetDirectoryName(Path.GetFullPath(args[1])); + HelperLocation location = new HelperLocation("JumpListUtil.exe"); + Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); - Application.Run(new MainForm(entryList, appResolver)); + Application.Run(new MainForm(entryList, appResolver, location)); } } } diff --git a/ShortcutUtil/ShortcutUtil.csproj b/ShortcutUtil/ShortcutUtil.csproj index 4dcb31a..6890dde 100755 --- a/ShortcutUtil/ShortcutUtil.csproj +++ b/ShortcutUtil/ShortcutUtil.csproj @@ -115,6 +115,9 @@ NativeHelpers.cs + + ShellLink.cs + UserControl @@ -188,7 +191,7 @@ This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - + - + \ No newline at end of file diff --git a/JumpListUtil/FodyWeavers.xml b/JumpListUtil/FodyWeavers.xml new file mode 100755 index 0000000..f00ec6d --- /dev/null +++ b/JumpListUtil/FodyWeavers.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/JumpListUtil/JumpListUtil.csproj b/JumpListUtil/JumpListUtil.csproj index 378d940..d722456 100755 --- a/JumpListUtil/JumpListUtil.csproj +++ b/JumpListUtil/JumpListUtil.csproj @@ -1,5 +1,6 @@  + Debug @@ -27,6 +28,8 @@ false false true + + AnyCPU @@ -70,6 +73,9 @@ true + + ..\packages\Costura.Fody.4.1.0\lib\net40\Costura.dll + ..\packages\Microsoft.Bcl.AsyncInterfaces.1.1.0\lib\net461\Microsoft.Bcl.AsyncInterfaces.dll @@ -159,5 +165,16 @@ false + + + + + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + \ No newline at end of file diff --git a/JumpListUtil/packages.config b/JumpListUtil/packages.config index abb0b89..2d77df4 100755 --- a/JumpListUtil/packages.config +++ b/JumpListUtil/packages.config @@ -1,5 +1,7 @@  + + diff --git a/ShellLink.cs b/ShellLink.cs index ba4d16d..73f3e58 100755 --- a/ShellLink.cs +++ b/ShellLink.cs @@ -113,7 +113,7 @@ // No limitation to length of buffer string in the case of Unicode though. StringBuilder description = new StringBuilder(NativeValues.INFOTIPSIZE); - NativeCalls.VerifySucceeded(shellLinkW.GetArguments(description, description.Capacity)); + NativeCalls.VerifySucceeded(shellLinkW.GetDescription(description, description.Capacity)); return description.ToString(); } @@ -123,6 +123,23 @@ } } + public string WorkingDirectory + { + get + { + // No limitation to length of buffer string in the case of Unicode though. + StringBuilder workingDirectory = new StringBuilder(NativeValues.INFOTIPSIZE); + + NativeCalls.VerifySucceeded(shellLinkW.GetWorkingDirectory(workingDirectory, workingDirectory.Capacity)); + + return workingDirectory.ToString(); + } + set + { + NativeCalls.VerifySucceeded(shellLinkW.SetWorkingDirectory(value)); + } + } + public Tuple IconLocation { get diff --git a/ShortcutUtil/ListBoxButton.cs b/ShortcutUtil/ListBoxButton.cs index e5f6b49..82da678 100755 --- a/ShortcutUtil/ListBoxButton.cs +++ b/ShortcutUtil/ListBoxButton.cs @@ -56,11 +56,22 @@ public int? IndexOver { get; private set; } + public Action OnClick; + public ListBoxControl(T control, ListBox listBox) { Control = control; this.listBox = listBox; listBox.MouseMove += ListBoxMouseMove; + listBox.Click += ListBoxClick; + } + + private void ListBoxClick(object sender, EventArgs e) + { + if (IndexOver.HasValue && OnClick != null) + { + OnClick(IndexOver.Value); + } } public Rectangle BoundsInList(int index) diff --git a/ShortcutUtil/MainForm.Designer.cs b/ShortcutUtil/MainForm.Designer.cs index 3f482fe..dee63e1 100755 --- a/ShortcutUtil/MainForm.Designer.cs +++ b/ShortcutUtil/MainForm.Designer.cs @@ -29,12 +29,15 @@ private void InitializeComponent() { this.defaultShortcutLabel = new System.Windows.Forms.Label(); - this.entryListBox = new ListBoxEx(); + this.entryListBox = new ShortcutUtil.ListBoxEx(); this.createButton = new System.Windows.Forms.Button(); this.appUserModelIdLabel = new System.Windows.Forms.Label(); this.appButton = new System.Windows.Forms.Button(); this.hwndButton = new System.Windows.Forms.Button(); this.appUserModelIdBox = new ShortcutUtil.WatermarkTextBox(); + this.helperLocationText = new System.Windows.Forms.TextBox(); + this.helperLocationButton = new System.Windows.Forms.Button(); + this.helperLocationLabel = new System.Windows.Forms.Label(); this.SuspendLayout(); // // defaultShortcutLabel @@ -55,7 +58,7 @@ this.entryListBox.FormattingEnabled = true; this.entryListBox.Location = new System.Drawing.Point(16, 98); this.entryListBox.Name = "entryListBox"; - this.entryListBox.Size = new System.Drawing.Size(770, 355); + this.entryListBox.Size = new System.Drawing.Size(770, 316); this.entryListBox.TabIndex = 1; this.entryListBox.DrawItem += new System.Windows.Forms.DrawItemEventHandler(this.entryListBox_DrawItem); this.entryListBox.MeasureItem += new System.Windows.Forms.MeasureItemEventHandler(this.entryListBox_MeasureItem); @@ -63,12 +66,13 @@ // createButton // this.createButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); - this.createButton.Location = new System.Drawing.Point(644, 458); + this.createButton.Location = new System.Drawing.Point(642, 424); this.createButton.Name = "createButton"; this.createButton.Size = new System.Drawing.Size(144, 40); this.createButton.TabIndex = 2; - this.createButton.Text = "Create Shortcut"; + this.createButton.Text = "&Create Shortcut"; this.createButton.UseVisualStyleBackColor = true; + this.createButton.Click += new System.EventHandler(this.createButton_Click); // // appUserModelIdLabel // @@ -77,7 +81,7 @@ this.appUserModelIdLabel.Name = "appUserModelIdLabel"; this.appUserModelIdLabel.Size = new System.Drawing.Size(213, 20); this.appUserModelIdLabel.TabIndex = 3; - this.appUserModelIdLabel.Text = "Shortcut App User Model ID:"; + this.appUserModelIdLabel.Text = "&Shortcut App User Model ID:"; // // appButton // @@ -86,7 +90,7 @@ this.appButton.Name = "appButton"; this.appButton.Size = new System.Drawing.Size(74, 31); this.appButton.TabIndex = 5; - this.appButton.Text = "APP"; + this.appButton.Text = "&APP"; this.appButton.UseVisualStyleBackColor = true; this.appButton.Click += new System.EventHandler(this.appButton_Click); // @@ -98,7 +102,7 @@ this.hwndButton.Name = "hwndButton"; this.hwndButton.Size = new System.Drawing.Size(76, 31); this.hwndButton.TabIndex = 6; - this.hwndButton.Text = "HWND"; + this.hwndButton.Text = "&HWND"; this.hwndButton.UseVisualStyleBackColor = true; this.hwndButton.Click += new System.EventHandler(this.hwndButton_Click); // @@ -113,12 +117,45 @@ this.appUserModelIdBox.WaterMarkColor = System.Drawing.Color.Gray; this.appUserModelIdBox.WaterMarkText = "Enter a manual ID, or select on from a UWP App or open Window"; // + // helperLocationText + // + this.helperLocationText.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.helperLocationText.Location = new System.Drawing.Point(79, 470); + this.helperLocationText.Name = "helperLocationText"; + this.helperLocationText.Size = new System.Drawing.Size(654, 26); + this.helperLocationText.TabIndex = 7; + this.helperLocationText.TextChanged += new System.EventHandler(this.helperLocationText_TextChanged); + // + // helperLocationButton + // + this.helperLocationButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.helperLocationButton.Location = new System.Drawing.Point(739, 470); + this.helperLocationButton.Name = "helperLocationButton"; + this.helperLocationButton.Size = new System.Drawing.Size(46, 31); + this.helperLocationButton.TabIndex = 8; + this.helperLocationButton.Text = "..."; + this.helperLocationButton.UseVisualStyleBackColor = true; + this.helperLocationButton.Click += new System.EventHandler(this.helperLocationButton_Click); + // + // helperLocationLabel + // + this.helperLocationLabel.AutoSize = true; + this.helperLocationLabel.Location = new System.Drawing.Point(13, 473); + this.helperLocationLabel.Name = "helperLocationLabel"; + this.helperLocationLabel.Size = new System.Drawing.Size(60, 20); + this.helperLocationLabel.TabIndex = 9; + this.helperLocationLabel.Text = "H&elper:"; + // // MainForm // this.AcceptButton = this.createButton; this.AutoScaleDimensions = new System.Drawing.SizeF(9F, 20F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.ClientSize = new System.Drawing.Size(800, 508); + this.Controls.Add(this.helperLocationLabel); + this.Controls.Add(this.helperLocationButton); + this.Controls.Add(this.helperLocationText); this.Controls.Add(this.hwndButton); this.Controls.Add(this.appButton); this.Controls.Add(this.appUserModelIdBox); @@ -142,6 +179,9 @@ private System.Windows.Forms.Button appButton; private System.Windows.Forms.Button hwndButton; private WatermarkTextBox appUserModelIdBox; + private System.Windows.Forms.TextBox helperLocationText; + private System.Windows.Forms.Button helperLocationButton; + private System.Windows.Forms.Label helperLocationLabel; } } diff --git a/ShortcutUtil/MainForm.cs b/ShortcutUtil/MainForm.cs index a336e63..2b71b0f 100755 --- a/ShortcutUtil/MainForm.cs +++ b/ShortcutUtil/MainForm.cs @@ -5,11 +5,15 @@ using System.Collections.Generic; using System.ComponentModel; using System.Data; +using System.Diagnostics; using System.Drawing; +using System.IO; using System.Linq; using System.Reflection; using System.Runtime.InteropServices; using System.Text; +using System.Text.Json; +using System.Text.RegularExpressions; using System.Threading.Tasks; using System.Windows.Forms; using Windows.ApplicationModel; @@ -43,12 +47,15 @@ private EntryListItem listLayout; + private HelperLocation helperLocation; + private bool designMode; - public MainForm(EntryList entryList, AppResolver appResolver) + public MainForm(EntryList entryList, AppResolver appResolver, HelperLocation helperLocation) { designMode = System.ComponentModel.LicenseManager.UsageMode == System.ComponentModel.LicenseUsageMode.Designtime; + this.helperLocation = helperLocation; InitializeComponent(); @@ -77,6 +84,30 @@ listLayout = new EntryListItem(entryListBox); + listLayout.TestButton.OnClick += ClickedTestButton; + + helperLocationText.Text = helperLocation.Location; + + UpdateHelperValidity(); + + } + + private void UpdateHelperValidity() + { + bool valid = helperLocation.Valid; + helperLocationText.ForeColor = valid ? SystemColors.ControlText : Color.Red; + createButton.Enabled = valid && entryList.Entries.Count > 0; + } + + private void ClickedTestButton(int index) + { + ProcessStartInfo startInfo = new ProcessStartInfo + { + + FileName = entryList.Entries[index].Target, + UseShellExecute = true + }; + Process.Start(startInfo); } private Dictionary, Icon> iconsByFileIndex = new Dictionary, Icon>(); @@ -295,5 +326,79 @@ hwndButton.Enabled = true; } + + public static string EncodeParameterArgument(string original) + { + if (string.IsNullOrEmpty(original)) + return original; + string value = Regex.Replace(original, @"(\\*)" + "\"", @"$1\$0"); + value = Regex.Replace(value, @"^(.*\s.*?)(\\*)$", "\"$1$2$2\"", RegexOptions.Singleline); + + return value; + } + + private void createButton_Click(object sender, EventArgs e) + { + if (helperLocation.Valid && entryList.Entries.Count > 0) + { + int index = entryListBox.SelectedIndex; + if (index < 0 || index >= entryList.Entries.Count) index = 0; + + SaveFileDialog sfd = new SaveFileDialog(); + sfd.InitialDirectory = Environment.CurrentDirectory; + sfd.Filter = "Shortcut (*.lnk)|*.lnk"; + sfd.Title = "Select output file"; + sfd.DefaultExt = "lnk"; + sfd.CheckPathExists = true; + sfd.CreatePrompt = false; + sfd.OverwritePrompt = true; + + DialogResult res = sfd.ShowDialog(); + + if (res == DialogResult.OK) + { + Entry selected = entryList.Entries[index]; + + ShellLink shellLink = new ShellLink(); + + shellLink.TargetPath = helperLocation.Location; + shellLink.Arguments = String.Join(" ", + new string[] + { + "-s", entryList.FilePath, "-i", "" + index, "-a", appUserModelIdBox.Text + }.Select(a => EncodeParameterArgument(a))); + shellLink.Description = selected.Description; + shellLink.IconLocation = new Tuple(selected.Icon, selected.IconIndex); + shellLink.WorkingDirectory = Path.GetDirectoryName(entryList.FilePath); + shellLink.AppUserModelID = appUserModelIdBox.Text; + + shellLink.Save(sfd.FileName); + } + } + } + + private void helperLocationText_TextChanged(object sender, EventArgs e) + { + helperLocation.Location = helperLocationText.Text; + UpdateHelperValidity(); + } + + private void helperLocationButton_Click(object sender, EventArgs e) + { + OpenFileDialog ofd = new OpenFileDialog(); + ofd.Filter = "Executables (*.exe)|*.exe"; + ofd.InitialDirectory = Path.GetDirectoryName(helperLocation.Location); + ofd.Title = "Select helper executable"; + ofd.DefaultExt = "exe"; + ofd.Multiselect = false; + ofd.CheckFileExists = true; + DialogResult result = ofd.ShowDialog(); + if (result == DialogResult.OK) + { + helperLocation.Location = ofd.FileName; + helperLocationText.Text = helperLocation.Location; + UpdateHelperValidity(); + } + } } } diff --git a/ShortcutUtil/Program.cs b/ShortcutUtil/Program.cs index a46ce5b..bc6eb5a 100755 --- a/ShortcutUtil/Program.cs +++ b/ShortcutUtil/Program.cs @@ -10,6 +10,24 @@ namespace ShortcutUtil { + public class HelperLocation + { + public string Location; + public bool Valid + { + get + { + return File.Exists(Location); + } + } + public HelperLocation(string fileName) + { + Location = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, fileName); + if (Valid) return; + + Location = Path.Combine(Environment.CurrentDirectory, fileName); + } + } static class Program { /// @@ -47,10 +65,12 @@ Environment.CurrentDirectory = Path.GetDirectoryName(Path.GetFullPath(args[1])); + HelperLocation location = new HelperLocation("JumpListUtil.exe"); + Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); - Application.Run(new MainForm(entryList, appResolver)); + Application.Run(new MainForm(entryList, appResolver, location)); } } } diff --git a/ShortcutUtil/ShortcutUtil.csproj b/ShortcutUtil/ShortcutUtil.csproj index 4dcb31a..6890dde 100755 --- a/ShortcutUtil/ShortcutUtil.csproj +++ b/ShortcutUtil/ShortcutUtil.csproj @@ -115,6 +115,9 @@ NativeHelpers.cs + + ShellLink.cs + UserControl @@ -188,7 +191,7 @@ This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - + - + \ No newline at end of file diff --git a/ShortcutUtil/packages.config b/ShortcutUtil/packages.config index 4aa3f58..9f84c27 100755 --- a/ShortcutUtil/packages.config +++ b/ShortcutUtil/packages.config @@ -1,7 +1,7 @@  - +