7zip Shell funktioneirt nicht auf Server

Bild

Betrifft: 7zip Shell funktioneirt nicht auf Server
von: Hannes Respondek
Geschrieben am: 05.10.2015 12:21:09

Hallo Zusammen,
habe ein etwas spezielles Problem, hoffe ihr könnt mir trotzdem helfen.
Wenn ich mein Makro auf meinen PC laufen lasse funktioniert es tadellos und kann mit Hilfe der Shell Funktion eine Datei mit 7zip entpacken.
Wenn ich das Makro allerdings auf einen Server laufen lasse dann entpackt er die Datei nicht. Ohne Fehlermeldung.
Woran kann das liegen? Wenn ich den Shell Befehle direkt in der cmd Kommandozeile eingebe dann klappt das entpacken, in Excel jedoch nicht.
Hier mein Codeaussicht.


Private Declare Function OpenProcess Lib "kernel32.dll" ( _
    ByVal dwDesiredAccess As Long, _
    ByVal bInheritHandle As Long, _
    ByVal dwProcessId As Long) As Long
Private Declare Function CloseHandle Lib "kernel32.dll" ( _
    ByVal hObject As Long) As Long
Private Declare Function WaitForSingleObject Lib "kernel32.dll" ( _
    ByVal hHandle As Long, _
    ByVal dwMilliseconds As Long) As Long
Private Const PROCESS_QUERY_INFORMATION = &H400
Private Const SYNCHRONIZE = &H100000
Private Const INFINITE As Long = &HFFFFFFFF
___________________________________________________________________
Sub gz_entpacken()
'Dieses SUB entpackt eine Datei welche in GZDATEIPFAD
'hinterlegt ist und wartet solange bis die Datei fertig entpackt ist.
Dim fso As Object
Dim str7zipProgramm As String
Dim str7zipArchiv As String
Dim str7zipOrdner As String
Dim lngTaskID As Long
Dim lngProcID As Long
Dim lngExitCode As Long
'ausgewählte Datei entpacken mit 7-Zip
str7zipProgramm = "C:\Program Files\7-Zip\7z.exe" 'Pfad zur 7zip .exe
str7zipArchiv = GZDATEIPFAD  'Pfad zu entpackender Datei
str7zipOrdner = "D:\TEMP"  'Pfad Zielordner
Set fso = CreateObject("Scripting.FileSystemObject")
str7zipProgramm = fso.GetFile(str7zipProgramm).ShortPath
str7zipArchiv = fso.GetFile(str7zipArchiv).ShortPath
str7zipOrdner = fso.GetFolder(str7zipOrdner).ShortPath
'Shell für 7zip.exe verdeckt ausführen und solange warten bis 7zip.exe fertig ist mit entpacken
lngTaskID = Shell(str7zipProgramm & " x " & str7zipArchiv & " -o" & str7zipOrdner,  _
vbMinimizedNoFocus)
    lngProcID = OpenProcess(SYNCHRONIZE + PROCESS_QUERY_INFORMATION, 0&, lngTaskID)
    Call WaitForSingleObject(lngProcID, INFINITE)
    Call CloseHandle(lngProcID)
    AppActivate Application.Caption, True
    
End Sub

Bild

Betrifft: AW: 7zip Shell funktioneirt nicht auf Server
von: Tino
Geschrieben am: 05.10.2015 12:45:33
Hallo,
versuch mal und schließe die Pfadangaben alle in Anführungszeichen ein.
z.Bsp. so.
str7zipProgramm = CHR(34) & "C:\Program Files\7-Zip\7z.exe" & CHR(34)
oder so
str7zipProgramm = """C:\Program Files\7-Zip\7z.exe"""
Gruß Tino

Bild

Betrifft: AW: 7zip Shell funktioneirt nicht auf Server
von: ede
Geschrieben am: 05.10.2015 12:47:36
Hallo Hannes,
wo wird den GZDATEIPFAD gefüllt bzw. welchen Inhalt hat die Variable?
Gruss

Bild

