Làm thế nào tôi có thể dẫn đầu ra giao diện điều khiển trực tiếp vào Notepad?


47

Tôi đang chạy một ứng dụng trên dấu nhắc lệnh hoặc shell Git và tôi muốn đưa đầu ra vào Notepad, để xem lại và chỉnh sửa dễ dàng hơn sau này.

Tôi đã thử các cách sau, nhưng tôi luôn nhận được một phiên bản trống của Notepad:

diff file1.txt file2.txt | notepad

Tôi biết rằng tôi có thể chuyển hướng đầu ra sang tệp khác và sau đó mở tệp trong Notepad. Tôi muốn tránh bước thêm, vì tôi chỉ quen với việc chuyển sang Vim hoặc ít hơn trên các hệ thống không phải Windows.


2
Tất nhiên, bạn cũng có thể chuyển sang moreWindows.
Gabe

1
Tại sao không chuyển sang tệp và chỉ đơn giản là thực thi đường dẫn tệp mới - hãy để HĐH xử lý ứng dụng trình bày. Nó phải là notepad không?
Gusdor

@Gusdor Câu hỏi chủ yếu là về việc tránh tạo tệp (tạm thời).
Der Hochstapler

1
Chức năng của Notepad bị hạn chế đến mức bạn hầu như không thể làm gì với nó. Vì bạn đã quen thuộc vim, tại sao không chỉ cài đặt nó?
Siyuan Ren

@CR Tôi có thể làm điều đó trên máy tính của mình, nhưng tôi thường xuyên làm việc trên máy tính mà tôi không sở hữu. Vì vậy, thật hữu ích khi biết có những tùy chọn nào mà không cần cài đặt phần mềm của bên thứ ba.
Der Hochstapler

Câu trả lời:


63

Từ những gì tôi có thể nói, không có cách nào để chuyển trực tiếp vào Notepad.

Tuy nhiên, bạn có thể đặt vào clipvà sau đó dán vào notepad, như vậy:

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

Sau đó chỉ cần nhấn Ctrl+ Vtrong Notepad.


3
Nó có hoạt động không nếu bạn chuyển hướng đầu ra sang file3.txt, sau đó && notepad file3.txt?
Konerak

4
@Konerak Vâng, điều đó sẽ hiệu quả và đó chính xác là những gì tôi đã cố tránh (như đã giải thích trong câu hỏi);)
Der Hochstapler

32

Cân nhắc sử dụng Vim hoặc trong trường hợp của bạn gVim nếu bạn thích môi trường đồ họa.

Sau đó, bạn có thể dẫn vào nó với một dấu gạch nối làm đối số, hướng dẫn Vim / gVim đọc từ đầu vào tiêu chuẩn.

diff file1.txt file2.txt | gvim -

1
Cài đặt nó, Notepad thực sự bị giới hạn, bạn không thể sử dụng nó cho việc này. bạn thậm chí có thể có nó trong các ứng dụng di động
portablooms.com/apps/development/gvim_portable

3
Cũng có thể làm điều này từ trong vim::%!diff file1.txt file2.txt
SlightlyCuban

