Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 09/28/2016 in all areas

  1. After AutoIt 3.3.12.0 the handling of COM errors has been "fixed". Now nested COM operations crash the script in case of an error even when there is a COM error handler. Edit: All 3 problems have been fixed in AutoIt 3.3.14.3. Here you find a fixed version of function _Excel_RangeFind. I simply removed all nestings and added the missing COM error hander: Another function that needed some modification is _Excel_BookOpen. It crashed when a workbook was opened using _Excel_BookOpen with parameter $bVisible = True, saved and then reopened. The following modification solves the problem: 2017/06/19: Another function that needed some modification is _Word_DocSaveAs. It doesn't work with Word 2013 or later as MS felt the urge to change the name of the save method from SaveAs to SaveAs2. The following modification solves the problem: Please tell me if you still have problems with this or any other function from the Excel or Word UDF!
    1 point
  2. Here a small function to mark a region on the desktop and capture that region to a bitmap handle or to the clipboard: #include-once #include <Clipboard.au3> #include <GUIConstantsEx.au3> #include <MsgBoxConstants.au3> #include <WinAPIGdi.au3> #include <WindowsConstants.au3> #Region Example ;capture manual coordinates FileDelete(@ScriptDir & "\Captured.bmp") Global $hHBitmap = _WinAPI_MarkScreenRegionAndCapture(0, False, True, 0, 0, 99, 99) _WinAPI_SaveHBITMAPToFile(@ScriptDir & "\Captured.bmp", $hHBitmap) _WinAPI_DeleteObject($hHBitmap) If FileExists(@ScriptDir & "\Captured.bmp") Then ShellExecute(@ScriptDir & "\Captured.bmp") ;save the captured bitmap to a file FileDelete(@ScriptDir & "\Captured.bmp") Global $hHBitmap = _WinAPI_MarkScreenRegionAndCapture() _WinAPI_SaveHBITMAPToFile(@ScriptDir & "\Captured.bmp", $hHBitmap) _WinAPI_DeleteObject($hHBitmap) If FileExists(@ScriptDir & "\Captured.bmp") Then ShellExecute(@ScriptDir & "\Captured.bmp") ;copy captured bitmap to clipboard Switch _WinAPI_MarkScreenRegionAndCapture(1, True) Case 1 MsgBox($MB_ICONINFORMATION, "Information", "Marked region was properly captured to clipboard!", 30) Case 0 MsgBox($MB_ICONERROR, "ERROR", "An error has occured!", 30) EndSwitch #EndRegion ; #FUNCTION# ==================================================================================================================== ; Name ..........: _WinAPI_MarkScreenRegionAndCapture ; Description ...: Selected area on desktop will be captured and save to clipbord or GDI bitmap handle will be returned. ; Syntax ........: _WinAPI_MarkScreenRegionAndCapture([$iFillMode = 0[, $bClipboard = True]]) ; Parameters ....: $iFillMode - [optional] an integer value. Default is 0. ; 0: marked area filled with solid color ; 1: marked area filled with hatch pattern ($HS_DIAGCROSS) ; 2: marked area without any fill pattern / color - only red border ; $bClipboard - [optional] a boolean value. Default is False. If True then no GDI bitmap handle will be returned. ; If false then GDI bitmap handle will be returned. ; $bManual - [optional] a boolean value. Default is False. If True manual capturing is activated. ; $iX1 - [optional] an integer value. Default is 0. If $bManual is true enter the x1 screen pos. ; $iY1 - [optional] an integer value. Default is 0. If $bManual is true enter the Y1 screen pos. ; $iX2 - [optional] an integer value. Default is 0. If $bManual is true enter the x2 screen pos. ; $iY2 - [optional] an integer value. Default is 0. If $bManual is true enter the y2 screen pos. ; Return values .: 0 / 1 / -1 / GDI bitmap handle ; Author ........: UEZ ; Version .......: 0.92 build 2017-01-22 ; Modified ......: ; Remarks .......: Do not forget to dispose returned GDI bitmap handle for non clipboard mode using _WinAPI_DeleteObject! ; Related .......: ; Link ..........: ; Example .......: Yes ; =============================================================================================================================== Func _WinAPI_MarkScreenRegionAndCapture($iFillMode = 0, $bClipboard = False, $bManual = False, $iX1 = 0, $iY1 = 0, $iX2 = 0, $iY2 = 0) If @OSBuild > 6299 Then ;https://msdn.microsoft.com/en-us/library/windows/desktop/ms724832(v=vs.85).aspx DllCall("Shcore.dll", "long", "PROCESS_DPI_AWARENESS", 1) ;PROCESS_SYSTEM_DPI_AWARE = 1 (https://msdn.microsoft.com/en-us/library/windows/desktop/dn280512(v=vs.85).aspx) Else DllCall("User32.dll", "bool", "SetProcessDPIAware") EndIf Local $iOld = AutoItSetOption("MouseCoordMode", 1) If Not $bManual Then Local Const $hDesktop = WinGetHandle("[TITLE:Program Manager;CLASS:Progman]") Local Const $aFullScreen = WinGetPos($hDesktop) ;should work also on multi screens Local Const $iW = $aFullScreen[2], $iH = $aFullScreen[3] Local Const $hGUI_Screencapture = GUICreate("", $iW, $iH, $aFullScreen[0], $aFullScreen[1], $WS_POPUP, BitOR($WS_EX_TOPMOST, $WS_EX_LAYERED)) GUISetState(@SW_SHOW, $hGUI_Screencapture) Local Const $hDC = _WinAPI_GetDC($hGUI_Screencapture) Local Const $hGfxDC = _WinAPI_CreateCompatibleDC($hDC) Local Const $hBitmapGDI = _WinAPI_CreateCompatibleBitmap($hDC, $iW, $iH) Local $hObjOld = _WinAPI_SelectObject($hGfxDC, $hBitmapGDI) Local $tSize = DllStructCreate($tagSIZE) $tSize.x = $iW $tSize.y = $iH Local $tSource = DllStructCreate($tagPOINT) Local $tBlend = DllStructCreate($tagBLENDFUNCTION) $tBlend.Alpha = 0xFF $tBlend.Format = 1 Local $tDest = DllStructCreate($tagPOINT), $pPoint = DllStructGetPtr($tDest) $tDest.x = $aFullScreen[0] $tDest.y = $aFullScreen[1] Local Const $hPen = _WinAPI_CreatePen($PS_SOLID, 1, 0x0000FF) Local Const $hPen_Orig = _WinAPI_SelectObject($hGfxDC, $hPen) Local $hBrush, $iAlpha2, $iFlag $iFillMode = $iFillMode > 2 ? 2 : $iFillMode < 0 ? 0 : $iFillMode Switch $iFillMode Case 0 $hBrush = _WinAPI_CreateBrushIndirect($BS_SOLID, 0x808080) $iAlpha2 = 0xA0 $iFlag = $ULW_ALPHA Case 1 $hBrush = _WinAPI_CreateBrushIndirect($BS_HATCHED, 0x808000, $HS_DIAGCROSS) $iAlpha2 = 0x30 $iFlag = $ULW_ALPHA Case 2 $hBrush = _WinAPI_CreateBrushIndirect($BS_HOLLOW, 0x000000) $iAlpha2 = 0xFF ;not needed $iFlag = $ULW_COLORKEY EndSwitch Local $hBrush_Orig = _WinAPI_SelectObject($hGfxDC, $hBrush) Else If Not BitOr($iX1, $iX2, $iY1, $iY2) Then Return SetError(4, 0, 0) EndIf Local $aMPos[5], $aMPos_old[4], $tRECT = _WinAPI_CreateRect(0, 0, 0, 0) Do If $bManual Then $aMPos[2] = 1 Else GUISetCursor(16, 1, $hGUI_Screencapture) $aMPos = GUIGetCursorInfo($hGUI_Screencapture) $aMPos_old[0] = $aMPos[0] $aMPos_old[1] = $aMPos[1] $aMPos_old[2] = MouseGetPos(0) $aMPos_old[3] = MouseGetPos(1) EndIf Switch $aMPos[2] Case 0 ;display crosshair _WinAPI_BitBlt($hGfxDC, 0, 0, $iW, $iH, $hGfxDC, 0, 0, $CAPTUREBLT) _WinAPI_DrawLine($hGfxDC, $tDest.x, $aMPos[1], $iW, $aMPos[1]) _WinAPI_DrawLine($hGfxDC, $aMPos[0], $tDest.y, $aMPos[0], $iH) _WinAPI_UpdateLayeredWindow($hGUI_Screencapture, $hDC, $tDest, $tSize, $hGfxDC, $tSource, 0, $tBlend, $ULW_COLORKEY) Case 1 ;capture selected region If Not $bManual Then $tBlend.Alpha = $iAlpha2 While $aMPos[2] ;mark region GUISetCursor(14, 1, $hGUI_Screencapture) ;WinGetHandle(AutoItWinGetTitle())) $aMPos = GUIGetCursorInfo($hGUI_Screencapture) _WinAPI_BitBlt($hGfxDC, 0, 0, $iW, $iH, $hGfxDC, 0, 0, $CAPTUREBLT) ;clear bitmap ;draw rectangle $tRECT.Left = $aMPos_old[0] $tRECT.Top = $aMPos_old[1] $tRECT.Right = $aMPos[0] $tRECT.Bottom = $aMPos[1] _WinAPI_Rectangle($hGfxDC, $tRECT) If $iFillMode <> 2 Then _WinAPI_InvertRect($hGfxDC, $tRECT) _WinAPI_UpdateLayeredWindow($hGUI_Screencapture, $hDC, $tDest, $tSize, $hGfxDC, $tSource, 0, $tBlend, $iFlag) Sleep(10) WEnd _WinAPI_SelectObject($hGfxDC, $hObjOld) _WinAPI_ReleaseDC($hGUI_Screencapture, $hDC) _WinAPI_DeleteDC($hGfxDC) _WinAPI_DeleteObject($hBitmapGDI) _WinAPI_SelectObject($hGfxDC, $hPen_Orig) _WinAPI_DeleteObject($hPen) _WinAPI_SelectObject($hGfxDC, $hBrush_Orig) _WinAPI_DeleteObject($hBrush) GUIDelete($hGUI_Screencapture) ;capture region $aMPos[0] = MouseGetPos(0) $aMPos[1] = MouseGetPos(1) Else $aMPos_old[2] = $iX1 $aMPos_old[3] = $iY1 $aMPos[0] = $iX2 $aMPos[1] = $iY2 EndIf Local Const $hDC_Region = _WinAPI_GetDC(0) Local Const $hMemDC = _WinAPI_CreateCompatibleDC($hDC_Region) Local Const $iW_Region = Abs($aMPos[0] - $aMPos_old[2]) + 1, $iH_Region = Abs($aMPos[1] - $aMPos_old[3]) + 1 Local $hHBitmap_Captured = _WinAPI_CreateCompatibleBitmap($hDC_Region, $iW_Region, $iH_Region) $hObjOld = _WinAPI_SelectObject($hMemDC, $hHBitmap_Captured) _WinAPI_BitBlt($hMemDC, 0, 0, $iW_Region, $iH_Region, $hDC_Region, _ $aMPos[0] > $aMPos_old[2] ? $aMPos_old[2] : $aMPos[0], _ $aMPos[1] > $aMPos_old[3] ? $aMPos_old[3] : $aMPos[1], BitOR($SRCCOPY, $CAPTUREBLT)) Local $hHBitmap_Clipboard = _WinAPI_CopyImage($hHBitmap_Captured, 0, 0, 0, BitOR($LR_COPYDELETEORG, $LR_COPYRETURNORG)) _WinAPI_SelectObject($hHBitmap_Captured, $hObjOld) _WinAPI_DeleteDC($hHBitmap_Captured) _WinAPI_ReleaseDC(0, $hDC_Region) AutoItSetOption("MouseCoordMode", $iOld) If $bClipboard Then ;put captured region to clipboard If Not _ClipBoard_Open(0) Then _WinAPI_DeleteObject($hHBitmap_Clipboard) Return SetError(1, 0, 0) EndIf If Not _ClipBoard_Empty() Then _WinAPI_DeleteObject($hHBitmap_Clipboard) Return SetError(2, 0, 0) EndIf Local Const $hCP = _ClipBoard_SetDataEx($hHBitmap_Clipboard, $CF_BITMAP) If Not $hCP Or @error Then _WinAPI_DeleteObject($hHBitmap_Clipboard) Return SetError(3, 0, 0) EndIf _ClipBoard_Close() _WinAPI_DeleteObject($hHBitmap_Clipboard) Return 1 Else Return $hHBitmap_Clipboard EndIf EndSwitch Switch GUIGetMsg() Case $GUI_EVENT_CLOSE _WinAPI_SelectObject($hGfxDC, $hObjOld) _WinAPI_ReleaseDC($hGUI_Screencapture, $hDC) _WinAPI_DeleteDC($hGfxDC) _WinAPI_DeleteObject($hBitmapGDI) _WinAPI_SelectObject($hGfxDC, $hPen_Orig) _WinAPI_DeleteObject($hPen) GUIDelete($hGUI_Screencapture) AutoItSetOption("MouseCoordMode", $iOld) Return -1 EndSwitch Until False EndFunc ;==>_WinAPI_MarkScreenRegionAndCapture Might be useful... Download: _WinAPI_MarkScreenRegionAndCapture.au3 (same as above in the code box) Tested only on Win10 x64 but should work also on other Window versions. If not please reply.
    1 point
  3. Hi, Sorry I ddin't read up prior posts well enough, where you specified which engine and date-time format you were using. I have close to zero knowledge of MSSQL by itself, but if I had to check for datetime validity, I'd do something like his using my pet SQL engine (SQLite): create trigger CheckDateTime before insert on mytable for each row when length(new.`datetimecolumn`) != 19 or datetime(new.`datetimecolumn`) != new.`datetimecolumn` begin update mytable set new.`datetimecolumn` = NULL -- or put there your default literal value or expression where idcolumn = new.idcolumn; end This triggers act before the row is actually inserted and gives you the opportunity to change its content. In the above example, I check that the date is exactly 19 character long and the conversion form this input datetime ISO string to a datetime ISO string gives the input back, meaning that the date is valid. If not, I change this row date column to NULL (or as commented, to some default value you think is more convenient). You'll probably have to adapt this to bizarre MSSQL syntax but the idea will remain the same. EDIT: thanks @mLipok for adding what a schema is, I was just about editing my own post to add something about that.
    1 point
  4. The WMIExplorer tool helped me figure out the issue. The problem was I was searching for SELECT * FROM Win32_PnPEntity WHERE Name LIKE '%%' a Win32_PnPEntity where it's name could be anything. Thus, when I tried to specify a name, SELECT * FROM Win32_PnPEntity WHERE Name LIKE '%USB\\VID_045E&PID_02E4&IGA_00%' it returned nothing because I wasn't inputting a name, I was inputting a DeviceID. Changing it to SELECT * FROM Win32_PnPEntity WHERE DeviceID Like '%USB\\VID_045E&PID_02E4&IGA_00%' gave me the device I was looking for. This is going in my Xbox-One-Headset-AutoConnection script on Github. Would you like to be mentioned as a Contributor, @jguinch?
    1 point
  5. FWIW - I use this to enumerate cimv2 class properties #include <array.au3> local $ret = _WMI('win32_pnpentity') ;local $ret = _WMI('Win32_bios') If @error Then Exit (ConsoleWrite(@LF & '!> @ERROR = ' & @error & @LF & '!> @EXTENDED = ' & @extended & @LF & '!> $RET = ' & $ret & @LF & @LF)) If IsArray($ret) Then _ArrayDisplay($ret) If IsString($ret) Then ConsoleWrite($ret & @CRLF) ; #FUNCTION# ==================================================================================================================== ; Name...........: _WMI ; Description ...: Returns formatted output from a query against any class of the CIMV2 namespace using WMI. ; Syntax.........: _WMI($sWQL, $bReturnType, $sDelimiter, $sTargetPC) ; Parameters ....: $sWQL - Any class in the WMI CIMV2 namespace (e.g. Win32_Process, Win32_BIOS, Win32_Desktop, etc.) ; or any WQL 'Select' query. If only the class is specified then all columns ; for all items are returned. ; $bReturnType - Indicates return format. $bReturnType can be a string or integer. ; |0 - Return a 2D array with item names in col 0 (on the left). ; |1 - Return a 2D array with item names in row 0 (on top). (DEFAULT) ; |2 - Return a @CRLF delimited string of item names (row #1) followed by items. Each value is ; delimited by $sDelimiter. ; $sDelimiter - The delimiter used to seperate values/property names within an item. The default is ; '`' because other common delimiter characters (e.g. '|', ',', '=', ':', '~' etc. appear ; in some values returned by various WQL queries. This can be a string of characters (e.g. '//'). ; $sTargetPC - Name of the PC to run the query on. ; Return values .: Success - A 2D array or string depending on $bReturnType. ; Failure - Sets @ERROR and returns a value as follows: ; |1 - $sWQL is blank Return value - None ; |2 - $bReturnType invalid Return value - The parm supplied ; |3 - $sDelimiter not specified Return value - None ; |4 - WMI ObjGet failure Return value - None ; |5 - ExecQuery failure Return value - $sWQL ; |6 - No items returned Return value - $sWQL ; ; Author ........: kylomas ; Modified.......: 02/02/2015 V01R01M01 initial release ; Remarks .......: ; Related .......: WMI is required ; Link ..........: ; Example .......: Yes ; =============================================================================================================================== Func _WMI($sWQL, $bReturnType = 1, $sDelimiter = '`', $sTargetPC = @ComputerName) ; flush parms Switch $bReturnType Case 0, 1, 2, '0', '1', '2' Case -1, Default $bReturnType = 1 Case Else Return SetError(2, 0, $bReturnType) EndSwitch Switch True Case $sDelimiter = -1 Or $sDelimiter = Default $sDelimiter = '`' Case StringLen($sDelimiter) > 0 Case Else Return SetError(3, 0, $sDelimiter) EndSwitch If StringLen($sWQL) = 0 Then Return SetError(1) If StringInStr($sWQL, 'select') = 0 Then $sWQL = 'select * from ' & $sWQL Local $oWMI = '', $oItem = '', $oItems = '', $P = '' ; Get WMI instance ; Do NOT use $wbemFlagReturnImmediately or $wbeForwardOnly as this disables the "Count" property $oWMI = ObjGet("winmgmts:{impersonationLevel=impersonate}!\\" & $sTargetPC & "\root\CIMV2") If Not IsObj($oWMI) Then Return SetError(4) ; Run query $oItems = $oWMI.ExecQuery($sWQL) If Not IsObj($oItems) Then Return SetError(5, 0, $sWQL) If $oItems.count = 0 Then Return SetError(6, 0, $sWQL) Local $str = '' ; format header / use this method as opposed to the "itemindex" method for XP compatibility For $oItem In $oItems For $P In $oItem.Properties_() $str &= '<' & $P.Name & '>' & $sDelimiter Next $str = StringTrimRight($str, StringLen($sDelimiter)) & @CRLF ExitLoop Next ; format each detail item For $oItem In $oItems For $P In $oItem.Properties_() Switch True Case $P.isarray $aTmp1 = $P.Value $str &= _ArrayToString($aTmp1) & $sDelimiter Case $P.CIMTYPE = 101 $str &= CNVTDate($P.Value) & $sDelimiter Case Else $str &= $P.Value & $sDelimiter EndSwitch Next $str = StringTrimRight($str, StringLen($sDelimiter)) & @CRLF Next $str = StringTrimRight($str, 2) Switch $bReturnType Case '1', 1, -1, Default ; return 2D array / column names are at top (row 0) Local $aTmp1 = StringSplit($str, @CRLF, 3), $aTmp2 Local $aRet[UBound($aTmp1)][UBound(StringSplit($aTmp1[0], $sDelimiter, 3))] For $1 = 0 To UBound($aTmp1) - 1 $aTmp2 = StringSplit($aTmp1[$1], $sDelimiter, 3) For $2 = 0 To UBound($aTmp2) - 1 $aRet[$1][$2] = $aTmp2[$2] Next Next Return $aRet Case '0', 0 ; return 2D array / column names are to the left (col 0) Local $aTmp1 = StringSplit($str, @CRLF, 3), $aTmp2 Local $aRet[UBound(StringSplit($aTmp1[0], $sDelimiter, 3))][UBound($aTmp1)] For $1 = 0 To UBound($aTmp1) - 1 $aTmp2 = StringSplit($aTmp1[$1], $sDelimiter, 3) For $2 = 0 To UBound($aTmp2) - 1 $aRet[$2][$1] = $aTmp2[$2] Next Next Return $aRet Case '2', 2 ; return string Return $str Case Else Return SetError(7, 0, $bReturnType) EndSwitch EndFunc ;==>_WMI Func CNVTDate($dtmDate) ; reformat date to mm/dd/yyyy hh:mm:ss and zero fill single digit values Return StringRegExpReplace(StringRegExpReplace($dtmDate, '(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2}).*', '$2/$3/$1 $4:$5:$6'), '(?<!\d)(\d/)', '0$1') EndFunc ;==>CNVTDate Array values are separated by a '|' kylomas
    1 point
  6. I think your problem comes from the operator "= ". Replace it by "like" and add "%" at this end of the string. Look : Local $oDevice, $PNPDeviceID, $sHardwareIDs, $oWMIService = ObjGet("winmgmts:\\.\root\CIMV2") If Not IsObj($oWMIService) Then Exit MsgBox(16, "Error", "WMI error") Local $oPNPDevices = $oWMIService.ExecQuery("SELECT * FROM Win32_PnPEntity WHERE PNPDeviceID LIKE 'USB\\VID%'", "WQL", 48) If IsObj($oPNPDevices) Then For $oDevice In $oPNPDevices $sHardwareIDs = "" $PNPDeviceID = $oDevice.PNPDeviceID $aHardwareID = $oDevice.HardwareID For $i = 0 To UBound($aHardwareID) - 1 $sHardwareIDs &= $aHardwareID[$i] & @CRLF Next MsgBox (4096, "PNPDeviceID found", "PNPDeviceID : " & $PNPDeviceID & @CRLF & "HardwareID : " & $sHardwareIDs) Next EndIf As you can see, HardwareID is no a string but an array of strings. See here : https://msdn.microsoft.com/en-us/library/aa394353(v=vs.85).aspx Also, you can check out your query result with a graphic tool, it would be easier. Try with WMIExlorer
    1 point
  7. Indeed! @Muhammad_Awais_Sharif ...Use a single equals (=) for comarison, as well as assignment in AutoIt for cases like this...or just say "If X Then" (whenever X is true..."Then" will execute) (...It took me a few minutes to wrap my head around the 'single equals comparison' as well, so you're in good company!) bloopie
    1 point
  8. More precisely, when you write: If StringIsDigit($tmp) == True Then the interpretor understands: If '1' == 'True' Then because == forces the conversion of its operands to strings and StringIsDigit returns the integer 0 or 1 (1 in your case), while the string 'True' stays by itself. Since the == comparison is over verbatim (case-insensitive) strings, it clearly fails. The lazy, simple and robust way to code that condition is: If StringIsDigit($tmp) Then
    1 point
  9. UEZ

    transparent paint?, How to?

    Signore Chimp, I tried that script on Win10 x64 version 1607. I will try it in my vm Win7 just after my meeting. Tested on Win7 (vm) with enabled Aero -> not working. Seems to be a problem with _WinAPI_SetParent() function. Try these lines instead: ... Global $hGUI_Child = GUICreate("", $iW, $iH, 10, 10, $WS_POPUP, BitOr($WS_EX_MDICHILD, $WS_EX_LAYERED), $hGUI) ;~ _WinAPI_SetParent($hGUI_Child, $hGUI) GUISetState(@SW_SHOWNA, $hGUI_Child) ...
    1 point
  10. I have updated the tutorial to match with freenode's current infrastructure
    1 point
  11. Version 3.2.0.3

    1,403 downloads

    ADCU displays two Active Directory users and their group membership in two listviews. You can filter and export the data to Excel, Outlook mail and the clipboard. Before running the script you need to change file AD-Tools.ini and function _Check_Access in AD-Tools_User.au3. BTW: If you like this UDF please click the "I like this" button. This tells me where to next put my development effort Needs to be run with the latest AutoIt production version (>= 3.3.12.0). Needs to be run with the latest version of the AD UDF (>= 1.4.2.0).
    1 point
  12. Hello Everyone, I was just made aware of the free PowerShell App Deployment Toolkit and wanted to share it here. One could fairly easily customize this toolkit by adding the AutoItX DLL/COM control to it thereby utilizing the AutoIt PowerShell CmdLets making it a complete solution for all types of deployments! Regards, TXTechie
    1 point
  13. That's cool. Going to my special folder of special folders of... special things. edit: I did some thinking ( ) and I'm confused by the return values of the duck's code. For me it returns something like this: DiskDrive = \\.\PHYSICALDRIVE0 Caption = WDC WD1200JS-00MVB1 Partition = Disk #0, Partition #0 LogicalDisk = C: Partition = Disk #0, Partition #1 LogicalDisk = F: Partition = Disk #0, Partition #2 LogicalDisk = G: LogicalDisk = H: Partition = Disk #0, Partition #3 LogicalDisk = E:What confuses me is that I never heard of partition #0 and that code returned drive C to be partition #0. I did some searching too and thing is that there shouldn't be partition 0 with windows (better say, partition(0) refers to the entire disk <- link, this too). Further more, my mum (what?) told me that I should try to do something with DeviceIoControl function found in kernel32.dll. I got this: Local $aCall = DllCall("kernel32.dll", "dword", "GetLogicalDrives") Local $iMask = $aCall[0] Local $tIOCTL_STORAGE_GET_DEVICE_NUMBER = DllStructCreate("dword DeviceType;" & _ "dword DeviceNumber;" & _ "int PartitionNumber") Local $hDevice Local $a_hCall, $a_iCall For $i = 0 To 25; alphabet (A = 0) If BitAND(BitShift($iMask, $i), 1) Then; drive exists $a_hCall = DllCall("kernel32.dll", "hwnd", "CreateFile", _ "str", "\\.\" & Chr(65 + $i) & ":", _; want handle to the logical drive "dword", 0, _ "dword", 0, _ "ptr", 0, _ "dword", 3, _; OPEN_EXISTING "dword", 128, _; FILE_ATTRIBUTE_NORMAL "ptr", 0) $hDevice = $a_hCall[0] $a_iCall = DllCall("kernel32.dll", "int", "DeviceIoControl", _ "hwnd", $hDevice, _ "dword", 0x2D1080, _; IOCTL_STORAGE_GET_DEVICE_NUMBER "ptr", 0, _ "dword", 0, _ "ptr", DllStructGetPtr($tIOCTL_STORAGE_GET_DEVICE_NUMBER), _ "dword", DllStructGetSize($tIOCTL_STORAGE_GET_DEVICE_NUMBER), _ "dword*", 0, _ "ptr", 0) DllCall("kernel32.dll", "int", "CloseHandle", "hwnd", $hDevice) ConsoleWrite("Drive " & Chr(65 + $i) & ": " & @CRLF) ConsoleWrite(@TAB & "DeviceType: " & DllStructGetData($tIOCTL_STORAGE_GET_DEVICE_NUMBER, "DeviceType") & @CRLF) ConsoleWrite(@TAB & "DeviceNumber: " & DllStructGetData($tIOCTL_STORAGE_GET_DEVICE_NUMBER, "DeviceNumber") & @CRLF) ConsoleWrite(@TAB & "PartitionNumber: " & DllStructGetData($tIOCTL_STORAGE_GET_DEVICE_NUMBER, "PartitionNumber") & @CRLF) ConsoleWrite(@CRLF) EndIf NextData returned by that is in some degree different than using PsaltyDS's code. In case that code is correct something like this could be written: $sDDriveLetter = "C" $iDiskNumber = _GetDiskNimberForDrive($sDDriveLetter) If @error Then MsgBox(48, "Error", "Error Number " & @error & @CRLF) Else MsgBox(64, "_GetDiskNimberForDrive", "Drive " & StringUpper($sDDriveLetter) & " is on disk #" & $iDiskNumber) EndIf Func _GetDiskNimberForDrive($sDriveLetter) Local $a_hCall = DllCall("kernel32.dll", "hwnd", "CreateFile", _ "str", "\\.\" & $sDriveLetter & ":", _; logical drive "dword", 0, _ "dword", 0, _ "ptr", 0, _ "dword", 3, _; OPEN_EXISTING "dword", 128, _; FILE_ATTRIBUTE_NORMAL "ptr", 0) If @error Then Return SetError(1, 0, -1); your system is very old. Do something. EndIf If $a_hCall[0] = -1 Then Return SetError(2, 0, -1); non-existing drive EndIf Local $hDevice = $a_hCall[0] Local $tIOCTL_STORAGE_GET_DEVICE_NUMBER = DllStructCreate("dword DeviceType;" & _ "dword DeviceNumber;" & _ "int PartitionNumber") Local $a_iCall = DllCall("kernel32.dll", "int", "DeviceIoControl", _ "hwnd", $hDevice, _ "dword", 0x2D1080, _; IOCTL_STORAGE_GET_DEVICE_NUMBER "ptr", 0, _ "dword", 0, _ "ptr", DllStructGetPtr($tIOCTL_STORAGE_GET_DEVICE_NUMBER), _ "dword", DllStructGetSize($tIOCTL_STORAGE_GET_DEVICE_NUMBER), _ "dword*", 0, _ "ptr", 0) If @error Or Not $a_hCall[0] Then DllCall("kernel32.dll", "int", "CloseHandle", "hwnd", $hDevice) Return SetError(3, 0, -1); DeviceIoControl failed for some reason EndIf DllCall("kernel32.dll", "int", "CloseHandle", "hwnd", $hDevice) ; will write some data ConsoleWrite("Drive " & StringUpper($sDriveLetter) & ": " & @CRLF) ConsoleWrite(@TAB & "DeviceType: " & DllStructGetData($tIOCTL_STORAGE_GET_DEVICE_NUMBER, "DeviceType") & @CRLF) ConsoleWrite(@TAB & "DeviceNumber: " & DllStructGetData($tIOCTL_STORAGE_GET_DEVICE_NUMBER, "DeviceNumber") & @CRLF) ConsoleWrite(@TAB & "PartitionNumber: " & DllStructGetData($tIOCTL_STORAGE_GET_DEVICE_NUMBER, "PartitionNumber") & @CRLF) ConsoleWrite(@CRLF) ; end writing If DllStructGetData($tIOCTL_STORAGE_GET_DEVICE_NUMBER, "DeviceType") = 7 Then; FILE_DEVICE_DISK Return SetError(0, 0, DllStructGetData($tIOCTL_STORAGE_GET_DEVICE_NUMBER, "DeviceNumber")) EndIf Return SetError(4, 0, -1); not a disk partition EndFunc ;==>_GetDiskNimberForDrive I only have one disk, so I cannot test it.
    1 point
×
×
  • Create New...