Added *some* clipboard commands.
This commit is contained in:
parent
b89a076a14
commit
ca71367f9c
@ -8,5 +8,7 @@ global using System.IO;
|
|||||||
global using System.IO.Compression;
|
global using System.IO.Compression;
|
||||||
global using System.Linq;
|
global using System.Linq;
|
||||||
global using System.Reflection;
|
global using System.Reflection;
|
||||||
|
global using System.Runtime.InteropServices;
|
||||||
|
global using System.Text;
|
||||||
global using System.Threading;
|
global using System.Threading;
|
||||||
global using static SrcMod.Shell.Tools;
|
global using static SrcMod.Shell.Tools;
|
||||||
|
|||||||
11
SrcMod/Shell/Interop/Kernel32.cs
Normal file
11
SrcMod/Shell/Interop/Kernel32.cs
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
namespace SrcMod.Shell.Interop;
|
||||||
|
|
||||||
|
internal static partial class Kernel32
|
||||||
|
{
|
||||||
|
[LibraryImport("kernel32.dll", SetLastError = true)]
|
||||||
|
public static partial uint GetFinalPathNameByHandleA(nint hFile, [MarshalAs(UnmanagedType.LPTStr)] string lpszFilePath,
|
||||||
|
uint cchFilePath, uint dwFlags);
|
||||||
|
|
||||||
|
[LibraryImport("kernel32.dll")]
|
||||||
|
public static partial nuint GlobalSize(nint hPtr);
|
||||||
|
}
|
||||||
29
SrcMod/Shell/Interop/User32.cs
Normal file
29
SrcMod/Shell/Interop/User32.cs
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
namespace SrcMod.Shell.Interop;
|
||||||
|
|
||||||
|
internal static partial class User32
|
||||||
|
{
|
||||||
|
[LibraryImport("user32.dll")]
|
||||||
|
[return: MarshalAs(UnmanagedType.Bool)]
|
||||||
|
public static partial bool CloseClipboard();
|
||||||
|
|
||||||
|
[LibraryImport("user32.dll")]
|
||||||
|
public static partial uint EnumClipboardFormats(uint uFormat);
|
||||||
|
|
||||||
|
[LibraryImport("user32.dll")]
|
||||||
|
public static partial nint GetClipboardData(uint uFormat);
|
||||||
|
|
||||||
|
[LibraryImport("user32.dll")]
|
||||||
|
[return: MarshalAs(UnmanagedType.Bool)]
|
||||||
|
public static partial bool IsClipboardFormatAvailable(uint uFormat);
|
||||||
|
|
||||||
|
[LibraryImport("user32.dll")]
|
||||||
|
[return: MarshalAs(UnmanagedType.Bool)]
|
||||||
|
public static partial bool OpenClipboard(nint hWndNewOwner);
|
||||||
|
|
||||||
|
[LibraryImport("user32.dll")]
|
||||||
|
[return: MarshalAs(UnmanagedType.Bool)]
|
||||||
|
public static partial bool EmptyClipboard();
|
||||||
|
|
||||||
|
[LibraryImport("user32.dll")]
|
||||||
|
public static partial nint SetClipboardData(uint uFormat, nint hMem);
|
||||||
|
}
|
||||||
112
SrcMod/Shell/Modules/ClipboardModule.cs
Normal file
112
SrcMod/Shell/Modules/ClipboardModule.cs
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
using SrcMod.Shell.Interop;
|
||||||
|
|
||||||
|
namespace SrcMod.Shell.Modules;
|
||||||
|
|
||||||
|
[Module("clipboard")]
|
||||||
|
public static class ClipboardModule
|
||||||
|
{
|
||||||
|
[Command("clear")]
|
||||||
|
public static void ClearClipboard()
|
||||||
|
{
|
||||||
|
if (!ValidateUnsafe()) return;
|
||||||
|
|
||||||
|
User32.OpenClipboard(0);
|
||||||
|
User32.EmptyClipboard();
|
||||||
|
User32.CloseClipboard();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Command("copy")]
|
||||||
|
public static void CopyClipboard(string text)
|
||||||
|
{
|
||||||
|
const uint format = 1;
|
||||||
|
|
||||||
|
if (!ValidateUnsafe()) return;
|
||||||
|
|
||||||
|
if (!text.EndsWith("\0")) text += "\0";
|
||||||
|
byte[] data = Encoding.Default.GetBytes(text);
|
||||||
|
|
||||||
|
nint hGlobal = Marshal.AllocHGlobal(data.Length + 1);
|
||||||
|
Marshal.Copy(data, 0, hGlobal, data.Length);
|
||||||
|
|
||||||
|
User32.OpenClipboard(0);
|
||||||
|
User32.EmptyClipboard();
|
||||||
|
|
||||||
|
User32.SetClipboardData(format, hGlobal);
|
||||||
|
|
||||||
|
User32.CloseClipboard();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Command("view")]
|
||||||
|
public static void ViewClipboard()
|
||||||
|
{
|
||||||
|
// TODO (maybe): Make this support other formats?
|
||||||
|
// I spent way too long trying to make that a reality
|
||||||
|
// but the whole "clipboard format" thing is a nightmare.
|
||||||
|
|
||||||
|
if (!ValidateUnsafe()) return;
|
||||||
|
|
||||||
|
User32.OpenClipboard(0);
|
||||||
|
|
||||||
|
nint hClipboard;
|
||||||
|
uint format;
|
||||||
|
if (User32.IsClipboardFormatAvailable(format = (uint)ClipboardFormat.DspText) ||
|
||||||
|
User32.IsClipboardFormatAvailable(format = (uint)ClipboardFormat.OemText) ||
|
||||||
|
User32.IsClipboardFormatAvailable(format = (uint)ClipboardFormat.Text) ||
|
||||||
|
User32.IsClipboardFormatAvailable(format = (uint)ClipboardFormat.UnicodeText))
|
||||||
|
hClipboard = User32.GetClipboardData(format);
|
||||||
|
else throw new("Clipboard doesn't contain text data.");
|
||||||
|
|
||||||
|
nuint length = Kernel32.GlobalSize(hClipboard);
|
||||||
|
byte[] data = new byte[length];
|
||||||
|
|
||||||
|
Marshal.Copy(hClipboard, data, 0, (int)length);
|
||||||
|
|
||||||
|
User32.CloseClipboard();
|
||||||
|
|
||||||
|
string msg = (ClipboardFormat)format switch
|
||||||
|
{
|
||||||
|
ClipboardFormat.DspText or ClipboardFormat.OemText or ClipboardFormat.Text =>
|
||||||
|
Encoding.UTF8.GetString(data),
|
||||||
|
ClipboardFormat.UnicodeText => Encoding.Unicode.GetString(data),
|
||||||
|
_ => throw new("Unknown text format.")
|
||||||
|
};
|
||||||
|
|
||||||
|
Write(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum ClipboardFormat
|
||||||
|
{
|
||||||
|
Biff5 = 49988,
|
||||||
|
Biff8 = 49986,
|
||||||
|
Biff12 = 50009,
|
||||||
|
Bitmap = 2,
|
||||||
|
Csv = 49989,
|
||||||
|
DataObject = 49161,
|
||||||
|
Dib = 8,
|
||||||
|
Dif = 5,
|
||||||
|
DspText = 129,
|
||||||
|
EmbedSource = 49163,
|
||||||
|
EnhancedMetafile = 14,
|
||||||
|
HandleDrop = 15,
|
||||||
|
HtmlFormat = 49381,
|
||||||
|
Hyperlink = 50006,
|
||||||
|
Link = 49985,
|
||||||
|
LinkSource = 49165,
|
||||||
|
LinkSourceDescriptor = 49167,
|
||||||
|
Locale = 16,
|
||||||
|
Max = 17,
|
||||||
|
MetafilePicture = 3,
|
||||||
|
Native = 49156,
|
||||||
|
ObjectDescriptor = 49166,
|
||||||
|
ObjectLink = 49154,
|
||||||
|
OemText = 7,
|
||||||
|
OlePrivateData = 49171,
|
||||||
|
OwnerLink = 49155,
|
||||||
|
Palette = 9,
|
||||||
|
RichTextFormat = 49308,
|
||||||
|
SYLK = 4,
|
||||||
|
Text = 1,
|
||||||
|
UnicodeText = 13,
|
||||||
|
XmlSpreadSheet = 50007
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -12,6 +12,7 @@
|
|||||||
<Authors>That_One_Nerd</Authors>
|
<Authors>That_One_Nerd</Authors>
|
||||||
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
|
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
|
||||||
<ApplicationIcon>Logo.ico</ApplicationIcon>
|
<ApplicationIcon>Logo.ico</ApplicationIcon>
|
||||||
|
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
||||||
|
|||||||
@ -1,4 +1,6 @@
|
|||||||
namespace SrcMod.Shell;
|
using System.Text;
|
||||||
|
|
||||||
|
namespace SrcMod.Shell;
|
||||||
|
|
||||||
public static class Tools
|
public static class Tools
|
||||||
{
|
{
|
||||||
@ -137,4 +139,18 @@ public static class Tools
|
|||||||
|
|
||||||
Console.ForegroundColor = prevCol;
|
Console.ForegroundColor = prevCol;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static bool ValidateUnsafe()
|
||||||
|
{
|
||||||
|
Write("You are about to execute an unsafe command.\nProceed? > ", ConsoleColor.DarkYellow, false);
|
||||||
|
|
||||||
|
Console.ForegroundColor = ConsoleColor.Yellow;
|
||||||
|
Console.CursorVisible = true;
|
||||||
|
string result = Console.ReadLine()!.Trim().ToLower();
|
||||||
|
Console.CursorVisible = false;
|
||||||
|
Console.ResetColor();
|
||||||
|
|
||||||
|
return result == "y" || result == "yes" || result == "t" ||
|
||||||
|
result == "true" || result == "p" || result == "proceed";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user