10 Commits

Author SHA1 Message Date
Jed Laundry
c5e9ab752a Fix F8 hotkey not respecting Enter option
The Typer._typeEnter property was not being updated, because the LowLevelKeyboardListener was creating it's own instance, without reading settings
2025-04-06 10:05:07 +12:00
Jed Laundry
0722af4b74 v1.4.0: Add option to type newlines 2022-06-25 17:31:17 +12:00
Jed Laundry
34fed5e5ba Add files via upload 2021-10-05 12:36:30 +13:00
Jed Laundry
f3cc28e379 Delete screenshot.png 2021-10-05 12:36:18 +13:00
Jed Laundry
2a714f8bef Add files via upload 2021-10-05 12:35:51 +13:00
Jed Laundry
66029e7b3a Update README.md 2021-10-05 12:35:41 +13:00
Jed Laundry
741821c2a3 Add files via upload 2021-10-05 12:33:58 +13:00
Jed Laundry
154a7fd63e update for 1.3.8 2021-08-18 10:15:39 +12:00
Jed Laundry
264ba03421 Update 1.3.7.0
Add macro text box, allow minimizing
2021-08-14 12:44:11 +12:00
Jed Laundry
60e7804aba Create README.md 2020-09-16 16:50:57 +12:00
15 changed files with 205 additions and 60 deletions

14
README.md Normal file
View File

@@ -0,0 +1,14 @@
# TypeClipboard
For IT professionals everywhere who are sick of typing long complex passwords into remote consoles. Just copy the password into your clipboard, select the password box, and press F8 or click Type!
![Screenshot of Type Clipboard](/screenshot.png)
(Doesn't have to be a password either, also useful for URLs, Base64-encoded things, etc.)
Also, if you don't want to compile yourself, this is also available in the Windows Store:
https://www.microsoft.com/en-us/p/type-clipboard/9p5r4jk7r8h5
Tested with a wide variety of consoles, including vSphere, Horizon (HTML5), and Citrix. There is a known issue where VMWare Horizon's client seems to be using a very low-level keyboard driver, so it doesn't work with it. Sorry.

View File

@@ -13,6 +13,9 @@
<setting name="enableHotkey" serializeAs="String">
<value>False</value>
</setting>
<setting name="enableEnter" serializeAs="String">
<value>False</value>
</setting>
</TypeClipboard.Properties.Settings>
</userSettings>
</configuration>

View File

@@ -28,9 +28,15 @@
/// </summary>
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
this.textBox1 = new System.Windows.Forms.TextBox();
this.button1 = new System.Windows.Forms.Button();
this.chkHotkey = new System.Windows.Forms.CheckBox();
this.button2 = new System.Windows.Forms.Button();
this.textBox2 = new System.Windows.Forms.TextBox();
this.button3 = new System.Windows.Forms.Button();
this.chkEnter = new System.Windows.Forms.CheckBox();
this.toolTip1 = new System.Windows.Forms.ToolTip(this.components);
this.SuspendLayout();
//
// textBox1
@@ -55,27 +61,77 @@
// chkHotkey
//
this.chkHotkey.AutoSize = true;
this.chkHotkey.Location = new System.Drawing.Point(12, 41);
this.chkHotkey.Location = new System.Drawing.Point(172, 42);
this.chkHotkey.Name = "chkHotkey";
this.chkHotkey.Size = new System.Drawing.Size(109, 17);
this.chkHotkey.Size = new System.Drawing.Size(73, 17);
this.chkHotkey.TabIndex = 2;
this.chkHotkey.Text = "Enable F8 hotkey";
this.chkHotkey.Text = "F8 hotkey";
this.toolTip1.SetToolTip(this.chkHotkey, "Enables the F8 hotkey");
this.chkHotkey.UseVisualStyleBackColor = true;
this.chkHotkey.CheckedChanged += new System.EventHandler(this.chkHotkey_CheckedChanged);
//
// button2
//
this.button2.Location = new System.Drawing.Point(219, 65);
this.button2.Name = "button2";
this.button2.Size = new System.Drawing.Size(103, 22);
this.button2.TabIndex = 4;
this.button2.Text = "Type (2s delay)";
this.button2.UseVisualStyleBackColor = true;
this.button2.Click += new System.EventHandler(this.button2_Click);
//
// textBox2
//
this.textBox2.Font = new System.Drawing.Font("Consolas", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.textBox2.Location = new System.Drawing.Point(12, 65);
this.textBox2.Name = "textBox2";
this.textBox2.ReadOnly = true;
this.textBox2.Size = new System.Drawing.Size(201, 22);
this.textBox2.TabIndex = 5;
//
// button3
//
this.button3.Location = new System.Drawing.Point(12, 39);
this.button3.Name = "button3";
this.button3.Size = new System.Drawing.Size(154, 22);
this.button3.TabIndex = 6;
this.button3.Text = "Copy clipboard to buffer";
this.button3.UseVisualStyleBackColor = true;
this.button3.Click += new System.EventHandler(this.button3_Click);
//
// chkEnter
//
this.chkEnter.AutoSize = true;
this.chkEnter.Location = new System.Drawing.Point(244, 42);
this.chkEnter.Name = "chkEnter";
this.chkEnter.Size = new System.Drawing.Size(78, 17);
this.chkEnter.TabIndex = 7;
this.chkEnter.Text = "Type Enter";
this.toolTip1.SetToolTip(this.chkEnter, "If set, Type will type newline (\\n) as Enter, which is useful for large blobs of " +
"text.\r\n\r\nIf unset, Type will stop before the first newline, which is useful for " +
"passwords.");
this.chkEnter.UseVisualStyleBackColor = true;
this.chkEnter.CheckedChanged += new System.EventHandler(this.chkEnter_CheckedChanged);
//
// toolTip1
//
this.toolTip1.ShowAlways = true;
//
// Form1
//
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;
this.ClientSize = new System.Drawing.Size(334, 66);
this.ClientSize = new System.Drawing.Size(334, 99);
this.Controls.Add(this.chkEnter);
this.Controls.Add(this.button3);
this.Controls.Add(this.textBox2);
this.Controls.Add(this.button2);
this.Controls.Add(this.chkHotkey);
this.Controls.Add(this.button1);
this.Controls.Add(this.textBox1);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
this.MaximizeBox = false;
this.MinimizeBox = false;
this.Name = "Form1";
this.ShowIcon = false;
this.ShowInTaskbar = false;
this.Text = "Type Clipboard";
this.TopMost = true;
this.Activated += new System.EventHandler(this.Form1_Activated);
@@ -93,6 +149,11 @@
private System.Windows.Forms.TextBox textBox1;
private System.Windows.Forms.Button button1;
private System.Windows.Forms.CheckBox chkHotkey;
private System.Windows.Forms.Button button2;
private System.Windows.Forms.TextBox textBox2;
private System.Windows.Forms.Button button3;
private System.Windows.Forms.CheckBox chkEnter;
private System.Windows.Forms.ToolTip toolTip1;
}
}