@TankorSmash Vì vậy, làm tôi, nhưng đó không phải là điểm của câu hỏi;) Để biết thêm các cuộc thảo luận chuyên nghiệp và con về vim (hoặc bất kỳ chủ đề khác), xin vui lòng tìm thấy tôi trên Super User trò chuyện , bình luận đề không phải là một cách tuyệt vời để có một cuộc trò chuyện :(
Der Hochstapler

1
@OliverSalzburg Tôi đã cố gắng đề xuất rằng gvim có sẵn trên Windows, vì tôi hiểu nhận xét của bạn có nghĩa là nó không có. Tôi đã sai.
TankorSmash

-thường được sử dụng để có nghĩa là "đọc từ stdin", vì vậy điều này không bị giới hạn nghiêm ngặt vim. Các biên tập viên khác sử dụng -i(ví dụ kate).
Bakuriu

8

đây là một chương trình Windows ngắn thực hiện đúng cách (không ghi đè lên bảng tạm). Nó có thể thích ứng với PowerShell và tôi có thể cập nhật câu trả lời này nếu tôi có thời gian, nhưng bạn cũng có thể chỉ cần sử dụng chương trình đó trực tiếp.

Chà, thế còn PowerShell thì sao? Không cần phải cài đặt ứng dụng khác. Thật không may, bạn sẽ cần tạo một tệp tập lệnh ở đâu đó trong PATH...

Phiên bản ngắn bạn có thể sử dụng

Nếu bạn tạo một tệp bó (ví dụ ShowInNotepad.bat) với các nội dung sau và đặt nó vào PATHđâu đó:

@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');

sau đó bạn có thể gọi echo blah | ShowInNotepadtừ bất cứ đâu!

Lưu ý rằng điều này không cho rằng bạn đang sử dụng phiên bản Windows gần đây (Vista +) và chưa tắt PowerShell hoặc gỡ cài đặt .NET framework. Nói cách khác, cài đặt Windows mặc định sẽ hoạt động.


Giải thích dài dòng và giải pháp thay thế

Cách dễ nhất tôi có thể nghĩ đến là tự động hóa hành động dán ( Ctrl+ V). Mà ít nhất một câu trả lời khác đã được thực hiện, nhưng câu trả lời đó sử dụng AHK - bạn có thể may mắn hơn khi PowerShell hoạt động trong môi trường công ty bị khóa.

Hãy bắt đầu với kịch bản, phải không?

#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');

Điều này khá đơn giản, vì vậy tôi sẽ không bận tâm giải thích kịch bản nhiều hơn những bình luận đã làm.

Sử dụng

Để sử dụng nó, bạn chỉ cần đặt tập lệnh vào một .ps1tệp (ví dụ ShowInNotepad.ps1), đặt nó ở đâu đó trong của bạn PATHvà sau đó gọi powershell ShowInNotepad.ps1sau khi đặt văn bản bạn muốn hiển thị vào bảng tạm.

Thí dụ:

echo blah | clip && powershell ShowInNotepad.ps1

Thật không may, việc thực thi các tập lệnh PowerShell đôi khi có thể khó khăn (chính sách thực thi và tất cả). Do đó, tôi đã cô đọng tập lệnh này thành một tập lệnh mà bạn có thể gọi trực tiếp từ Dấu nhắc Lệnh hoặc thậm chí đặt vào một tệp bó:

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');

Nếu bạn tạo một tệp bó (ví dụ ShowInNotepad.bat) với các nội dung sau và đặt nó vào PATHđâu đó:

@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');

sau đó bạn có thể gọi echo blah | ShowInNotepadtừ bất cứ đâu!


Thành thật mà nói, nếu bạn định viết một tập lệnh PS, tôi sẽ chỉ tạo một tệp có tên Guid trong thư mục tệp tạm thời và xóa nó khi tôi hoàn thành. Tự động dán có vẻ quá giòn (như nếu bạn mất tập trung không đúng lúc hoặc một cái gì đó)?
Casey

@emodendroket Thật không may, khi bạn đang cố gắng buộc luồng đầu vào vào một chương trình không thực sự hỗ trợ nó, không có gì thực sự sạch. Tạo một tệp tạm thời có nhược điểm riêng (phụ): bạn thực sự không nhận được "tệp mới", do đó, Savevà thoát khỏi các hành vi đã sửa đổi là khác nhau. Không thể tự thay thế Notepad hoặc đưa trực tiếp văn bản vào điều khiển chỉnh sửa, không có nhiều tùy chọn khác. Tất nhiên, phương pháp này có nhược điểm của nội dung clipboard ghi đè (mặc dù những nội dung được cho là phù du dù thế nào đi nữa). Tôi không nghĩ mất tập trung là một vấn đề lớn; đó là ...
Bob

... Điều kiện cuộc đua cực kỳ khó xảy ra (giữa ShowWindowvà gửi tổ hợp phím). Và phương pháp này đòi hỏi phải thiết lập thêm một chút (tạo tệp tập lệnh) để sử dụng, vâng.
Bob

5

Làm thế nào về việc sử dụng AutoHotkey ?

Lưu các mục sau stdin.ahkvà đặt nó vào thư mục AutoHotkey của bạn:

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 = 
        }
}

