SQLを生成して文字列変数に格納する.NET4.0コンソールアプリケーションがあります。この文字列をクリップボードに直接コピーしたい。
これまでのところ、私の調査によると、これを実行できる唯一の方法は、System.Windows.Formsへの参照を追加することです。コンソールアプリケーションに関係のないアセンブリへの参照を追加したくありません。
私たちが現在存在しているユニバース内に、System.Windows.Formsへの参照や、目的が必要最低限のコンソールアプリケーション?
SQLを生成して文字列変数に格納する.NET4.0コンソールアプリケーションがあります。この文字列をクリップボードに直接コピーしたい。
これまでのところ、私の調査によると、これを実行できる唯一の方法は、System.Windows.Formsへの参照を追加することです。コンソールアプリケーションに関係のないアセンブリへの参照を追加したくありません。
私たちが現在存在しているユニバース内に、System.Windows.Formsへの参照や、目的が必要最低限のコンソールアプリケーション?
クリップボードAPIを呼び出すプラットフォームが可能な解決策です。例:
using System.Runtime.InteropServices;
class Program
{
[DllImport("user32.dll")]
internal static extern bool OpenClipboard(IntPtr hWndNewOwner);
[DllImport("user32.dll")]
internal static extern bool CloseClipboard();
[DllImport("user32.dll")]
internal static extern bool SetClipboardData(uint uFormat, IntPtr data);
[STAThread]
static void Main(string[] args)
{
OpenClipboard(IntPtr.Zero);
var yourString = "Hello World!";
var ptr = Marshal.StringToHGlobalUni(yourString);
SetClipboardData(13, ptr);
CloseClipboard();
Marshal.FreeHGlobal(ptr);
}
}
これは単なる例です。P / Invoke関数の戻り値をチェックするなど、コードの周りに少しエラー処理を追加すると、良い追加になります。
SetClipboardData
面白いビットです。また、クリップボードも必ず開閉する必要があります。
最初の13
引数として渡されるのはデータ形式です。13はUnicode文字列を意味します。
このMarshal.StringToHGlobalUni
関数は、実際には に不適切な方法でメモリを割り当てますSetClipboardData (using LocalAlloc with LMEM_FIXED)
。これにより、クラッシュが発生する可能性があります (メソッド名が指定されているとは思わないでしょうが、ReSharperを使用するなどしてコードにステップインすると、これが明らかになります)。
SetClipboardData
ドキュメントに従って必要です: GlobalAlloc
MSDNのSetClipboardData。GMEM_MOVABLE
以下は、MIT ライセンスの System.Windows.Forms の代替で、テスト済みでエラー処理が完了しています: Clippy
(コード自体をプッシュするクリップボードは、Clippy.csにあります。)