有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

在Windows 7中通过VBA宏绕过System32/SysWOW64 javaw运行java。exe

有没有办法绕过由以下VBA代码“强制”的32位java版本(可能是在VBA中启动进程以调用64位版本cmd、关闭UAC或其他类型的tweek的另一种方式)(这只是一个假设,我在下面解释调试过程):

handleDbl = Shell("javaw -cp theJar.jar com.java.SampleClass", vbNormalFocus)

这里的要点是,我想分享我的宏,避免给接收者添加额外的指令,所以我尝试在代码上做所有事情(我在VBA代码上使用后期绑定,以避免手动设置引用之类的事情)

调试过程

抛出了一个错误,因此我使用了以下行:

handleDbl = Shell("cmd /k java -cp theJar.jar com.java.SampleClass", vbNormalFocus)

得到了错误Exception in thread "main" java.lang.UnsupportedClassVersionError: Unsupported major.minor version,所以我检查了java -version,试图找出运行的是哪个java:

C:\>where java
C:\Windows\System32\java.exe
C:\Program Files\Java\_anyJava.x.x.x_\bin\java.exe

我去了System32文件夹,那里没有java,但我知道redirection从那里发生到C:\Windows\SysWOW64,所以我将之前提取的java版本与C:\Windows\SysWOW64\java.exe -version进行了比较,它们匹配

之后,我检查了我的Outlook版本,结果是32位安装。这是一个暗示,但主要是cmd旁边的那个和那个大的*32。任务管理器中的exe。我不知道64位Outlook是否会有所不同,或者是否会因为VBA实现而有所不同,但这就是我如何总结VBA的Shell函数导致32位java调用的原因


