2017-05-26 33 views
5

Czy można skopiować coś do schowka przy użyciu .Net Core (w sposób niezależny od platformy)?.Net Core - skopiuj do schowka?

Wygląda na to, że brakuje klasy Clipboard, a P/Invoking nie jest opcją poza systemem Windows.

+0

jestem trochę zdezorientowany przez przypadek użycia tutaj. Zazwyczaj aplikacje .netcore to aplikacje internetowe lub aplikacje konsolowe.Żadne z nich nie ma sensu mieć integracji ze schowkiem (twój klient sieciowy byłby tym, który obsługuje kopiowanie/wklejanie, więc aby to zrobić, musiałbyś napisać javascript po stronie klienta). Jeśli piszesz aplikację UWP, najprawdopodobniej istnieje api schowka w UWP, ale nie jest to platforma krzyżowa. co dokładnie próbujesz "spiąć"? –

+1

W sposób agnostyczny platformy - nie. Można to oczywiście zrobić na różne sposoby związane z platformą i nie wszystkie wymagają P/Invoking. 'xsel' w systemie Linux,' pbcopy'/'pbpaste' w systemie Mac,' clip.exe' w systemie Windows umożliwiają proste wprowadzanie/wylogowywanie tekstu przy użyciu standardowego wejścia/wyjścia. Zgaduję, że działająca klasa 'Clipboard' dla wszystkich platform .NET Core nie jest wysoka na większości list priorytetów. Nie mówiąc już o czymś więcej niż prostym tekście, ponieważ jest to wysoce specyficzne dla platformy. –

+0

@ErikFunkenbusch W tym przypadku jest to aplikacja konsolowa i zwykły tekst. Zgadzam się, że istnieje lepsza droga, ale na to pytanie interesuje mnie tylko to, co jest możliwe. –

Odpowiedz

9

Schowek Brakuje klasy, nadzieja w niedalekiej przyszłości zostanie do tego dodana opcja. O ile to się dzieje ... możesz uruchomić natywne polecenie powłoki z ProcessStartInfo.

jestem noobem w Net Rdzenia, ale tworzyć ten kod do wysyłania i ciąg do schowka Windows i Mac:

Detection System operacyjny klasy

public static class OperatingSystem 
{ 
    public static bool IsWindows() => 
     RuntimeInformation.IsOSPlatform(OSPlatform.Windows); 

    public static bool IsMacOS() => 
     RuntimeInformation.IsOSPlatform(OSPlatform.OSX); 

    public static bool IsLinux() => 
     RuntimeInformation.IsOSPlatform(OSPlatform.Linux); 
} 

Shell Klasa
Based na https://loune.net/2017/06/running-shell-bash-commands-in-net-core/

public static class Shell 
{ 
    public static string Bash(this string cmd) 
    { 
     var escapedArgs = cmd.Replace("\"", "\\\""); 
     string result = Run("/bin/bash", $"-c \"{escapedArgs}\""); 
     return result; 
    } 

    public static string Bat(this string cmd) 
    { 
     var escapedArgs = cmd.Replace("\"", "\\\""); 
     string result = Run("cmd.exe", $"/c \"{escapedArgs}\""); 
     return result; 
    } 

    private static string Run (string filename, string arguments){ 
     var process = new Process() 
     { 
      StartInfo = new ProcessStartInfo 
      { 
       FileName = filename, 
       Arguments = arguments, 
       RedirectStandardOutput = true, 
       UseShellExecute = false, 
       CreateNoWindow = false, 
      } 
     }; 
     process.Start(); 
     string result = process.StandardOutput.ReadToEnd(); 
     process.WaitForExit(); 
     return result; 
    } 
} 

Schowek Klasa

public static class Clipboard 
{ 
    public static void Copy(string val) 
    { 
     if (OperatingSystem.IsWindows()) 
     { 
      $"echo {val} | clip".Bat(); 
     } 

     if (OperatingSystem.IsMacOS()) 
     { 
      $"echo \"{val}\" | pbcopy".Bash(); 
     } 
    } 
} 

wreszcie można nazwać kopiowanie do schowka i może uzyskać wartość w schowku.

var dirPath = @"C:\MyPath"; 
Clipboard.Copy(dirPath); 

Mam nadzieję, że pomoże to innym! Ulepszenia są mile widziane.

Pracuję w bibliotece ToolBox dla .net core z wszystkimi tymi rzeczami: https://github.com/deinsoftware/toolbox (dostępne również jako pakiet NuGet).

+0

Bardzo podoba mi się to ogólne rozwiązanie. Wydaje się, że nie działa on dla bardzo dużych fragmentów tekstu, ponieważ program cmd.exe nie akceptuje danych przekraczających określony rozmiar. Wszelkie pomysły na inny sposób, aby coś dostać do schowka systemu Windows? –

1

ponieważ nie mogę jeszcze polecić, i pisać to jako odpowiedź, ale w rzeczywistości jest to tylko wzmocnienie Rozwiązanie Equiman za:

Jego rozwiązanie działa świetnie, ale nie dla multi-line tekstów

działa ze zmodyfikowaną metodą kopiuj i tymczasowego pliku, aby pomieścić wszystkie wiersze tekstu:

public static void Copy(string val) 
{ 
    string[] lines = val.Split('\n'); 
    if (lines.Length == 0) 
     $"echo {val} | clip".Bat(); 
    else 
    { 
     StringBuilder output = new StringBuilder(); 

     foreach(string line in lines) 
     { 
      string text = line.Trim(); 
      if (!string.IsNullOrWhiteSpace(text)) 
      { 
       output.AppendLine(text); 
      } 
     } 

     string tempFile = @"D:\tempClipboard.txt"; 

     File.WriteAllText(tempFile, output.ToString()); 
     $"type { tempFile } | clip".Bat(); 

    } 
} 

Uwaga: możesz poprawić kod, aby nie użyć stałego plik tymczasowy jak w moim przykładzie, lub zmodyfikować ścieżkę .

To rozwiązanie działa w systemie Windows, ale nie ma pewności co do systemu Mac/Linux itp., Ale zasada powinna dotyczyć również innych systemów. O ile pamiętam, może być konieczne zastąpienie "type" przez "cat" w Linuksie.

Ponieważ moje rozwiązanie musi działać tylko w systemie Windows, nie badałem dalej.

Jeśli używasz kodu jak wyżej dla Windows, Ścieżka do pliku tymczasowego nie powinna zawierać spacji!

Jeśli chcesz zachować puste linie w schowku Kopiuj, a także, należy usunąć zaznaczenie dla „string.IsNullOrWhiteSpace”

Powiązane problemy