Как изменить заголовок окна командной строки (консоли) из Java-приложения командной строки? - PullRequest
9 голосов
/ 15 июня 2009

Как изменить и обновить заголовок окна командной строки из приложения командной строки java? Каждый раз, когда я запускаю свое приложение, заголовок окна командной строки показывает: C:\WINDOWS\system32\cmd.exe - java MyApp.

Я хочу изменить и обновить заголовок окна при запуске java-программы, например, когда wget (win32) обновляет статус загрузки в заголовке: Wget [12%].

Ответы [ 4 ]

21 голосов
/ 15 июня 2009

Хотя я сам не пробовал, в Windows можно использовать вызов Win32 API для SetConsoleTitle, чтобы изменить заголовок консоли.

Однако, поскольку это вызов собственной библиотеки, для выполнения вызова потребуется что-то вроде Собственный интерфейс Java (JNI) , и это будет работать только в Windows 2000 и позже.

Редактировать - решение с использованием JNI

Ниже приведен пример использования JNI для изменения заголовка окна консоли с Java в Windows. Чтобы реализовать это, необходимо некоторое знание C и использование компилятора / компоновщика.

Во-первых, вот результат:

Changing the console title from a Java application
(источник: coobird.net )

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

Программа на Java была следующей:

class ChangeTitle {

    private static native void setTitle(String s);

    static {
        System.loadLibrary("ChangeTitle");
    }

    public static void main(String[] args) throws Exception {

        for (int i = 0; i < 5; i++) {
            String title = "Hello! " + i;
            System.out.println("Setting title to: " + title);
            setTitle(title);
            Thread.sleep(1000);
        }
    }
}

Обычно заголовок меняется каждые 5 секунд, вызывая собственный метод setTitle во внешней собственной библиотеке с именем ChangeTitle.

После того как приведенный выше код скомпилирован для создания файла ChangeTitle.class, команда javah используется для создания заголовка C, который используется при создании библиотеки C.

Написание родной библиотеки

Написание библиотеки потребует написания исходного кода C для файла заголовка C, сгенерированного javah.

Заголовок ChangeTitle.h был следующим:

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class ChangeTitle */

#ifndef _Included_ChangeTitle
#define _Included_ChangeTitle
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     ChangeTitle
 * Method:    setTitle
 * Signature: (Ljava/lang/String;)V
 */
JNIEXPORT void JNICALL Java_ChangeTitle_setTitle
  (JNIEnv *, jclass, jstring);

#ifdef __cplusplus
}
#endif
#endif

Теперь, реализация, ChangeTitle.c:

#include <windows.h>
#include <stdio.h>
#include <conio.h>
#include <jni.h>
#include "ChangeTitle.h"

JNIEXPORT void JNICALL
Java_ChangeTitle_setTitle(JNIEnv* env, jclass c, jstring s) {
    const jbyte *str;
    str = (*env)->GetStringUTFChars(env, s, NULL);

    SetConsoleTitle(str);

    (*env)->ReleaseStringUTFChars(env, s, str);
};

A String, который передается в собственную функцию, заменяется на строку C в кодировке UTF-8, которая отправляется в SetConsoleTitle функцию , которая, как следует из названия функции, изменяет название консоли.

(Примечание: могут быть некоторые проблемы с передачей строки в функцию SetConsoleTitle, но, согласно документации, она также принимает Unicode. Я не слишком уверен, насколько хорошо будет работать приведенный выше код при отправке в разных строках.)

Приведенное выше описание представляет собой комбинацию примера кода, полученного из Раздел 3.2: Доступ к строкам из Руководство и спецификация Java Native Interface для программиста и SetConsoleTitle страница из MSDN.

Более подробный пример кода с проверкой ошибок приведен в Раздел 3.2: Доступ к строкам и SetConsoleTitle Функция страниц.

Сборка DLL

Часть, которая, как выяснилось, заняла у меня больше всего времени, заключалась в том, чтобы заставить файлы C скомпилироваться в DLL, которая фактически могла быть прочитана без вызова UnsatisfiedLinkError.

После долгих поисков и испытаний я смог получить исходный код C для компиляции в DLL, которая может быть вызвана из Java. Так как я использую MinGW, я нашел форму страницы mingw.org, в которой точно описано, как создать DLL для JNI .

Источники:

6 голосов
/ 15 июня 2009

Это зависит от вашего эмулятора терминала, но по сути это просто распечатка управляющих последовательностей на консоль.

Теперь мне неясно, на какие управляющие последовательности отвечает CMD.EXE (у меня нет ни одной, чтобы попробовать это), но я слышал, что есть команда с именем TITLE , которая устанавливает заголовок окно. Я попытался передать вывод TITLE в файл, но, очевидно, он не устанавливает заголовок, выводя управляющие символы. Команда START может принимать параметр, который является заголовком окна, за которым следует команда для запуска в окне. Так что-то вроде

cmd TITLE "lovely Application that is in a command window." && "java" MyApp
REM or
start "lovely Application that is java based." java MyApp

Лично я бы просто связал все это с помощью ярлыка, где вы можете редактировать свойства, такие как текущий каталог, команда, ее параметры, а также размер окна, стиль и заголовок (если я правильно помню). Дайте ему хороший значок, и люди будут им пользоваться.

3 голосов
/ 14 мая 2010

Вот мое решение с использованием JNA:

import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.Platform;

public class SetTitle {

    public interface CLibrary extends Library {
        CLibrary INSTANCE = (CLibrary)
            Native.loadLibrary((Platform.isWindows() ? "kernel32" : "c"),
                               CLibrary.class);

        boolean SetConsoleTitleA(String title);
    }

    public static void main(String[] args) {
        CLibrary.INSTANCE.SetConsoleTitleA("Testing 123");
        System.exit(0);
    }
}
0 голосов
/ 15 июня 2009

после откровения Дламблина ;-) Вот код Python. обратите внимание, что в большинстве языков программирования есть две разные команды:

  • система
  • * Exec 1006 *

система выдаст системную команду, exec действительно порождает новый процесс. таким образом:

C:\>python
>>> import os
>>> os.system("title berry tsakala")

, который работает внутри работающей программы. Просто найдите Java-эквивалент.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...