Sau đó, dòng lệnh:

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

Đặt đầu ra của lệnh vào Notepad, miễn là cửa sổ được mở và có tiêu đề Untitled - Notepad. Trong trường hợp cửa sổ không hoạt động thì nó sẽ vui vẻ đệm trong nền cho đến khi cửa sổ được kích hoạt. Bạn thậm chí có thể đi đến một chương trình khác và nó sẽ tiếp tục đệm một lần nữa.

Điều này dường như sẽ chết khi chương trình xuất ra đầu vào tiêu chuẩn của chúng tôi chết mặc dù ...

(Để biết thông tin, mã stdin () không biết xấu hổ nửa inch từ đây )


... wow. Nếu bạn sẽ đi đến mức đó, cũng có thể viết cả một chương trình được biên dịch! Có lẽ cũng hiệu quả hơn: P Upvote cho những nỗ lực mặc dù.
Bob

Downvote từ tôi tôi sợ. Áp đảo trong ý nghĩa cổ điển. Ai là phiên bản kiểm soát kịch bản này? Autohotkey có cần giấy phép cho các ứng dụng thương mại không? Ai giám sát điều đó?
Gusdor

7
@Gusdor Toàn bộ Internet có đầy đủ các đoạn mã được kiểm soát không phải phiên bản. Chúng tôi có lợi ích thậm chí có một lịch sử sửa đổi cho bài đăng này. Tôi cũng không thấy việc cấp phép thương mại có liên quan gì đến câu hỏi này? AHK được sử dụng bởi rất nhiều người, và họ có thể thấy câu trả lời này hữu ích.
slhck

@slhck Tôi chỉ đơn giản là nhận xét về những cạm bẫy của giải pháp này, không phải là hiệu lực của nó.
Gusdor

@slhck: Nội dung trên trang web này được Creative Commons bảo vệ.
Brian

4

Điều này là hoàn toàn có thể; Tôi chỉ thử nó. Tôi giả sử Notepad được đặt để mở tệp txt theo mặc định:

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

OK, về mặt kỹ thuật bạn đang tạo một tệp, nhưng nó không được lưu.

Đường ống vào nhiều hơn cũng là một lựa chọn.


4
Hãy cẩn thận - nếu bạn đã có một output.txtcái này sẽ ghi đè lên nó. An toàn hơn sẽ được sử dụng %temp%/somerandomstring.txt.
Bob

An toàn hơn để lưu tệp đầu ra trong thư mục temp - hãy xem câu trả lời này .
Lu55

1

Đây là một cách xấu xí, nhưng hiệu quả để thực hiện điều này:

$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)

Chỉ cần chắc chắn để chỉ gửi văn bản đầu ra. Các dữ liệu khác có khả năng sẽ được hiểu là các ký tự điều khiển (CTRL, ALT, DEL, v.v.).


0

Đây là một vài giải pháp dựa trên VBScript có thể hoạt động (mặc dù .. chúng phụ thuộc một chút vào các ứng dụng mở đúng giờ):

pipe2key.vbs - mở ứng dụng được chỉ định làm đối số đầu tiên và sau đó gửi StdIn dưới dạng tổ hợp phím cho nó. Cần được sử dụng với cscript.exe vì wscript không cung cấp quyền truy cập StdIn. Có lẽ khá chậm đối với các tài liệu dài - nhưng sẽ không ghi đè lên bảng tạm

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

Ví dụ sử dụng: diff file1.txt file2.txt | cscript pipe2key.vbs notepad.exe

Hoặc, pasteinto.vbs. Tự động hóa hoạt động CTRL-V sau khi khởi chạy một ứng dụng (do đó sử dụng lệnh 'clip' như đã đề cập trong các câu trả lời trước). Nhanh hơn và sạch hơn (theo ý kiến ​​của tôi) so với pipe2key.vbs, nhưng quá trình này sẽ ghi đè lên bảng tạm

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"

Ví dụ sử dụng: diff file1.txt file2.txt | clip && pasteinto notepad.exe


-1

Một cái gì đó như "có thể" làm việc.