Betrifft: AW: 7zip Shell funktioneirt nicht auf Server
von: Hannes Respondek
Geschrieben am: 05.10.2015 12:55:44
@ede:
In GZDATEIPFAD befindet sich der komplette Pfad der zu entpackenden Datei.
C:\Makro\Prozessdaten\M276 OP60.1\127601111011518800210151700000010104_20150707-135030.xml.gz
@Tino wenn ich das Ganze direkt in die CMD eingebe funktioniert es.. Dabei habe ich 1:1 den von Excel generierten Befehl verwendet.
Nur wenn Excel das selber tun möchte dann nicht

Bild

Betrifft: hast du es mal versuch?
von: Tino
Geschrieben am: 05.10.2015 13:12:14
Hallo,
hatte mal was vergleichbares gemacht zum packen in ein Archiv.
So würde ich es mal versuchen, habe ich jetzt aber nicht getestet.

Sub gz_entpacken()
Dim str7zipProgramm$, str7zipArchiv$, str7zipOrdner$, sShell$
Dim oShell As Object
Set oShell = CreateObject("WScript.Shell")
'ausgewählte Datei entpacken mit 7-Zip
str7zipProgramm = Chr(34) & "C:\Program Files\7-Zip\7z.exe" & Chr(34) 'Pfad zur 7zip .exe
str7zipArchiv = Chr(34) & GZDATEIPFAD & Chr(34) 'Pfad zu entpackender Datei
str7zipOrdner = Chr(34) & "D:\TEMP\" & Chr(34)  'Pfad Zielordner
'Shell Kommando
sShell = str7zipProgramm & " x " & str7zipArchiv & " -o" & str7zipOrdner
'0   Verberge das Fenster und aktiviere ein anderes Fenster.
'1   Aktiviert und zeigt das Fenster in seiner original Größe und Position on.
    'Beim ersten Start einer Anweldung sollte dieser Parameter angegeben werden.
'2   Aktiviert und zeigt das Fenster minimiert an.
'3   Aktiviert und zeigt das Fenster maximiert an.
'4   lZeigt ein Fenster in seinem jüngsten Größe und Position. Das aktive Fenster bleibt aktiv.
'5   Aktiviert das Fenster und zeigt es in seiner jetzigen Größe und Position.
'6   Minimiert das angegebene Fenster und aktiviert das nächste Top-Level-Fenster 
    'in der Z-Reihenfolge
'7   Zeigt das Fenster als einem minimierten Fenster. Das aktive Fenster bleibt aktiv.
'8   Zeigt das Fenster in seinem aktuellen Zustand. Das aktive Fenster bleibt aktiv.
'9   Aktiviert und zeigt das Fenster. Wenn das Fenster minimiert oder maximiert ist,
    'wird Windows es auf seine ursprüngliche Größe und Position anpassen.
    'Eine Anwendung sollte diesen Flag angeben, 
    'bei der Wiederherstellung eines minimierten Fensters.
'10  Aktiviert und zeigt das Fenster gleich der Anwendung aus der das Programm gestartet wurde
'False Script wartet nicht auf die Beendigung des Programms
'True  Script wartet.
oShell.Run sShell, 1, True
    
End Sub
Gruß Tino

Bild

Betrifft: noch was Ähnliches
von: Michael
Geschrieben am: 05.10.2015 16:37:08
Hallo zusammen,
ich habe auch mal was Ähnliches gemacht (allerdings auch nur auf dem PC), hier der Schnipsel:

Set objShell = CreateObject("WScript.Shell")
  Set objExec = objShell.Exec(PfadeUndParameter)
  
  Application.ScreenUpdating = False
'  Application.Calculation = xlCalculationManual
  Do While Not objExec.StdOut.AtEndOfStream
    Debug.Print objExec.StdOut.ReadLine()
  Loop

