Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何使Windows文件关联与非ASCII文件名一起工作?_Java_Windows_Unicode_Batch File_File Association - Fatal编程技术网

Java 如何使Windows文件关联与非ASCII文件名一起工作?

Java 如何使Windows文件关联与非ASCII文件名一起工作?,java,windows,unicode,batch-file,file-association,Java,Windows,Unicode,Batch File,File Association,我需要注册特定文件类型的文件关联-事实上,我只需要启动一个带有特定参数和文件名的特定Java程序 我得到的结果如下: // in fff-assoc.cmd file: assoc .fff=SomeFile ftype SomeFile=java -jar some.jar <arguments1> "%%1" <arguments2> 它适用于ASCII文件名。但是,当我试图双击某个名称中带有非ASCII符号的文件时,传递的参数看起来像????每个字符的int值=6

我需要注册特定文件类型的文件关联-事实上,我只需要启动一个带有特定参数和文件名的特定Java程序

我得到的结果如下:

// in fff-assoc.cmd file:
assoc .fff=SomeFile
ftype SomeFile=java -jar some.jar <arguments1> "%%1" <arguments2>
它适用于ASCII文件名。但是,当我试图双击某个名称中带有非ASCII符号的文件时,传递的参数看起来像????每个字符的int值=63

如何修复这些关联

我只需要启动一个带有特定参数和文件名的Java程序

不幸的是,这实际上是不可能的,因为Java使用标准C库的MS实现来接收参数输入。除非直接使用本机Win32 API,绕过标准Java或C接口

有关背景信息,请参阅

我只需要启动一个带有特定参数和文件名的Java程序

不幸的是,这实际上是不可能的,因为Java使用标准C库的MS实现来接收参数输入。除非直接使用本机Win32 API,绕过标准Java或C接口


有关背景信息,请参阅。

从命令行调用java时,可以指定用于在args[]中创建字符串的参数的编码:

使用非ASCII字符时,指定的字符集对args[0]的值有影响。但不确定这是否适用于文件关联


注意:我不确定该参数的其他用途是什么-似乎说没有。

从命令行调用java时,可以指定参数的编码,该编码将用于在args[]中创建字符串:

使用非ASCII字符时,指定的字符集对args[0]的值有影响。但不确定这是否适用于文件关联


注释:我不确定这个参数还有什么用,似乎没有。

< p>如果bobince说的是精确的,并且不能直接把数据直接送到java,一个替代的解决方案是用另一种语言编写一个小的SIMM程序,例如C、C++或C.</P>。 其思想是,程序将输入获取为UNICODE,对其进行编码,使其仅可使用ASCII字符(例如,通过使用base64)表达,甚至可以使用简单的方法(如将每个字符编码为其数字等效项),然后组装命令行参数以使用,并使用CreateProcess启动java本身

Java代码可以撤消编码,重建UNICODE名称并继续使用它。这是一种迂回的方式,需要为您的软件添加一个额外的组件,但如果确实是一个实际的限制,它应该可以绕过上面详述的限制

更新:这是垫片程序的基本代码。它将输入编码为整数序列,用冒号分隔。它在错误检查方面做得不多,您可能想稍微改进一下,但它至少应该让您开始并朝着正确的方向前进

您应该抓取VisualStudio Express,如果您还没有VisualStudio并创建一个新的VisualC++项目,请选择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;
}

你应该能够很容易地找到如何编译等细节。

< P>如果bobince说的是精确的,并且你不能直接把数据直接送到java,那么一个替代的解决方案是用另一种语言编写一个小的SIMM程序,例如C++、C++或C.< 其思想是,程序将输入获取为UNICODE,对其进行编码,使其仅可使用ASCII字符(例如,通过使用base64)表达,甚至可以使用简单的方法(如将每个字符编码为其数字等效项),然后组装命令行参数以使用,并使用CreateProcess启动java本身

Java代码可以撤消编码,重建UNICODE名称并继续使用它。这是一种迂回的方式,需要为您的软件添加一个额外的组件,但如果确实是一个实际的限制,它应该可以绕过上面详述的限制

更新:这是垫片程序的基本代码。它将输入编码为整数序列,用冒号分隔。它在错误检查方面做得不多,您可能想稍微改进一下,但它至少应该让您开始并朝着正确的方向前进

您应该抓取VisualStudio Express,如果您还没有VisualStudio并创建一个新的VisualC++项目,请选择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;
}
你应该能够弄清楚如何进行的细节

编译等都相当容易。

