Live-Forum - Die aktuellen Beiträge
Anzeige
Archiv - Navigation
1572to1576
Aktuelles Verzeichnis
Verzeichnis Index
Übersicht Verzeichnisse
Vorheriger Thread
Rückwärts Blättern
Nächster Thread
Vorwärts blättern
Anzeige
HERBERS
Excel-Forum (Archiv)
20+ Jahre Excel-Kompetenz: Von Anwendern, für Anwender
Inhaltsverzeichnis

Shell("cmd") Ersatz:zum Start von 64Bit-"cmd"

Shell("cmd") Ersatz:zum Start von 64Bit-"cmd"
21.08.2017 13:53:41
64Bit-"cmd"
Hallo zusammen,
Ein exotischer Titel, bedarf genauerer Erklärung.
Voraussetzung: Windows (7) - 64Bit / Excel (2010) 32-Bit
Wenn ich per VBA-Shell Funktion ein Programm starte, läuft diese automatisch in einer cmd.exe *32 (siehe Taskmanager). Das Java-Programm das ich starten möchte, läuft aber nur richtig, wenn ich es in einer nativen (d.h. 64Bit) cmd.exe starten kann.
Egal, was ich bis jetzt versucht habe: Direkter Aufruf via
lngPid = Shell("cmd")
lngPid = Shell("C:\Windows\system32\cmd")
lngPid = Shell("C:\Windows\sysWOW64\cmd")
Applicatio.OnTime aller Varianten
es wird immer die cmd.exe *32 gestartet.
Vielleicht kennt ein API-Profi (wie z.B. Nepumuk) einen Trick, wie ich aus einer 32Bit-Office Umgebung die 32Bit Schranke durchbrechen und eine 64Bit cmd.exe starten kann?
Vielen Dank und Gruess Hansueli

10
Beiträge zum Forumthread
Beiträge zu diesem Forumthread

Betreff
Datum
Anwender
Anzeige
AW: Shell("cmd") Ersatz:zum Start von 64Bit-"cmd"
21.08.2017 14:00:47
64Bit-"cmd"
Hallo!
Lege mal eine Verknüpfung zur 64-bit-Kommandozeile an (z.B. auf dem Desktop) und führe die Verknüpfung per VBA aus.
Gruß, René
Verknüpfung startet ebenfalls cmd.exe *32
21.08.2017 14:07:48
EtoPHG
Hallo René
Windows ist nicht so einfach auszutricksen:
Starte ich direkt über die Verknüpfung wird cmd.exe (native) gestartet.
Starte ich über VBA-Shell wird cmd.exe *32 gestartet.
Guter Rat ist anscheinend teurer!
Gruess Hansueli
64bit cmd.exe aus office-32bit starten ist offen!
21.08.2017 14:08:37
EtoPHG

AW: 64bit cmd.exe aus office-32bit starten ist offen!
21.08.2017 14:22:42
Nepumuk
Hallo Hansueli,
teste mal:
Option Explicit

Public Declare PtrSafe Function Wow64EnableWow64FsRedirection Lib "kernel32.dll" ( _
    ByVal Enable As Boolean) As Boolean

Public Sub Test()
    Call Wow64EnableWow64FsRedirection(False)
    Call Shell("C:\WINDOWS\System32\cmd.exe")
    Call Wow64EnableWow64FsRedirection(True)
End Sub

Gruß
Nepumuk
Anzeige
Das funktioniert.. cmd.exe 64Bit wird gestartet
21.08.2017 14:59:27
EtoPHG
Danke Nepumuk,
Ich hab gewusst, du hast da was im Ärmel...
Gruess Hansueli
AW: Das funktioniert.. cmd.exe 64Bit wird gestartet
21.08.2017 15:08:36
mumpel
Eine kleine Erweiterung von mir. Mit Unterscheidung zwischen 32-bit und 64-bit. Und da bei "Shell" das Fenster nicht in den Vordergrund rückt arbeite ich mit ShellExecute.
Declare Function ShellExecute Lib "shell32.dll" Alias "ShellExecuteA" _
                                                       (ByVal hWnd As Long, _
                                                        ByVal lpOperation As String, _
                                                        ByVal lpFile As String, _
                                                        ByVal lpParameters As String, _
                                                        ByVal lpDirectory As String, _
                                                        ByVal nshowcmd As Long) As Long
  
Public Declare PtrSafe Function Wow64EnableWow64FsRedirection Lib "kernel32.dll" _
                                                       (ByVal Enable As Boolean) As Boolean
    