Der Unterschied zu .Run ist, daß man mit .Exec die Kommandozeilenausgabe des Programms auslesen kann, d.h. man sieht evtl. Fehlermeldungen des Programms.
Ich muß allerdings dazu sagen, daß ich *nicht* 7z.exe verwende, sondern die spezielle Kommandozeilen-Version 7za.exe.
Wenn man 7z installiert, ist die automatisch mit dabei (so weit ich mich erinnere).
@ Tino: danke für die Parameterliste...
Schöne Grüße,
Michael
P.S.: eine ganz saublöde Idee: wenn's gar nicht anders geht, kannst Du evtl. eine Batchdatei auf dem Server mit dem Aufruf erstellen und die über die Shell aufrufen.

Bild

Betrifft: AW: noch was Ähnliches
von: Hannes Respondek
Geschrieben am: 06.10.2015 08:48:56
Erst einmal vielen Dank für eure Hilfe.
Ich habe die Version von Tino genommen,
die entpackt auch einwandfrei (ENDLICH EIN LICHTBLICK :D)
Denke mein Problem war die Anpassung der Pfade.


'ausgewählte Datei entpacken mit 7-Zip
str7zipProgramm = Chr(34) & "C:\Program Files\7-Zip\7z.exe" & Chr(34) 'Pfad zur 7zip .exe
str7zipArchiv = Chr(34) & GZDATEIPFAD & Chr(34) 'Pfad zu entpackender Datei
str7zipOrdner = Chr(34) & "D:\TEMP\" & Chr(34)  'Pfad Zielordner
So ging es einwandfrei. Allerdings hängt sich Excel danach auf. Also bestimmt 5 Minuten, obwohl die Datei längst entpackt ist (das dauert unter 1 Sekunde). Egal ob ich Tinos oder Michaels Variante benutze.
@Michael
wie würde das mit der Batchdatei funktionieren?
Also Datei entpacken, die entpackte Datei in Excel einlesen, entpackte Datei löschen, nächste Datei entpacken usw... Die Datei die entpackt werden soll heißt immer anders

Bild

Betrifft: AW: noch was Ähnliches
von: Tino
Geschrieben am: 06.10.2015 09:05:22
Hallo,
hast du mal den zweiten Parameter auf False gesetzt?
Damit der Code nicht auf die Beendigung wartet!
Gruß Tino

Bild

Betrifft: AW: noch was Ähnliches
von: Hannes Respondek
Geschrieben am: 06.10.2015 09:10:06
GuMo Tino :)
ja habe den Parameter Testweise auch auf False gesetzt, Excel macht nach ausführen der Shell überhaupt nichts mehr. Ich verstehe das nicht.
Die Datei wird entpackt aber Excel hängt sich auf.

Bild

Betrifft: AW: noch was Ähnliches
von: Hannes Respondek
Geschrieben am: 06.10.2015 09:13:52
PS: Excel macht doch was, es dauert nur 10 Minuten :O
Gibt's ne andere Möglichkeit außer das mit ner Shell zu realisieren?

Bild

Betrifft: Datenmenge o. Netzwerk
von: Tino
Geschrieben am: 06.10.2015 09:42:09
Hallo,
wenn sonst kein Code läuft der diese Verzögerung auslöst,
wird es wohl an der Datenmenge die entpackt werden oder/und an der
Netzwerkverbindung liegen die zu langsam ist.
Versuch mal kopiere die Zip lokal auf deinen Rechner und lass deinen Code auch lokal entpacken,
wenn es dann schneller ist sollte klar sein woran es liegt.
Gruß Tino

Bild

Betrifft: 7za
von: Michael
Geschrieben am: 06.10.2015 15:03:34
Hi zusammen,
ich habe Tinos Schnipsel mal angepaßt und um Zeitangaben ergänzt:

