Wie kann ich die Konsolenausgabe direkt an Notepad leiten?


47

Ich führe eine Anwendung über die Eingabeaufforderung oder eine Git- Shell aus und möchte die Ausgabe in den Editor übertragen, um sie später leichter überprüfen und bearbeiten zu können.

Ich habe Folgendes versucht, erhalte aber immer eine leere Instanz von Notepad:

diff file1.txt file2.txt | notepad

Mir ist bekannt, dass ich die Ausgabe in eine andere Datei umleiten und die Datei dann im Editor öffnen kann. Ich möchte den zusätzlichen Schritt vermeiden, da ich es nur gewohnt bin, auf Nicht-Windows-Systemen auf Vim oder weniger zuzugreifen.


2
Natürlich können Sie auch moreunter Windows eine Pipe-Funktion verwenden .
Gabe

1
Warum nicht in eine Datei umleiten und einfach den neuen Dateipfad ausführen - das Betriebssystem übernimmt die Präsentationsanwendung. Hat es hat Notizblock sein?
Gusdor

@Gusdor Bei der Frage geht es hauptsächlich darum, das Erstellen einer (temporären) Datei zu vermeiden.
Der Hochstapler

1
Die Funktionalität von Notepad ist so eingeschränkt, dass Sie kaum etwas damit anfangen können. vimWarum nicht einfach installieren, da Sie mit vertraut sind ?
Siyuan Ren

@CR Ich könnte das auf meinen eigenen Computern machen, aber ich arbeite regelmäßig auf Computern, die ich nicht besitze. Daher ist es hilfreich zu wissen, welche Optionen es gibt, ohne Software von Drittanbietern zu installieren.
Der Hochstapler

Antworten:


63

Soweit ich das beurteilen kann, gibt es keine Möglichkeit, direkt in Notepad weiterzuleiten.

Sie können jedoch Rohr in clipund dann fügen Sie ihn in Notepad, etwa so:

 diff file1.txt file2.txt | clip && notepad

Dann drücken Sie einfach Ctrl+ Vim Editor.


3
Würde es funktionieren, wenn Sie die Ausgabe nach file3.txt umleiten würden und dann && notepad file3.txt?
Konerak

4
@Konerak Ja, das würde funktionieren und genau das habe ich versucht zu vermeiden (wie in der Frage erklärt);)
Der Hochstapler

32

Ziehen Sie in Betracht, Vim oder in Ihrem Fall gVim zu verwenden, wenn Sie eine grafische Umgebung bevorzugen.

Anschließend können Sie einen einzelnen Bindestrich als Argument eingeben, der Vim / gVim anweist, von der Standardeingabe zu lesen.

diff file1.txt file2.txt | gvim -

1
installiere es, Notepad ist wirklich limitiert, du kannst es dafür nicht benutzen. Sie können es sogar in tragbaren Apps haben: portableapps.com/apps/development/gvim_portable
higuita

3
Kann dies auch von vim aus tun::%!diff file1.txt file2.txt
SlightlyCuban

