Expertenfrage Pipe, Shell, Rückgabewerte

  • Access

Es gibt 1 Antwort in diesem Thema. Der letzte Beitrag () ist von Petersilie.

    Expertenfrage Pipe, Shell, Rückgabewerte

    Hallo Gemeinde,

    ich habe ein kleines Problem. Der Aufruf der Shell und das Warten auf Antwort funktioniert ganz gut, ich möchte jedoch auch das Ergebnis auswerten. Dazu übergebe ich | find /c "100%" und erhalte eine 1, wenn der Download erfolgreich war (sicheres FTP. Alles funktioniert fein, aber leider nicht auf einem Windows 7 mit 64 Bit Office. Die Deklarationen habe ich allesamt angepasst, es scheitert an der Funktion Readfile ganz am Ende, davor wird alles erfolgreich durchlaufen. Noch ein kleiner Unterschied, das Dos-Fenster wird unter Windows 10 32 Bit Office (Access) nicht angezeigt, sw_hide, unter Windows 7 64 Bit jedoch schon. Keine Ahnung, warum sich das anders verhält, der Parameter in der Startupinfo ist derselbe.

    Hier der Code.

    Quellcode

    1. Option Explicit
    2. Private Declare PtrSafe Function CreatePipe Lib "kernel32" (phReadPipe As LongPtr, phWritePipe As LongPtr, lpPipeAttributes As SECURITY_ATTRIBUTES, ByVal nSize As Long) As Long
    3. Private Declare PtrSafe Function ReadFile Lib "kernel32" (ByVal hFile As LongPtr, ByVal lpBuffer As Any, ByVal nNumberOfBytesToRead As Long, lpNumberOfBytesRead As Long, lpOverlapped As OVERLAPPED) As Long
    4. Private Declare PtrSafe Function GetNamedPipeInfo Lib "kernel32" (ByVal hNamedPipe As LongPtr, ltype As Long, llenoutbuf As Long, lleninbuf As Long, lpMaxInstances As Long) As Long
    5. Type SECURITY_ATTRIBUTES
    6. nLength As Long
    7. lpSecurityDescriptor As LongPtr
    8. bInheritHandle As Long
    9. End Type
    10. Private Type OVERLAPPED
    11. Internal As LongPtr
    12. InternalHigh As LongPtr
    13. offset As Long
    14. OffsetHigh As Long
    15. hEvent As LongPtr
    16. End Type
    17. Private Type STARTUPINFO
    18. cb As Long
    19. lpReserved As Long
    20. lpDesktop As Long
    21. lpTitle As Long
    22. dwX As Long
    23. dwY As Long
    24. dwXSize As Long
    25. dwYSize As Long
    26. dwXCountChars As Long
    27. dwYCountChars As Long
    28. dwFillAttribute As Long
    29. dwFlags As Long
    30. wShowWindow As Integer
    31. cbReserved2 As Integer
    32. lpReserved2 As Long
    33. hStdInput As Long
    34. hStdOutput As LongPtr
    35. hStdError As Long
    36. End Type
    37. Private Type PROCESS_INFORMATION
    38. hProcess As Long
    39. hThread As Long
    40. dwProcessID As Long
    41. dwThreadID As Long
    42. End Type
    43. Private Declare PtrSafe Function WaitForSingleObject Lib "kernel32" (ByVal hHandle As Long, ByVal dwMilliseconds As Long) As Long
    44. Private Declare PtrSafe Function CreateProcessA Lib "kernel32" (ByVal lpApplicationName As Long, ByVal lpCommandLine As String, lpProcessAttributes As Any, lpThreadAttributes As Any, ByVal bInheritHandles As Long, ByVal dwCreationFlags As Long, ByVal lpEnvironment As Long, ByVal lpCurrentDirectory As Long, lpStartupInfo As Any, lpProcessInformation As Any) As Long
    45. Private Declare PtrSafe Function CloseHandle Lib "kernel32" (ByVal hObject As LongPtr) As Long
    46. Function ShellExecuteCapture(sCommandLine As String, Optional bShowWindow As Boolean = False) As String
    47. Const clReadBytes As Long = 256, INFINITE As Long = &HFFFFFFFF
    48. Const STARTF_USESHOWWINDOW = &H1, STARTF_USESTDHANDLES = &H100&
    49. Const SW_HIDE = 0, SW_NORMAL = 1
    50. Const NORMAL_PRIORITY_CLASS = &H20&
    51. Const PIPE_CLIENT_END = &H0 'The handle refers to the client end of a named pipe instance. This is the default.
    52. Const PIPE_SERVER_END = &H1 'The handle refers to the server end of a named pipe instance. If this value is not specified, the handle refers to the client end of a named pipe instance.
    53. Const PIPE_TYPE_BYTE = &H0 'The named pipe is a byte pipe. This is the default.
    54. Const PIPE_TYPE_MESSAGE = &H4 'The named pipe is a message pipe. If this value is not specified, the pipe is a byte pipe
    55. Dim tProcInfo As PROCESS_INFORMATION, lRetVal As Long, lSuccess As Long
    56. Dim tStartupInf As STARTUPINFO
    57. Dim tSecurAttrib As SECURITY_ATTRIBUTES, lhwndReadPipe As LongPtr, lhwndWritePipe As LongPtr
    58. Dim lBytesRead As Long, sBuffer As String
    59. Dim lPipeOutLen As Long, lPipeInLen As Long, lMaxInst As Long
    60. tSecurAttrib.nLength = Len(tSecurAttrib)
    61. tSecurAttrib.bInheritHandle = 1&
    62. tSecurAttrib.lpSecurityDescriptor = 0&
    63. lRetVal = CreatePipe(lhwndReadPipe, lhwndWritePipe, tSecurAttrib, 0)
    64. If lRetVal = 0 Then
    65. 'CreatePipe failed
    66. Exit Function
    67. End If
    68. tStartupInf.cb = Len(tStartupInf)
    69. tStartupInf.dwFlags = STARTF_USESTDHANDLES Or STARTF_USESHOWWINDOW
    70. tStartupInf.hStdOutput = lhwndWritePipe
    71. If bShowWindow Then
    72. 'Show the DOS window
    73. tStartupInf.wShowWindow = SW_NORMAL
    74. Else
    75. 'Hide the DOS window
    76. tStartupInf.wShowWindow = SW_HIDE
    77. End If
    78. lRetVal = CreateProcessA(0&, sCommandLine, tSecurAttrib, tSecurAttrib, 1&, NORMAL_PRIORITY_CLASS, 0&, 0&, tStartupInf, tProcInfo)
    79. If lRetVal <> 1 Then
    80. 'CreateProcess failed
    81. Exit Function
    82. End If
    83. 'Process created, wait for completion. Note, this will cause your application
    84. 'to hang indefinately until this process completes.
    85. WaitForSingleObject tProcInfo.hProcess, INFINITE
    86. Dim K As OVERLAPPED
    87. 'Determine pipes contents
    88. lSuccess = GetNamedPipeInfo(lhwndReadPipe, PIPE_TYPE_BYTE, lPipeOutLen, lPipeInLen, lMaxInst)
    89. If lSuccess Then
    90. 'Got pipe info, create buffer
    91. sBuffer = String(lPipeOutLen, 0)
    92. 'Read Output Pipe
    93. 'lSuccess = ReadFile(lhwndReadPipe, sBuffer, lPipeOutLen, lBytesRead, 0&)
    94. lSuccess = ReadFile(lhwndReadPipe, sBuffer, lPipeOutLen, lBytesRead, K)
    95. If lSuccess = 1 Then
    96. 'Pipe read successfully
    97. ShellExecuteCapture = Left$(sBuffer, lBytesRead)
    98. End If
    99. End If
    100. 'Close handles
    101. Call CloseHandle(tProcInfo.hProcess)
    102. Call CloseHandle(tProcInfo.hThread)
    103. Call CloseHandle(lhwndReadPipe)
    104. Call CloseHandle(lhwndWritePipe)
    105. End Function


    Der Übergabewert ist: (verändert)
    cmd /c D:\winscp.com /command " open ftps://benutzer:kennwort@firma.de/Ordner -certificate="AA:BB:..." -explicittls " "get datei.endung D:\datei.endung" "exit " > more && type more | find /c "100%"

    Ich danke euch. Wie geschrieben, das Access hängt sich weg beim readfile, bleibt dort mit der Sanduhr stehen. Die Übergabewerte sind allesamt gefüllt, unter Win 10 Office 32 Bit funktioniert alles.
    Hallo,

    du hast deine WinAPI Functions für VBA7 Office64 bit ausgelegt.

    Visual Basic-Quellcode

    1. #if Vba7 then
    2. ' Code is running in the new VBA7 editor
    3. #if Win64 then
    4. ' Code is running in 64-bit version of Microsoft Office
    5. #else
    6. ' Code is running in 32-bit version of Microsoft Office
    7. #end if
    8. #else
    9. ' Code is running in VBA version 6 or earlier
    10. #end if


    msdn.microsoft.com/de-de/vba/l…for-applications-overview


    Du musst deine Types und Declares auf jede eventualität anpassen, sofern diese auf mehereren Windows Systemen laufen sollen.

    Ist nervig, da man alles doppelt und dreifach machen muss, aber was solls...
    Hab damit auch oft zu kämpfen