我理解得对吗?完全不可能将文件关联+java或javaws与非ascii文件名一起使用?我不坚持使用命令行,我会完全满足于任何其他的解决方案。它更多的是关于一般的命令行参数,而不是具体的文件关联。但是,看看您的示例,我发现您使用的是%1-通常它会在命令行上传递DOS样式的8.3文件名,这应该可以避免这个问题,而不是%L,它提供完整的长/Unicode名称。是否在计算机上禁用了8.3文件名?或者非ASCII字符是否在文件名以外的其他参数中?不,没有其他非ASCII参数。据我记忆所及,如果我从.bat文件运行它,那么DOS样式的名称将被传递——但切换到.cmd会传递专有名称。切换运行ftype命令的方式会有所不同吗?这不应该发生-就我所知,两种格式应该以相同的方式处理百分比。在HKEY_CLASSES_ROOT\Somefile\Shell\Open\命令下检查注册表,查看通过.bat或.cmd调用ftype是否有任何差异。有一件事让我感到不舒服——例如,如果我启动的不是带有该参数的java程序,而是带有该参数的iexplore.exe IE 7,则它在地址栏中显示正确的名称,即使它不是ascii。因此,可能有一些不明显的方法来启动具有适当参数的应用程序。我理解正确吗?完全不可能将文件关联+java或javaws与非ascii文件名一起使用?我不坚持使用命令行,我会完全满足于任何其他的解决方案。它更多的是关于一般的命令行参数,而不是具体的文件关联。但是,看看您的示例,我发现您使用的是%1-通常它会在命令行上传递DOS样式的8.3文件名,这应该可以避免这个问题,而不是%L,它提供完整的长/Unicode名称。是否在计算机上禁用了8.3文件名?或者非ASCII字符是否在文件名以外的其他参数中?不,没有其他非ASCII参数。据我记忆所及,如果我从.bat文件运行它,那么DOS样式的名称将被传递——但切换到.cmd会传递专有名称。切换运行ftype命令的方式会有所不同吗?这不应该发生-就我所知,两种格式应该以相同的方式处理百分比。在HKEY_CLASSES_ROOT\Somefile\Shell\Open\命令下检查注册表,查看通过.bat或.cmd调用ftype是否有任何差异。有一件事让我感到不舒服——例如,如果我启动的不是带有该参数的java程序,而是带有该参数的iexplore.exe IE 7,则它在地址栏中显示正确的名称,即使它不是ascii。因此,可能有一些不明显的方法来启动具有适当参数的应用程序。是的,这可能会起作用。你能举一个这样的程序的小例子吗?不是转换代码,我可能自己会弄明白,而是包装细节。例如,我应该如何编译它,我应该如何将它打包成.exe?我对C和windows API都不熟练。我在iPhone上打这个,所以我现在很难给你一个示例,但是我明天会发布一个小的框架应用程序来实现这一点。非常感谢这个例子!我抓取了VSE 2010,创建了项目,粘贴了代码和其他东西,但是运行的部分真的让我困惑。如果我将配置更改为Release并点击F7 Build Solution,我将在Release目录中获得Program.exe。但当我试图从命令行program.exe运行它时,我什么也得不到。即使我包括std::cout啊,它也不是一个控制台项目。是的,这可能会起作用。你能举一个这样的程序的小例子吗?不是转换代码,我可能自己会弄明白,而是包装细节。例如,我应该如何编译它,我应该如何将它打包成.exe?我对C和windows API都不熟练。我在iPhone上打这个,所以我现在很难给你一个示例,但是我明天会发布一个小的框架应用程序来实现这一点。非常感谢这个例子!我抓取了VSE 2010,创建了项目,粘贴了代码和其他东西,但是运行的部分真的让我困惑。如果我将配置更改为Release并点击F7 Build Solution,我将在Release目录中获得Program.exe。但当我试图从命令行program.exe运行它时,我什么也得不到。即使我包括std::cout啊,它也不是一个控制台项目。我不确定普通java进程,但它肯定不能通过javaws+关联工作-它只是挂起进程。您没有提到javaws。您也可以在jnlp中传递参数,但不确定非签名jar是否允许使用该参数-例如:。我尝试使用javaws-JDsun.jnu.encoding=cp1252来传递参数…我认为应该是javaws-J-Dsun.jnu.encoding=cp1252是的,您是对的。但那是一个错误
idn没有帮助-它仍然无法识别参数。我不确定普通java进程,但它肯定不能通过javaws+关联工作-它只是挂起进程。您没有提到javaws。您也可以在jnlp中传递参数,但不确定非签名jar是否允许使用该参数-例如:。我尝试使用javaws-JDsun.jnu.encoding=cp1252来传递参数…我认为应该是javaws-J-Dsun.jnu.encoding=cp1252是的,您是对的。但这并没有起到任何作用——它仍然无法识别这些论点。