@TankorSmash Das tue ich auch, aber das ist nicht der Punkt der Frage;) Für weitere Pro und Contra-Diskussionen bezüglich vim (oder eines anderen Themas) finde ich mich im Super User Chat . Kommentarthreads sind keine großartige Möglichkeit, ein Gespräch zu führen :(
Der Hochstapler

1
@OliverSalzburg Ich habe versucht vorzuschlagen, dass gvim unter Windows verfügbar ist, da ich Ihren Kommentar als falsch verstanden habe. Ich lag falsch.
TankorSmash

-wird oft als "read from stdin" bezeichnet, daher ist dies nicht streng auf "read from stdin" beschränkt vim. Andere Editoren verwenden -i(zB kate).
Bakuriu

8

Hier ist ein kurzes Windows-Programm, das es richtig macht (ohne die Zwischenablage zu überladen). Es sollte an PowerShell anpassbar sein, und ich könnte diese Antwort aktualisieren, wenn ich die Zeit dazu habe, aber Sie können das Programm auch direkt verwenden.

Wie wäre es mit PowerShell? Keine Notwendigkeit, eine andere Anwendung zu installieren. Leider haben Sie werden benötigen eine Skriptdatei irgendwo in Ihrem erstellen PATH...

Kurze Version, die Sie verwenden können

Wenn Sie eine Batch-Datei (z. B. ShowInNotepad.bat) mit folgendem Inhalt erstellen und an einem beliebigen Ort PATHablegen:

@echo off
clip
powershell -Command $process = Start-Process -PassThru notepad;$SW_SHOW = 5;$sig = '[DllImport("""user32.dll""")] public static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);';Add-Type -MemberDefinition $sig -name NativeMethods -namespace Win32;[Win32.NativeMethods]::ShowWindow($process.Id, $SW_SHOW) ^| Out-Null;Add-Type -AssemblyName System.Windows.Forms;[System.Windows.Forms.SendKeys]::SendWait('^^V');

Sie können dann einfach echo blah | ShowInNotepadvon überall anrufen !

Beachten Sie, dass dies voraussetzt , dass Sie eine neuere Version von Windows (Vista +) verwenden und PowerShell nicht deaktiviert oder das .NET Framework nicht deinstalliert haben. Mit anderen Worten, eine Windows-Standardinstallation wird funktionieren.


Ausführliche Erklärung und Alternativen

Der einfachste Weg, den ich mir vorstellen kann, ist die Automatisierung der Einfüge- ( Ctrl+ V) Aktion. Was zumindest eine andere Antwort bereits tut, aber diese AHK verwendet - Sie haben möglicherweise mehr Glück, wenn PowerShell in einer gesperrten Unternehmensumgebung funktioniert.

Fahren wir mit dem Drehbuch fort, ja?

#start notepad, get process object (to get pid later)
$process = Start-Process -PassThru notepad;

# activate Notepad window
# based on http://stackoverflow.com/a/4994020/1030702
# SW_SHOW activates and shows a window http://msdn.microsoft.com/en-us/library/windows/desktop/ms633548%28v=vs.85%29.aspx
$SW_SHOW = 5;
$sig = '[DllImport("user32.dll")] public static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);';
Add-Type -MemberDefinition $sig -name NativeMethods -namespace Win32;
[Win32.NativeMethods]::ShowWindow($process.Id, $SW_SHOW) | Out-Null;

# send a "Ctrl+V" keystroke to the active window
# from http://stackoverflow.com/a/17851491/1030702
Add-Type -AssemblyName System.Windows.Forms;
[System.Windows.Forms.SendKeys]::SendWait('^V');

Es ist ziemlich unkompliziert, daher werde ich das Skript nicht mehr erklären als die Kommentare, die es bereits tun.

Verwendungszweck

Um es zu verwenden, müssen Sie nur das Skript in eine .ps1Datei (z. B. ShowInNotepad.ps1) platzieren, es irgendwo in Ihrer PATHund dann aufrufen, powershell ShowInNotepad.ps1nachdem Sie den Text, den Sie in der Zwischenablage anzeigen möchten, platziert haben.

Beispiel:

echo blah | clip && powershell ShowInNotepad.ps1

Leider kann das Ausführen von PowerShell-Skripten manchmal schwierig sein (Ausführungsrichtlinien und alles). Aus diesem Grund habe ich dieses Skript zu einem Einzeiler zusammengefasst, den Sie direkt über die Eingabeaufforderung aufrufen oder in eine Batchdatei einfügen können:

powershell -Command $process = Start-Process -PassThru notepad;$SW_SHOW = 5;$sig = '[DllImport("""user32.dll""")] public static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);';Add-Type -MemberDefinition $sig -name NativeMethods -namespace Win32;[Win32.NativeMethods]::ShowWindow($process.Id, $SW_SHOW) ^| Out-Null;Add-Type -AssemblyName System.Windows.Forms;[System.Windows.Forms.SendKeys]::SendWait('^^V');

Wenn Sie eine Batch-Datei (z. B. ShowInNotepad.bat) mit folgendem Inhalt erstellen und an einem beliebigen Ort PATHablegen:

@echo off
clip
powershell -Command $process = Start-Process -PassThru notepad;$SW_SHOW = 5;$sig = '[DllImport("""user32.dll""")] public static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);';Add-Type -MemberDefinition $sig -name NativeMethods -namespace Win32;[Win32.NativeMethods]::ShowWindow($process.Id, $SW_SHOW) ^| Out-Null;Add-Type -AssemblyName System.Windows.Forms;[System.Windows.Forms.SendKeys]::SendWait('^^V');

Sie können dann einfach echo blah | ShowInNotepadvon überall anrufen !


Um ehrlich zu sein, wenn Sie ein PS-Skript schreiben möchten, würde ich einfach eine Datei mit einem Guid-Namen im temporären Dateiordner erstellen und sie löschen, wenn ich fertig bin. Die Automatisierung der Paste erscheint zu spröde (wie, wenn Sie den Fokus zum falschen Zeitpunkt verlieren oder so etwas)?
Casey

@emodendroket Leider ist nichts wirklich sauber, wenn Sie versuchen, Streaming-Eingaben in ein Programm zu erzwingen, das es nicht von Haus aus unterstützt. Das Erstellen einer temporären Datei hat seine eigenen (geringfügigen) Nachteile: Sie erhalten eigentlich keine "neue Datei", daher sind die Saveund das Beenden bei geändertem Verhalten unterschiedlich. Abgesehen davon, dass Sie Notepad nicht selbst ersetzen oder den Text direkt in das Bearbeitungssteuerelement einfügen müssen, gibt es nicht viele andere Optionen. Natürlich hat diese Methode den Nachteil, dass die Inhalte der Zwischenablage gelöscht werden (obwohl diese ohnehin kurzlebig sein sollen). Ich denke nicht, dass es ein großes Problem ist, den Fokus zu verlieren. Es ist ein ...
Bob

... extrem unwahrscheinlicher Rennzustand (zwischen dem ShowWindowund dem Senden von Tastenanschlägen). Und diese Methode erfordert ein bisschen mehr Setup (Erstellen der Skriptdatei), ja.
Bob

5

Wie wäre es mit AutoHotkey ?

Speichern Sie Folgendes als stdin.ahkund legen Sie es in Ihrem AutoHotkey-Verzeichnis ab:

StdIn(max_chars=0xfff)
{
    static hStdIn=-1
    ; The following is for vanilla compatibility
    ptrtype := (A_PtrSize = 8) ? "ptr" : "uint"

    if (hStdIn = -1)
    {
        hStdIn := DllCall("GetStdHandle", "UInt", -10,  ptrtype) ; -10=STD_INPUT_HANDLE
        if ErrorLevel
            return 0
    }

    max_chars := VarSetCapacity(text, max_chars*(!!A_IsUnicode+1), 0)

    ret := DllCall("ReadFile"
        ,  ptrtype, hStdIn        ; hFile
        ,  "Str", text          ; lpBuffer
        , "UInt", max_chars*(!!A_IsUnicode+1)     ; nNumberOfBytesToRead
        , "UInt*", bytesRead    ; lpNumberOfBytesRead
        ,  ptrtype, 0)            ; lpOverlapped

    return text
}

loop 
{
    sleep 100 ;wait for data
    Buffer:=StdIn()
    PipeText:=PipeText . Buffer
    IfWinActive Untitled - Notepad
        {
        SendInput {Raw}%PipeText%
        PipeText = 
        }
}

Dann die Kommandozeile:

ping -t www.google.com | AutoHotkeyA32.exe stdin.ahk

Leitet die Ausgabe des Befehls in den Editor, solange das Fenster geöffnet und mit einem Titel versehen ist Untitled - Notepad. Falls das Fenster nicht aktiv ist, puffert es fröhlich im Hintergrund, bis das Fenster aktiv ist. Sie können sogar zu einem anderen Programm wechseln und es wird erneut gepuffert.

Dies scheint zu sterben, wenn das Programm, das auf unsere Standardeingabe ausgegeben wird, stirbt ...

(Zur Information, der stdin () Code war von hier aus unverschämt einen halben Zoll entfernt )


...Beeindruckend. Wenn Sie so weit gehen, können Sie auch ein ganzes kompiliertes Programm schreiben! Wahrscheinlich auch effizienter: P Stimmen Sie der Anstrengung zu.
Bob

Ich habe Angst, von mir abstimmen zu müssen. Überarbeitung im klassischen Sinne. Wer kontrolliert die Version dieses Skripts? Benötigt autohotkey eine Lizenz für kommerzielle Anwendungen? Wer überwacht das?
Gusdor

7
@Gusdor Das gesamte Internet ist voll von nicht versionskontrollierten Codefragmenten. Wir haben den Vorteil, dass wir sogar einen Änderungsverlauf für diesen Beitrag haben. Ich sehe auch nicht, wie kommerzielle Lizenzen mit dieser Frage zu tun haben. Die AHK wird von vielen Menschen verwendet, und sie finden diese Antwort möglicherweise hilfreich.
Slhck

@slhck Ich habe nur auf die Fallstricke dieser Lösung hingewiesen, nicht auf ihre Gültigkeit.
Gusdor

@slhck: Der Inhalt dieser Website wird von Creative Commons abgedeckt.
Brian

4

Das ist durchaus möglich; Ich habe es einfach versucht. Ich gehe davon aus, dass Notepad standardmäßig zum Öffnen von txt-Dateien eingerichtet ist:

diff file1.txt file2.txt > output.txt && start output.txt && timeout /T 3 && del output.txt

OK, Sie erstellen technisch eine Datei, diese wird jedoch nicht gespeichert.

Eine weitere Option ist das Piping in mehr.


4
Seien Sie vorsichtig - wenn Sie bereits eine output.txthaben, wird dies zu Problemen führen. Etwas sicherer wäre zu bedienen %temp%/somerandomstring.txt.
Bob,

Es ist sicherer, eine Ausgabedatei im temporären Verzeichnis zu speichern - sehen Sie sich diese Antwort an.
Lu55

1

Hier ist ein hässlicher, aber effektiver Weg, um dies zu erreichen:

$OutputString = 'Hello World'
$WScript = New-Object -ComObject 'wscript.shell'
$WScript.Run('notepad.exe') | Out-Null
do 
    {
    Start-Sleep -Milliseconds 100
    }
until ($WScript.AppActivate('notepad'))
$WScript.SendKeys($OutputString)

Versenden Sie nur Textausgaben. Andere Daten werden möglicherweise als Steuerzeichen interpretiert (STRG, ALT, ENTF usw.).


0

Hier sind einige VBScript-basierte Lösungen, die möglicherweise funktionieren (obwohl sie sich ein wenig darauf verlassen, dass Apps rechtzeitig geöffnet werden):

pipe2key.vbs - öffnet die als erstes Argument angegebene Anwendung und sendet StdIn als Tastendruck an diese. Muss mit cscript.exe verwendet werden, da wscript keinen StdIn-Zugriff bietet. Wahrscheinlich ziemlich langsam für lange Dokumente - aber die Zwischenablage wird nicht überladen

Set inPipe=wScript.StdIn
Set wShell=wScript.CreateObject("wscript.shell")
wShell.Run wScript.Arguments(0), 5 ' Execute specified app, foreground it's window
wScript.Sleep 500 ' Wait for app to load
KeysToEscape="{}[]()^+%"
KeysToDrop=vbLf
While Not inPipe.AtEndOfStream
    keyChar=inPipe.Read(1)
    If InStr(KeysToDrop, keyChar) = 0 Then
        If InStr(KeysToEscape, keyChar) > 0 Then
            wShell.SendKeys "{" & keyChar & "}"
        Else
            wShell.SendKeys keyChar
        End If
    End If
Wend

Anwendungsbeispiel: diff file1.txt file2.txt | cscript pipe2key.vbs notepad.exe

Oder pasteinto.vbs. Automatisiert die STRG-V-Operation nach dem Start einer App (verwendet daher den Befehl 'clip', wie in den vorherigen Antworten erwähnt). Deutlich schneller und sauberer (meiner Meinung nach) als pipe2key.vbs, aber der Prozess wird die Zwischenablage überschreiben

Set wShell=wScript.CreateObject("wscript.shell")
wShell.Run wScript.Arguments(0), 5 ' Execute specified app, foreground it's window
wScript.Sleep 500 ' Wait for app to load
wShell.SendKeys "^v"

Anwendungsbeispiel: diff file1.txt file2.txt | clip && pasteinto notepad.exe


-1

So etwas "könnte" funktionieren.

Oh, du hast nicht gemerkt, dass du das jedes Mal manuell machen würdest (nach den Geräuschen). Möglicherweise können Sie jedes Mal ein Makro oder eine andere Methode erstellen, um den Vorgang zu beschleunigen. Da bin ich mir nicht sicher.

diff file1.txt file2.txt > file.txt | sleep 1 | notepad.exe file.txt | rm file.txt

Es müsste den Diff-Inhalt in die Datei file.txt schreiben, damit er die gesamte Diff-Operation lädt. Ich bin mir nicht sicher, ob dies der Fall ist. In diesem Fall gibt es möglicherweise eine Möglichkeit, zwischen den Pipe-Vorgängen eine Pause einzulegen.


5
Das Ziel ist es, keine temporäre Datei zu erstellen, und ich bin mir ziemlich sicher, dass Ihre Syntax dort nicht stimmt;)
Der Hochstapler

