Jump to content

DXRW4E

Active Members
  • Posts

    387
  • Joined

  • Last visited

  • Days Won

    1

Everything posted by DXRW4E

  1. the GUI is completely down, I can not write Label or otherwise, does not respond any more any gui control ect ect I am no expert, but I think maybe a bug in autoit hmmmm, because at work the CPU and RAM and All are ok, there no symptom indicating them and an error occurred during some process, in fact the CPU and the RAM even if archive cab and large, I still work in low levels, and only GUI which does not responding hmmmmmm sorry for my english Ciao
  2. Hi JFX, the point is just that, that happens to me with the setupapi, but used as an example advpack saw there was more simple ;#requireadmin #include <Array.au3>; #include <ButtonConstants.au3> #include <GUIConstantsEx.au3> #include <WindowsConstants.au3> Global Const $h_SetupApiDll = DllOpen("SetupApi.dll") Global Const $h_Kernel32DLL = DllOpen("Kernel32.dll") ;; ;; These are used with SetupIterateCabinet(). ;; Global Const $SPFILENOTIFY_CABINETINFO = 16 ;; 0x00000010 Global Const $SPFILENOTIFY_FILEINCABINET = 17 ;; 0x00000011 Global Const $SPFILENOTIFY_NEEDNEWCABINET = 18 ;; 0x00000012 Global Const $SPFILENOTIFY_FILEEXTRACTED = 19 ;; 0x00000013 Global Const $SPFILENOTIFY_FILEOPDELAYED = 20 ;; 0x00000014 ;; ;; File operation codes and callback outcomes. ;; Global Const $FILEOP_ABORT = 0 Global Const $FILEOP_DOIT = 1 Global Const $FILEOP_SKIP = 2 Global Const $FILEOP_RETRY = $FILEOP_DOIT Global Const $FILEOP_NEWPATH = 4 Global Const $_Context = "WCHAR Encoding[12];WCHAR tContext[108];int Act;WCHAR DestDir[508];WCHAR sDir[508];int cFiles;int sFiles;WCHAR cFilename[508];int cFileSize;WCHAR sFilter[508]" Global $PSPFILECALLBACK, $cCallbackEx, $cCallback[11], $FileInCabinetInfo, $FilePathInfo, $CabinetInfo Global Const $_PSP_FILE_CALLBACK = "" & _ "ptr" & _ ; Context, context used by the callback routine ";UINT" & _ ; Notification, cabinet notification ";UINT_PTR" & _ ; Param1, additional notification information ";UINT_PTR" ; Param2, additional notification information ; $MsgHandler ; Pointer to a FileCallback routine that will process the notifications SetupIterateCabinet returns as it iterates through the files ; in the cabinet file. The callback routine may then return a value specifying whether to decompress, copy, or skip the file. Global $PSP_FILE_CALLBACK = DllCallbackRegister("_FILE_CALLBACK", "UINT", $_PSP_FILE_CALLBACK) Global $pPSP_FILE_CALLBACK = DllCallbackGetPtr($PSP_FILE_CALLBACK) Global $CABINET_CALLBACK_EX = DllCallbackRegister("_CABINET_CALLBACK_EX", "UINT", $_PSP_FILE_CALLBACK) Global $pCABINET_CALLBACK_EX = DllCallbackGetPtr($CABINET_CALLBACK_EX) Global $CABINET_CALLBACK = DllCallbackRegister("_CABINET_CALLBACK", "UINT", $_PSP_FILE_CALLBACK) Global $pCABINET_CALLBACK = DllCallbackGetPtr($CABINET_CALLBACK) Global Const $_FILE_IN_CABINET_INFO_A = "" & _ "ptr" & _ ; File name as it exists within the cabinet file. ("CHAR NameInCabinet[260]" - "STR NameInCabinet") ";DWORD FileSize" & _ ; Uncompressed size of the file in the cabinet, in bytes. ";DWORD Win32Error" & _ ; If an error occurs, this member is the system error code. If no error has occurred, it is NO_ERROR. ";WORD DosDate" & _ ; Date that the file was last saved. ";WORD DosTime" & _ ; MS-DOS time stamp of the file in the cabinet. ";WORD DosAttribs" & _ ; Attributes of the file in the cabinet. ";CHAR FullTargetName[260]" ; Target path and file name. (";STR FullTargetName") Global Const $_FILE_IN_CABINET_INFO_W = "" & _ "ptr" & _ ; File name as it exists within the cabinet file. ("WCHAR NameInCabinet[260]" - "WSTR NameInCabinet") ";DWORD FileSize" & _ ; Uncompressed size of the file in the cabinet, in bytes. ";DWORD Win32Error" & _ ; If an error occurs, this member is the system error code. If no error has occurred, it is NO_ERROR. ";WORD DosDate" & _ ; Date that the file was last saved. ";WORD DosTime" & _ ; MS-DOS time stamp of the file in the cabinet. ";WORD DosAttribs" & _ ; Attributes of the file in the cabinet. ";WCHAR FullTargetName[260]" ; ";WCHAR FullTargetName[260]" - ";WSTR FullTargetName", Target path and file name. Global Const $_FILE_IN_CABINET_INFO_X = "" & _ "ptr" & _ ; File name as it exists within the cabinet file. ("WCHAR NameInCabinet[260]" - "WSTR NameInCabinet") ";DWORD FileSize" & _ ; Uncompressed size of the file in the cabinet, in bytes. ";DWORD Win32Error" & _ ; If an error occurs, this member is the system error code. If no error has occurred, it is NO_ERROR. ";WORD DosDate" & _ ; Date that the file was last saved. ";WORD DosTime" & _ ; MS-DOS time stamp of the file in the cabinet. ";WORD DosAttribs" & _ ; Attributes of the file in the cabinet. ";WCHAR FullTargetName[520]" ; ";WCHAR FullTargetName[260]" - ";WSTR FullTargetName", Target path and file name. Global $_FILE_IN_CABINET_INFO = $_FILE_IN_CABINET_INFO_W ;, $FILE_IN_CABINET_INFO = DllStructCreate($_FILE_IN_CABINET_INFO_W) Global Const $_FILEPATHS_A = "" & _ "ptr" & _ ; Path to the target file. ("CHAR Target[260]" - "STR Target") ";ptr" & _ ; Path to the source file. This member is not used when the FILEPATHS structure is used with a file delete operation. (";CHAR Source[260]" - ";STR Source") ";UINT Win32Error" & _ ; If an error occurs, this member is the system error code. If no error has occurred, it is NO_ERROR. ";DWORD Flags" ; Additional information that depends on the notification sent with the FILEPATHS structure. Global Const $_FILEPATHS_W = "" & _ "ptr" & _ ; Path to the target file. ("WCHAR Target[260]" - "STR Target") ";ptr" & _ ; Path to the source file. This member is not used when the FILEPATHS structure is used with a file delete operation. (";WCHAR Source[260]" - ";STR Source") ";UINT Win32Error" & _ ; If an error occurs, this member is the system error code. If no error has occurred, it is NO_ERROR. ";DWORD Flags" ; Additional information that depends on the notification sent with the FILEPATHS structure. Global $_FILEPATHS = $_FILEPATHS_W ;,$FILEPATHS = DllStructCreate($_FILEPATHS_W) Global Const $_CABINET_INFO_A = "" & _ "ptr" & _ ; Path to the cabinet file. ("CHAR CabinetPath[260]" - "STR CabinetPath") ";ptr" & _ ; Name of the cabinet file. (";CHAR CabinetFile[260]" - ";STR CabinetFile") ";ptr" & _ ; Name of the source media that contains the cabinet file. (";CHAR DiskName[260]" - ";STR DiskName") ";USHORT SetId" & _ ; Identifier of the current set. This number is generated by the software that builds the cabinet. ";USHORT CabinetNumber" ; Number of the cabinet. This number is generated by the software that builds the cabinet and is generally ; a zero- or 1-based index indicating the ordinal of the position of the cabinet within a set. Global Const $_CABINET_INFO_W = "" & _ "ptr" & _ ; Path to the cabinet file. ("WCHAR CabinetPath[260]" - "WSTR CabinetPath") ";ptr" & _ ; Name of the cabinet file. (";WCHAR CabinetFile[260]" - ";WSTR CabinetFile") ";ptr" & _ ; Name of the source media that contains the cabinet file. (";WCHAR DiskName[260]" - ";WSTR DiskName") ";USHORT SetId" & _ ; Identifier of the current set. This number is generated by the software that builds the cabinet. ";USHORT CabinetNumber" ; Number of the cabinet. This number is generated by the software that builds the cabinet and is generally ; a zero- or 1-based index indicating the ordinal of the position of the cabinet within a set. Global $_CABINET_INFO = $_CABINET_INFO_W ;,$CABINET_INFO = DllStructCreate($_CABINET_INFO_W) Local $a1, $a2, $a, $b, $c, $d, $Context ;~ $Context = DllStructCreate($_Context) ;~ DllStructSetData($Context, "Encoding", "WCHAR[260]") ;~ DllStructSetData($Context, "tContext", $_FILE_IN_CABINET_INFO_W) ;~ DllStructSetData($Context, "Act", "1") ;~ ;;DllStructSetData($Context, "DestDir", "D:\aa aa\amd64_3ware.inf.resources_31bf3856ad364e35_6.2.") ;~ ;DllStructSetData($Context, "sFilter", "Startu.*n\.dll\.m.*i") Local $Form, $Button1, $nMsg, $Test $Form1 = GUICreate("Test", 472, 210, 259, 207) $Button1 = GUICtrlCreateButton("Test", 56, 56, 353, 81) GUISetState(@SW_SHOW) While 1 $nMsg = GUIGetMsg() Switch $nMsg Case $GUI_EVENT_CLOSE Exit Case $Button1 ;; example "..\WinXPCD\I386\DRIVER.CAB" $Test = FileOpenDialog("Cab Files", @DesktopDir, "Cab Files (*.cab;*.*_;*.*$)", 1) If Not @Error Then _SetupIterateCabinet($Test, 1) ;;DirCreate(StringLeft($Test, StringInStr($Test, ".", 1, -1) - 1)) ;;Local $ExtractFilesW = DllCall("AdvPack.DLL", "LONG", "ExtractFilesW", "wstr", $Test, "wstr", StringLeft($Test, StringInStr($Test, ".", 1, -1) - 1), "DWORD", 0, "ptr", 0, "ptr", 0, "DWORD", 0) ;;Local $ExtractFiles = DllCall("AdvPack.DLL", "LONG", "ExtractFiles", "str", $Test, "str", StringLeft($Test, StringInStr($Test, ".", 1, -1) - 1), "DWORD", 0, "ptr", 0, "ptr", 0, "DWORD", 0) EndIf EndSwitch WEnd ; #FUNCTION# ============================================================================================================================================== ; Name...........: _SetupIterateCabinet ; Description ...: The SetupIterateCabinet function iterates through all the files in a cabinet and sends a notification to a callback function for each file found. ; Syntax.........: _SetupIterateCabinet($CabinetFile, $Action, $DestDir, $sFilter) ; Parameters ....: $CabinetFile - Cabinet (.CAB) file to iterate through. ; $Action - Optional ; |0 = Count Files & Total Size, Default ; |1 = Extract Files ; $DestDir - Optional, Destination directory (Default is $CabinetFile) ; $sFilter - Optional the filter to use, default is ".*" $sFilter is REGEXP Mod, See Pattern Parameters in StringRegExp ; Return values .: Success - Return The total number of bytes and Set @Extended = The count of files ; Failure - @Error ; |1 = Path not found or invalid ; |2 = If there is an error creating the directory. ; |3 = No File(s) Found ; |4 = The function fails ; Remarks .......: Global Array $cCallback ; If Set $Action = 0 ; $cCallback[0] = The count of files ; $cCallback[1] = The total number of bytes ; $cCallback[2] = Destination directory ; $cCallback[3] = $sFilter ; $cCallback[4] = Last processed File SubDir ; $cCallback[5] = Last processed File Name ; $cCallback[6] = Last processed File Size ; $cCallback[7] = ;;; ; ; If Set $Action = 1 ; $cCallback[0] = The count of files processed ; $cCallback[1] = The total number of bytes extracted ; $cCallback[2] = Destination directory ; $cCallback[3] = $sFilter ; $cCallback[4] = Last processed File SubDir ; $cCallback[5] = Last processed File Name ; $cCallback[6] = Last processed File Size ; $cCallback[7] = ;;; ; Remarks .......: ; Related .......: ; Author ........: DXRW4E ; ========================================================================================================================================================= Func _SetupIterateCabinet($CabinetFile, $Action = 0, $DestDir = "", $sFilter = ".*") $CabinetFile = StringRegExpReplace($CabinetFile, "[\\/]+", "\\") If Not FileExists($CabinetFile) Then Return SetError(1, 0, 0) If $Action Then If Not $DestDir Then $DestDir = StringRegExpReplace($CabinetFile, "(?i)\.cab$", "\\") $DestDir = StringLeft($DestDir, StringInStr($DestDir, "\", 1, -1)) EndIf If StringRight($DestDir, 1) <> "\" Then $DestDir = StringRegExpReplace($DestDir & "\", "[\\/]+", "\\") If Not FileExists($DestDir) And DirCreate($DestDir) = 0 Then Return SetError(2, 0, 0) ;_WinAPI_GetLastErrorEx() EndIf Global $cCallback[11] = [0,0,$DestDir] If Not ($sFilter = ".*") Then $cCallback[3] = $sFilter Local $SetupIterateCabinet = DllCall($h_SetupApiDll, "BOOL", "SetupIterateCabinetW", "wstr", $CabinetFile, "DWORD", 0, "ptr", $pCABINET_CALLBACK, "ptr", $Action) If @Error Or Not $SetupIterateCabinet[0] Then Return SetError(4, 0, "") ;SetError(4, _WinAPI_GetLastErrorEx(), "") If Not $cCallback[0] Then Return SetError(3, 0, "") Return SetError(0, $cCallback[0], $cCallback[1]) EndFunc ;==>_SetupIterateCabinet ; #FUNCTION# ============================================================================================================================================== ; Name...........: _SetupIterateCabinetEx ; Description ...: The SetupIterateCabinet function iterates through all the files in a cabinet and sends a notification to a callback function for each file found. ; Syntax.........: _SetupIterateCabinetEx($CabinetFile, $iFlags, $DestDir, $sFilter) ; Parameters ....: $CabinetFile - Cabinet (.CAB) file to iterate through. ; $iFlags - Optional, Default is ANSI Mod (MAX_PATH = 260), add the flags together for multiple operations: ; |0 = Count Files & Total Size, Default ; |1 = List Files & Total Size & LastEditFies & Attributes & Count Files ; |2 = Extract Files ; |4 = Unicode Mod (MAX_PATH = 260) ; |8 = Unicode Mod, (try to use MAX_PATH = 520) ; |16 = $sFilter do Case-Sensitive matching (By Default $sFilter do Case-Insensitive matching) ; |32 = $sFilter is REGEXP Mod, See Pattern Parameters in StringRegExp (Can not be combined with flag 16) ; $DestDir - Optional, Destination directory (Default is $CabinetFile) ; $sFilter - Optional the filter to use, default is *. (Multiple filter groups such as "All "*.png|*.jpg|*.bmp") Search the Autoit3 helpfile for the word "WildCards" For details. ; Return values .: Success - Return Value or 2D Array (See Remarks) ; Failure - @Error ; |1 = Path not found or invalid ; |2 = If there is an error creating the directory. ; |3 = No File(s) Found ; |4 = The function fails, set extended = GetLastError. ; Remarks .......: If Not Set $iFlags = 1 or $iFlags = 2 ; Set @Extended = The count of files processed and Return The total number of bytes ; If is set the $iFlag = 1 Return is 2D array and is made up as follows: ; $array[0][0] = Number of Files ; $array[0][1] = All Files Size in byte ; $array[1][0] = 1st File Name ; $array[1][1] = 1st File Size in byte ; $array[1][2] = 1st File Data-Time (Modified) ; $array[1][3] = 1st File Attributes ; $array[1][4] = 1st File SubDirectory (example file Path DirName\FilesName.xxx, $array[1][0] = "FilesName.xxx" and $array[1][4] = "DirName\") ; $array[2][0] = 2st File Name ; $array[2][1] = 2st File Size in byte ; $array[2][2] = 2st File Data-Time (Modified) ; $array[2][3] = 2st File Attributes ; $array[2][4] = 2st File SubDirectory (example file Path DirName1\DirName2\FilesName.xxx, $array[2][0] = "FilesName.xxx" and $array[2][4] = "DirName1\DirName2\") ; $array[n][xx] = nth File\Folder ; If is set the $iFlag = 2 ; Set @Extended = The count of files processed and Return The total number of bytes extracted. ; Remarks .......: ; Related .......: ; Author ........: DXRW4E ; ========================================================================================================================================================= Func _SetupIterateCabinetEx($CabinetFile, $iFlags = 1, $DestDir = "", $sFilter = "*") $CabinetFile = StringRegExpReplace($CabinetFile, "[\\/]+", "\\") If Not FileExists($CabinetFile) Then Return SetError(1, 0, 0) Local $SetupIterateCabinet, $cFilter = StringReplace($sFilter, "*", "") If BitAND($iFlags, 2) = 2 Then If Not $DestDir Then $DestDir = StringRegExpReplace($CabinetFile, "(?i)\.cab$", "\\") $DestDir = StringLeft($DestDir, StringInStr($DestDir, "\", 1, -1)) EndIf If StringRight($DestDir, 1) <> "\" Then $DestDir = StringRegExpReplace($DestDir & "\", "[\\/]+", "\\") If Not FileExists($DestDir) And DirCreate($DestDir) = 0 Then Return SetError(2, _WinAPI_GetLastErrorEx(), 0) EndIf If $cFilter And BitAND($iFlags, 32) <> 32 Then $sFilter = StringRegExpReplace(BitAND($iFlags, 16) & "(?i)(", "16\(\?\i\)|\d+", "") & StringRegExpReplace(StringRegExpReplace(StringRegExpReplace(StringRegExpReplace($sFilter, "[^*?|]+", "\\Q$0\\E"), "\\E(?=\||$)", "$0\$"), "(?<=^|\|)\\Q", "^$0"), "\*+", ".*") & ")" Global $cCallbackEx[1564][5] = [[0,0,1562,1563]] If BitAND($iFlags, 1) = 1 Then $cCallbackEx[1563][0] = 1 If BitAND($iFlags, 2) = 2 Then $cCallbackEx[1563][0] = 2 $cCallbackEx[1563][3] = $DestDir If $cFilter Then $cCallbackEx[1563][4] = $sFilter If BitAND($iFlags, 4) = 4 Then $cCallbackEx[1563][1] = $_FILE_IN_CABINET_INFO_W $cCallbackEx[1563][2] = "WCHAR[260]" $SetupIterateCabinet = DllCall($h_SetupApiDll, "BOOL", "SetupIterateCabinetW", "wstr", $CabinetFile, "DWORD", 0, "ptr", $pCABINET_CALLBACK_EX, "ptr", 0) ElseIf BitAND($iFlags, 8) = 8 Then $cCallbackEx[1563][1] = $_FILE_IN_CABINET_INFO_X $cCallbackEx[1563][2] = "WCHAR[520]" $SetupIterateCabinet = DllCall($h_SetupApiDll, "BOOL", "SetupIterateCabinetW", "wstr", $CabinetFile, "DWORD", 0, "ptr", $pCABINET_CALLBACK_EX, "ptr", 0) Else $cCallbackEx[1563][1] = $_FILE_IN_CABINET_INFO_A $cCallbackEx[1563][2] = "CHAR[260]" $SetupIterateCabinet = DllCall($h_SetupApiDll, "BOOL", "SetupIterateCabinet", "str", $CabinetFile, "DWORD", 0, "ptr", $pCABINET_CALLBACK_EX, "ptr", 0) EndIf If @Error Or Not $SetupIterateCabinet[0] Then Return SetError(4, _WinAPI_GetLastErrorEx(), "") If $cCallbackEx[0][0] = 0 Then Return SetError(3, 0, "") If BitAND($iFlags, 1) <> 1 Then Return SetError(0, $cCallbackEx[0][0], $cCallbackEx[0][1]) ReDim $cCallbackEx[$cCallbackEx[0][0] + 1][5] $SetupIterateCabinet = $cCallbackEx $cCallbackEx = 0 Return $SetupIterateCabinet EndFunc ;==>_SetupIterateCabinetEx ; #FUNCTION# ============================================================================================================================================== ; Name...........: _WinAPI_SetupIterateCabinet ; Description ...: The SetupIterateCabinet function iterates through all the files in a cabinet and sends a notification to a callback function for each file found. ; Syntax.........: _WinAPI_SetupIterateCabinet($CabinetFile, $Context, $iFlags) ; Parameters ....: $CabinetFile - Cabinet (.CAB) file to iterate through. ; $Context - The $Context struct returned by DllStructCreate($_Context) (value that is passed into the routine specified in MsgHandler. This enables the callback routine to track) ; Example: ; $Context = DllStructCreate($_Context) ; DllStructSetData($Context, "Encoding", "WCHAR[260]") ; Unicode Mod (MAX_PATH = 260) or "CHAR[260]" ANSI Mod (MAX_PATH = 260) or "WCHAR[520]" Unicode Mod (try to use MAX_PATH = 520) ; DllStructSetData($Context, "tContext", $_FILE_IN_CABINET_INFO_W) ; ;; Unicode Mod (MAX_PATH = 260) $_FILE_IN_CABINET_INFO_W - "ptr;DWORD FileSize;DWORD Win32Error;WORD DosDate;WORD DosTime;WORD DosAttribs;WCHAR FullTargetName[260]" ; ;; ANSI Mod (MAX_PATH = 260) $_FILE_IN_CABINET_INFO_A - "ptr;DWORD FileSize;DWORD Win32Error;WORD DosDate;WORD DosTime;WORD DosAttribs;CHAR FullTargetName[260]" ; ;; Unicode Mod (MAX_PATH = 520) $_FILE_IN_CABINET_INFO_X - "ptr;DWORD FileSize;DWORD Win32Error;WORD DosDate;WORD DosTime;WORD DosAttribs;WCHAR FullTargetName[520]" ; DllStructSetData($Context, "Act", "0") ; Optional, "0" = Get Count Files & Total Size Or 1 = List Files & Total Size & LastEditFiles & Attributes & Count Files Or 2 = Extract ; DllStructSetData($Context, "DestDir", "X:\xxx\") ; Optional, Destination directory (Default is $CabinetFile) ; DllStructSetData($Context, "sFilter", ".*\.dll") ; sFilter is REGEXP Mod, See Pattern Parameters in StringRegExp ; Return values .: ; Return values .: Success - Return Value (See Remarks) ; Failure - @Error ; |1 = Path not found or invalid ; |2 = $Context is not DllStruct type as return by DllStructCreate($_Context) ; |3 = If there is an error creating the (Extract) directory. ; |4 = No File(s) Found ; |5 = The function fails, set extended = GetLastError. ; Remarks .......: If Action - DllStructGetData($Context, "Act") = 0 ; Set @Extended = The count of files processed & Return The total number of bytes ; If Action - DllStructGetData($Context, "Act") = 1 ; Set @Extended = The count of files processed & Return List Files & Total Size & LastEditFiles & Attributes ; FileName1.xxx|147968|17/08/2001 22.36|32 & @LF & FileName2.xxx|187654|05/12/2012 02.36|32 & @LF & FileName1.xxx|ect ect ect ; If Action - DllStructGetData($Context, "Act") = 2 ; Set @Extended = The count of files processed & Return The total number of bytes extracted. ; Related .......: ; Author ........: DXRW4E ; ========================================================================================================================================================= Func _WinAPI_SetupIterateCabinet($CabinetFile, $Context) If Not FileExists($CabinetFile) Then Return SetError(1, 0, 0) If Not IsDllStruct($Context) Then Return SetError(2, 0, 0) Local $DestDir, $SetupIterateCabinet If DllStructGetData($Context, "Act") = 2 Then $DestDir = DllStructGetData($Context, "DestDir") If Not $DestDir Then $DestDir = StringRegExpReplace($CabinetFile, "(?i)\.cab$", "\\") $DestDir = StringLeft($DestDir, StringInStr($DestDir, "\", 1, -1)) EndIf If StringRight($DestDir, 1) <> "\" Then $DestDir = StringRegExpReplace($DestDir & "\", "[\\/]+", "\\") If Not FileExists($DestDir) And DirCreate($DestDir) = 0 Then Return SetError(3, _WinAPI_GetLastErrorEx(), 0) DllStructSetData($Context, "DestDir", $DestDir) EndIf Global $PSPFILECALLBACK If DllStructGetData($Context, "Encoding") = "CHAR[260]" Then $SetupIterateCabinet = DllCall($h_SetupApiDll, "BOOL", "SetupIterateCabinet", "str", $CabinetFile, "DWORD", 0, "ptr", $pPSP_FILE_CALLBACK, "ptr", DllStructGetPtr($Context)) Else $SetupIterateCabinet = DllCall($h_SetupApiDll, "BOOL", "SetupIterateCabinetW", "wstr", $CabinetFile, "DWORD", 0, "ptr", $pPSP_FILE_CALLBACK, "ptr", DllStructGetPtr($Context)) EndIf If @Error Or Not $SetupIterateCabinet[0] Then Return SetError(5, _WinAPI_GetLastErrorEx(), "") If DllStructGetData($Context, "cFiles") = 0 Then Return SetError(4, 0, "") If DllStructGetData($Context, "Act") <> 1 Then Return SetError(0, DllStructGetData($Context, "cFiles"), DllStructGetData($Context, "sFiles")) Return SetError(0, DllStructGetData($Context, "cFiles"), $PSPFILECALLBACK) EndFunc ;==>_WinAPI_SetupIterateCabinet Func _CABINET_CALLBACK($Context, $Notification, $Param1, $Param2) Switch $Notification Case $SPFILENOTIFY_FILEINCABINET ;; 17 - 0x00000011 ; FILE_IN_CABINET_INFO structure ($FileInCabinetInfo) $FileInCabinetInfo = DllStructCreate($_FILE_IN_CABINET_INFO_W, $Param1) ; If an error occurs, this member is the system error code. If no error has occurred, it is NO_ERROR. ;$Win32Error = DllStructGetData($FileInCabinetInfo, "Win32Error") If DllStructGetData($FileInCabinetInfo, "Win32Error") Then Return $FILEOP_SKIP If Not $Context Then If $cCallback[3] And StringRegExp(StringRegExpReplace(DllStructGetData(DllStructCreate("WCHAR[260]", DllStructGetData($FileInCabinetInfo, 1)), 1), ".*\\", ""), $cCallback[3]) = 0 Then Return $FILEOP_SKIP $cCallback[0] += 1 $cCallback[1] += DllStructGetData($FileInCabinetInfo, "FileSize") Return $FILEOP_SKIP EndIf ; File name as it exists within the cabinet file. ;;;$NameInCabinet = DllStructGetData($FileInCabinetInfo, "NameInCabinet") $cCallback[7] = DllStructGetData(DllStructCreate("WCHAR[260]", DllStructGetData($FileInCabinetInfo, 1)), 1) $cCallback[8] = StringInStr($cCallback[7], "\", 1, -1) $cCallback[9] = StringTrimLeft($cCallback[7], $cCallback[8]) If $cCallback[3] And StringRegExp($cCallback[9], $cCallback[3]) = 0 Then Return $FILEOP_SKIP If $cCallback[8] Then $cCallback[8] = StringLeft($cCallback[7], $cCallback[8]) If $Context And Not ($cCallback[4] == $cCallback[8]) And DirCreate($cCallback[2] & $cCallback[8]) = 0 Then Return $FILEOP_SKIP $cCallback[4] = $cCallback[8] Else $cCallback[4] = "" EndIf ;;$cCallback[10] &= $cCallback[7] & ";" $cCallback[0] += 1 $cCallback[5] = $cCallback[9] ; Uncompressed size of the file in the cabinet, in bytes. $cCallback[6] = DllStructGetData($FileInCabinetInfo, "FileSize") ; Target path and file name. ;;;$FullTargetName = DllStructSetData($FileInCabinetInfo, "FullTargetName", "xxxx") DllStructSetData($FileInCabinetInfo, "FullTargetName", $cCallback[2] & $cCallback[4] & $cCallback[5]) Return $FILEOP_DOIT ;; ; Date that the file was last saved. ;; $cCallback[7] = DllStructGetData($FileInCabinetInfo, "DosDate") ;; ; MS-DOS time stamp of the file in the cabinet. ;; $cCallback[8] = DllStructGetData($FileInCabinetInfo, "DosTime") ;; ; _DOSDateTimeToStr($cCallback[7], $cCallback[8]) ;; $cCallback[7] = StringFormat("%02d/%02d/%04d %02d.%02d", BitAND($cCallback[7], 31), BitAND(BitShift($cCallback[7], 5), 15), BitAND(BitShift($cCallback[7], 9), 63) + 1980, BitAND(BitShift($cCallback[8], 11), 31), BitAND(BitShift($cCallback[8], 5), 63)) ;; ; Attributes of the file in the cabinet. ;; ;;;$cCallback[8] = DllStructGetData($FileInCabinetInfo, "DosAttribs") ;; $cCallback[1] += $cCallback[6] ;; Return $FILEOP_SKIP ; callback routine should return one of the following. ; $FILEOP_ABORT = 0 ;Abort cabinet processing. ; $FILEOP_SKIP = 1 ;Do not extract the file, skip it. ; $FILEOP_DOIT = 2 ;Extract the file. ; If your callback routine returns $FILEOP_DOIT, the name to use for the extracted file should be specified in the FullTargetName member ; of the FILE_IN_CABINET_INFO ($FileInCabinetInfo) structure passed to the routine in Param1 ($FileInCabinetInfo). ; Note: There is no default cabinet callback routine. The setup application should supply a callback routine to handle the ; notifications sent by SetupIterateCabinet. Case $SPFILENOTIFY_FILEEXTRACTED ;; 19 - 0x00000013 ; $Param2 Unused. $FilePathInfo = DllStructCreate($_FILEPATHS, $Param1) ; $FilePathInfo contains path information for the extracted file, The SourceFile member of the FILEPATHS structure contains the full ; source path of the cabinet. The TargetFile member supplies the full target path of the file to be installed on the system ; Path to the target file. ;;;$TargetFile = DllStructGetData($FilePathInfo, "Target") ;Local $TargetFile = DllStructGetData(DllStructCreate($tContext, DllStructGetData($FilePathInfo, 1)), 1) ; Path to the source file. This member is not used when the FILEPATHS structure is used with a file delete operation. ;;;$SourceFile = DllStructGetData($FilePathInfo, "Source") ;Local $SourceFile = DllStructGetData(DllStructCreate($tContext, DllStructGetData($FilePathInfo, 2)), 1) ; If an error occurs, this member is the system error code. If no error has occurred, it is NO_ERROR. ;Local $FNFE_Win32Error = DllStructGetData($FilePathInfo, "Win32Error") ; Additional information that depends on the notification sent with the FILEPATHS structure. ;Local $Flags = DllStructGetData($FilePathInfo, "Flags") ; Additional information that depends on the notification sent with the FILEPATHS structure. ; For SPFILENOTIFY_COPYERROR notifications, Flags specifies dialog box behavior and can be one of the following values. ; $SP_COPY_NOBROWSE - Do not offer the user the option to browse. ; $SP_COPY_NOSKIP - Do not offer the user the option to skip the file. ; $SP_COPY_WARNIFSKIP - Inform the user that skipping the file may affect the installation. ; ; For SPFILENOTIFY_FILEOPDELAYED notifications, Flags specifies the type of file operation delayed and can be one of the following values. ; $FILEOP_COPY - A file copy operation was delayed. ; $FILEOP_DELETE - A file delete operation was delayed. ; cabinet callback routine should return one of the following values. ; NO_ERROR - No error was encountered, continue processing the cabinet. ; ERROR_XXX - An error of the specified type occurred. SetupIterateCabinet will return zero. GetLastError will return the specified error code. ; Note: There is no default cabinet callback routine supplied with the Setup API. Your setup application should supply a callback routine to ; handle the notifications sent by the SetupIterateCabinet function. If DllStructGetData($FilePathInfo, "Win32Error") Then Return DllStructGetData($FilePathInfo, "Win32Error") $cCallback[1] += $cCallback[6] Return 0 ;NO_ERROR Case $SPFILENOTIFY_CABINETINFO ;; 16 - 0x00000010 Return 0 ;NO_ERROR $CabinetInfo = DllStructCreate($_CABINET_INFO, $Param1) ;If the callback returns NO_ERROR, $Param2 is a pointer to a null-terminated string. ; If the string is not empty, it specifies a new path to the cabinet. Local $CabinetPath, $CabinetFile, $DiskName, $SetId, $CabinetNumber, $NewPath ; Path to the cabinet file. ;;$CabinetPath = DllStructGetData($CabinetInfo, "CabinetPath") $CabinetPath = DllStructGetData(DllStructCreate("WCHAR[260]", DllStructGetData($CabinetInfo, 1)), 1) ; Name of the cabinet file. ;;;$CabinetFile = DllStructGetData($CabinetInfo, "CabinetFile") $CabinetFile = DllStructGetData(DllStructCreate("WCHAR[260]", DllStructGetData($CabinetInfo, 2)), 1) ; Name of the source media that contains the cabinet file. ;;;$DiskName = DllStructGetData($CabinetInfo, "DiskName") $DiskName = DllStructGetData(DllStructCreate("WCHAR[260]", DllStructGetData($CabinetInfo, 2)), 1) ; Identifier of the current set. This number is generated by the software that builds the cabinet. $SetId = DllStructGetData($CabinetInfo, "SetId") ; Number of the cabinet. This number is generated by the software that builds the cabinet and is generally ; a zero- or 1-based index indicating the ordinal of the position of the cabinet within a set. $CabinetNumber = DllStructGetData($CabinetInfo, "CabinetNumber") ; $SPFILENOTIFY_NEEDNEWCABINET will not have to ever happen, so set to return error, or use FileOpenDialog() ; example $NewPath = FileOpenDialog("Cab Files", @DesktopDir & "\", "Cab Files (*.cab;*.*_;*.*$)", 1) ;Return 3 ;ERROR_PATH_NOT_FOUND, The system cannot find the path specified. ; routine should return one of the following values. ; NO_ERROR - No error was encountered, continue processing the cabinet. ; ERROR_XXX - An error of the specified type occurred. The SetupIterateCabinet function will return FALSE, and the specified ; error code will be returned by a call to GetLastError. ; Note: There is no default cabinet callback routine; thus, you must supply a callback routine to handle the notifications sent by SetupIterateCabinet. ; Remarks: If the callback routine returns NO_ERROR, SetupIterateCabinet checks the buffer pointed to by Param2. If the buffer is not empty, ; then it contains a new source path. If the buffer is empty, the source path is assumed to be unchanged. ; ; callback function should ensure that the cabinet is accessible before it returns, calling the SetupPromptForDisk function, ; if new media needs to be inserted. Return 0 ;NO_ERROR Case $SPFILENOTIFY_NEEDNEWCABINET ;; 18 - 0x00000012 $CabinetInfo = DllStructCreate($_CABINET_INFO, $Param1) ;If the callback returns NO_ERROR, $Param2 is a pointer to a null-terminated string. ; If the string is not empty, it specifies a new path to the cabinet. Local $CabinetPath, $CabinetFile, $DiskName, $SetId, $CabinetNumber, $NewPath ; Path to the cabinet file. ;;;$CabinetPath = DllStructGetData($CabinetInfo, "CabinetPath") $CabinetPath = DllStructGetData(DllStructCreate("WCHAR[260]", DllStructGetData($CabinetInfo, 1)), 1) ; Name of the cabinet file. ;;;$CabinetFile = DllStructGetData($CabinetInfo, "CabinetFile") ;$CabinetFile = DllStructGetData(DllStructCreate("WCHAR[260]", DllStructGetData($CabinetInfo, 2)), 1) ; Name of the source media that contains the cabinet file. ;;;$DiskName = DllStructGetData($CabinetInfo, "DiskName") ;$DiskName = DllStructGetData(DllStructCreate("WCHAR[260]", DllStructGetData($CabinetInfo, 2)), 1) ; Identifier of the current set. This number is generated by the software that builds the cabinet. ;$SetId = DllStructGetData($CabinetInfo, "SetId") ; Number of the cabinet. This number is generated by the software that builds the cabinet and is generally ; a zero- or 1-based index indicating the ordinal of the position of the cabinet within a set. $CabinetNumber = DllStructGetData($CabinetInfo, "CabinetNumber") ; $SPFILENOTIFY_NEEDNEWCABINET will not have to ever happen, so set to return error 3 ERROR_PATH_NOT_FOUND - The system cannot find the path specified, ; or use FileOpenDialog(), example FileOpenDialog("Cab Files", @DesktopDir & "\", "Cab Files (*.cab;*.*_;*.*$)", 1) $NewPath = FileOpenDialog("Cab Files", $CabinetPath, "Cab Files (*.cab;*.*_;*.*$)", 1) If @Error Then Return 3 ;ERROR_PATH_NOT_FOUND, The system cannot find the path specified. DllStructSetData(DllStructCreate("WCHAR[260]", $Param2), 1, $NewPath) Return 0 ;NO_ERROR ; routine should return one of the following values. ; NO_ERROR - No error was encountered, continue processing the cabinet. ; ERROR_XXX - An error of the specified type occurred. The SetupIterateCabinet function will return FALSE, and the specified ; error code will be returned by a call to GetLastError. ; Note: There is no default cabinet callback routine; thus, you must supply a callback routine to handle the notifications sent by SetupIterateCabinet. ; Remarks: If the callback routine returns NO_ERROR, SetupIterateCabinet checks the buffer pointed to by Param2. If the buffer is not empty, ; then it contains a new source path. If the buffer is empty, the source path is assumed to be unchanged. ; ; callback function should ensure that the cabinet is accessible before it returns, calling the SetupPromptForDisk function, ; if new media needs to be inserted. ;Case Else ; EndSwitch Return $FILEOP_ABORT EndFunc Func _CABINET_CALLBACK_EX($Context, $Notification, $Param1, $Param2) Switch $Notification Case $SPFILENOTIFY_FILEINCABINET ;; 17 - 0x00000011 ; FILE_IN_CABINET_INFO structure ($FileInCabinetInfo) $cCallbackEx[0][4] = DllStructCreate($cCallbackEx[$cCallbackEx[0][3]][1], $Param1) ; If an error occurs, this member is the system error code. If no error has occurred, it is NO_ERROR. ;$Win32Error = DllStructGetData($cCallbackEx[0][4], "Win32Error") If DllStructGetData($cCallbackEx[0][4], "Win32Error") Then Return $FILEOP_SKIP If $cCallbackEx[0][0] = $cCallbackEx[0][2] Then If $cCallbackEx[0][2] = 3198976 Then Return $FILEOP_ABORT $cCallbackEx[0][2] *= 2 ReDim $cCallbackEx[$cCallbackEx[0][2] + 2][5] For $i = 0 To 4 $cCallbackEx[$cCallbackEx[0][2] + 1][$i] = $cCallbackEx[$cCallbackEx[0][3]][$i] Next $cCallbackEx[0][3] = $cCallbackEx[0][2] + 1 EndIf $cCallbackEx[0][0] += 1 If Not ($cCallbackEx[$cCallbackEx[0][3]][0] & $cCallbackEx[$cCallbackEx[0][3]][4]) Then $cCallbackEx[0][1] += DllStructGetData($cCallbackEx[0][4], "FileSize") Return $FILEOP_SKIP EndIf ; File name as it exists within the cabinet file. ;;;$NameInCabinet = DllStructGetData($cCallbackEx[0][4], "NameInCabinet") $cCallbackEx[$cCallbackEx[0][0]][0] = DllStructGetData(DllStructCreate($cCallbackEx[$cCallbackEx[0][3]][2], DllStructGetData($cCallbackEx[0][4], 1)), 1) $cCallbackEx[$cCallbackEx[0][0]][1] = StringInStr($cCallbackEx[$cCallbackEx[0][0]][0], "\", 1, -1) $cCallbackEx[$cCallbackEx[0][0]][2] = StringTrimLeft($cCallbackEx[$cCallbackEx[0][0]][0], $cCallbackEx[$cCallbackEx[0][0]][1]) If $cCallbackEx[$cCallbackEx[0][3]][4] And StringRegExp($cCallbackEx[$cCallbackEx[0][0]][2], $cCallbackEx[$cCallbackEx[0][3]][4]) = 0 Then $cCallbackEx[0][0] -= 1 Return $FILEOP_SKIP EndIf If $cCallbackEx[$cCallbackEx[0][0]][1] Then $cCallbackEx[$cCallbackEx[0][0]][4] = StringLeft($cCallbackEx[$cCallbackEx[0][0]][0], $cCallbackEx[$cCallbackEx[0][0]][1]) $cCallbackEx[$cCallbackEx[0][0]][0] = $cCallbackEx[$cCallbackEx[0][0]][2] If $cCallbackEx[$cCallbackEx[0][3]][0] = 2 And Not ($cCallbackEx[$cCallbackEx[0][0] - 1][4] == $cCallbackEx[$cCallbackEx[0][0]][4]) Then If Not DirCreate($cCallbackEx[$cCallbackEx[0][3]][3] & $cCallbackEx[$cCallbackEx[0][0]][4]) Then $cCallbackEx[0][0] -= 1 Return $FILEOP_SKIP EndIf EndIf EndIf ; Uncompressed size of the file in the cabinet, in bytes. $cCallbackEx[$cCallbackEx[0][0]][1] = DllStructGetData($cCallbackEx[0][4], "FileSize") If $cCallbackEx[$cCallbackEx[0][3]][0] = 2 Then ; Target path and file name. ;;;$FullTargetName = DllStructSetData($cCallbackEx[0][4], "FullTargetName", "xxxx") DllStructSetData($cCallbackEx[0][4], "FullTargetName", $cCallbackEx[$cCallbackEx[0][3]][3] & $cCallbackEx[$cCallbackEx[0][0]][4] & $cCallbackEx[$cCallbackEx[0][0]][0]) Return $FILEOP_DOIT Else ; Date that the file was last saved. $cCallbackEx[$cCallbackEx[0][0]][2] = DllStructGetData($cCallbackEx[0][4], "DosDate") ; MS-DOS time stamp of the file in the cabinet. $cCallbackEx[$cCallbackEx[0][0]][3] = DllStructGetData($cCallbackEx[0][4], "DosTime") ; _DOSDateTimeToStr($cCallbackEx[$cCallbackEx[0][0]][2], $cCallbackEx[$cCallbackEx[0][0]][3]) $cCallbackEx[$cCallbackEx[0][0]][2] = StringFormat("%02d/%02d/%04d %02d.%02d", BitAND($cCallbackEx[$cCallbackEx[0][0]][2], 31), BitAND(BitShift($cCallbackEx[$cCallbackEx[0][0]][2], 5), 15), BitAND(BitShift($cCallbackEx[$cCallbackEx[0][0]][2], 9), 63) + 1980, BitAND(BitShift($cCallbackEx[$cCallbackEx[0][0]][3], 11), 31), BitAND(BitShift($cCallbackEx[$cCallbackEx[0][0]][3], 5), 63)) ; Attributes of the file in the cabinet. $cCallbackEx[$cCallbackEx[0][0]][3] = DllStructGetData($cCallbackEx[0][4], "DosAttribs") $cCallbackEx[0][1] += $cCallbackEx[$cCallbackEx[0][0]][1] Return $FILEOP_SKIP EndIf ; callback routine should return one of the following. ; $FILEOP_ABORT = 0 ;Abort cabinet processing. ; $FILEOP_SKIP = 1 ;Do not extract the file, skip it. ; $FILEOP_DOIT = 2 ;Extract the file. ; If your callback routine returns $FILEOP_DOIT, the name to use for the extracted file should be specified in the FullTargetName member ; of the FILE_IN_CABINET_INFO ($cCallbackEx[0][4]) structure passed to the routine in Param1 ($cCallbackEx[0][4]). ; Note: There is no default cabinet callback routine. The setup application should supply a callback routine to handle the ; notifications sent by SetupIterateCabinet. Case $SPFILENOTIFY_FILEEXTRACTED ;; 19 - 0x00000013 ; $Param2 Unused. $cCallbackEx[0][4] = DllStructCreate($_FILEPATHS, $Param1) ; $cCallbackEx[0][4] ($FilePathInfo) contains path information for the extracted file, The SourceFile member of the FILEPATHS structure contains the full ; source path of the cabinet. The TargetFile member supplies the full target path of the file to be installed on the system ; Path to the target file. ;;;$TargetFile = DllStructGetData($cCallbackEx[0][4], "Target") ;Local $TargetFile = DllStructGetData(DllStructCreate($tContext, DllStructGetData($cCallbackEx[0][4], 1)), 1) ; Path to the source file. This member is not used when the FILEPATHS structure is used with a file delete operation. ;;;$SourceFile = DllStructGetData($cCallbackEx[0][4], "Source") ;Local $SourceFile = DllStructGetData(DllStructCreate($tContext, DllStructGetData($cCallbackEx[0][4], 2)), 1) ; If an error occurs, this member is the system error code. If no error has occurred, it is NO_ERROR. ;Local $FNFE_Win32Error = DllStructGetData($cCallbackEx[0][4], "Win32Error") ; Additional information that depends on the notification sent with the FILEPATHS structure. ;Local $Flags = DllStructGetData($cCallbackEx[0][4], "Flags") ; Additional information that depends on the notification sent with the FILEPATHS structure. ; For SPFILENOTIFY_COPYERROR notifications, Flags specifies dialog box behavior and can be one of the following values. ; $SP_COPY_NOBROWSE - Do not offer the user the option to browse. ; $SP_COPY_NOSKIP - Do not offer the user the option to skip the file. ; $SP_COPY_WARNIFSKIP - Inform the user that skipping the file may affect the installation. ; ; For SPFILENOTIFY_FILEOPDELAYED notifications, Flags specifies the type of file operation delayed and can be one of the following values. ; $FILEOP_COPY - A file copy operation was delayed. ; $FILEOP_DELETE - A file delete operation was delayed. ; cabinet callback routine should return one of the following values. ; NO_ERROR - No error was encountered, continue processing the cabinet. ; ERROR_XXX - An error of the specified type occurred. SetupIterateCabinet will return zero. GetLastError will return the specified error code. ; Note: There is no default cabinet callback routine supplied with the Setup API. Your setup application should supply a callback routine to ; handle the notifications sent by the SetupIterateCabinet function. If DllStructGetData($cCallbackEx[0][4], "Win32Error") Then Return DllStructGetData($cCallbackEx[0][4], "Win32Error") $cCallbackEx[0][1] += $cCallbackEx[$cCallbackEx[0][0]][1] Return 0 ;NO_ERROR Case $SPFILENOTIFY_CABINETINFO ;; 16 - 0x00000010 Return 0 ;NO_ERROR ; $CabinetInfo - $cCallbackEx[0][4] $cCallbackEx[0][4] = DllStructCreate($_CABINET_INFO, $Param1) ;If the callback returns NO_ERROR, $Param2 is a pointer to a null-terminated string. ; If the string is not empty, it specifies a new path to the cabinet. Local $CabinetPath, $CabinetFile, $DiskName, $SetId, $CabinetNumber, $NewPath ; Path to the cabinet file. ;;$CabinetPath = DllStructGetData($cCallbackEx[0][4], "CabinetPath") $CabinetPath = DllStructGetData(DllStructCreate($cCallbackEx[$cCallbackEx[0][3]][2], DllStructGetData($cCallbackEx[0][4], 1)), 1) ; Name of the cabinet file. ;;;$CabinetFile = DllStructGetData($cCallbackEx[0][4], "CabinetFile") $CabinetFile = DllStructGetData(DllStructCreate($cCallbackEx[$cCallbackEx[0][3]][2], DllStructGetData($cCallbackEx[0][4], 2)), 1) ; Name of the source media that contains the cabinet file. ;;;$DiskName = DllStructGetData($cCallbackEx[0][4], "DiskName") $DiskName = DllStructGetData(DllStructCreate($cCallbackEx[$cCallbackEx[0][3]][2], DllStructGetData($cCallbackEx[0][4], 2)), 1) ; Identifier of the current set. This number is generated by the software that builds the cabinet. $SetId = DllStructGetData($cCallbackEx[0][4], "SetId") ; Number of the cabinet. This number is generated by the software that builds the cabinet and is generally ; a zero- or 1-based index indicating the ordinal of the position of the cabinet within a set. $CabinetNumber = DllStructGetData($cCallbackEx[0][4], "CabinetNumber") ; $SPFILENOTIFY_NEEDNEWCABINET will not have to ever happen, so set to return error, or use FileOpenDialog() ; example $NewPath = FileOpenDialog("Cab Files", @DesktopDir & "\", "Cab Files (*.cab;*.*_;*.*$)", 1) ;Return 3 ;ERROR_PATH_NOT_FOUND, The system cannot find the path specified. ; routine should return one of the following values. ; NO_ERROR - No error was encountered, continue processing the cabinet. ; ERROR_XXX - An error of the specified type occurred. The SetupIterateCabinet function will return FALSE, and the specified ; error code will be returned by a call to GetLastError. ; Note: There is no default cabinet callback routine; thus, you must supply a callback routine to handle the notifications sent by SetupIterateCabinet. ; Remarks: If the callback routine returns NO_ERROR, SetupIterateCabinet checks the buffer pointed to by Param2. If the buffer is not empty, ; then it contains a new source path. If the buffer is empty, the source path is assumed to be unchanged. ; ; callback function should ensure that the cabinet is accessible before it returns, calling the SetupPromptForDisk function, ; if new media needs to be inserted. Return 0 ;NO_ERROR Case $SPFILENOTIFY_NEEDNEWCABINET ;; 18 - 0x00000012 ; $CabinetInfo - $cCallbackEx[0][4] $cCallbackEx[0][4] = DllStructCreate($_CABINET_INFO, $Param1) ;If the callback returns NO_ERROR, $Param2 is a pointer to a null-terminated string. ; If the string is not empty, it specifies a new path to the cabinet. Local $CabinetPath, $CabinetFile, $DiskName, $SetId, $CabinetNumber, $NewPath ; Path to the cabinet file. ;;;$CabinetPath = DllStructGetData($cCallbackEx[0][4], "CabinetPath") $CabinetPath = DllStructGetData(DllStructCreate($cCallbackEx[$cCallbackEx[0][3]][2], DllStructGetData($cCallbackEx[0][4], 1)), 1) ; Name of the cabinet file. ;;;$CabinetFile = DllStructGetData($cCallbackEx[0][4], "CabinetFile") ;$CabinetFile = DllStructGetData(DllStructCreate($cCallbackEx[$cCallbackEx[0][3]][2], DllStructGetData($cCallbackEx[0][4], 2)), 1) ; Name of the source media that contains the cabinet file. ;;;$DiskName = DllStructGetData($cCallbackEx[0][4], "DiskName") ;$DiskName = DllStructGetData(DllStructCreate($cCallbackEx[$cCallbackEx[0][3]][2], DllStructGetData($cCallbackEx[0][4], 2)), 1) ; Identifier of the current set. This number is generated by the software that builds the cabinet. ;$SetId = DllStructGetData($cCallbackEx[0][4], "SetId") ; Number of the cabinet. This number is generated by the software that builds the cabinet and is generally ; a zero- or 1-based index indicating the ordinal of the position of the cabinet within a set. $CabinetNumber = DllStructGetData($cCallbackEx[0][4], "CabinetNumber") ; $SPFILENOTIFY_NEEDNEWCABINET will not have to ever happen, so set to return error 3 ERROR_PATH_NOT_FOUND - The system cannot find the path specified, ; or use FileOpenDialog(), example FileOpenDialog("Cab Files", @DesktopDir & "\", "Cab Files (*.cab;*.*_;*.*$)", 1) $NewPath = FileOpenDialog("Cab Files", $CabinetPath, "Cab Files (*.cab;*.*_;*.*$)", 1) If @Error Then Return 3 ;ERROR_PATH_NOT_FOUND, The system cannot find the path specified. DllStructSetData(DllStructCreate($cCallbackEx[$cCallbackEx[0][3]][2], $Param2), 1, $NewPath) Return 0 ;NO_ERROR ; routine should return one of the following values. ; NO_ERROR - No error was encountered, continue processing the cabinet. ; ERROR_XXX - An error of the specified type occurred. The SetupIterateCabinet function will return FALSE, and the specified ; error code will be returned by a call to GetLastError. ; Note: There is no default cabinet callback routine; thus, you must supply a callback routine to handle the notifications sent by SetupIterateCabinet. ; Remarks: If the callback routine returns NO_ERROR, SetupIterateCabinet checks the buffer pointed to by Param2. If the buffer is not empty, ; then it contains a new source path. If the buffer is empty, the source path is assumed to be unchanged. ; ; callback function should ensure that the cabinet is accessible before it returns, calling the SetupPromptForDisk function, ; if new media needs to be inserted. ;Case Else ; EndSwitch Return $FILEOP_ABORT EndFunc Func _FILE_CALLBACK($Context, $Notification, $Param1, $Param2) Switch $Notification Case $SPFILENOTIFY_FILEINCABINET ;; 17 - 0x00000011 Local $sContext = DllStructCreate($_Context, $Context), $Act = DllStructGetData($sContext, "Act"), $sFilter = DllStructGetData($sContext, "sFilter") Local $FileInCabinetInfo = DllStructCreate(DllStructGetData($sContext, "tContext"), $Param1) ; If an error occurs, this member is the system error code. If no error has occurred, it is NO_ERROR. ;$FNFIC_Win32Error = DllStructGetData($FileInCabinetInfo, "Win32Error") If DllStructGetData($FileInCabinetInfo, "Win32Error") Then Return $FILEOP_SKIP If Not $Act And Not $sFilter Then DllStructSetData($sContext, "cFiles", DllStructGetData($sContext, "cFiles") + 1) DllStructSetData($sContext, "sFiles", DllStructGetData($sContext, "sFiles") + DllStructGetData($FileInCabinetInfo, "FileSize")) Return $FILEOP_SKIP EndIf Local $tContext = DllStructGetData($sContext, 1), $DestDir, $NameInCabinet, $sNameInCabinet, $FileSize, $DosDate, $DosTime;;, $DateTimeStr, $DosAttribs, $CabinetFile, $FNFIC_Win32Error, $FullTargetName $DestDir = DllStructGetData($sContext, "DestDir") ; File name as it exists within the cabinet file. ;;;$NameInCabinet = DllStructGetData($FileInCabinetInfo, "NameInCabinet") $NameInCabinet = DllStructGetData(DllStructCreate($tContext, DllStructGetData($FileInCabinetInfo, 1)), 1) DllStructSetData($sContext, "cFilename", $NameInCabinet) $sNameInCabinet = StringInStr($NameInCabinet, "\", 1, -1) If $sFilter And StringRegExp(StringTrimLeft($NameInCabinet, $sNameInCabinet), $sFilter) = 0 Then Return $FILEOP_SKIP If $sNameInCabinet Then $sNameInCabinet = StringLeft($NameInCabinet, $sNameInCabinet) If $Act = 2 And Not (DllStructGetData($sContext, "sDir") == $sNameInCabinet) Then If Not DirCreate($DestDir & $sNameInCabinet) Then Return $FILEOP_SKIP DllStructSetData($sContext, "sDir", $sNameInCabinet) EndIf EndIf DllStructSetData($sContext, "cFiles", DllStructGetData($sContext, "cFiles") + 1) ; Uncompressed size of the file in the cabinet, in bytes. $FileSize = DllStructGetData($FileInCabinetInfo, "FileSize") DllStructSetData($sContext, "cFileSize", $FileSize) If $Act = 2 Then ; Target path and file name. ;;;$FullTargetName = DllStructSetData($FileInCabinetInfo, "FullTargetName", "xxxx") DllStructSetData($FileInCabinetInfo, "FullTargetName", DllStructGetData($sContext, "DestDir") & $NameInCabinet) Return $FILEOP_DOIT Else ; Date that the file was last saved. $DosDate = DllStructGetData($FileInCabinetInfo, "DosDate") ; MS-DOS time stamp of the file in the cabinet. $DosTime = DllStructGetData($FileInCabinetInfo, "DosTime") ; _DOSDateTimeToStr($DosDate, $DosTime) ;$DateTimeStr = StringFormat("%02d/%02d/%04d %02d.%02d", BitAND($DosDate, 31), BitAND(BitShift($DosDate, 5), 15), BitAND(BitShift($DosDate, 9), 63) + 1980, BitAND(BitShift($DosTime, 11), 31), BitAND(BitShift($DosTime, 5), 63)) ; Attributes of the file in the cabinet. ;$DosAttribs = DllStructGetData($FileInCabinetInfo, "DosAttribs") DllStructSetData($sContext, "sFiles", DllStructGetData($sContext, "sFiles") + $FileSize) $PSPFILECALLBACK &= $NameInCabinet & "|" & $FileSize & "|" & StringFormat("%02d/%02d/%04d %02d.%02d", BitAND($DosDate, 31), BitAND(BitShift($DosDate, 5), 15), BitAND(BitShift($DosDate, 9), 63) + 1980, BitAND(BitShift($DosTime, 11), 31), BitAND(BitShift($DosTime, 5), 63)) & "|" & DllStructGetData($FileInCabinetInfo, "DosAttribs") & @LF Return $FILEOP_SKIP EndIf ; callback routine should return one of the following. ; $FILEOP_ABORT = 0 ;Abort cabinet processing. ; $FILEOP_SKIP = 1 ;Do not extract the file, skip it. ; $FILEOP_DOIT = 2 ;Extract the file. ; If your callback routine returns $FILEOP_DOIT, the name to use for the extracted file should be specified in the FullTargetName member ; of the FILE_IN_CABINET_INFO ($FileInCabinetInfo) structure passed to the routine in Param1 ($FileInCabinetInfo). ; Note: There is no default cabinet callback routine. The setup application should supply a callback routine to handle the ; notifications sent by SetupIterateCabinet. Case $SPFILENOTIFY_FILEEXTRACTED ;; 19 - 0x00000013 ; $Param2 Unused. Local $FilePathInfo = DllStructCreate($_FILEPATHS, $Param1), $sContext = DllStructCreate($_Context, $Context);, $tContext = DllStructGetData($sContext, 1) ; $FilePathInfo contains path information for the extracted file, The SourceFile member of the FILEPATHS structure contains the full ; source path of the cabinet. The TargetFile member supplies the full target path of the file to be installed on the system ; Path to the target file. ;;;$TargetFile = DllStructGetData($FilePathInfo, "Target") ;Local $TargetFile = DllStructGetData(DllStructCreate($tContext, DllStructGetData($FilePathInfo, 1)), 1) ; Path to the source file. This member is not used when the FILEPATHS structure is used with a file delete operation. ;;;$SourceFile = DllStructGetData($FilePathInfo, "Source") ;Local $SourceFile = DllStructGetData(DllStructCreate($tContext, DllStructGetData($FilePathInfo, 2)), 1) ; If an error occurs, this member is the system error code. If no error has occurred, it is NO_ERROR. ;Local $FNFE_Win32Error = DllStructGetData($FilePathInfo, "Win32Error") ; Additional information that depends on the notification sent with the FILEPATHS structure. ;Local $Flags = DllStructGetData($FilePathInfo, "Flags") ; Additional information that depends on the notification sent with the FILEPATHS structure. ; For SPFILENOTIFY_COPYERROR notifications, Flags specifies dialog box behavior and can be one of the following values. ; $SP_COPY_NOBROWSE - Do not offer the user the option to browse. ; $SP_COPY_NOSKIP - Do not offer the user the option to skip the file. ; $SP_COPY_WARNIFSKIP - Inform the user that skipping the file may affect the installation. ; ; For SPFILENOTIFY_FILEOPDELAYED notifications, Flags specifies the type of file operation delayed and can be one of the following values. ; $FILEOP_COPY - A file copy operation was delayed. ; $FILEOP_DELETE - A file delete operation was delayed. ; cabinet callback routine should return one of the following values. ; NO_ERROR - No error was encountered, continue processing the cabinet. ; ERROR_XXX - An error of the specified type occurred. SetupIterateCabinet will return zero. GetLastError will return the specified error code. ; Note: There is no default cabinet callback routine supplied with the Setup API. Your setup application should supply a callback routine to ; handle the notifications sent by the SetupIterateCabinet function. If DllStructGetData($sContext, "Win32Error") Then Return DllStructGetData($sContext, "Win32Error") DllStructSetData($sContext, "sFiles", DllStructGetData($sContext, "sFiles") + DllStructGetData($sContext, "cFileSize")) Return 0 ;NO_ERROR Case $SPFILENOTIFY_CABINETINFO ;; 16 - 0x00000010 Return 0 ;NO_ERROR Local $CabinetInfo = DllStructCreate($_CABINET_INFO, $Param1), $sContext = DllStructCreate($_Context, $Context), $tContext = DllStructGetData($sContext, 1) ;If the callback returns NO_ERROR, $Param2 is a pointer to a null-terminated string. ; If the string is not empty, it specifies a new path to the cabinet. Local $CabinetPath, $CabinetFile, $DiskName, $SetId, $CabinetNumber, $NewPath ; Path to the cabinet file. ;;$CabinetPath = DllStructGetData($CabinetInfo, "CabinetPath") $CabinetPath = DllStructGetData(DllStructCreate($tContext, DllStructGetData($CabinetInfo, 1)), 1) ; Name of the cabinet file. ;;;$CabinetFile = DllStructGetData($CabinetInfo, "CabinetFile") $CabinetFile = DllStructGetData(DllStructCreate($tContext, DllStructGetData($CabinetInfo, 2)), 1) ; Name of the source media that contains the cabinet file. ;;;$DiskName = DllStructGetData($CabinetInfo, "DiskName") $DiskName = DllStructGetData(DllStructCreate($tContext, DllStructGetData($CabinetInfo, 2)), 1) ; Identifier of the current set. This number is generated by the software that builds the cabinet. $SetId = DllStructGetData($CabinetInfo, "SetId") ; Number of the cabinet. This number is generated by the software that builds the cabinet and is generally ; a zero- or 1-based index indicating the ordinal of the position of the cabinet within a set. $CabinetNumber = DllStructGetData($CabinetInfo, "CabinetNumber") ; $SPFILENOTIFY_NEEDNEWCABINET will not have to ever happen, so set to return error, or use FileOpenDialog() ; example $NewPath = FileOpenDialog("Cab Files", @DesktopDir & "\", "Cab Files (*.cab;*.*_;*.*$)", 1) ;Return 3 ;ERROR_PATH_NOT_FOUND, The system cannot find the path specified. ; routine should return one of the following values. ; NO_ERROR - No error was encountered, continue processing the cabinet. ; ERROR_XXX - An error of the specified type occurred. The SetupIterateCabinet function will return FALSE, and the specified ; error code will be returned by a call to GetLastError. ; Note: There is no default cabinet callback routine; thus, you must supply a callback routine to handle the notifications sent by SetupIterateCabinet. ; Remarks: If the callback routine returns NO_ERROR, SetupIterateCabinet checks the buffer pointed to by Param2. If the buffer is not empty, ; then it contains a new source path. If the buffer is empty, the source path is assumed to be unchanged. ; ; callback function should ensure that the cabinet is accessible before it returns, calling the SetupPromptForDisk function, ; if new media needs to be inserted. Return 0 ;NO_ERROR Case $SPFILENOTIFY_NEEDNEWCABINET ;; 18 - 0x00000012 Local $CabinetInfo = DllStructCreate($_CABINET_INFO, $Param1), $sContext = DllStructCreate($_Context, $Context), $tContext = DllStructGetData($sContext, 1) ;If the callback returns NO_ERROR, $Param2 is a pointer to a null-terminated string. ; If the string is not empty, it specifies a new path to the cabinet. Local $CabinetPath, $CabinetFile, $DiskName, $SetId, $CabinetNumber, $NewPath ; Path to the cabinet file. ;;;$CabinetPath = DllStructGetData($CabinetInfo, "CabinetPath") $CabinetPath = DllStructGetData(DllStructCreate($tContext, DllStructGetData($CabinetInfo, 1)), 1) ; Name of the cabinet file. ;;;$CabinetFile = DllStructGetData($CabinetInfo, "CabinetFile") ;$CabinetFile = DllStructGetData(DllStructCreate($tContext, DllStructGetData($CabinetInfo, 2)), 1) ; Name of the source media that contains the cabinet file. ;;;$DiskName = DllStructGetData($CabinetInfo, "DiskName") ;$DiskName = DllStructGetData(DllStructCreate($tContext, DllStructGetData($CabinetInfo, 2)), 1) ; Identifier of the current set. This number is generated by the software that builds the cabinet. ;$SetId = DllStructGetData($CabinetInfo, "SetId") ; Number of the cabinet. This number is generated by the software that builds the cabinet and is generally ; a zero- or 1-based index indicating the ordinal of the position of the cabinet within a set. $CabinetNumber = DllStructGetData($CabinetInfo, "CabinetNumber") ; $SPFILENOTIFY_NEEDNEWCABINET will not have to ever happen, so set to return error 3 ERROR_PATH_NOT_FOUND - The system cannot find the path specified, ; or use FileOpenDialog(), example FileOpenDialog("Cab Files", @DesktopDir & "\", "Cab Files (*.cab;*.*_;*.*$)", 1) $NewPath = FileOpenDialog("Cab Files", $CabinetPath, "Cab Files (*.cab;*.*_;*.*$)", 1) If @Error Then Return 3 ;ERROR_PATH_NOT_FOUND, The system cannot find the path specified. DllStructSetData(DllStructCreate($tContext, $Param2), 1, $NewPath) Return 0 ;NO_ERROR ; routine should return one of the following values. ; NO_ERROR - No error was encountered, continue processing the cabinet. ; ERROR_XXX - An error of the specified type occurred. The SetupIterateCabinet function will return FALSE, and the specified ; error code will be returned by a call to GetLastError. ; Note: There is no default cabinet callback routine; thus, you must supply a callback routine to handle the notifications sent by SetupIterateCabinet. ; Remarks: If the callback routine returns NO_ERROR, SetupIterateCabinet checks the buffer pointed to by Param2. If the buffer is not empty, ; then it contains a new source path. If the buffer is empty, the source path is assumed to be unchanged. ; ; callback function should ensure that the cabinet is accessible before it returns, calling the SetupPromptForDisk function, ; if new media needs to be inserted. ;Case Else ; EndSwitch Return $FILEOP_ABORT EndFunc ; #FUNCTION# ==================================================================================================================== ; Name...........: _WinAPI_DOSDateTimeToStr ; Description ...: Decode a DOS date to a string ; Syntax.........: _WinAPI_DOSDateTimeToStr($iDosDate, $iDosTime) ; Parameters ....: $iDosDate - MS-DOS date, packed as follows: ; |Bits 0- 4 Day of the month (1–31) ; |Bits 5- 8 Month (1 = January, 2 = February, and so on) ; |Bits 9-15 Year offset from 1980 (add 1980 to get actual year) ; $iDosTime - MS-DOS date, packed as follows: ; |Bits 0- 4 Second divided by 2 ; |Bits 5-10 Minute (0–59) ; |Bits 11-15 Hour (0–23 on a 24-hour clock) ; $LCID - The locale identifier (LCID), Default is 1033 (EN-US) ; Return values .: Success - Date/time string formatted as dd/MM/yyyy HH.mm ; Author ........: DXRW4E ; Modified.......: ; Remarks .......: ; Related .......: ; Link ..........: ; Example .......: ; =============================================================================================================================== Func _WinAPI_DOSDateTimeToStr($iDosDate, $iDosTime, $LCID = "1033") Local $aResult, $bResult, $tTime = DllStructCreate("struct;dword Lo;dword Hi;endstruct"), $tSystTime = DllStructCreate("struct;word Year;word Month;word Dow;word Day;word Hour;word Minute;word Second;word MSeconds;endstruct") DllCall("kernel32.dll", "bool", "DosDateTimeToFileTime", "word", $iDosDate, "word", $iDosTime, "struct*", $tTime) DllCall("kernel32.dll", "bool", "FileTimeToSystemTime", "struct*", $tTime, "struct*", $tSystTime) $aResult = DllCall("kernel32.dll", "int", "GetDateFormatW", "ulong", $LCID, "dword", 0, "struct*", $tSystTime, "wstr", "dd/MM/yyyy", "wstr", "", "int", 2048) $bResult = DllCall("kernel32.dll", "int", "GetTimeFormatW", "ulong", $LCID, "dword", 0, "struct*", $tSystTime, "wstr", " HH.mm", "wstr", "", "int", 2048) ;;If @error Then Return SetError(@error, @extended, 0) Return $aResult[5] & $bResult[5] EndFunc ;==>_WinAPI_DOSDateTimeToStr ; #FUNCTION# ==================================================================================================================== ; Name...........: _DOSDateTimeToStr ; Description ...: Decode a DOS date to a string ; Syntax.........: _DOSDateTimeToStr($iDosDate, $iDosTime) ; Parameters ....: $iDosDate - MS-DOS date, packed as follows: ; |Bits 0- 4 Day of the month (1–31) ; |Bits 5- 8 Month (1 = January, 2 = February, and so on) ; |Bits 9-15 Year offset from 1980 (add 1980 to get actual year) ; $iDosTime - MS-DOS date, packed as follows: ; |Bits 0- 4 Second divided by 2 ; |Bits 5-10 Minute (0–59) ; |Bits 11-15 Hour (0–23 on a 24-hour clock) ; Return values .: Success - Date/time string formatted as mm/dd/yyyy hh:mm:ss ; Author ........: Paul Campbell (PaulIA) ; Modified.......: DXRW4E ; Remarks .......: ; Related .......: _Date_Time_DOSDateTimeToStr, _Date_Time_DOSDateToStr, _Date_Time_DOSTimeToStr ; Link ..........: ; Example .......: ; =============================================================================================================================== Func _DOSDateTimeToStr($iDosDate, $iDosTime) ;; The MS-DOS date. The date is a packed value with the following format. ;; Bits Description ;; 0-4 Day of the month (1–31) = BitAND($iDosDate, 31) ;; 5-8 Month (1 - January, 2 - February, and so on) = BitAND(BitShift($iDosDate, 5), 15) ;; 9-15 Year offset from 1980 (add 1980 to get actual year) = BitAND(BitShift($iDosDate, 9), 63) + 1980 ;; ;; The MS-DOS time. The time is a packed value with the following format. ;; Bits Description ;; 0-4 Second divided by 2 = BitAND($iDosTime, 31) * 2 ;; 5-10 Minute (0–59) = BitAND(BitShift($iDosTime, 5), 63) ;; 11-15 Hour (0–23 on a 24-hour clock) = BitAND(BitShift($iDosTime, 11), 31) Return StringFormat("%02d/%02d/%04d %02d.%02d", BitAND($iDosDate, 31), BitAND(BitShift($iDosDate, 5), 15), BitAND(BitShift($iDosDate, 9), 63) + 1980, BitAND(BitShift($iDosTime, 11), 31), BitAND(BitShift($iDosTime, 5), 63)) EndFunc ;==>_WinAPI_DOSDateTimeToStr Func _WinAPI_GetLastErrorEx() Local $GetLastError = DllCall($h_Kernel32DLL, "long", "GetLastError") Return $GetLastError[0] EndFunc ;==>_WinAPI_GetLastErrorEx Ciao.
  3. Hi all, the problem occurs with every dllcall that to do with the Extract Cab file, both Setupapi & AdvPack, here is an example using AdvPack #include <ButtonConstants.au3> #include <GUIConstantsEx.au3> #include <WindowsConstants.au3> Local $Form, $Button1, $nMsg, $Test $Form1 = GUICreate("Test", 472, 210, 259, 207) $Button1 = GUICtrlCreateButton("Test", 56, 56, 353, 81) GUISetState(@SW_SHOW) While 1 $nMsg = GUIGetMsg() Switch $nMsg Case $GUI_EVENT_CLOSE Exit Case $Button1 ;; example "..\WinXPCD\I386\DRIVER.CAB" $Test = FileOpenDialog("Cab Files", @DesktopDir, "Cab Files (*.cab;*.*_;*.*$)", 1) If Not @Error Then DirCreate(StringLeft($Test, StringInStr($Test, ".", 1, -1) - 1)) Local $ExtractFilesW = DllCall("AdvPack.DLL", "LONG", "ExtractFilesW", "wstr", $Test, "wstr", StringLeft($Test, StringInStr($Test, ".", 1, -1) - 1), "DWORD", 0, "ptr", 0, "ptr", 0, "DWORD", 0) ;Local $ExtractFiles = DllCall("AdvPack.DLL", "LONG", "ExtractFiles", "str", $Test, "str", StringLeft($Test, StringInStr($Test, ".", 1, -1) - 1), "DWORD", 0, "ptr", 0, "ptr", 0, "DWORD", 0) EndIf EndSwitch WEnd the point is that the GUi crashes (when archive Cab and a little big, example ..\WinXPCD\I386\DRIVER.CAB), however the process of extract file, proceed right, on his own sorry for my english Ciao.
  4. Hi Digisoul, impossible to read the entire file using the flag $Cols and $Rows (I mean we do not recommended because it takes a long time), basic logic that Microsoft uses in its files xml and inf ect ect, first load the file and then start the loop ec ect (is the fastest way to read these types of files), example local $a, $b, $c, $t, $Error, $Extended ;; $t = TimerInit() ;; InetGet("http://go.microsoft.com/fwlink/?LinkID=245778", @UserProfileDir & "DownloadsBulletinSearch.xlsx") ;; $a = _XLSXReadToArray(@UserProfileDir & "DownloadsBulletinSearch.xlsx") ;; $Error = @Error ;; $Extended = @Extended ;; $t = TimerDiff($t) ;; ConsoleWrite("Timer = " & $t & @LF) ;; ConsoleWrite("Return = " & $a & " - $Error = " & $Error & " - $Extended = " & $Extended & @LF) ;; Return ;; $a = 2D Array ;; Timer = 11600.4528335857 ;; $Error = 0 ;; $Extended = 15 ;; _ArrayDisplay($a, $t) $a = _XLSXReadToArray(@UserProfileDir & "DownloadsBulletinSearch.xlsx") If Not @Error Then ;use $b = @Extended - 1 or $b = UBound($a, 2) - 1 For $i = 1 To $a[0][0] For $y = 0 To $b $c &= $a[$i][$y] & "|" ; ect ect Next Next EndIf ;; $t = TimerInit() ;; $a = _XLSXReadToArray(@UserProfileDir & "DownloadsBulletinSearch.xlsx", 0, 7) ;; $Error = @Error ;; $Extended = @Extended ;; $t = TimerDiff($t) ;; ConsoleWrite("Timer = " & $t & @LF) ;; ConsoleWrite("Return = " & $a & " - $Error = " & $Error & " - $Extended = " & $Extended & @LF) ;; Return ;; $a = 2D Array ;; Timer = 8768.37496942515 ;; $Error = 0 ;; $Extended = 1 ;; _ArrayDisplay($a, $t) $a = _XLSXReadToArray(@UserProfileDir & "DownloadsBulletinSearch.xlsx", 0, 7) If Not @Error Then ; use $b = @Extended - 1 or $b = UBound($a, 2) - 1, @Extended or UBound($a, 2) is always 1 in this case since it has been chosen read only 1 Column ; even if only one Column, return always is 2D Array, done so as not to create confusion them For $i = 1 To $a[0][0] $c &= $a[$i][0] & "|" ; ect ect Next EndIf ;; $t = TimerInit() ;; $a = _XLSXReadToArray(@UserProfileDir & "DownloadsBulletinSearch.xlsx", 0, 0, 1) ;; $Error = @Error ;; $Extended = @Extended ;; $t = TimerDiff($t) ;; ConsoleWrite("Timer = " & $t & @LF) ;; ConsoleWrite("Return = " & $a & " - $Error = " & $Error & " - $Extended = " & $Extended & @LF) ;; Return ;; $a = 2D Array ;; Timer = 2342.78631833739 ;; $Error = 0 ;; $Extended = 15 ;; _ArrayDisplay($a, $t) $a = _XLSXReadToArray(@UserProfileDir & "DownloadsBulletinSearch.xlsx", 0, 0, 1) If Not @Error Then ; use $b = @Extended - 1 or $b = UBound($a, 2) - 1 ; $a[0][0] is always 1 in this case since it has been chosen read only 1 Row For $i = 0 To $b $c &= $a[1][$b] & "|" ; ect ect Next EndIf ;; $t = TimerInit() ;; $a = _XLSXReadToArray(@UserProfileDir & "DownloadsBulletinSearch.xlsx", 0, 7, 4) ;; $Error = @Error ;; $Extended = @Extended ;; $t = TimerDiff($t) ;; ConsoleWrite("Timer = " & $t & @LF) ;; ConsoleWrite("Return = " & $a & " - $Error = " & $Error & " - $Extended = " & $Extended & @LF) ;; Return ;; $a = Windows Server 2008 R2 for Itanium-Based Systems ;; Timer = 2164.4779710023 ;; $Error = 0 ;; $Extended = 0 $a = _XLSXReadToArray(@UserProfileDir & "DownloadsBulletinSearch.xlsx", 0, 7, 4) If Not @Error Then ;;If @Extended = 1, the ColumnRows was found, but is empty ($a = "") $c = $a EndIf sorry again for my English Ciao a tutti.
  5. Hi Digisoul, Thank you already done, use flags $Cols and $Rows Ciao.
  6. you mean this? $str = StringRegExpReplace(@LF & StringRegExpReplace($str, 'r(?!n)', @CRLF), 'n(r?n)+', "") This is even more easy in this regard, idea however was not the script itself, but the way the regexp works about the speed sorry for my english Ciao.
  7. Hi all, another quick way $iFlag = 2 or $iFlag = 4 or $str = "ect ect ect" $str = StringTrimLeft(StringRegExpReplace(@LF & StringRegExpReplace($str, 'r(?!n)', @CRLF), 'ns*(?=n)', ""), 1) about speed RegExp does not like too much "|" (Or. The expression on one side or the other can be matched.) (rn|r|n) ;or (*BSR_ANYCRLF)(^R|R(?=R)|Rz) ;ect ect ect ;ect ect ectI mean takes a reference point for strength (always takes a reference point to go fast), precisely the ; n Not (rn|n|r) ect ect $str = StringRegExpReplace(@LF & StringRegExpReplace($str, 'r(?!n)', @CRLF), 'n(r?n)+', "") or $str = StringRegExpReplace(@LF & StringRegExpReplace($str, 'r(?!n)', @CRLF), 'ns*(?=n)', "")almost x3 times faster than the local $str2 = StringRegExpReplace($str1,'(*BSR_ANYCRLF)(^R|R(?=R))',"") ;or local $str2 = stringregexpreplace($str1,'(rn|r|n){2,}',"1") ;ect ect ect ;ect ect ectCiao.
  8. I find this really strange, because it is impossible ?? that to me in x86 (in very old and slow pc) and faster that in x64 (Time1 _XLSXReadToArray - 10686.4807752785) hmmmmmmm, maybe something wrong when you do the test I think (as logical) the REGEXP way and more direct (for this reason and also faster than the office, because it ignores many things and goes directly to the point, read only what you need, because the regexp in Autoit I do not think and faster than of what uses Office2013 ehhhhhhh), and logically normally should be faster than __ExcelReadSheetToArray or the use of Excel Object in Autoit, or so I believe may be used as a converter (without having office installed), seen that a time had the array, after and very easy to write the file xml or csv ot txt ect ec, or be of help for script like sorry again for my english Good job to All
  9. not to mention after this (Date Posted) look here Excel 2013 __ExcelReadSheetToArray _XLSXReadToArray however all ok, it was only to clarify the speed is not important, I mean in general important and that one thing work well, after the speed less importance (I also believe the bug "Date" in __ExcelReadSheetToArray i think it will solve quickly and immediately, i think and a small thing, as mentioned above was just to clarify) Good job to all
  10. NO ehhhhh, as I suspected and as I said above and as a logical (object in autoit, they will never be faster than the same Office ehhhhh, if 2 times faster than Office 2013, was not logical that the__ExcelReadSheetToArray will be 2 times faster than ), __ExcelReadSheetToArray and 3 times more slowly then #include <Array.au3> #include "_XLSXReadToArray.au3" #include <excel.au3> Local $a1, $b1 InetGet("http://go.microsoft.com/fwlink/?LinkID=245778", @WindowsDir & "TempBulletinSearch.xlsx") $a1 = TimerInit() $b1 = _XLSXReadToArray(@WindowsDir & "TempBulletinSearch.xlsx") $a1 = TimerDiff($a1) _ArrayDisplay($b1, $a1) ConsoleWrite("Time1 - " & $a1 & @LF) $a1 = TimerInit() $File = _ExcelBookOpen(@WindowsDir & "TempBulletinSearch.xlsx", 0) $b1 = __ExcelReadSheetToArray($File) $a1 = TimerDiff($a1) _ArrayDisplay($b1, $a1) ConsoleWrite("Time1 - " & $a1 & @LF) _ExcelBookClose($File) Exit ; #FUNCTION# ==================================================================================================================== ; Name...........: __ExcelReadSheetToArray ; Description ...: Create a 2D array from the rows/columns of the active worksheet. ; Syntax.........: _ExcelReadSheetToArray($oExcel[, $iStartRow = 1[, $iStartColumn = 1[, $iRowCnt = 0[, $iColCnt = 0]]]]) ; Parameters ....: $oExcel - excel object opened by a preceding call to _ExcelBookOpen() or _ExcelBookNew() ; $iStartRow - Row number to start reading, defaults to 1 (first row) ; $iStartColumn - Column number to start reading, defaults to 1 (first column) ; $iRowCnt - Count of rows to read, defaults to 0 (all) ; $iColCnt - Count of columns to read, defaults to 0 (all) ; $iColShift - Match R1C1 column position, or start array in column 0. Default is 0 (match R1C1 values) ; Return values .: Success - Returns a 2D array with the specified cell contents by [$row][$col] ; Failure - Returns 0 and sets @error on errors: ; [email="|@error=1"]|@error=1[/email] - Specified object does not exist ; [email="|@error=2"]|@error=2[/email] - Start parameter out of range ; [email="|@extended=0"]|@extended=0[/email] - Row out of range ; [email="|@extended=1"]|@extended=1[/email] - Column out of range ; [email="|@error=3"]|@error=3[/email] - Count parameter out of range ; [email="|@extended=0"]|@extended=0[/email] - Row count out of range ; [email="|@extended=1"]|@extended=1[/email] - Column count out of range ; Author ........: SEO ; Modified.......: PsaltyDS 01/04/08 - 2D version, litlmike - Column shift parm, Golfinhu - Speed enhancement, Spiff59 - Allow protected sheets ; Remarks .......: Returned array has row count in [0][0] and column count in [0][1] (unless ; Except for the counts above, row 0 and col 0 of the returned array are empty, as actual ; cell data starts at [1][1] to match R1C1 numbers. ; By default the entire sheet is returned. ; If the sheet is empty [0][0] and [0][1] both = 0. ; Related .......: ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func __ExcelReadSheetToArray($oExcel, $iStartRow = 1, $iStartColumn = 1, $iRowCnt = 0, $iColCnt = 0, $iColShift = 0) ; Parameter edits If Not IsObj($oExcel) Then Return SetError(1, 0, 0) If $iStartRow < 1 Then Return SetError(2, 0, 0) If $iStartColumn < 1 Then Return SetError(2, 1, 0) If $iRowCnt < 0 Then Return SetError(3, 0, 0) If $iColCnt < 0 Then Return SetError(3, 1, 0) Local $iLastRow = $oExcel.Activesheet.UsedRange.Rows.Count Local $iLastColumn = $oExcel.Activesheet.UsedRange.Columns.Count If ($iLastRow + $iLastColumn = 2) And $oExcel.Activesheet.Cells(1, 1).Value = "" Then ; empty result Local $avRET[1][2] = [[0, 0]] Return $avRET EndIf ; Parameter edits (continued) If $iStartRow > $iLastRow Then Return SetError(2, 0, 0) If $iStartColumn > $iLastColumn Then Return SetError(2, 1, 0) If $iStartRow + $iRowCnt - 1 > $iLastRow Then Return SetError(3, 0, 0) If $iStartColumn + $iColCnt - 1 > $iLastColumn Then Return SetError(3, 1, 0); Check for defaulted counts If $iRowCnt Then $iLastRow = $iStartRow + $iRowCnt - 1 Else $iRowCnt = $iLastRow - $iStartRow + 1 EndIf If $iColCnt Then $iLastColumn = $iStartColumn + $iColCnt - 1 Else $iColCnt = $iLastColumn - $iStartColumn + 1 EndIf ; Read data Local $aArray = $oExcel.ActiveSheet.Range($oExcel.Cells($iStartRow, $iStartColumn), $oExcel.Cells($iLastRow, $iLastColumn)).Value If Not IsArray($aArray) Then ; single-cell result Local $avRET[2][2] = [[1, 1],["", $aArray]] Return $avRET EndIf ; Convert Col/Row array from Excel to Row/Col Local $avRET[$iRowCnt + 1][$iColCnt + ($iColCnt = 1 Or $iColShift = 0)] = [[$iRowCnt, $iColCnt]] For $i = 1 To $iColCnt For $j = 1 To $iRowCnt $avRET[$j][$i - $iColShift] = $aArray[$i - 1][$j - 1] Next Next Return $avRET EndFunc ;==>_ExcelReadSheetToArray
  11. you mean post #8 right ???I'm really very curious about your test ???, can you just post exactly all the the script to that used during the your test ????? because if it's true what you said, means that your test and x 4 times faster than the Office 2013, this does not seem very logical hmmmmmmmmm the and 2 times faster than Office 2013 because it uses a different way (or direct way) to read the file, but using the object, or the same way of the office, I do not see how he could never be faster than the same office, and not faster but 4 times faster than hmmmmmmmmm this is not little, that makes a really big difference in my opinion
  12. and even faster and does not useneed office & object ect ect, but only for the XLSX (Office 2007 or more recent) Ciao.
  13. @jazzyjeff Thank You, You are welcome @All Updated, add $iFlag = 64 now you can use the $sFilter in RegExp Mod (See Pattern Parameters in StringRegExp ) Ciao.
  14. Updated, add $iFlag = 128 Return Backslash at the beginning of the file name, example Return "Filename1.xxx" and the $iFlag = 64 now you can use the $sFilter in RegExp Mod (See Pattern Parameters in StringRegExp ) use $iFlag 64 and $sFilter = "[123]+.txt" to find files 1231.txt or 12313.txt 1111111.txt ect ect ("[123]+" = "123???"), see StringRegExp the options are endless them For example #include <Array.au3> #include <_FileListToArrayEx.au3> Global $a1, $b1 $a1 = TimerInit() $b1 = _FileListToArrayEx(@WindowsDir, "[123]+.txt", 64) $a1 = TimerDiff($a1) _ArrayDisplay($b1, $a1) now or attached _FileListToArrayEx.au3, because only now noticed that there were parts of the code, the autoit codetag (in the first post of the topic) removed the "=" from the pattern of the regexp ect ect Ciao.
  15. The _XLSXReadToArray Fuction Reads the EXCEL XLSX Sheet into an Array, not needed that Office is installed and do not use Object just use the REGEXP so_XLSXReadToArray works very fast, in a test done by me here with BulletinSearch_20121008_170143.xlsx (1,5 Mb, Rows = 12148 & Column = 15), the _XLSXReadToArray Return Array in 10 seconds, instead to Excel 2013 them have served more than 20 seconds to open the file ect ect, Normally should not happen ever of not finding the "[Content_Types].xml" or other files mentioned in "[Content_Types].xml", but if anything happens already Added the >_FileListToArrayEx to try to search the *.xml files in "Temp Extract Diretory" #include-once ; #UDF# ======================================================================================================================= ; Title .........: XLSX Read To Array ; AutoIt Version : 3.3.8.1 ; Language ......: English ; Description ...: Fuction Reads the EXCEL XLSX Sheet into an Array ; Author(s) .....: DXRW4E ; Notes .........: ; =============================================================================================================================== ; #CURRENT# ===================================================================================================================== ;~ _XLSXReadToArray ;~ _XLSXSheetGetColumnNumber ;~ _SSNToDate ;~ _DateToSSN ;~ _FileListToArrayEx ; =============================================================================================================================== If Not ObjEvent("AutoIt.Error") Then Global Const $_XLSXZip_COMErrorFunc = ObjEvent("AutoIt.Error", "_XLSXZip_COMErrorFunc") Global $DateSSN[27] = [0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31, 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335] ; #FUNCTION# ================================================================================================================================ ; Name...........: _XLSXReadToArray ; Description ...: The _XLSXReadToArray Fuction Reads the EXCEL XLSX Sheet into an Array ; Syntax.........: _XLSXReadToArray($XLSXFilePath, $iFlag) ; Parameters ....: $XLSXFilePath - Path and filename of the XLSX file to be read. ; $iFlag - Optional ; |$iFlag = 0 (Default) None ; |$iFlag = 1 if there are also add HyperLinks in the Array ; Strings\Test in Column\Rows will separate from HyperLink by @LF, example "Value" & @LF & http://www.autoitscript.com/forum/ ; |$Cols - Optional, Columns Number to Read (read only X column) ; |$Rows - Optional, Rows Number to Read (read only X Row) ; |$iSheet - Optional, Number of Sheet*.xml to Read, Default is 1 ; Return values .: Success - Return ; Array ($Array[0][0] = Rows Number & @Extended = Column Nmmber) ; If Set $Cols and $Rows Return is String Data, if Return Strigs = "" @Extended is Set to 1 ; @Error - Set Error ; |1 = XLSX file not found or invalid (Can not Read\Extract XLSX file) ; |2 = [Content_Types].xml not found or invalid ; |3 = sheet1.xml file not found or invalid ; |4 = Sheet Dimension Not found Or is Greater than 15999999 (Array Size Limit) ; |5 = No SheetDate (Columns & Rows) Found ; Author ........: DXRW4E ; Modified.......: ; Remarks .......: ; Related .......: ; Link ..........: ; Example .......: __XLSXReadToArray("C:\file.xlsx") ; Note ..........: ; =========================================================================================================================================== Func _XLSXReadToArray($XLSXFilePath, $iFlag = 0, $Cols = 0, $Rows = 0, $iSheet = 1) If ($Cols * ($Rows + 1)) > 15999999 Then Return SetError(4, 0, "") Local $XLSXExtractDir = @WindowsDir & "\Temp\XLSX_" & @YEAR & @MON & @MDAY & @HOUR & @MIN & @SEC & @MSEC, $XLSXZip, $oShell, $X $XLSXZip = FileCopy($XLSXFilePath, $XLSXExtractDir & "\__xlsx.zip", 9) If Not $XLSXZip Then Return SetError(1, DirRemove($XLSXExtractDir, 1), "") $oShell = ObjCreate("shell.application") $oShell.Namespace($XLSXExtractDir).CopyHere($oShell.Namespace($XLSXExtractDir & "\__xlsx.zip").items, 20) Local $ContentTypesXML = StringReplace(FileRead($XLSXExtractDir & "\[Content_Types].xml"), "/", "\", 0, 1) If Not $ContentTypesXML Then $ContentTypesXML = _FileListToArrayEx($XLSXExtractDir, "*Content*Types*.xml", 37) If Not @Error Then $ContentTypesXML = StringReplace(FileRead($XLSXExtractDir & "\" & $ContentTypesXML[0]), "/", "\", 0, 1) If Not $ContentTypesXML Then Return SetError(2, DirRemove($XLSXExtractDir, 1), "") EndIf Local $SharedStringsXMLPath = StringRegExp($ContentTypesXML, '(?si)<Override\s*PartName="([^"]*\\sharedStrings\.xml)"', 1) If @Error Then $SharedStringsXMLPath = _FileListToArrayEx($XLSXExtractDir, "sharedStrings.xml", 165) If Not @Error Then $SharedStringsXMLPath = $XLSXExtractDir & $SharedStringsXMLPath[0] Local $SheetXMLPath = StringRegExp($ContentTypesXML, '(?si)<Override\s*PartName="([^"]*\\sheet' & $iSheet & '\.xml)"', 1) If @Error Then $SheetXMLPath = _FileListToArrayEx($XLSXExtractDir, "sheet" & $iSheet & ".xml", 165) If @Error Then $SheetXMLPath = StringRegExp($ContentTypesXML, '(?si)<Override\s*PartName="([^"]*\\sheet[^"]*\.xml)"', 1) If @Error Then $SheetXMLPath = _FileListToArrayEx($XLSXExtractDir, "sheet*.xml", 165) If Not @Error Then $SheetXMLPath = $XLSXExtractDir & $SheetXMLPath[0] Local $WorkSheet = FileRead($SheetXMLPath) If Not $WorkSheet Then Return SetError(3, DirRemove($XLSXExtractDir, 1), "") Local $SharedStringsXML = FileRead($SharedStringsXMLPath) ;; Example Get File Path using the StringRegExpReplace(), but more slowly than StringRegExp Mod. ;; Local $WorkBookXMLPath = $XLSXExtractDir & StringRegExpReplace($ContentTypesXML, '(?si).*<Override\s+PartName="([^"]*\\workbook\.xml)".*', "$1") ;; Local $StylesXMLPath = $XLSXExtractDir & StringRegExpReplace($ContentTypesXML, '(?si).*<Override\s+PartName="([^"]*\\styles\.xml)".*', "$1") ;; Local $SharedStringsXMLPath = $XLSXExtractDir & StringRegExpReplace($ContentTypesXML, '(?si).*<Override\s+PartName="([^"]*\\sharedStrings\.xml)".*', "$1") ;; Local $SheetXMLPath = $XLSXExtractDir & StringRegExpReplace($ContentTypesXML, '(?si).*<Override\s+PartName="([^"]*\\sheet1\.xml)".*', "$1") ;; ;; ;; read other ect ect ect ;; Local $WorkBookXMLPath = StringRegExp($ContentTypesXML, '(?si)<Override\s*PartName="([^"]*\\workbook\.xml)"', 1) ;; If @Error Then $WorkBookXMLPath = _FileListToArrayEx($XLSXExtractDir, "workbook.xml", 165) ;; If Not @Error Then $WorkBookXMLPath = $XLSXExtractDir & $WorkBookXMLPath[0] ;; $WorkBookXML = FileRead($WorkBookXMLPath) ;; ;Example using the StringRegExpReplace() ;; Local $SheetName = $XLSXExtractDir & StringRegExpReplace($WorkBookXML, '(?si).*<sheet\s+name="([^"]*)".*', "$1") ;; ;; Local $AppXMLPath = StringRegExp($ContentTypesXML, '(?si)<Override\s*PartName="([^"]*\\app\.xml)"', 1) ;; If @Error Then $AppXMLPath = _FileListToArrayEx($XLSXExtractDir, "app.xml", 165) ;; If Not @Error Then $AppXMLPath = $XLSXExtractDir & $AppXMLPath[0] ;; $AppXML = FileRead($AppXMLPath) ;; ;Example using the StringRegExpReplace() ;; Local $AppVersion = $XLSXExtractDir & StringRegExpReplace($AppXML, '(?si).*<AppVersion>([^<]*)</AppVersion>.*', "$1") ;; ;; Local $CoreXMLPath = StringRegExp($ContentTypesXML, '(?si)<Override\s*PartName="([^"]*\\core\.xml)"', 1) ;; If @Error Then $CoreXMLPath = _FileListToArrayEx($XLSXExtractDir, "core.xml", 165) ;; If Not @Error Then $CoreXMLPath = $XLSXExtractDir & $CoreXMLPath[0] ;; $CoreXML = FileRead($CoreXMLPath) ;; ;Example using the StringRegExpReplace() ;; Local $Modified = $XLSXExtractDir & StringRegExpReplace($CoreXML, '(?si).*<dcterms\:modified[^>]([^<]*)</dcterms:modified>.*', "$1") ;; ;; Local $StylesXMLPath = StringRegExp($ContentTypesXML, '(?si)<Override\s*PartName="([^"]*\\styles\.xml)"', 1) ;; If @Error Then $StylesXMLPath = _FileListToArrayEx($XLSXExtractDir, "styles.xml", 165) ;; If Not @Error Then $StylesXMLPath = $XLSXExtractDir & $StylesXMLPath[0] ;; $StylesXML = FileRead($StylesXMLPath) ;; ;ect ect ect ect ;; ;; Local $SheetViews = StringRegExp($WorkSheet, '(?si)<sheetView\s+tabSelected="([^"]*)".*?\sworkbookViewId="([^"]*)".*?\stopLeftCell="([A-Z]{1,3})([0-9]+)".*?\sactiveCell="([A-Z]{1,3})([0-9]+)".*?\sdefaultRowHeight="([^"]*)"', 1) ;; If @Error Then Local $SheetViews[7] ;; $SheetViews[2] = _XLSXSheetGetColumnNumber($SheetViews[2]) ;; $SheetViews[4] = _XLSXSheetGetColumnNumber($SheetViews[4]) ;; ;;;; $SheetViews.... ;; ;;;; $SheetViews[0] = tabSelected ;; ;;;; $SheetViews[1] = workbookViewId ;; ;;;; $SheetViews[2] = top Left Cell - Column Number ;; ;;;; $SheetViews[3] = top Left Cell - Rows Nmmber ;; ;;;; $SheetViews[4] = active Cell - Column Number ;; ;;;; $SheetViews[5] = active Cell - Rows Nmmber ;; ;;;; $SheetViews[6] = default Row Height DirRemove($XLSXExtractDir, 1) Local $nCols = Number($Cols), $nRows = "[0-9]+", $X = StringRegExp($WorkSheet, '(?si)<([^:><]*:?)?worksheet\s+', 1) If Not @Error Then $X = $X[0] If $Rows > 0 Then ;;;; StringRegExp($WorkSheet, '(?s)<' & $X & 'row\s+r="' & $Rows & '".*?</' & $X & 'row>', 1) $nRows = $Rows $Rows = 1 EndIf Local $SheetDimension = StringRegExp($WorkSheet, '(?si)<' & $X & '(?:dimension|autoFilter)\s+ref="([A-Z]{1,3})([0-9]+):([A-Z]{1,3})(?i)([0-9]+)', 1) If Not @Error Then $Cols = _XLSXSheetGetColumnNumber($SheetDimension[2]) If $nRows = "[0-9]+" Then $Rows = $SheetDimension[3] EndIf $SheetDimension = StringRegExp($WorkSheet, '(?si)<' & $X & 'col\s+min="?(\d+)[^>]*></' & $X & 'cols>', 1) If Not @Error And $SheetDimension[0] > $Cols Then $Cols = $SheetDimension[0] If $nRows = "[0-9]+" Then $SheetDimension = StringRegExp($WorkSheet, '(?si).*<' & $X & 'c\s+r="?[A-Z]*(\d+)', 1) If Not @Error And $SheetDimension[0] > $Rows Then $Rows = $SheetDimension[0] EndIf If $nCols > ($Cols + 1) Then Return SetError(5, 0, "") If $Cols < 1 Or $Rows < 1 Or ($Cols * ($Rows + 1)) > 15999999 Then Return SetError(4, 0, "") Local $SheetData = StringRegExp($WorkSheet, '(?s)<' & $X & 'c\s+r="([A-Z]{1,3})(?i)(' & $nRows & ')"\s*(?:s=")?([0-9]*)"?\s*(?:t=")?([^">]*)"?\s*><' & $X & 'v>([^<]*)\s*</' & $X & 'v>\s*</' & $X & 'c>', 3) If @Error Then Return SetError(5, 0, "") If $nCols Then $Cols = 1 Local $SheetDataA[($Rows + 1)][$Cols] = [[UBound($SheetData) - 1]], $ColumnName, $ColumnNumber, $ColumnSize, $SharedStringsXMLSize If $SharedStringsXML Then Local $S = StringRegExp($SharedStringsXML, '(?si)<([^:><]*:?)?sst\s+', 1) If Not @Error Then $S = $S[0] $SharedStringsXML = StringRegExp($SharedStringsXML, '(?si)<' & $S & 'si>(?:<' & $S & 'r>.*?)?<' & $S & 't(?:/|\s[^>]*)?>(.*?)(?:</' & $S & 't>)?(?:</' & $S & 'r>)?</' & $S & 'si>', 3) If Not @Error Then $SharedStringsXMLSize = UBound($SharedStringsXML) For $i = 0 To $SharedStringsXMLSize - 1 If StringInStr($SharedStringsXML[$i], "<", 1) Then $SharedStringsXML[$i] = StringRegExpReplace($SharedStringsXML[$i], '</' & $S & 't>.*?<' & $S & 't>', "") If StringInStr($SharedStringsXML[$i], "&", 1) Then $SharedStringsXML[$i] = StringReplace(StringReplace(StringReplace($SharedStringsXML[$i], "&lt;", "<", 0, 1), "&gt;", ">", 0, 1), "&amp;", "&", 0, 1) Next EndIf EndIf For $i = 0 To $SheetDataA[0][0] Step 5 $ColumnSize = StringLen($SheetData[$i]) - 1 If Not $ColumnSize Then $ColumnNumber = Asc($SheetData[$i]) - 65 Else $ColumnName = StringToASCIIArray($SheetData[$i]) $ColumnNumber = $ColumnName[$ColumnSize] - 65 $ColumnNumber += 26 * ($ColumnName[$ColumnSize - 1] - 64) ;(26 ^ 1) * ($ColumnName[1] - 64) If $ColumnSize > 1 Then $ColumnNumber += 676 * ($ColumnName[0] - 64) ;(26 ^ 2) * ($ColumnName[0] - 64) ;;;$ColumnNumber = _XLSXSheetGetColumnNumber($SheetData[$i], 1) EndIf If $nCols Then If $nCols <> ($ColumnNumber + 1) Then ContinueLoop $ColumnNumber = 0 EndIf If $Rows = 1 Then $SheetData[$i + 1] = 1 If $SheetData[$i + 3] = "s" And $SharedStringsXMLSize > $SheetData[$i + 4] Then $SheetDataA[$SheetData[$i + 1]][$ColumnNumber] = $SharedStringsXML[$SheetData[$i + 4]] ElseIf $SheetData[$i + 2] = 2 Then $SheetDataA[$SheetData[$i + 1]][$ColumnNumber] = _SSNToDate($SheetData[$i + 4]) Else $SheetDataA[$SheetData[$i + 1]][$ColumnNumber] = $SheetData[$i + 4] EndIf Next $SheetDataA[0][0] = $Rows If $iFlag Then $HyperLinks = StringRegExp($WorkSheet, '(?si)<' & $X & 'hyperlink\s+ref="([A-Z]{1,3})(?i)(' & $nRows & ')".*?\s+display="([^"]*)"', 3) ;;$HyperLinks = StringRegExp($WorkSheet, '(?si)<' & $X & 'hyperlink\s+ref="([A-Z]{1,3})(?i)' & $nRows & '"\s+r:id="([^"]*)"\s+display="([^"]*)"', 3) If Not @Error Then Local $HyperLinksSize = UBound($HyperLinks) - 1 For $i = 0 To $HyperLinksSize Step 3 $ColumnNumber = _XLSXSheetGetColumnNumber($HyperLinks[$i], 1) If $Rows = 1 Then $HyperLinks[$i + 1] = 1 $SheetDataA[$HyperLinks[$i + 1]][$ColumnNumber] &= @LF & $HyperLinks[$i + 2] Next EndIf EndIf If $nCols And $Rows = 1 Then Return SetError(0, $SheetDataA[1][0] = "", $SheetDataA[1][0]) Return SetError(0, UBound($SheetDataA, 2), $SheetDataA) EndFunc ;==>_XLSXReadToArray ; #FUNCTION# ================================================================================================================= ; Name...........: _XLSXSheetGetColumnNumber ; Description ...: The _XLSXSheetGetColumnNumber Fuction return Column Number of EXCEL XLSX Sheet ; Syntax.........: _XLSXSheetGetColumnNumber($ColumnName) ; Parameters ....: $ColumnName - [A-Z] Uppercase Caracter\String, are not Supported line with more than 3 characters ; $iFlag - Optional ; |$iFlag = 0 (Default) Column Number ; |$iFlag = 1 Column Number - 1 (for Array Index 0) ; Return values .: Success - Return Column Number ; Failure - @Error ; Author ........: DXRW4E ; Modified.......: ; Remarks .......: Limit is 18278 (A = 1 & AB = 27 & ZZZ = 18278) ; Related .......: ; Link ..........: ; Example .......: _XLSXSheetGetColumnNumber("ABC") ; Note ..........: ; ============================================================================================================================ Func _XLSXSheetGetColumnNumber($ColumnName, $iFlag = 0) If Not StringRegExp($ColumnName, '^[A-Z]{1,3}$') Or $iFlag < 0 Or $iFlag > 1 Then Return SetError(1, 0, 0) Local $ColumnNumber, $SheetDimension = StringLen($ColumnName) - 1 If Not $SheetDimension Then $ColumnNumber = Asc($ColumnName) - 64 - $iFlag Else $ColumnName = StringToASCIIArray($ColumnName) $ColumnNumber = $ColumnName[$SheetDimension] - 64 - $iFlag $ColumnNumber += 26 * ($ColumnName[$SheetDimension - 1] - 64) ;(26 ^ 1) * ($ColumnName[1] - 64) If $SheetDimension > 1 Then $ColumnNumber += 676 * ($ColumnName[0] - 64) ;(26 ^ 2) * ($ColumnName[0] - 64) EndIf Return $ColumnNumber EndFunc ;==>_XLSXSheetGetColumnNumber ; #FUNCTION# ================================================================================================================= ; Name...........: _SSNToDate ; Description ...: The _SSNToDate Fuction return Date from sequential serial number ; Syntax.........: _SSNToDate($iDay) ; Parameters ....: $iDay - sequential serial number (generated from DATE fuction on EXCEL, example 39637 = 7/8/2008) ; Return values .: Success - Return DATE ; Failure - @Error ; Author ........: DXRW4E ; Modified.......: ; Remarks .......: DATE String is Month/Day/Year, Year - is number is 1900 to 9999 ; Related .......: ; Link ..........: ; Example .......: _SSNToDate(39637) ; Note ..........: ; ============================================================================================================================ Func _SSNToDate($iDay) If $iDay < 1 Or $iDay > 2958465 Then Return SetError(1, 0, "") $DateSSN[0] = Int($iDay / 365) $DateSSN[25] = $DateSSN[0] / 4 $DateSSN[26] = IsFloat($DateSSN[25]) $iDay = $iDay - ($DateSSN[0] * 365) - Int($DateSSN[25]) - $DateSSN[26] If $iDay < 1 Then $DateSSN[0] -= 1 $DateSSN[25] = IsInt(($DateSSN[0] -1) / 4) $iDay += 365 + $DateSSN[25] $DateSSN[26] = Int($DateSSN[25] = 0) EndIf $DateSSN[2] -= $DateSSN[26] For $iMonth = 1 To 11 If $DateSSN[$iMonth] >= $iDay Then ExitLoop $iDay -= $DateSSN[$iMonth] Next $DateSSN[2] += $DateSSN[26] Return $iMonth & "/" & $iDay & "/" & (1900 + $DateSSN[0]) EndFunc ;==>_SSNToDate ; #FUNCTION# ================================================================================================================= ; Name...........: _DateToSSN ; Description ...: The _DateToSSN Fuction return sequential serial number that represent a particular Date ; Syntax.........: _DateToSSN($iYear, $iMonth, $iDay) ; Parameters ....: $iYear - Year - is number is 1900 to 9999 ; Required. The value of the year argument can include one to four digits. Excel interprets the year argument ; according to the date system your computer is using. By default, Microsoft Excel for Windows uses the 1900 date system. ; We recommend using four digits for the year argument to prevent unwanted results. For example, "07" could mean "1907" or "2007." Four digit years prevent confusion. ; If year is between 0 (zero) and 1899 (inclusive), Excel adds that value to 1900 to calculate the year. For example, DATE(108,1,2) returns January 2, 2008 (1900+108). ; If year is between 1900 and 9999 (inclusive), Excel uses that value as the year. For example, _DateToSSN((2008,1,2) returns January 2, 2008. ; If year is less than 0 or is 10000 or greater, _DateToSSN returns the @Error ; $iMonth - is number is 1 to 12, If Month is less than 0 or is 13 or greater, _DateToSSN returns the @Error ; $iDay - Required. A positive or negative integer representing the day of the month from 1 to 31. ; If day is greater than the number of days in the month specified, day adds that number of days to the first day in the month. ; For example, _DateToSSN(2008,1,35) returns the serial number representing February 4, 2008. ; If day is less than 1, day subtracts the magnitude that number of days, plus one, from the first day of the month specified. ; For example, _DateToSSN(2008,1,-15) returns the serial number representing December 16, 2007. ; Return values .: Success - Return Sequential Serial Number ; Failure - @Error ; Author ........: DXRW4E ; Modified.......: ; Remarks .......: Sequential Serial Number, _DateToSSN(2008, 7, 8) Return 39637, that represent 7/8/2008 ; ; NOTE - Excel stores dates as sequential serial numbers so that they can be used in calculations. January 1, 1900 is serial number 1, ; and January 1, 2008 is serial number 39448 because it is 39,447 days after January 1, 1900. ; ; _DateToSSN NOT SUPPORT FOR NOW, THIS ; $iMonth Required. A positive or negative integer representing the month of the year from 1 to 12 (January to December). ; If month is greater than 12, month adds that number of months to the first month in the year specified. For example, ; DATE(2008,14,2) returns the serial number representing February 2, 2009. ; If month is less than 1, month subtracts the magnitude of that number of months, plus 1, from the first month in the ; year specified. For example, DATE(2008,-3,2) returns the serial number representing September 2, 2007. ; Related .......: ; Link ..........: ; Example .......: _DateToSSN(39637) ; Note ..........: ; ============================================================================================================================ Func _DateToSSN($iYear, $iMonth, $iDay) If $iYear < 1900 Or $iYear > 9999 Or $iMonth < 1 Or $iMonth > 12 Then Return SetError(1, 0, "") $iYear -= 1900 $DateSSN[0] = $iYear / 4 If IsFloat($DateSSN[0]) And $iMonth < 3 Then $iDay += 1 Return ($iYear * 365) + Int($DateSSN[0]) + $DateSSN[$iMonth + 12] + $iDay EndFunc ;==>_DateToSSN ; #FUNCTION# ======================================================================================================================================================= ; Name...........: _FileListToArrayEx ; Description ...: Lists files and\or folders in a specified path (Similar to using Dir with the /B Switch) ; Syntax.........: _FileListToArrayEx($sPath[, $sFilter = "*"[, $iFlag = 0]]) ; Parameters ....: $sPath - Path to generate filelist for. ; $sFilter - Optional the filter to use, default is *. (Multiple filter groups such as "All "*.png|*.jpg|*.bmp") Search the Autoit3 helpfile for the word "WildCards" For details. ; $iFlag - Optional: specifies whether to return files folders or both Or Full Path (add the flags together for multiple operations): ; |$iFlag = 0 (Default) Return both files and folders ; |$iFlag = 1 Return files only ; |$iFlag = 2 Return Folders only ; |$iFlag = 4 Search SubDirectory ; |$iFlag = 8 Return Full Path ; |$iFlag = 16 $sFilter do Case-Sensitive matching (By Default $sFilter do Case-Insensitive matching) ; |$iFlag = 32 Disable the return the count in the first element - effectively makes the array 0-based (must use UBound() to get the size in this case). ; By Default the first element ($array[0]) contains the number of file found, the remaining elements ($array[1], $array[2], etc.) ; |$iFlag = 64 $sFilter is REGEXP Mod, See Pattern Parameters in StringRegExp (Can not be combined with flag 16) ; |$iFlag = 128 Return Backslash at the beginning of the file name, example Return "\Filename1.xxx" (Can not be combined with flag 8) ; Return values .: Failure - @Error ; |1 = Path not found or invalid ; |2 = Invalid $sFilter ; |3 = No File(s) Found ; Author ........: DXRW4E ; Modified.......: ; Remarks .......: The array returned is one-dimensional and is made up as follows: ; $array[0] = Number of Files\Folders returned ; $array[1] = 1st File\Folder ; $array[2] = 2nd File\Folder ; $array[3] = 3rd File\Folder ; $array[n] = nth File\Folder ; Related .......: ; Link ..........: ; Example .......: Yes ; Note ..........: Special Thanks to SolidSnake & Tlem ; ================================================================================================================================================================== Func _FileListToArrayEx($sPath, $sFilter = "*", $iFlag = 0) $sPath = StringRegExpReplace($sPath & "\", "[\\/]+", "\\") If Not FileExists($sPath) Then Return SetError(1, 1, "") If StringRegExp($sFilter, StringReplace('^\s*$|\v|[\\/:><"]|^\||\|\||\|$', "[" & Chr(BitAND($iFlag, 64) + 28) & '\/:><"]|^\||\|\||\|$', "\\\\")) Then Return SetError(2, 2, "") Local $hSearch, $sFile, $sFileList, $sSubDir = BitAND($iFlag, 4), $sDelim = "|", $sDirFilter = StringReplace($sFilter, "*", "") $hSearch = FileFindFirstFile($sPath & "*") If @Error Then Return SetError(3, 3, "") Local $hWSearch = $hSearch, $hWSTMP, $SearchWD, $Extended, $iFlags = StringReplace(BitAND($iFlag, 1) + BitAND($iFlag, 2), "3", "0") If BitAND($iFlag, 8) Then $sDelim &= $sPath If BitAND($iFlag, 128) Then $sDelim = "|\" If Not BitAND($iFlag, 64) Then $sFilter = StringRegExpReplace(BitAND($iFlag, 16) & "(?i)(", "16\(\?\i\)|\d+", "") & StringRegExpReplace(StringRegExpReplace(StringRegExpReplace(StringRegExpReplace($sFilter, "[^*?|]+", "\\Q$0\\E"), "\\E(?=\||$)", "$0\$"), "(?<=^|\|)\\Q", "^$0"), "\*+", ".*") & ")" While 1 $sFile = FileFindNextFile($hWSearch) If @Error Then If $hWSearch = $hSearch Then ExitLoop FileClose($hWSearch) $hWSearch -= 1 $SearchWD = StringLeft($SearchWD, StringInStr(StringTrimRight($SearchWD, 1), "\", 1, -1)) ElseIf $sSubDir Then $Extended = @Extended If ($iFlags + $Extended <> 2) Then If $sDirFilter Then If StringRegExp($sFile, $sFilter) Then $sFileList &= $sDelim & $SearchWD & $sFile Else $sFileList &= $sDelim & $SearchWD & $sFile EndIf EndIf If Not $Extended Then ContinueLoop $hWSTMP = FileFindFirstFile($sPath & $SearchWD & $sFile & "\*") If $hWSTMP = -1 Then ContinueLoop $hWSearch = $hWSTMP $SearchWD &= $sFile & "\" Else If ($iFlags + @Extended = 2) Or StringRegExp($sFile, $sFilter) = 0 Then ContinueLoop $sFileList &= $sDelim & $sFile EndIf WEnd FileClose($hSearch) If Not $sFileList Then Return SetError(3, 3, "") Return StringSplit(StringTrimLeft($sFileList, 1), "|", StringReplace(BitAND($iFlag, 32), "32", 2)) EndFunc ;==>_FileListToArrayEx Func _XLSXZip_COMErrorFunc() Return SetError(1, 0, "") EndFunc ;==>_XLSXZip_COMErrorFunc example #include <Array.au3> #include <_XLSXReadToArray.au3> local $a, $t, $Error, $Extended $t = TimerInit() InetGet("http://go.microsoft.com/fwlink/?LinkID=245778", @WindowsDir & "\Temp\BulletinSearch.xlsx") $a = _XLSXReadToArray(@WindowsDir & "\Temp\BulletinSearch.xlsx", 0, 0, 0) $t = TimerDiff($t) _ArrayDisplay($a, $t) ;;or $t = TimerInit() $a = _XLSXReadToArray(@WindowsDir & "\Temp\BulletinSearch.xlsx", 0, 2, 11) $Error = @Error $Extended = @Extended $t = TimerDiff($t) ConsoleWrite("Timer = " & $t & @LF) ConsoleWrite("Return = " & $a & " - $Error = " & $Error & " - $Extended = " & $Extended & @LF) exit _XLSXReadToArray.au3
  16. Updated, added _DateToSSN Fuction Ciao.
  17. _DateToSSN Fuction return sequential serial number that represent a particular Date, and _SSNToDate Fuction return Date from sequential serial number (generated from DATE fuction on EXCEL or _DateToSSN Fuction, example 39637 = 7/8/2008), as already look at the function and too simple and uses few line of code, so that it is very fast (_DateToSSN processes about 55000 per second & _SSNToDate processes about 20000 per second) Global $DateSSN[27] = [0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31, 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335] ConsoleWrite("7/8/2008 - 39637 = " & _SSNToDate(39637) & " - " & _DateToSSN(2008, 7, 8) & @LF) ConsoleWrite("6/1/1998 - 35947 = " & _SSNToDate(35947) & " - " & _DateToSSN(1998, 6, 1) & @LF) ConsoleWrite("1/1/2000 - 36526 = " & _SSNToDate(36526) & " - " & _DateToSSN(2000, 1, 1) & @LF) ConsoleWrite("10/9/2010 - 40460 = " & _SSNToDate(40460) & " - " & _DateToSSN(2010, 10, 9) & @LF) ConsoleWrite("10/9/2011 - 40825 = " & _SSNToDate(40825) & " - " & _DateToSSN(2011, 10, 9) & @LF) ConsoleWrite("10/9/2012 - 41191 = " & _SSNToDate(41191) & " - " & _DateToSSN(2012, 10, 9) & @LF) ConsoleWrite("10/9/2013 - 41556 = " & _SSNToDate(41556) & " - " & _DateToSSN(2013, 10, 9) & @LF) ConsoleWrite("10/9/2015 - 42286 = " & _SSNToDate(42286) & " - " & _DateToSSN(2015, 10, 9) & @LF) ConsoleWrite("10/9/2014 - 41921 = " & _SSNToDate(41921) & " - " & _DateToSSN(2014, 10, 9) & @LF) ; #FUNCTION# ================================================================================================================= ; Name...........: _SSNToDate ; Description ...: The _SSNToDate Fuction return Date from sequential serial number ; Syntax.........: _SSNToDate($iDay) ; Parameters ....: $iDay - sequential serial number (generated from DATE fuction on EXCEL, example 39637 = 7/8/2008) ; Return values .: Success - Return DATE ; Failure - @Error ; Author ........: DXRW4E ; Modified.......: ; Remarks .......: DATE String is Month/Day/Year, Year - is number is 1900 to 9999 ; Related .......: ; Link ..........: ; Example .......: _SSNToDate(39637) ; Note ..........: ; ============================================================================================================================ Func _SSNToDate($iDay) If $iDay < 1 Or $iDay > 2958465 Then Return SetError(1, 0, "") $DateSSN[0] = Int($iDay / 365) $DateSSN[25] = $DateSSN[0] / 4 $DateSSN[26] = IsFloat($DateSSN[25]) $iDay = $iDay - ($DateSSN[0] * 365) - Int($DateSSN[25]) - $DateSSN[26] If $iDay < 1 Then $DateSSN[0] -= 1 $DateSSN[25] = IsInt(($DateSSN[0] -1) / 4) $iDay += 365 + $DateSSN[25] $DateSSN[26] = Int($DateSSN[25] = 0) EndIf $DateSSN[2] -= $DateSSN[26] For $iMonth = 1 To 11 If $DateSSN[$iMonth] >= $iDay Then ExitLoop $iDay -= $DateSSN[$iMonth] Next $DateSSN[2] += $DateSSN[26] Return $iMonth & "/" & $iDay & "/" & (1900 + $DateSSN[0]) EndFunc ; #FUNCTION# ================================================================================================================= ; Name...........: _DateToSSN ; Description ...: The _DateToSSN Fuction return sequential serial number that represent a particular Date ; Syntax.........: _DateToSSN($iYear, $iMonth, $iDay) ; Parameters ....: $iYear - Year - is number is 1900 to 9999 ; Required. The value of the year argument can include one to four digits. Excel interprets the year argument ; according to the date system your computer is using. By default, Microsoft Excel for Windows uses the 1900 date system. ; We recommend using four digits for the year argument to prevent unwanted results. For example, "07" could mean "1907" or "2007." Four digit years prevent confusion. ; If year is between 0 (zero) and 1899 (inclusive), Excel adds that value to 1900 to calculate the year. For example, DATE(108,1,2) returns January 2, 2008 (1900+108). ; If year is between 1900 and 9999 (inclusive), Excel uses that value as the year. For example, _DateToSSN((2008,1,2) returns January 2, 2008. ; If year is less than 0 or is 10000 or greater, _DateToSSN returns the @Error ; $iMonth - is number is 1 to 12, If Month is less than 0 or is 13 or greater, _DateToSSN returns the @Error ; $iDay - Required. A positive or negative integer representing the day of the month from 1 to 31. ; If day is greater than the number of days in the month specified, day adds that number of days to the first day in the month. ; For example, _DateToSSN(2008,1,35) returns the serial number representing February 4, 2008. ; If day is less than 1, day subtracts the magnitude that number of days, plus one, from the first day of the month specified. ; For example, _DateToSSN(2008,1,-15) returns the serial number representing December 16, 2007. ; Return values .: Success - Return Sequential Serial Number ; Failure - @Error ; Author ........: DXRW4E ; Modified.......: ; Remarks .......: Sequential Serial Number, _DateToSSN(2008, 7, 8) Return 39637, that represent 7/8/2008 ; ; NOTE - Excel stores dates as sequential serial numbers so that they can be used in calculations. January 1, 1900 is serial number 1, ; and January 1, 2008 is serial number 39448 because it is 39,447 days after January 1, 1900. ; ; _DateToSSN NOT SUPPORT FOR NOW, THIS ; $iMonth Required. A positive or negative integer representing the month of the year from 1 to 12 (January to December). ; If month is greater than 12, month adds that number of months to the first month in the year specified. For example, ; DATE(2008,14,2) returns the serial number representing February 2, 2009. ; If month is less than 1, month subtracts the magnitude of that number of months, plus 1, from the first month in the ; year specified. For example, DATE(2008,-3,2) returns the serial number representing September 2, 2007. ; Related .......: ; Link ..........: ; Example .......: _DateToSSN(39637) ; Note ..........: ; ============================================================================================================================ Func _DateToSSN($iYear, $iMonth, $iDay) If $iYear < 1900 Or $iYear > 9999 Or $iMonth < 1 Or $iMonth > 12 Then Return SetError(1, 0, "") $iYear -= 1900 $DateSSN[0] = $iYear / 4 If IsFloat($DateSSN[0]) And $iMonth < 3 Then $iDay += 1 Return ($iYear * 365) + Int($DateSSN[0]) + $DateSSN[$iMonth + 12] + $iDay EndFunc Ciao.
  18. Updated, Added $sFilter Case-sensitivity flag & Disable the return the count in the first element, for more see the first post Ciao.
  19. Updated, Added $sFilter Case-sensitivity flag & Disable the return the count in the first element, for more see the first post Ciao.
  20. Thank You I was editing the post, because as use the REGEXP, the options are endless, example ; #FUNCTION# ==================================================================================================================== ; Name...........: _FileReadToArray ; Description ...: Reads the specified file into an array. ; Syntax.........: _FileReadToArray($sFilePath, ByRef $aArray [, $iFlag = 1]) ; Parameters ....: $sFilePath - Path and filename of the file to be read. ; $aArray - The array to store the contents of the file. ; $iFlag - Optional: (add the flags together for multiple operations): ; |$iFlag = 0 Return the array count in the 0th index (Default) ; |$iFlag = 1 Don't return the array count ; |$iFlag = 2 Don't return Line empty (ignores @CRLF & @CRLF & @CRLF ect ect) ; |$iFlag = 4 Don't return Line empty or contain only whitespace character (ignores @CRLF & " " & @CRLF & @Tab & @CRLF ect ect) ; |$iFlag = 8 Strip Line leading white space ; Return values .: Success - Returns a 1 ; Failure - Returns a 0 ; @error - 0 = No error. ; |1 = Error opening specified file ; |2 = Unable to Split the file ; Author ........: Jonathan Bennett <jon at hiddensoft dot com>, Valik - Support Windows Unix and Mac line separator ; Modified.......: Jpm - fixed empty line at the end, Gary Fixed file contains only 1 line, guinness & DXRW4E - Add Optional flag, see $iFlag. ; Remarks .......: $aArray[0] will contain the number of records read into the array. ; Related .......: _FileWriteFromArray ; Link ..........: ; Example .......: Yes ; =============================================================================================================================== Func _FileReadToArray($sFilePath, ByRef $aArray, $iFlag = 0) Local $ArrayCount, $RegExp = "(?:rn|n|r)([^rn]*)", $hFileOpen = FileOpen($sFilePath, $FO_READ) If $hFileOpen = -1 Then Return SetError(1, 0, 0) Local $sFileRead = FileRead($hFileOpen) FileClose($hFileOpen) ; Check Optional $iFlag If Not BitAND($iFlag, 1) Then $ArrayCount = "ArrayCount" & @LF If BitAND($iFlag, 2) Then $RegExp = "(?:rn|n|r)([^rn]+)" If BitAND($iFlag, 4) Then $RegExp = "s*(?:rn|n|r)([^rn]+)" If BitAND($iFlag, 8) Then $RegExp = StringReplace($RegExp, ")", ")h*", 1, 1) $aArray = StringRegExp(@LF & $ArrayCount & $sFileRead, $RegExp, 3) If @error Then If StringLen($sFileRead) Then Local $aReturn[2] = [1, $sFileRead] $aArray = $aReturn Else Return SetError(2, 0, 0) EndIf ElseIf $ArrayCount Then $aArray[0] = UBound($aArray) - 1 EndIf Return 1 EndFunc ;==>_FileReadToArray tested with a INF File 42 MB approximately 1,000,000 line, Return in approximately 6802.4406 seconds, instead Default UDF that uses StringSplit Return in approximately 6620.1655 seconds, more or less StringRegExp and StringSplit have exactly the same speed sorry again for my english Ciao.
  21. hi guinness, does not seem to make sense, if you use the StringRegExpReplace (passing twice), then why not use the StringRegExp (passing once, very much faster) ?? #include <Array.au3> #include <FileConstants.au3> Local $aArray = 0 _FileReadToArray(@ScriptFullPath, $aArray, Default) _ArrayDisplay($aArray) ; #FUNCTION# ==================================================================================================================== ; Name...........: _FileReadToArray ; Description ...: Reads the specified file into an array. ; Syntax.........: _FileReadToArray($sFilePath, ByRef $aArray [, $iFlag = 1]) ; Parameters ....: $sFilePath - Path and filename of the file to be read. ; $aArray - The array to store the contents of the file. ; $iFlag - [optional] 1 - Return the array count in the 0th index or 0 - Don't return the array count. Default is 1. ; Return values .: Success - Returns a 1 ; Failure - Returns a 0 ; @error - 0 = No error. ; |1 = Error opening specified file ; |2 = Unable to Split the file ; Author ........: Jonathan Bennett <jon at hiddensoft dot com>, Valik - Support Windows Unix and Mac line separator ; Modified.......: Jpm - fixed empty line at the end, Gary Fixed file contains only 1 line, guinness - Optional flag to return the array count. ; Remarks .......: $aArray[0] will contain the number of records read into the array. ; Related .......: _FileWriteFromArray ; Link ..........: ; Example .......: Yes ; =============================================================================================================================== Func _FileReadToArray($sFilePath, ByRef $aArray, $iFlag) Local $hFileOpen = FileOpen($sFilePath, $FO_READ) If $hFileOpen = -1 Then Return SetError(1, 0, 0) Local $sFileRead = FileRead($hFileOpen) FileClose($hFileOpen) ; Check if to return the array count in the 0th index If $iFlag = Default Or $iFlag = 1 Then $iFlag = @LF Else $iFlag = "" EndIf ; or $iFlag optional, so _FileReadToArray($sFilePath, ByRef $aArray, $iFlag = "") ; If $iFlag <> "" Then $iFlag = @LF $aArray = StringRegExp($iFlag & $sFileRead & @LF, "([^rn]*)(?:rn|n|r)", 3) If @error Then If StringLen($sFileRead) Then Local $aReturn[2] = [1, $sFileRead] $aArray = $aReturn Else Return SetError(2, 0, 0) EndIf Else If $iFlag Then $aArray[0] = UBound($aArray) - 1 EndIf EndFunc ;==>_FileReadToArray and so 200% faster, or equally as fast as the StringSplit in fuction default Ciao.
  22. Yeah right, do Lobing
×
×
  • Create New...