如何从命令行Java应用程序更改命令提示符(控制台)窗口标题?

时间:2009-06-15 02:02:37

标签: java windows command-line

如何从java命令行应用程序更改和更新命令提示符窗口的标题?每次运行我的应用程序时,命令提示符窗口标题显示: C:\WINDOWS\system32\cmd.exe - java MyApp

我想在java程序运行时更改和更新窗口标题,例如wget(win32)更新标题中的下载状态:Wget [12%]

4 个答案:

答案 0 :(得分:20)

虽然我自己没有尝试过,但在Windows中,可以使用对SetConsoleTitle的Win32 API调用来更改控制台的标题。

但是,由于这是对本机库的调用,因此需要使用类似Java Native Interface (JNI)的内容才能进行调用,而这只适用于Windows 2000及更高版本。

编辑 - 使用JNI的解决方案

以下是使用JNI从Windows中的Java更改控制台窗口标题的示例。为了实现这一点,prerequiste是C中的一些知识并使用编译器/链接器。

首先,结果如下:

Changing the console title from a Java application
(来源:coobird.net

免责声明:这是我第一个使用JNI的Java应用程序,因此它可能不会成为如何使用它的一个很好的例子 - 我根本不执行任何错误检查,我可能会遗漏一些细节

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

基本上,通过在名为setTitle的外部本机库中调用ChangeTitle本机方法,标题每5秒更改一次。

编译完上述代码以生成ChangeTitle.class文件后,javah命令用于创建在创建C库时使用的C头。

编写本机库

编写库将涉及针对javah生成的C头文件编写C源代码。

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

传递给本机函数的String将更改为UTF-8编码的C字符串,该字符串将发送到SetConsoleTitle function,正如函数名称所示,它将更改标题控制台。

(注意:将字符串传递到SetConsoleTitle函数可能会有一些问题,但根据文档,它也接受Unicode。我不太清楚上面的代码有多好在发送各种字符串时会有效。)

以上内容基本上是从Section 3.2: Accessing Strings The Java Native Interface Programmer's Guide and Specification获得的示例代码与MSDN的SetConsoleTitle Function页面的组合。

有关错误检查的更详细的示例代码,请参阅Section 3.2: Accessing StringsSetConsoleTitle Function页。

构建DLL

最终需要花费大量时间让我弄清楚的部分是将C文件编译成一个实际上可以在不导致UnsatisfiedLinkError的情况下读取的DLL。

经过大量的搜索和尝试后,我能够将C源代码编译为可以从Java调用的DLL。由于我使用的是MinGW,因此我找到了一个mingw.org页面described exactly how to build a DLL for JNI

来源:

答案 1 :(得分:6)

这取决于您的终端仿真器,但实质上它只是将控制序列打印到控制台。

现在我不清楚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

我个人会用快捷方式捆绑整个东西,你可以编辑属性,例如当前目录,命令,它的参数,窗口大小,样式和标题(如果我没记错的话)。给它一个漂亮的图标,人们会用它。

答案 2 :(得分:3)

这是我使用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);
    }
}

答案 3 :(得分:-1)

跟随dlamblin的启示;-) 这是一个python代码。 请注意,大多数编程语言中有两个不同的命令:

  • 系统
  • EXEC

系统会发出系统命令,exec确实会产生一个新进程。因此:

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

在正在运行的程序中运行。只需找到等效的java。