View File

@@ -89,11 +89,13 @@ namespace TypeClipboard
private void Form1_Load(object sender, EventArgs e)
{
_listener = new LowLevelKeyboardListener();
// Changing the Checked property also hooks the listener
_tc = new Typer();
_listener = new LowLevelKeyboardListener(_tc);
// Changing the chkHotkey.Checked property also hooks the listener
chkHotkey.Checked = Properties.Settings.Default.enableHotkey;
_tc = new Typer();
// Changing the chkEnter.Checked property also changes _tc.TypeEnter property
chkEnter.Checked = Properties.Settings.Default.enableEnter;
ClipboardNotification.ClipboardUpdate += delegate (object cb_sender, EventArgs cb_e) {
UpdateTextbox();
@@ -121,5 +123,23 @@ namespace TypeClipboard
Properties.Settings.Default.Save();
}
private void button2_Click(object sender, EventArgs e)
{
_tc.Type(textBox2.Text);
}
private void button3_Click(object sender, EventArgs e)
{
String clipboard = Clipboard.GetText(TextDataFormat.UnicodeText);
textBox2.Text = clipboard;
}
private void chkEnter_CheckedChanged(object sender, EventArgs e)
{
Properties.Settings.Default.enableEnter = chkEnter.Checked;
_tc.TypeEnter = chkEnter.Checked;
Properties.Settings.Default.Save();
}
}
}

View File

@@ -117,4 +117,13 @@
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<metadata name="toolTip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
<metadata name="toolTip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
<metadata name="toolTip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
</root>

View File

@@ -51,11 +51,12 @@ namespace TypeClipboard
private LowLevelKeyboardProc _proc;
private IntPtr _hookID = IntPtr.Zero;
private Typer _tc = new Typer();
public Typer _tc;
public LowLevelKeyboardListener()
public LowLevelKeyboardListener(Typer tc)
{
_proc = HookCallback;
_tc = tc;
}
public void HookKeyboard()

View File

@@ -10,7 +10,7 @@ using System.Runtime.InteropServices;
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Jed Laundry")]
[assembly: AssemblyProduct("Type Clipboard")]
[assembly: AssemblyCopyright("Copyright © Jed Laundry, 2020")]
[assembly: AssemblyCopyright("Copyright © Jed Laundry, 2022")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
@@ -32,5 +32,5 @@ using System.Runtime.InteropServices;
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.3.6.0")]
[assembly: AssemblyFileVersion("1.3.6.0")]
[assembly: AssemblyVersion("1.4.0.0")]
[assembly: AssemblyFileVersion("1.4.0.0")]

View File

@@ -12,7 +12,7 @@ namespace TypeClipboard.Properties {
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "16.5.0.0")]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.2.0.0")]
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
@@ -34,5 +34,17 @@ namespace TypeClipboard.Properties {
this["enableHotkey"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("False")]
public bool enableEnter {
get {
return ((bool)(this["enableEnter"]));
}
set {
this["enableEnter"] = value;
}
}
}
}