"Für eine einfachere Überprüfung und spätere Bearbeitung" Ich dachte, das ist, was Sie wollten? Und wie Rev1.0 hervorhob und anpasste, funktioniert es. Ich bin mir jedoch nicht sicher, ob Cygwin die gleichen Ergebnisse erzielen würde.
Codezilla

3
Ich denke, weil ein & angemessen wäre, da eigentlich nichts zwischen diesen Aufrufen "umgeleitet" werden muss.
Rev1.0

3
@ Rev1.0 Richtig. &, &&und ||sind Operatoren zum Verketten von Befehlen. Alle 3 verhalten sich unterschiedlich, wenn ein Befehl einen Rückgabewert ungleich 0 generiert. |ist ganz anders , wie es verwendet wird , Rohrausgang von einem Programm zum anderen. Das Ergebnis könnte das sein, was Sie wollten, aber die Verwendung eines der Verkettungsoperatoren macht die Absicht klarer, da in diesem Beispiel keine eigentliche Verrohrung gewünscht wird. Weitere Hinweise: microsoft.com/resources/documentation/windows/xp/all/proddocs/…
Der Hochstapler

1
@Codezilla Ich denke, die Idee in meinem Beitrag ist deiner ziemlich ähnlich, aber es ist eine gültige Syntax für die Eingabeaufforderung.
Casey

