从 VBScript 调用任何带有俄语名称的文件/脚本失败

Posted

技术标签:

【中文标题】从 VBScript 调用任何带有俄语名称的文件/脚本失败【英文标题】:Calling any file/script with Russian name from VBScript fails 【发布时间】:2011-04-26 09:56:12 【问题描述】:

我正在从 utf-8 编码的 XML 文件中读取文件/脚本的名称。然后将其传递给 VBScript。 VBScript 启动第二个程序,该传递的程序/脚本作为参数提供给该程序。当参数为英文时,VBScript 执行成功。

但如果从 XML 读取的名称不是英文(在我的情况下是俄语),VBScript 将无法找到该文件。

当我在 Windows 上运行它时,我只使用“cscript”从 Java 代码运行 VBScript。

但是,如果我复制 Java 程序触发的命令以运行 VBScript,并将其粘贴到命令提示符上,尽管参数名称是非英语语言,它仍会正常执行。

然后我在 VBScript 中硬编码文件/脚本名称。将 VBScript 的编码更改为 UCS2-LE,并直接从命令提示符运行。它正常执行。它无法执行用于 VBScript 的任何其他编码。非英文文本也显示为?采用除 UCS2-LE 以外的任何其他编码。

然后我尝试在 Java 中将文件/脚本名称编码为 UTF16-LE,然后将其传递给 VBScript。无论在 VBScript 中使用哪种编码,它都会失败。同样,如果我从 Java 程序复制打印在标准输出上的命令并从 cmd 运行它,它就会执行。 从 Java 打印的命令正确显示非英文文本。

谁能帮我解决这个问题? 任何相关的帮助将不胜感激。

这就是我目前正在做的事情。我需要将包含俄语文本的参数从 Java 传递给 VBScript。

我尝试使用两种不同的方法。

下面代码中的第一种方法是使用编码 UnicodeLittle 将俄语文本写入文件中。发现文件在编码 UCS-2LE。然后VBScript从那个文件中读取值,脚本就执行成功了。

在第二种方法中,我尝试直接将编码的俄语文本作为参数传递给脚本。 VbScript 无法打开脚本。这是我想要解决的方法。

下面附上Java代码。

任何帮助将不胜感激。

public class CallProgram

     private static String encodeType     = "UnicodeLittle";
private File scriptName          = new File( "F:\\Trial Files\\scriptName.txt" );

public static void main(String[] args) 

    CallProgram obj          = new CallProgram();
    Runtime rt           = Runtime.getRuntime();

    try 
    
        **//Approach1 - Writes text to file and calls vbscript which reads text from file and uses it as an argument to a program**

        String sName    =  "D:\\CheckPoints_SCRIPTS\\Менеджер по качеству";  //Russian Text

        byte [] encodedByte= sName.getBytes( encodeType ); 

        String testCase = new String( encodedByte, encodeType ); //New string containing russian text in UnicodeLittle encoding...

        obj.writeToFile( testCase ); //Writing russian string to file...

        String mainStr  = "cscript /nologo \"D:\\Program Files\\2.0.1.3\\Adapter\\bin\\scriptRunner_FileRead_Write.vbs\"";

                        Process proc1   = rt.exec( mainStr );
        int exit        = proc1.waitFor();
        System.out.println( "Exit Value = " + exit );

                       **//Approach 2 - Passing encoded Russian text directly to VbScript...**
//This is not working for me...
        String [] arrArgs   =  "cscript", "/nologo", "\"D:\\Program Files\\IBM\\Rational Adapters\\2.0.1.3\\QTPAdapter\\bin\\scriptRunner.vbs\"", testcase ;

        ProcessBuilder process     = new ProcessBuilder( arrArgs );
                     Process proc2      = process.start();
        proc2.waitFor();

              
    catch (IOException e) 
    
        e.printStackTrace();
    
    catch ( InterruptedException intue ) 
    
        intue.printStackTrace();
     


     //Function to write Russian text to file using encoding UnicodeLittle...
private void writeToFile( String testCase ) 

    FileOutputStream fos    = null;
    Writer out      = null;
    try 
    
       fos          = new FileOutputStream( this.scriptName );
       out          = new OutputStreamWriter( fos, encodeType );
           out.write( testCase );
       out.close();
       fos.close();
    
    catch (FileNotFoundException e) 
    
       e.printStackTrace();
    
    catch ( IOException ioe )
    
       ioe.printStackTrace();
    
    finally
    
        try
        
            if ( fos != null )
            
                fos.close();
                fos = null;
            

            if ( out != null)
            
                out.close();
                out = null;
            
        
        catch( IOException ioe )
        
            fos = null;
            out = null;
        
    
 // End of method writeToFile....

【问题讨论】:

【参考方案1】:

我以前使用短的 8.3 样式文件名而不是长文件名解决了类似的问题。我使用FileSystemObjectShortPath 方法得到这个简称。这是一个 VBScript 示例...您可能想在 Java 中尝试类似的东西。

Function GetShortPath(strLongPath)

    Dim FSO 
    Dim objFolder 
    Dim objFile 
    Dim strShortPath 

    Set FSO = CreateObject("Scripting.FileSystemObject")

    ' Is it a file or a folder?
    If FSO.FolderExists(strLongPath) Then
       ' It's a folder.
       Set objFolder = FSO.GetFolder(strLongPath)
       strShortPath = objFolder.ShortPath
    ElseIf FSO.FileExists(strLongPath) Then
       ' It's a file.
       Set objFile = FSO.GetFile(strLongPath)
       strShortPath = objFile.ShortPath
    Else
        ' File not found.
        strShortPath = ""
    End If

    GetShortPath = strShortPath

End Function

例如,

Debug.Print GetShortPath("C:\öêåéèüø.çõâ")

返回C:\B373~1,它可以用来代替带有非英文字符的长文件名。以dir /x(显示短文件名)和记事本为例:

C:\sandbox>dir /x
 Volume in drive C has no label.
 Volume Serial Number is BC90-DF37

 Directory of C:\sandbox

13/01/2011  15:12    <DIR>                       .
13/01/2011  15:12    <DIR>                       ..
13/01/2011  14:52                22 NEWTEX~1.TXT New Text Document.txt
13/01/2011  15:05                 0 C7F0~1.TXT   öêåéèüø.txt
13/01/2011  15:05                 0 B373~1       öêåéèüø.çõâ
               3 File(s)             22 bytes
               2 Dir(s)  342,158,913,536 bytes free

C:\sandbox>notepad B373~1

【讨论】:

以上是关于从 VBScript 调用任何带有俄语名称的文件/脚本失败的主要内容,如果未能解决你的问题,请参考以下文章

ProgressBar 在 VBScript HTA 中没有得到刷新

带有俄语语言的 Grails 2.4 中的 UTF-8 问题

vbscript [.net] [vb]从目录发送带有文件附件的电子邮件

检查文件夹中是不是存在任何文件(VBScript)

tinyfiledialogs如何将文件保存在俄语命名文件夹中

无法在 vbscript 中调用“HTMLFile”对象的 Body 属性