Public Const SW_HIDE = 0            'Alternative: vbHide, Fenster versteckt öffnen 
Public Const SW_MAXIMIZE = 3        'Alternative: vbMaximizedFocus, Fenster maximiert öffnen 
Public Const SW_MINIMIZE = 6        'Alternative: vbMinimizedNoFocus, Fenster minimiert öffnen 
Public Const SW_RESTORE = 9
Public Const SW_SHOW = 5
Public Const SW_SHOWDEFAULT = 10
Public Const SW_SHOWMAXIMIZED = 3
Public Const SW_SHOWMINIMIZED = 2   'Alternative: vbMinimizedFocus 
Public Const SW_SHOWMINNOACTIVE = 7
Public Const SW_SHOWNA = 8
Public Const SW_SHOWNOACTIVATE = 4  'Alternative: vbNormalNoFocus 
Public Const SW_SHOWNORMAL = 1      'Alternative: vbNormalFocus 

  
Public Sub RunCMD64()

 Dim objWMI        As Object
 Dim objWMIe       As Object
 Dim obj           As Object
 Dim sql           As String
 Dim strSystemTyp  As String
 Dim strComputer   As String
 Dim varSystemTyp  As Variant
 
 strComputer = "."
 
 Set objWMI = GetObject("winmgmts:" & "{impersonationLevel=impersonate}!\\" _
                        & strComputer & "\root\cimv2")
  
 sql = "SELECT * FROM Win32_ComputerSystem"
 
 Set objWMIe = objWMI.ExecQuery(sql)
 
 For Each obj In objWMIe
     strSystemTyp = obj.SystemType & vbCrLf
 Next obj
 
  varSystemTyp = Split(strSystemTyp, "-")
  
  
  If varSystemTyp(0) = "x64" Then
     Call Wow64EnableWow64FsRedirection(False)
     Call ShellExecute(0, "open", "C:\Windows\system32\cmd.exe", _
                       vbNullString, vbNullString, SW_SHOW)
     Call Wow64EnableWow64FsRedirection(True)
  Else
     Call ShellExecute(0, "open", "C:\Windows\SysWOW64\cmd.exe", _
                       vbNullString, vbNullString, SW_SHOW)
  End If
  
End Sub

VBA/HTML-CodeConverter, AddIn für Office 2002-2016 - in VBA geschrieben von Lukas Mosimann. Projektbetreuung:RMH Software & Media

Code erstellt und getestet in Office 16 - mit VBAHTML 12.6.0


Anzeige
Nachtrag
21.08.2017 15:17:13
mumpel
Braucht man die Prüfung überhaupt?
AW: Nachtrag
21.08.2017 15:24:00
Nepumuk
Hallo René,
32 / 64 Bit Unterscheidung mache ich so (ab Office 2010):
Option Explicit

Private Declare PtrSafe Function GetProcAddress Lib "kernel32.dll" ( _
    ByVal hModule As LongPtr, _
    ByVal lpProcName As String) As LongPtr
Private Declare PtrSafe Function GetModuleHandleA Lib "kernel32.dll" ( _
    ByVal lpModuleName As String) As LongPtr
Private Declare PtrSafe Function IsWow64Process Lib "kernel32.dll" ( _
    ByVal hProcess As LongPtr, _
    ByRef Wow64Process As LongPtr) As Long
Private Declare PtrSafe Function GetCurrentProcess Lib "kernel32.dll" () As LongPtr

Public Sub Test()
    Dim lngptrHandle As LongPtr, lngptrAddress As LongPtr, lngptrIsWow64 As LongPtr
    lngptrHandle = GetModuleHandleA("kernel32.dll")
    lngptrAddress = GetProcAddress(lngptrHandle, "IsWow64Process")
    If lngptrAddress > 0 Then Call IsWow64Process(GetCurrentProcess, lngptrIsWow64)
    If lngptrIsWow64 = 0 Then
        MsgBox "32"
    Else
        MsgBox "64"
    End If
End Sub

WMI ist mir zu langsam.
Gruß
Nepumuk
Anzeige
AW: Nachtrag
21.08.2017 15:31:10
mumpel
Danke! Das verkürzt den Code um "ein paar" Zeilen.
Information: Abgelöste Wow64-Redirection
22.08.2017 15:29:34
EtoPHG
Hallo zäme,
Mein Problem konnte ich lösen.
Microsoft hat aber die API-Funktion Wow64EnableWow64FsRedirection durch 2 neue Funktionen ersetzt. Das Ganze funktioniert jetzt mit den neuen Funktionen so (Windows 64Bit Command Process aus 32Bit Umgebung starten):
' Disable Redirection
Public Declare PtrSafe Function Wow64DisableWow64FsRedirection Lib "kernel32.dll" ( _
ByVal Enable As Boolean) As Boolean
' Revert Disable (re-Enable) Redirection
Public Declare PtrSafe Function Wow64RevertWow64FsRedirection Lib "kernel32.dll" ( _
ByVal Enable As Boolean) As Boolean
Public lngPid As Long       ' PID des Command Processors
' Starts a 64Bit Command Process out of a 32Bit Office Environment
Sub Start64BitCmdProcess()
Dim vRedirected
If lngPid > 0 Then
MsgBox "The 64Bit Command Process is already running!", vbCritical
Exit Sub
End If
vRedirected = Wow64DisableWow64FsRedirection(vRedirected)
lngPid = Shell("cmd", vbNormalFocus)
vRedirected = Wow64RevertWow64FsRedirection(vRedirected)
If lngPid > 0 Then MsgBox "Command Process started as PID " & lngPid
End Sub
' Stopps the started Command Process based on its PID
Sub Stop64BitCmdProcess()
If lngPid > 0 Then
Shell ("taskkill /PID " & lngPid)
MsgBox "Command Process " & lngPid & " killed!"
lngPid = 0
End If
End Sub
Gruess Hansueli
Anzeige

300 Forumthreads zu ähnlichen Themen

Anzeige
Anzeige

Beliebteste Forumthreads (12 Monate)

Anzeige

Beliebteste Forumthreads (12 Monate)

Anzeige
Anzeige
Anzeige