Se ho impostato il mio programma come Windows Application
e utilizzato l'API AttachConsole(-1)
, come posso ottenere Console.WriteLine
per scrivere sulla console da cui ho avviato l'applicazione? Non sta funzionando per me.AttachConsole (-1), ma Console.WriteLine non verrà restituito al prompt dei comandi padre?
Nel caso sia rilevante, sto usando Windows 7 x64 e ho UAC abilitato. Elevare non sembra tuttavia risolvere il problema, né l'utilizzo di start /wait
.
Aggiornamento
Alcuni di fondo aggiuntivo che potrebbe aiutare:
Ho appena scoperto che se vado al prompt dei comandi e digitare cmd /c MyProgram.exe
, Poi console di output funziona. Lo stesso è vero se lancio un prompt dei comandi, apro un sottoprocesso ed eseguo il programma da quella sotto-shell.
Ho anche provato a disconnettermi e rientrare, eseguendo da un cmd.exe lanciato dal menu di avvio (al contrario di clic con il pulsante destro del mouse -> prompt dei comandi) ed eseguendo da a console2 instance. Nessuno di quei lavori.
Sfondo
Ho letto su altri siti e in diversi SO risposte che posso chiamare l'API Win32 AttachConsole
di legare la mia applicazione di Windows per la console che correva il mio programma, in modo da poter avere qualcosa che è "sia un'applicazione console che un'applicazione Windows".
Ad esempio, questa domanda: Is it possible to log message to cmd.exe in C#/.Net?.
Ho scritto un po 'di logica per fare questo lavoro (usando diverse altre API), e ho ottenuto ogni altro scenario di lavoro (incluso il reindirizzamento, che altri hanno sostenuto non funzionerà). L'unico scenario rimasto è quello di ottenere Console.WriteLine
per scrivere sulla console con cui ho avviato il mio programma. Da tutto ciò che ho letto, questo dovrebbe funzionare se uso AttachConsole
.
Repro
Ecco un esempio minimo - Si noti che il progetto è impostato per essere un Windows Application
:
using System;
using System.ComponentModel;
using System.Runtime.InteropServices;
using System.Windows.Forms;
class Program
{
[STAThread]
static void Main(string[] args)
{
if (!AttachConsole(-1))
{
MessageBox.Show(
new Win32Exception(Marshal.GetLastWin32Error())
.ToString()
);
}
Console.WriteLine("Test");
}
[DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)]
private static extern bool AttachConsole(int processId);
}
- Quando eseguo questo da un prompt dei comandi, non ottengo un errore, ma non ottengo alcun output della console. Questo è il problema
- Se aggiungo caselle di messaggio aggiuntive in qualsiasi punto del flusso di esecuzione dell'app, la finestra di messaggio viene visualizzata. Mi aspetto questo, quindi tutto bene qui.
- Quando eseguo questo da Visual Studio o facendo doppio clic su di esso, viene visualizzata una finestra di messaggio con un errore. Mi aspetto questo, quindi non ci sono problemi qui (userò
AllocConsole
nella mia vera app).
Se chiamo Marshal.GetLastWin32Error
dopo la chiamata a Console.WriteLine
, ho la "System.ComponentModel.Win32Exception (0x80004005): l'handle non valido" errore. Ho il sospetto che il collegamento alla console stia causando problemi con lo Console.Out
, ma non sono sicuro di come risolverlo.
Perché non si contrassegna il programma come applicazione per console? – CodesInChaos
Molto strano ... Uso anche 'AttachConsole (-1)' in un'applicazione e funziona senza problemi. Comparerò il codice quando entrerò nel lavoro e nel post-back se c'è qualche differenza. @CodeInChoas: se lo crei come un'applicazione console, avrai sempre la finestra della console in background. Usando AttachConsole ottieni il meglio da entrambi: un'applicazione che, una volta aperta tramite la riga di comando (console), scriverà sui flussi della console. – Dennis
@CodeInChaos: sembra il "bene, duh!" soluzione :) Ma non voglio realmente "sia una console che un'app per Windows", voglio * una * console o app per Windows, basata su opzioni della riga di comando. E non voglio che la console tocchi lo schermo quando lo avvio. Questo è uno scenario abbastanza comune, e ho trovato circa una dozzina di thread per far funzionare tutto, incluso questo pezzo. Tranne che questo pezzo non funziona. Se pensi che dovrei chiarire le mie esigenze nella mia domanda, fammelo sapere e lo sistemerò volentieri. –