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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/994273/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 12:38:16  来源:igfitidea点击:

How to change command prompt (console) window title from command line Java app?

javawindowscommand-line

提问by evaldaz

How to change and update the title of the command prompt window from the java command line application? Every time I run my application, the command prompt window title shows: C:\WINDOWS\system32\cmd.exe - java MyApp.

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

I'd like to change and update the window title as the java program runs, for example as wget(win32) updates downloading status in the title: Wget [12%].

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

回答by coobird

Although I haven't tried it myself, in Windows, one can use the Win32 API call to SetConsoleTitlein order to change the title of the console.

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

However, since this is a call to a native library, it will require the use of something like Java Native Interface (JNI)in order to make the call, and this will only work on Windows 2000 and later.

但是,由于这是对本机库的调用,因此需要使用Java 本机接口 (JNI) 之类的东西才能进行调用,而且这只适用于 Windows 2000 及更高版本。

Edit - A solution using JNI

编辑 - 使用 JNI 的解决方案

The following is an example of using JNI in order to change the title of the console window from Java in Windows. To implement this, the prerequiste is some knowledge in C and using the compiler/linker.

以下是使用 JNI 以在 Windows 中从 Java 更改控制台窗口标题的示例。要实现这一点,先决条件是一些 C 知识和使用编译器/链接器。

First, here's result:

首先,这是结果:

Changing the console title from a Java application
(source: coobird.net)

从 Java 应用程序更改控制台标题
(来源:coobird.net

Disclaimer: This is my first Java application using JNI, so it's probably not going to be a good example of how to use it -- I don't perform any error-checking at all, and I may be missing some details.

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

The Java program was the following:

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

Basically, the title is changed every 5 seconds by calling the setTitlenative method in an external native library called ChangeTitle.

基本上,标题每 5 秒更改一次,setTitle方法是调用名为ChangeTitle.

Once the above code is compiled to make a ChangeTitle.classfile, the javahcommand is used to create a C header that is used when creating the C library.

一旦将上述代码编译成ChangeTitle.class文件,该javah命令将用于创建 C 头文件,该头文件在创建 C 库时使用。

Writing the native library

编写本地库

Writing the library will involve writing the C source code against the C header file generated by javah.

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

The ChangeTitle.hheader was the following:

所述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

Now, the implementation, ChangeTitle.c:

现在,实现,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 Stringthat is passed into the native function is changed into an UTF-8 encoded C string, which is sent to the SetConsoleTitlefunction, which, as the function name suggests, changes the title of the console.

String传递到本地函数改变为UTF-8编码的C字符串,其被发送到所述SetConsoleTitle功能,其中,作为函数顾名思义,改变控制台的标题。

(Note: There may be some issues with just passing in the string into the SetConsoleTitlefunction, but according to the documentation, it does accept Unicode as well. I'm not too sure how well the code above will work when sending in various strings.)

(注意:仅将字符串传入SetConsoleTitle函数可能存在一些问题,但根据文档,它也接受 Unicode。我不太确定在发送各种字符串时上述代码的工作情况。 )

The above is basically a combination of sample code obtained from Section 3.2: Accessing Stringsof The Java Native Interface Programmer's Guide and Specification, and the SetConsoleTitleFunctionpage from MSDN.

上面的是基本上从获得的样品代码的组合的3.2部分:访问字符串Java本机接口程序员指南和规格,以及所述SetConsoleTitle功能从MSDN页。

For a more involved sample code with error-checking, please see the Section 3.2: Accessing Stringsand SetConsoleTitleFunctionpages.

有关更复杂的错误检查示例代码,请参阅第 3.2 节:访问字符串SetConsoleTitle函数页面。

Building the DLL

构建 DLL

The part that turned out to take the most amount of time for me to figure out was getting the C files to compile into an DLL that actually could be read without causing an UnsatisfiedLinkError.

结果证明我花了最多时间弄清楚的部分是让 C 文件编译成一个实际上可以读取的 DLL,而不会导致UnsatisfiedLinkError.

After a lot of searching and trying things out, I was able to get the C source to compile to a DLL that could be called from Java. Since I am using MinGW, I found a page form mingw.orgwhich described exactly how to build a DLL for JNI.

经过大量搜索和尝试,我能够将 C 源代码编译为可以从 Java 调用的 DLL。由于我使用的是 MinGW,我找到了一个页面表单mingw.org,它准确地描述了如何为 JNI 构建 DLL

Sources:

资料来源:

回答by dlamblin

This depends on your terminal emulator, but essentially it's just printing out control sequences to the console.

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

Now I'm not clear on what control sequences CMD.EXE responds to (I haven't one available to try this on) but I hear there's a command called TITLEwhich sets the title of the window. I tried piping TITLE's output to a file, but apparently, it doesn't actually set the title by outputting control characters. The START command can take a parameter which is title of the window followed by the command to run in the window. So something like

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

Personally I would just bundle the whole thing with a shortcut where you can edit the properties such as the current directory, the command, it's parameters, and the window size, style and title (if I remember rightly). Give it a nice icon and people will use it.

就我个人而言,我只是将整个内容与一个快捷方式捆绑在一起,您可以在其中编辑属性,例如当前目录、命令、它的参数以及窗口大小、样式和标题(如果我没记错的话)。给它一个漂亮的图标,人们就会使用它。

回答by user341477

Here's my solution using JNA:

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

回答by Berry Tsakala

following dlamblin's revelation ;-) here's a python code. note that there are 2 different commands in most programming languages:

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

  • system
  • exec
  • 系统
  • 执行

system will issue a system command, exec indeed spawns a new process. thus:

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

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

which works inside a running program. Just find the java equivalent.

它在正在运行的程序中工作。只需找到 j​​ava 等效项。