2014-12-03 4 views
1

Я начал программу Java из C# с помощьюблизко ява процесс от C# (на окнах)

... 
ProcessStartInfo startInfo = new ProcessStartInfo(); 
startInfo.WorkingDirectory = "C:\\path\\to\\jar\\"; 
startInfo.FileName = "C:\\Windows\\Sysnative\\java.exe"; 
startInfo.Arguments = "-jar JavaProg.jar"; 
process = new Process(); 
process.StartInfo = startInfo; 
try { 
    process.Start(); 
} 
... 

Процесс затем работает непрерывно, пока я не хочу, чтобы это остановить. В java-программе есть крючок отключения, который должен улавливать нормальные сигналы уничтожения. Например, если я запустил банку из сценария летучей мыши, то нажатие Ctrl + c в окне cmd приведет к запуску крюка остановки, но закрытие окна cmd завершит процесс без запуска крюка выключения (аналогично End Process в диспетчере задач).

Так что для того, чтобы остановить программу Java от C# Я пробовал:

process.CloseMainWindow(); 

или

process.Kill(); 

Метод CloseMainWindow не оказывает никакого влияния на процесс Java, и убийство прекращает его без срабатывания выключение крюк. Итак, что я могу сделать, чтобы закрыть java-программу изящно из кода C#? [Мне нужно внести изменения в мою программу Java для перехвата сигнала CloseMainWindow? Есть ли способ имитировать поведение Ctrl + c в окне cmd из C#? Должен ли я создать некоторый путь связи между моими кодами C# и Java, такими как труба или гнездо?]

P.S. Код C# является просто оболочкой для Java-кода, чтобы запускать его как службу в Windows (я не могу использовать существующие инструменты, такие как RunAsService для этой цели).

Общее описание программы: Моя программа java не создает никаких окон. Он имеет несколько потоков, основной работает в цикле, только ожидая соединений, другой выполняет определенную задачу во входящем соединении, другой поток выполняет периодические обновления с веб-сервера, и есть крюк отключения. Обычно программа запускается из командной строки (или терминала на linux) и принимает пользовательский ввод только тогда, когда она загружается в первый раз, после чего ее можно запустить снова без ввода пользователя. Программа выводит журналы в файл. Мой крюк отключения:

... 
shutdownHook = new ShutdownHook(); 
Runtime.getRuntime().addShutdownHook(shutdownHook); 
... 
class ShutdownHook extends Thread { 
    public void run() { 
     // log the shutdown is started 
     // terminate classes 
     // interrupt and join the other threads 
     // log the shutdown is done 
    } 
} 
+0

Я сомневаюсь, что это не имеет ничего общего с Java. Или вы хотите сказать, что вы можете убить другие процессы таким образом без проблем? – fge

+0

Как выглядит ваша Java-программа? Создает ли оно окно или запускает ли он в оболочке? – helb

+0

Является ли запуск при запуске, если вы убиваете процесс с помощью TaskManager? – helb

ответ

0

Это попытка закрыть все окна блокнота. Обратите внимание, что вы можете получить запрос, если хотите сохранить.

[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)] 
    static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam); 

    static uint WM_CLOSE = 0x10; 

    public void CloseWindow(IntPtr hWindow) 
    { 
    SendMessage(hWindow, WM_CLOSE, IntPtr.Zero, IntPtr.Zero); 
    } 

    public void test_close() 
    { 
    foreach (System.Diagnostics.Process p in System.Diagnostics.Process.GetProcessesByName("notepad")) 
    { 
     CloseWindow(p.MainWindowHandle); 
    } 
    } 
+0

В сценарии, описанном OP, это закроет все приложения Java, верно? Это не может быть хорошим решением ... – helb

+0

Забыл о запуске как java.exe - это его программа, скомпилированная с другим именем exe? В противном случае вы хотели бы получить список всех окон рабочего стола и, вероятно, перейти к заголовку окна. Кроме того, есть способы получить командную строку запущенного процесса (см. WMI). Включает ли в командной строке информацию о его фактическом процессе? – Derek

+0

Между тем OP опубликовал, что его приложение делает ** не ** создавать окно. Таким образом, ваш подход не будет работать. – helb

0

Лучший способ сделать это для вашей C# -программы, чтобы получить дескриптор stdin программы Java. Таким образом, программа C# может отправлять сообщение программе Java всякий раз, когда захочет, и программа Java может выслушать сообщение с просьбой умереть.

Это имеет то преимущество, что вам не нужно беспокоиться о завершающих крюках: программа может выполнять любую обработку, необходимую для получения сообщения о завершении работы. Это также намного более гибко: если позже вы хотите, чтобы программа C# отправляла другие управляющие сообщения, которые можно легко добавить.

На стороне Java вам понадобится отдельный поток, который откроет System.in и прочитает его, и выполнит любое выключение, когда вам понадобится правильное сообщение.

На C# стороне, это выглядит, как будто вы хотите

startInfo.RedirectStandardInput = true; 
startInfo.UseShellExecute = false; 

, а затем, когда вы хотите отправить сообщение:

process.StandardInput.WriteLine(...some message...); 

(но я программист Java, поэтому я неясно, есть ли у меня C# здесь).

+0

Можете ли вы рассказать о стороне java? – giladrv

0

Вы должны использовать GenerateConsoleCtrlEvent:

Вы можете назвать это с помощью P/Invoke.

Это позволит вам сгенерировать событие Ctrl + C, которое ваша программа Java будет обрабатывать так же, как если бы вы нажмете Ctrl + C в окне команд.

Примечание: Однако это будет работать, только если в процессе есть консоль. Java запускает обработчик Ctrl + C при запуске, поэтому вам нужно убедиться, что при запуске программа имеет консоль. Вы можете сделать это, вызвав AllocConsole в вызывающей программе, чтобы создать консоль, и программа java наследует консоль.

+0

он определенно не работает без SetConsoleCtrlHandler – giladrv

+0

@giladrv Вероятно, это не работает, потому что в программе Java нет консоли. Если ваша программа .Net запускает java-программу, она может дать себе консоль, и программа Java наследует ее. Чтобы попробовать это, вызовите AllocConsole, используя P/Invoke, перед запуском java-программы. http://msdn.microsoft.com/en-us/library/windows/desktop/ms681944(v=vs.85).aspx – Ben

+0

Автор здесь: http://stackoverflow.com/questions/16139571/how-to-cleanly-shut-down-a-console-app-started-with-process-start, утверждает, что он не сработает, поэтому я Я просто собираюсь реализовать tcp-сервер-клиент между java и .net. – giladrv

Смежные вопросы