Aw, bạn đã không nhận ra đây là điều bạn đang làm thủ công mỗi lần (từ âm thanh của nó). Bạn có thể tạo một số loại macro hoặc thứ gì đó để làm điều đó cho bạn mỗi lần để tăng tốc quá trình. Không chắc chắn về điều đó.

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

Nó sẽ phải hoàn thành việc ghi nội dung khác vào file.txt để nó tải toàn bộ hoạt động khác mà tôi không chắc liệu nó có làm được không. Có thể có một cách để tạm dừng bằng cách nào đó giữa các hoạt động đường ống nếu đó là trường hợp.


5
Mục tiêu là không tạo một tệp tạm thời và tôi khá chắc chắn có lỗi với cú pháp của bạn ở đó;)
Der Hochstapler

"Để xem xét và chỉnh sửa dễ dàng hơn sau này" Tôi đoán đó là những gì bạn muốn? Và như Rev1.0 đã chỉ ra và sửa đổi, nó hoạt động. Điều này là cho dos, tuy nhiên, tôi không chắc liệu Cygwin có kết quả tương tự hay không.
Codezilla

3
Tôi đoán bởi vì & sẽ là đầy đủ vì thực sự không có gì cần phải "chuyển" giữa các cuộc gọi đó.
Rev1.0

3
@ Rev1.0 Đúng. &, &&||là nhà khai thác các lệnh chuỗi với nhau. Tất cả 3 hành xử khác nhau trong cách họ tiến hành nếu một lệnh tạo ra giá trị trả về không 0. |là hoàn toàn khác nhau vì nó được sử dụng để đầu ra đường ống từ chương trình này sang chương trình khác. Kết quả có thể là những gì bạn muốn, nhưng sử dụng một trong các toán tử chuỗi làm cho ý định rõ ràng hơn, bởi vì không có đường ống thực tế nào được mong muốn trong ví dụ đó. Để tham khảo thêm: microsoft.com/resource/documentation/windows/xp/all/proddocs/NH
Der Hochstapler

1
@Codezilla Tôi nghĩ rằng ý tưởng trong bài viết của tôi khá giống với ý tưởng của bạn nhưng đó là cú pháp nhắc lệnh hợp lệ.
Casey

-3

Ngôn ngữ của tôi không phải là tiếng Anh nên xin lỗi vì những sai lầm.

Tôi nghĩ rằng bạn không thể trực tiếp đưa đầu ra vào Notepad mở. Có thể tôi sai về nó. Bạn phải tạo một tệp có đầu ra trong đó để làm việc với nó. Lệnh tee có thể dẫn đầu ra thành hai hoặc có thể nhiều lệnh hoặc tệp hơn cùng một lúc.

người đàn ông tee

Đừng quên sử dụng >> thay vào đó> khi bạn chuyển hướng đầu ra vào tệp. > Sẽ ghi đè lên tệp, >> sẽ thêm đầu ra sau khi mọi thứ đã có trong tệp đó.


1
teethường không có sẵn trên Windows và ngay cả khi có, nó sẽ không giúp ích gì cho vấn đề này.
Der Hochstapler

-4

Bạn không thể, Notepad quá giới hạn cho việc này! Tốt hơn hết là ... cài đặt Cygwin và giải quyết tất cả "thiếu tính năng" này của Windows. Sau đó bạn có thể sử dụng lệnh bạn đã biết.

AFAIK, rất ít chương trình Windows hỗ trợ pipelining, thậm chí còn tệ hơn cho các chương trình GUI.

Bạn có thể thử mở các yêu cầu tính năng cho một trong các chương trình "windows tail" để thêm điều đó.


2
Tôi đã sử dụng cygwin. Đây thực sự là một vấn đề cụ thể đối với tương tác với Notepad.
Der Hochstapler


1
@emodendroket đôi khi mọi người sử dụng công cụ sai cho công việc ... và trong hầu hết mọi trường hợp, notepad là công cụ sai, rất đơn giản và hạn chế :)
higuita

1
@higuita Tôi là người dùng Emacs tận tụy nhưng đôi khi Notepad là công cụ tốt hơn cho những gì tôi muốn làm.
Casey
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.