-3

Meine Sprache ist nicht Englisch, also entschuldige Fehler.

Ich denke, Sie können die Ausgabe nicht direkt in den geöffneten Editor stellen. Vielleicht irre ich mich. Sie müssen eine Datei mit der Ausgabe erstellen, um daran arbeiten zu können. Das Befehls-T-Stück kann die Ausgabe an zwei oder mehrere Befehle oder Dateien gleichzeitig leiten.

Mann Tee

Vergessen Sie nicht, >> stattdessen> zu verwenden, wenn Sie die Ausgabe in die Datei umwandeln. Das> überschreibt die Datei, >> fügt die Ausgabe nach dem hinzu, was sich bereits in dieser Datei befindet.


1
teeist normalerweise unter Windows nicht verfügbar, und selbst wenn dies der Fall wäre, würde dies bei diesem Problem nicht helfen.
Der Hochstapler

-4

Das kannst du nicht, Notepad ist dafür zu limitiert! Besser noch ... installieren Sie Cygwin und umgehen Sie all diesen "Mangel an Funktionen" von Windows. Sie können dann den Befehl verwenden, den Sie bereits kennen.

AFAIK, sehr wenige Windows-Programme unterstützen Pipelining, noch schlimmer für GUI-Programme.

Sie können versuchen, Funktionsanforderungen in einem der "Windows Tail" -Programme zu öffnen, um diese hinzuzufügen.


2
Ich benutze bereits Cygwin. Dies ist wirklich ein spezifisches Problem für die Interaktion mit Notepad.
Der Hochstapler


1
@emodendroket einige Male verwenden die Leute das falsche Werkzeug für einen Job ... und für fast jeden Fall ist Notizblock das falsche Werkzeug, ist so einfach und begrenzt :)
higuita

1
@higuita Ich bin ein begeisterter Emacs-Benutzer, aber manchmal ist Notepad das bessere Werkzeug für das, was ich tun möchte.
Casey
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.