Sub gz_entpacken_exec()
Dim str7zipProgramm$, str7zipArchiv$, str7zipOrdner$, sShell$
Dim oShell As Object, oExec As Object
'ausgewählte Datei entpacken mit 7-Zip
'str7zipProgramm = Chr(34) & "C:\Program Files\7-Zip\7z.exe" & Chr(34) 'Pfad zur 7zip .exe
str7zipProgramm = Chr(34) & "C:\7zKommandozeile\7za.exe" & Chr(34) 'Pfad zur 7za .exe
str7zipArchiv = Chr(34) & GZDATEIPFAD & Chr(34) 'Pfad zu entpackender Datei
str7zipOrdner = Chr(34) & "D:\TEMP\" & Chr(34)  'Pfad Zielordner
'Shell Kommando
sShell = str7zipProgramm & " x " & str7zipArchiv & " -o" & str7zipOrdner
Debug.Print Timer & ": Start von shell"
Set oShell = CreateObject("WScript.Shell")
Set oExec = oShell.Exec(strTarget)
  
  Do While Not oExec.StdOut.AtEndOfStream
    Debug.Print Timer & ": " & oExec.StdOut.ReadLine()
  Loop
Debug.Print Timer & ": Nach der Schleife"
Set objShell = Nothing
Set oExec = Nothing
End Sub

(ungetestet)
Zeig uns doch mal, was im Direktfenster steht.
VORAUSSETZUNG: 7za.exe in den Pfad kopieren. Das Ding kannst Du runterladen bei:
http://sourceforge.net/projects/sevenzip/files/7-Zip/9.20/ (dort die Datei 7za920.zip) oder gleich so:
http://sourceforge.net/projects/sevenzip/files/7-Zip/9.20/7za920.zip/download
Zur grundsätzlichen Logik: man führt keine Shell "auf dem Server" aus. Alles, was Du anwirfst, passiert (im RAM) auf Deinem PC: 7zip wird aufgerufen, das wiederum holt sich das Archiv vom Server, lädt es ins RAM, beackert es und speichert das Entpackte schlimmstenfalls wieder auf dem LAN-LW.
Selbst mit einer Batch-Datei wird es nicht anders sein, es sei denn, Du schaffst es, die direkt "auf dem Server" zu starten (scheduled task oder so).
Bitte probiere einfach mal das 7za, das tut bei mir sehr brav.
Zur Batchdatei:
  Dim Datei as integer
  Dim Pfad, ausgabe As String
  Pfad = ThisWorkbook.Path & "\dekomp.bat"
' oder wo auch immer
  Datei = FreeFile
  Open Pfad For Output As #Datei
  Print #Datei, strTarget
  Close #Datei
' die geschriebene Datei dekomp.bat rufst Du dann über die Shell auf

Das ist prinzipiell das Gleiche, wie wenn Du den kompletten Aufruf direkt in die Kommandozeile eingibst.
Ich sehe aber grundsätzlich die Frage, ob es denn wirklich erwünscht ist, ob das alles "asynchron" sein soll, d.h. daß Excel weiterarbeitet, ohne zu wissen, ob der "Auftrag" erfolgreich beendet wurde.
Wenn Du sagst, daß die Datei in Sekundenbruchteilen dekomprimiert ist, muß die Fehlerursache woanders stecken, und um das herauszufinden, habe ich die timer-Aufrufe eingebaut.
7za gibt dann etwa aus (beim debuggen oben MIT Zeitangaben):
7-Zip (A) 9.20  Copyright (c) 1999-2010 Igor Pavlov  2010-11-18
Processing archive: C:\YourDir\Datei.7z
Extracting  Blase.gif
Extracting  Katze.gif
Everything is Ok

und Du kannst anhand der letzten Zeile überprüfen (instr ok?), ob alles paßt.
7za hat im Detail andere, erweiterte Parameter als 7z.exe, aber da Du nur das -o verwendest, isses ok.
Schöne Grüße,
Michael

Bild

Betrifft: läuft danach noch ein anderer Code...
von: Tino
Geschrieben am: 06.10.2015 09:31:39
Hallo,
läuft danach noch ein anderer Code?
Evtl. mal versuchen noch zusätzlich den Parameter -y mit aufnehmen,
damit alle Fragen mit Ja beantwortet werden.
sShell = str7zipProgramm & " x " & str7zipArchiv & " -o" & str7zipOrdner & " -y"
Gruß Tino

 Bild

Beiträge aus den Excel-Beispielen zum Thema "7zip Shell funktioneirt nicht auf Server"