共 (2) 个答案

  1. # 1 楼答案

    通常有一个JAVA_HOME环境变量集。如果是这样的话,你可以这样做:

    Dim JavaExe As String
    JavaExe = """" & Environ("JAVA_HOME") & "\bin\java.exe"""
    handleDbl = Shell("cmd /k " & JavaExe & " -cp theJar.jar com.java.SampleClass", vbNormalFocus)
    

    如果未设置,则必须在编译命令之前通过搜索找到它

  2. # 2 楼答案

    Sam的答案很好,但我只是对用户进行更多设置感到不安,所以我编写了一些函数来检查java的版本,并通知用户它是否在那里(无论如何,在这种情况下都必须安装java),所以下面是我的代码。它可能包含一些有用的东西

    Private Function IsJavaAvailable(ByVal displayMessage As Boolean, Optional ByVal isJavaMandatory As Boolean) As Boolean
        Dim availability As Boolean
        Dim minJavaVersion As Integer
        minJavaVersion = 8
    
        'isJavaSetup is a global variable
        If (Not isJavaSetup) Then
            javawPathQuoted = GetMinimumJavaVersion(minJavaVersion)
            If StrComp(javawPathQuoted, "") <> 0 Then
                isJavaSetup = True
            End If
            SetGlobalVars
        End If
    
        If javawPathQuoted = Empty Then
            availability = False
        Else
            availability = True
        End If
    
        If (displayMessage) Then
            If (isJavaMandatory) Then
                If Not availability Then
                    MsgBox "This functionality is NOT available without Java " & minJavaVersion & "." & _
                    vbNewLine & vbNewLine & _
                    "Please install Java " & minJavaVersion & " or higher.", vbCritical, _
                    "Mimimum Version Required: Java " & minJavaVersion
                End If
            Else
                If Not availability Then
                    MsgBox "Some features of this functionality were disabled." & _
                    vbNewLine & vbNewLine & _
                    "Please install Java " & minJavaVersion & " or higher.", vbExclamation, _
                    "Mimimum Version Required: Java " & minJavaVersion
                End If
    
            End If
        End If
    
        IsJavaAvailable = availability
    
    End Function
    
    Private Function GetMinimumJavaVersion(ByVal javaMinimumMajorVersionInt As Integer) As String
    
        'Run a shell command, returning the output as a string
        Dim commandStr As String
        Dim javawPathVar As Variant
        Dim javaPathStr As Variant
        Dim javaVersionStr As String
        Dim javaMajorVersionInt As Integer
    
        Dim detectedJavaPaths As Collection
        Dim javaVersionElements As Collection
        Dim javaVersionOutput As Collection
        Dim detectedJavaVersions As Collection
    
        Dim suitableJavawPath As String
    
        'Check available javaw executables in the SO
        commandStr = "where javaw"
        Set detectedJavaPaths = GetCommandOutput(commandStr)
        Set detectedJavaVersions = New Collection
    
        For Each javawPathVar In detectedJavaPaths
    
            'Look for java.exe instead of javaw.exe by substituting it in path
            '  javaw.exe does NOT return version output like java.exe
            javaPathStr = StrReverse(Replace(StrReverse(javawPathVar), StrReverse("javaw.exe"), StrReverse("java.exe"), , 1))
            commandStr = """" & javaPathStr & """" & " -version"
            Set javaVersionOutput = GetCommandOutput(commandStr)
            javaVersionStr = javaVersionOutput.item(1)
    
            Debug.Print "Getting java version: ", commandStr
            Debug.Print "Version detected: "; javaVersionStr
    
            Set javaVersionElements = SplitOnDelimiter(javaVersionStr, " ")
    
            'Check that output is not an error or something else
            'java version "1.8.0_75"
            If javaVersionElements.Count > 2 Then
                If StrComp(javaVersionElements.item(1), "java", vbTextCompare) = 0 Then
                    If StrComp(javaVersionElements.item(2), "version", vbTextCompare) = 0 Then
                        detectedJavaVersions.Add javaVersionStr
                        'Remove quotes from "1.8.0_75", split on '.', get 2nd item (java major version) and cast it to Integer
                        javaMajorVersionInt = CInt(SplitOnDelimiter(SplitOnDelimiter(javaVersionElements.item(3), """").item(1), ".").item(2))
                        'JAR will only run in Java 8 or later
                        If (javaMajorVersionInt >= javaMinimumMajorVersionInt) Then
                            'Validate that "javaw.exe" exists since the validation was made with "java.exe"
                            Debug.Print "Verifying if javaw.exe exists: ", javawPathVar
                            If Len(Dir(javawPathVar)) > 0 Then
                                suitableJavawPath = javawPathVar
                                Debug.Print "A suitable javaw.exe version found: ", suitableJavawPath
                                Exit For
                            End If
                        End If
                    End If
                End If
            End If
        Next javawPathVar
    
        GetMinimumJavaVersion = suitableJavawPath
    
    End Function
    
    Private Function GetCommandOutput(ByRef commandStr As String) As Collection
    
        'Run a shell command, returning the output as a string
        Dim shellObj As Object
        Set shellObj = CreateObject("WScript.Shell")
    
        'run command
        Dim wshScriptExecObj As Object
        Dim stdOutObj As Object
        Dim stdErrObj As Object
        Set wshScriptExecObj = shellObj.Exec(commandStr)
        Set stdOutObj = wshScriptExecObj.StdOut
        Set stdErrObj = wshScriptExecObj.StdErr
    
        'handle the results as they are written to and read from the StdOut object
        Dim fullOutputCollection As Collection
        Set fullOutputCollection = New Collection
    
        Dim lineStr As String
        While Not stdOutObj.AtEndOfStream
            lineStr = stdOutObj.ReadLine
            If lineStr <> "" Then
                fullOutputCollection.Add lineStr
            End If
        Wend
    
        If fullOutputCollection.Count = 0 Then
            While Not stdErrObj.AtEndOfStream
                lineStr = stdErrObj.ReadLine
                If lineStr <> "" Then
                    fullOutputCollection.Add lineStr
                End If
            Wend
        End If
    
    
    
        Set GetCommandOutput = fullOutputCollection
    
    End Function