View File

@@ -5,5 +5,8 @@
<Setting Name="enableHotkey" Type="System.Boolean" Scope="User">
<Value Profile="(Default)">False</Value>
</Setting>
<Setting Name="enableEnter" Type="System.Boolean" Scope="User">
<Value Profile="(Default)">False</Value>
</Setting>
</Settings>
</SettingsFile>

View File

@@ -25,7 +25,7 @@
<UpdateRequired>false</UpdateRequired>
<MapFileExtensions>true</MapFileExtensions>
<ApplicationRevision>0</ApplicationRevision>
<ApplicationVersion>1.1.0.%2a</ApplicationVersion>
<ApplicationVersion>1.4.0.%2a</ApplicationVersion>
<UseApplicationTrust>false</UseApplicationTrust>
<BootstrapperEnabled>true</BootstrapperEnabled>
</PropertyGroup>

View File

@@ -12,52 +12,74 @@ namespace TypeClipboard
{
private const int INTERKEY_DELAY = 20;
private bool _typeEnter = false;
public bool TypeEnter { get => _typeEnter; set => _typeEnter = value; }
public void Type(String str, int delay = 2000)
{
Thread.Sleep(delay);
foreach (Char c in str.ToCharArray())
{
// Some characters have special meaning
// https://docs.microsoft.com/en-us/office/vba/language/reference/user-interface-help/sendkeys-statement
switch (c)
{
case '\n':
if (_typeEnter)
{
SendKeys.Send("{ENTER}");
break;
} else
{
return;
}
case '\r':
if (_typeEnter)
{
break;
}
else
{
return;
}
case '{':
SendKeys.Send("{{}");
break;
case '}':
SendKeys.Send("{}}");
break;
case '+':
SendKeys.Send("{+}");
break;
case '^':
SendKeys.Send("{^}");
break;
case '%':
SendKeys.Send("{%}");
break;
case '~':
SendKeys.Send("{~}");
break;
case '(':
SendKeys.Send("{(}");
break;
case ')':
SendKeys.Send("{)}");
break;
default:
SendKeys.Send(c.ToString());
break;
}
Thread.Sleep(INTERKEY_DELAY);
}
}
public void TypeClipboard(int delay = 2000)
{
if (Clipboard.ContainsText(TextDataFormat.UnicodeText))
{
String clipboard = Clipboard.GetText(TextDataFormat.UnicodeText);
Thread.Sleep(delay);
foreach (Char c in clipboard.ToCharArray())
{
// Some characters have special meaning
// https://docs.microsoft.com/en-us/office/vba/language/reference/user-interface-help/sendkeys-statement
switch (c)
{
case '\n':
return;
case '\r':
return;
case '{':
SendKeys.Send("{{}");
break;
case '}':
SendKeys.Send("{}}");
break;
case '+':
SendKeys.Send("{+}");
break;
case '^':
SendKeys.Send("{^}");
break;
case '%':
SendKeys.Send("{%}");
break;
case '~':
SendKeys.Send("{~}");
break;
case '(':
SendKeys.Send("{(}");
break;
case ')':
SendKeys.Send("{)}");
break;
default:
SendKeys.Send(c.ToString());
break;
}
Thread.Sleep(INTERKEY_DELAY);
}
this.Type(clipboard, delay);
}
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 11 KiB

View File

@@ -9,7 +9,7 @@
<Identity
Name="3373JedLaundry.TypeClipboard"
Publisher="CN=CE320BA0-58BC-4F47-AF5B-94DB661147CC"
Version="1.3.5.0" />
Version="1.4.0.0" />
<Properties>
<DisplayName>TypeClipboard</DisplayName>

View File

@@ -63,7 +63,8 @@
<AppxBundlePlatforms>neutral</AppxBundlePlatforms>
<AppInstallerUri>C:\temp</AppInstallerUri>
<HoursBetweenUpdateChecks>0</HoursBetweenUpdateChecks>
<PackageCertificateThumbprint>F1AC865F3B57360B33C17D9B7ECE4A4BFD2EC9CC</PackageCertificateThumbprint>
<PackageCertificateThumbprint>0AF17626AE23A8AA61789F56A539111877550E76</PackageCertificateThumbprint>
<PackageCertificateKeyFile>TypeClipboardAppx_TemporaryKey.pfx</PackageCertificateKeyFile>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<AppxBundle>Always</AppxBundle>
@@ -109,7 +110,6 @@
<Content Include="Images\StoreLogo.png" />
<Content Include="Images\Wide310x150Logo.scale-200.png" />
<None Include="Package.StoreAssociation.xml" />
<None Include="TypeClipboardAppx_TemporaryKey.pfx" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\TypeClipboard\TypeClipboard.csproj" />

BIN
screenshot.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.1 KiB