如果 bobince 说的是准确的,并且您不能可靠地将数据直接传递给 java,则另一种解决方案是用另一种语言(例如 C、C++ 或 C#)编写一个小的“shim”程序。
这个想法是程序将输入获取为 UNICODE,对其进行编码,以便仅使用 ASCII 字符(例如,通过使用 base64,或者甚至像将每个字符编码为其数字等价物一样简单),然后将命令行参数组装为使用 CreateProcess 使用并启动 java 本身。
您的 Java 代码可以“撤消”编码,重构 UNICODE 名称并继续使用它。这是一种迂回的方式,需要为您的软件添加一个额外的组件,但它应该可以解决上面详述的限制,如果这确实是一个实际限制的话。
更新:这是 shim 程序的基本代码。它将输入编码为整数序列,用冒号分隔。它在错误检查方面没有多大作用,您可能希望稍微改进它,但它至少应该让您开始并朝着正确的方向前进。
您应该获取 Visual Studio Express(如果您还没有 Visual Studio)并创建一个新的 Visual C++ 项目,选择“Win32”并选择“Win32 项目”。选择“Win32 应用程序”。创建项目后,将显示的 .cpp 文件中的所有内容替换为以下代码:
#include "stdafx.h"
#include <string>
int APIENTRY _tWinMain(HINSTANCE, HINSTANCE, LPTSTR lpCmdLine, int)
{
std::string filename;
while((lpCmdLine != NULL) && (*lpCmdLine != 0))
{
if(filename.length() != 0)
filename.append(":");
char buf[32];
sprintf(buf, "%u", (unsigned int)(*lpCmdLine++));
filename.append(buf);
}
if(filename.length() == 0)
return 0;
PROCESS_INFORMATION pi;
memset(&pi, 0, sizeof(PROCESS_INFORMATION));
STARTUPINFOA si;
memset(&si, 0, sizeof(STARTUPINFOA));
si.cb = sizeof(STARTUPINFOA);
char *buf = new char[filename.length() + 256]; // ensure that 256 is enough for your extra arguments!
sprintf(buf, "java.exe -jar some.jar <arguments1> \"%s\" <arguments2>", filename.c_str());
// CHECKME: You hard-coded the path for java.exe here. While that may work on your system
// is it guaranteed that it will work on every system?
if(CreateProcessA("C:\\Program Files\\Java\\jre7\\bin\\java.exe", buf, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi))
{
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
}
delete[] buf;
return 0;
}
您应该能够相当容易地弄清楚如何编译等细节。