Если я установил свою программу как Windows Application
и использовал API AttachConsole(-1)
, как мне получить Console.WriteLine
для записи на консоль, с которой я запускал приложение? Это не работает для меня.
В случае, если это имеет значение, я использую Windows 7 x64, и у меня включен UAC. Подъем, похоже, не решает проблему, но не использует start /wait
.
Обновление
Некоторый дополнительный фон, который может помочь:
Я только что обнаружил, что если я перейду в командную строку и наберем cmd /c MyProgram.exe
, Тогда работа консоли будет работать. То же самое верно, если я запускаю командную строку, открываю подпроцесс cmd.exe
и запускаю программу из этой под-оболочки.
Я также попробовал выйти из системы и вернуться в него, начиная с cmd.exe, запущенного из меню "Пуск" (в отличие от командной строки правой кнопкой мыши → ), и работает от экземпляр console2. Ни одна из этих работ не работает.
Фон
Я читал на других сайтах и в нескольких SO-ответах, которые я могу назвать win32 API AttachConsole
, чтобы связать мое приложение Windows с консолью, на которой запускалась моя программа, поэтому я могу иметь что-то, что является "и консольным приложением, и приложение Windows".
Например, этот вопрос: Возможно ли зарегистрировать сообщение в cmd.exe в С#/. Net?.
Я написал кучу логики, чтобы сделать эту работу (используя несколько других API), и я получил каждый другой сценарий для работы (в том числе перенаправление, которое, как утверждали другие, не будет работать). Единственный оставшийся сценарий - получить Console.WriteLine
для записи на консоль, с которой я запускал свою программу. Из всего, что я прочитал, это должно работать, если я использую AttachConsole
.
Репро
Здесь минимальная выборка. Обратите внимание, что для проекта задано значение 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);
}
- Когда я запускаю это из командной строки, я не получаю сообщение об ошибке, но я тоже не получаю никакого вывода на консоль. Это проблема
- Если я добавляю дополнительные сообщения в любом месте потока выполнения приложения, отображается окно сообщения. Я ожидаю этого, так что все хорошо здесь.
- Когда я запустил это из Visual Studio или дважды щелкнув по нему, появится окно с сообщением об ошибке. Я ожидаю этого, поэтому не беспокойтесь здесь (будет использовать
AllocConsole
в моем реальном приложении).
Если я вызываю Marshal.GetLastWin32Error
после вызова Console.WriteLine
, я получаю сообщение об ошибке "System.ComponentModel.Win32Exception (0x80004005): дескриптор недействителен". Я подозреваю, что присоединение к консоли вызывает Console.Out
, чтобы запутаться, но я не уверен, как это исправить.