Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

AHK Functions :: InCache() - Cache List of Recent Items


  • Please log in to reply
172 replies to this topic
Laszlo
  • Moderators
  • 4713 posts
  • Last active: Mar 31 2012 03:17 AM
  • Joined: 14 Feb 2005
It is good for associative arrays. The problem is not random collisions, but finding strings with the same hash is not very difficult, if you know the algorithm. I am not sure, how hard it is, because MSDN does not tell the algorithm.

For longer (<=7 bytes) hash you could try
Hash(Str, L=4, nSz=0) {
  Static HashData
  If (HashData="")
      HashData := DllCall("GetProcAddress", UInt,DllCall("LoadLibrary", Str,"shlwapi.dll"), Str,"HashData")
  DllCall(HashData, UInt,&Str, UInt,nSz<1 ? StrLen(Str):nSz, Int64P,Hash, UInt,8)
  FI := A_FormatInteger
  SetFormat Integer, H
  Hash := SubStr(Hash+0x100000000000000,1-2*L)
  StringUpper Hash, Hash
  SetFormat Integer, %FI%
  Return Hash
}
It computes 8 bytes hash even when less than 8 bytes are requested, and discards the unused part. A general solution was VarsetCapacity and Str type for the returned value, and convert the result to hex with a loop.

Sprintf handles the padding and hex conversion for up to 8 Bytes input, so the following code is better, little shorter, and could be faster
Hash(Str, L=4, nSz=0) { ; L Bytes, 2*L HEX digits output, 1<=L<=8
  Static HashData, sprintf, S=1234567890123456
  If (HashData="")
      HashData := DllCall("GetProcAddress", UInt,DllCall("LoadLibrary", Str,"shlwapi.dll"),Str,"HashData")
      ,sprintf := DllCall("GetProcAddress", UInt,DllCall("LoadLibrary", Str,"msvcrt.dll"), Str,"sprintf")
  DllCall(HashData, UInt,&Str, UInt,nSz<1 ? StrLen(Str):nSz, Int64P,Hash, UInt,8) ; 8-Byte= 64-bit hash
  DllCall(sprintf, Str,S, Str,"%016I64X", Int64,Hash) ; 0-padded (left), 16 HEX digits
  Return SubStr(S, 1-2*L) ; only 2L digits
}

Edit 20081120: shorter code added

SKAN
  • Administrators
  • 9115 posts
  • Last active:
  • Joined: 26 Dec 2005

It is good for associative arrays.


Glad to hear it..

DllCall(HashData, UInt,&Str, UInt,nSz<1 ? StrLen(Str):nSz, [color=red]Int64P[/color],Hash, UInt,8)

I missed that part :shock: .. Thank you.

It computes 8 bytes hash even when less than 8 bytes are requested, and discards the unused part. A general solution was VarsetCapacity and Str type for the returned value, and convert the result to hex with a loop.


Thank you very much Sir. Very useful info for me.

:)

SKAN
  • Administrators
  • 9115 posts
  • Last active:
  • Joined: 26 Dec 2005

ProcessOwner()

Returns the Owner for a given Process ID. To make it fully functional, one needs to call SetDebugPrivilege() prior to ProcessOwner()

Credit:

[*:weq5ghgg]Sincere thanks to Sean, for pointing out the method and for providing half the code
[*:weq5ghgg]Nibu Thomas : How to get name of owner of a process?

Additional Reference:

[*:weq5ghgg]CodeProject: How To Get Process Owner ID and Current User SID
[*:weq5ghgg]MSDN: GetTokenInformation()LookupAccountSid()

ProcessOwner( PID ) { 
 ; PROCESS_QUERY_INFORMATION=[color=red]0x400[/color], TOKEN_READ:=[color=red]0x20008[/color] , TokenUser:=[color=red]0x1[/color]
 hProcess := DllCall( "OpenProcess", UInt,[color=red]0x400[/color],Int,0,UInt,PID ) 
 DllCall( "Advapi32.dll\OpenProcessToken", UInt,hProcess, UInt,[color=red]0x20008[/color], UIntP,Tok )
 DllCall( "Advapi32.dll\GetTokenInformation", UInt,Tok, UInt,[color=red]0x1[/color], Int,0, Int,0, UIntP,RL )
 VarSetCapacity( TI,RL,0 )
 DllCall( "Advapi32.dll\GetTokenInformation"
          , UInt,Tok, UInt,0x1, UInt,&TI, Int,RL, UIntP,RL ),           pSid := NumGet(TI)
 DllCall( "CloseHandle", UInt,hProcess ), DllCall( "CloseHandle", UInt,Tok )
 ; following code taken from www.autohotkey.com/forum/viewtopic.php?p=116487 [color=Black]- Author Sean[/color]
 DllCall( "Advapi32\LookupAccountSidA"
         , Str,"", UInt,pSid, UInt,0, UIntP,nSizeNM, UInt,0, UIntP,nSizeRD, UIntP,eUser ) 
 VarSetCapacity( sName,nSizeNM,0 ), VarSetCapacity( sRDmn,nSizeRD,0 ) 
 DllCall( "Advapi32\LookupAccountSidA"
    , Str,"", UInt,pSid, Str,sName, UIntP,nSizeNM, Str,sRDmn, UIntP,nSizeRD, UIntP,eUser ) 
 DllCall( "LocalFree", UInt,pSid ) 
Return sName
}  

; usage example follows

; SetDebugPrivilege() ; www.autohotkey.com/forum/viewtopic.php?p=232199#232199 
Process Exist, svchost.exe
PID := ErrorLevel
MsgBox, % ProcessOwner( PID )

:)



Sean
  • Members
  • 2462 posts
  • Last active: Feb 07 2012 04:00 AM
  • Joined: 12 Feb 2007
Very nice. This is another one which surprised me at that it's not been done earlier.
BTW, as the first ones which attract my eyes are the flags as they are in red, I'd like to mention that TOKEN_QUERY ( :=8 ) is enough in place of TOKEN_READ although it's cosmetic one.
And one request: it may depend on an user, but I'd always like to include (referenced) domain name too like:
sRDmn . "\" . sName


SKAN
  • Administrators
  • 9115 posts
  • Last active:
  • Joined: 26 Dec 2005

Very nice. This is another one which surprised me at that it's not been done earlier.


Many thanks for your help Sean. :)

TOKEN_QUERY ( :=8 ) is enough in place of TOKEN_READ although it's cosmetic one.


I was wondering about it.. just adapted it : <!-- m -->http://nibuthomas.wo... ... a-process/<!-- m -->

And one request: it may depend on an user, but I'd always like to include (referenced) domain name too


Honestly, I did not notice it at all. I took your code for granted and all I did was to remove quote around Arg Types. . :)

SKAN
  • Administrators
  • 9115 posts
  • Last active:
  • Joined: 26 Dec 2005

ColorAdjL()

Adjust Luminance for a given RGB color. In other words, this function can derive a lighter / darker shade for a given RGB color

Parameters.

Luminance : Value between 1 - 239 ( 0 is black and 240 is White )
RGB : The RGB color to be adjusted. If ignored, a random color will be generated and used

Usage Examples:

; To derive a dark / light shade of red
darkRed := ColorAdjL(  70, 0xFF0000 )
liteRed := ColorAdjL( 235, 0xFF0000 )
; To derive a random ( but matching ) dark / light shade
darkRandom := ColorAdjL(  70 )
liteRandom := ColorAdjL( 235, "0x" darkRandom )

ColorAdjL( Lum=235, RGB="" ) {
 IfEqual,RGB,, Random,RGB,1,16777215
 DllCall( "shlwapi\ColorRGBToHLS", UInt,RGB, UIntP,H, UIntP,L, UIntP,S )
 CC := DllCall( "shlwapi\ColorHLSToRGB", UInt,H, UInt,Lum, UInt,S )
 VarSetCapacity(RGB,6,0), DllCall( "msvcrt.dll\sprintf", Str,RGB, Str,"%06X", UInt,CC )
Return RGB
}

[color=#808080]Gui +ToolWindow +AlwaysOnTop
Dark  := ColorAdjL(  70, 0xFF0000 )
Light := ColorAdjL( 235, 0xFF0000 )
Gui, Color, %Light%
Gui, Font, s50
Gui, Add, Text, x5 y5 w200 h75 c%Dark% Center vText, Hello
Gui, Font
Gui, Add, Edit, x36 y100 w30 h20 Limit3 Center vLum, 230
Gui, Add, Button, x+5 h20 w100 gChangeGuiColor, Random Color
Gui, Show, w210 h130, % " GuiColor : " Light
Return

ChangeGuiColor:
 GuiControlGet, Lum
 Light := ColorAdjL( Lum )
 Gui, Color, %Light%
 Gui, Show,, % " GuiColor : " Light
Return

GuiClose:
 ExitApp[/color]


:)



SKAN
  • Administrators
  • 9115 posts
  • Last active:
  • Joined: 26 Dec 2005

SoundExC() - SoundEx Classic Version

http://en.wikipedia.org/wiki/Soundex

Soundex is a phonetic algorithm for indexing names by sound, as pronounced in English. The goal is for names with the same pronunciation to be encoded to the same representation so that they can be matched despite minor differences in spelling. Soundex is the most widely known of all phonetic algorithms and is often used (incorrectly) as a synonym for "phonetic algorithm". Improvements to Soundex are the basis for many modern phonetic algorithms


How To: Understanding Classic SoundEx Algorithms

The Algorithm as an Outline
[*:2qfyhwt8]Capitalize all letters in the word and drop all punctuation marks. Pad the word with rightmost blanks as needed during each procedure step.
[*:2qfyhwt8]Retain the first letter of the word.
[*:2qfyhwt8]Change all occurrence of the following letters to '0' (zero):
'A', E', 'I', 'O', 'U', 'H', 'W', 'Y'.
[*:2qfyhwt8]Change letters from the following sets into the digit given:
1 = 'B', 'F', 'P', 'V'
2 = 'C', 'G', 'J', 'K', 'Q', 'S', 'X', 'Z'
3 = 'D','T'
4 = 'L'
5 = 'M','N'
6 = 'R'
[*:2qfyhwt8]Remove all pairs of digits which occur beside each other from the string that resulted after step (4).
[*:2qfyhwt8]Remove all zeros from the string that results from step 5.0 (placed there in step 3)
[*:2qfyhwt8]Pad the string that resulted from step (6) with trailing zeros and return only the first four positions, which will be of the form <uppercase letter> <digit> <digit> <digit>. The algorithm presented above is slightly improved over the originally patented algorithm.
The original Soundex algorithm of 1918 starts to fail when the number of words in the database gets to be large. For example, the diversity of names in a large database with many foreign spellings starts to put more and more phonetically unlike names into the same code.

The slightly improved algorithm presented here differs from the original in step three, where the vowel sounds are replaced with zeros ('0'), and in step (6.0) where those zeros are removed. The original algorithm eliminated the vowels completely in step 3.0, before duplicate adjacent digits are removed.

This improved version will produce SoundEx codes with duplicate digits in them; for example, "HERMAN" will code to "H06505" which will then reduce to "H655" in the last step. In the original version, "HERMAN" would code to "H655" which will then reduce to "H65" and finally to "H650" in the last step.


SoundExC( Wrd="" ) {
 Static A=0, B=1, C=2, D=3, E=0, F=1, G=2, H=0, I=0, J=2, K=2, L=4, M=5
 Static N=5, O=0, P=1, Q=2, R=6, S=2, T=3, U=0, V=1, W=0, X=2, Y=0, Z=2
 StringUpper, Wrd, Wrd 
 Pre:=SubStr( Wrd,1,1 ), Prv:=%Pre%, Word:=SubStr(Wrd,2)
 Loop, Parse, Word
  If ( Asc(A_LoopField)>64 && Asc(A_LoopField)< 91 ) 
       StringReplace, Word, Word, %A_LoopField%, % %A_LoopField%
  Else StringReplace, Word, Word, %A_LoopField%
 Loop, Parse, Word
   SE .= A_LoopField=Prv ? "" : Prv:=A_LoopField
 StringReplace,SE,SE,0,, All
Return Pre SubStr( SE "000", 1,3 ) 
}

[color=black]words=crazy|crazie|craezie|crazi|crasie|cracie|crecie|crazee|crezie|crraazziiee
Loop, Parse, words, |
  List .= A_LoopField "`t=  " SoundExC( A_LoopField ) "`n"
MsgBox, % List[/color]

Note: Leading spaces, if any, should be trimmed out before passing it to SoundExC()

:)



SKAN
  • Administrators
  • 9115 posts
  • Last active:
  • Joined: 26 Dec 2005

FA() - A Tiny 2L Function to maintain a single dimension UINT array

FA(E=0,V="",S="") { ; www.autohotkey.com/forum/viewtopic.php?p=242750#242750
 Static C,P
Return ((E+0)>=0&&V="")?(NumGet(P+0,E*4)):(E&&(V+0)>=0)?(NumPut(V,P+0,E*4)-4):(S="+"&&V
 >0)?((O:=NumPut((V:=NumGet(E*4+P)+V),E*4+P))-O+V):(S="-"&&V>0)?((O:=NumPut((V:=NumGet(E*4
 +P)-V),E*4+P))-O+V):(E>0&&V="Init")?(VarSetCapacity(C,(E+1)*4,0)+(P:=NumPut(E,C)-4)-P):(E
 ="Rel"&&P)?((P:=0)+VarSetCapacity(C,0)+1):(E="Ptr"&&P) ? P : ""
}

; [color=red]The above ternary version was derived from following code[/color]

/*

[color=darkblue]FA( E=0,V="",S="" ) { 
 Static C,P 

 If ((E+0)>=0&&V="")                                           ;  NumGet 
  Return (NumGet(P+0,E*4)) 

 If (E&&(V+0)>=0)                                              ;  NumPut 
  Return (NumPut(V,P+0,E*4)-4) 

 If (S="+"&&V>0)                                               ;  NumAdd 
  Return ((O:=NumPut((V:=NumGet(E*4+P)+V),E*4+P))-O+V) 

 If (S="-"&&V>0)                                               ;  NumSub 
  Return ((O:=NumPut((V:=NumGet(E*4+P)-V),E*4+P))-O+V) 

 If (E>0&&V="Init")                                            ;  Init Var 
  Return,(VarSetCapacity(C,(E+1)*4,0)+(P:=NumPut(E,C)-4)-P) 

 If (E="Rel"&&P)                                               ;  Release Var 
  Return ((P:=0)+VarSetCapacity(C,0)+1) 

 If (E="Ptr"&&P)                                               ;  Obtain Pointer 
  Return P 
} [/color]
*/


The primary objective of this function is to provide a mechanism to share Integers between functions, thereby avoiding a clutter of Global variables.
In short, FA() is a function that acts as an single dimension array

The parameters are cumbersome to document, and so, I provide here example calls, instead.

Basic:
FA(10,"Init")   ; Initialise capacity for 10 UINT elements
               ; Returns the Static Variable's size

FA(6,25000)     ; Put 25000 in element 6
               ; Returns the pointer to the UINT

FA(4,0)         ; Nullify element 4
               ; same as above

FA(7)           ; Return the value stored in element 7


Extended:
Support for counters.

FA(6,1230,"+")  ; Increment the value stored in element 6 by 1230
               ; Returns the new value

FA(6,1230,"-")  ; Decrement the value stored in element 6 by 1230
               ; Returns the new value

For any further manipulation, the pointer to the array can be retrieved..

FA("Ptr")

..and to release/reset the array

FA("Rel")


My Requirement:
With forth-coming release: 1.0.48, using ProcAddress directly in DllCall() would increase the performance significantly. I needed a mechanism to initialise the and share the ProcAddresses between many functions of the same wrapper - without creating global variables, and hence I wrote FA()

The following is a dumb, but working example of my intended use.

MsgBox, % FormatBytes( GetFileSize( A_AhkPath ) )
MsgBox, % FormatBytes( GetFileSize( A_ScriptFullPath ) )

GetFileSize( File ) { ; 4GB Limit
 Static Init,FOpen,FSeek,FClose
 If !Init
   Init:=InitAPI(), FOpen:=FA(1),FSeek:=FA(3),FClose:=FA(4)
 If ( H := DllCall(FOpen,Str,File,Int,0x0) ) < 1
    Return H
 FilePointer := DllCall(FSeek,Int,H,Int,0,Int,2), DllCall(FClose,UInt,H)
Return FilePointer
}

FormatBytes( Bytes ) {
 Static FormatBytes
 If !FormatBytes
     FormatBytes:=FA(11), VarSetCapacity(Formatted,16)
 DllCall(FormatBytes, Int64,Bytes, Str,Formatted, UInt,16 )
Return Formatted
}

InitAPI() {
 Static Funx
 IfNotEqual,Funx,,Return,Funx
 FA( 20, "Init" ) ; Initialise 20 UINT elements

 Kernel32 := DllCall( "GetModuleHandle", Str,"Kernel32.dll" )
 FA( 1, DllCall( "GetProcAddress", UInt,Kernel32, Str,"_lopen"  ) )
 FA( 2, DllCall( "GetProcAddress", UInt,Kernel32, Str,"_lread"  ) )
 FA( 3, DllCall( "GetProcAddress", UInt,Kernel32, Str,"_llseek" ) )
 FA( 4, DllCall( "GetProcAddress", UInt,Kernel32, Str,"_lclose" ) )
 FA( 5, DllCall( "GetProcAddress", UInt,Kernel32, Str,"_lcreat" ) )
 FA( 6, DllCall( "GetProcAddress", UInt,Kernel32, Str,"_lwrite" ) )
 FA( 7, DllCall( "GetProcAddress", UInt,Kernel32, Str,"RtlMoveMemory" ) )

 ShlwAPI := DllCall( "LoadLibrary", Str,"Shlwapi.dll" )
 FA( 11, DllCall( "GetProcAddress", UInt,ShlwAPI, Str,"StrFormatByteSize64A" ) )
 ; unused elements are for future use
Return (Funx:=1)
}

FA(E=0,V="",S="") { ; www.autohotkey.com/forum/viewtopic.php?p=242750#242750
Static C,P
Return ((E+0)>=0&&V="")?(NumGet(P+0,E*4)):(E&&(V+0)>=0)?(NumPut(V,P+0,E*4)-4):(S="+"&&V
 >0)?((O:=NumPut((V:=NumGet(E*4+P)+V),E*4+P))-O+V):(S="-"&&V>0)?((O:=NumPut((V:=NumGet(E*4
 +P)-V),E*4+P))-O+V):(E>0&&V="Init")?(VarSetCapacity(C,(E+1)*4,0)+(P:=NumPut(E,C)-4)-P):(E
 ="Rel"&&P)?((P:=0)+VarSetCapacity(C,0)+1):(E="Ptr"&&P) ? P : ""
}



SKAN
  • Administrators
  • 9115 posts
  • Last active:
  • Joined: 26 Dec 2005

GetDeviceSerialFromUSBdrive()

2009-06-08: Deprecated, does not work in Vista! Use USBD_GetDeviceSerial() instead

Given an USB Storage Drive Letter, this function will retrieve the Serial Number and the Friendly name of the USB device by looking up the registry.

Reference: Ask for Help topic: possible to tell une usb stick from another?

Note: Limited testing done only in XP SP2 - with available HW ( Flash Sticks, DSC, MP3 Player and Card Reader ) and results were compared with USBDeview


[color=black]MsgBox, % GetDeviceSerialFromUSBdrive( "J:" )[/color] ; Usage Example

GetDeviceSerialFromUSBdrive( Drv="" ) {
 DriveGet, DriveType, Type, %Drv%
 IfNotEqual,DriveType,Removable, Return
 RegRead, Hex, HKLM, SYSTEM\MountedDevices, \DosDevices\%Drv%
 VarSetCapacity(U,(Sz:=StrLen(Hex)//2)),  VarSetCapacity(A,Sz+1)
 Loop % Sz
  NumPut( "0x" . SubStr(hex,2*A_Index-1,2), U, A_Index-1, "Char" )
 DllCall( "WideCharToMultiByte", Int,0,Int,0, UInt,&U,UInt,Sz, Str,A,UInt,Sz, Int,0,Int,0)
 StringSplit, Part, A, #
 ParentIdPrefixCheck := SubStr( Part3,1,InStr(Part3,"&",0,0)-1 )
 Loop, HKLM, SYSTEM\CurrentControlSet\Enum\USBSTOR,1,0
 { Device := A_LoopRegName
   Loop, HKLM, SYSTEM\CurrentControlSet\Enum\USBSTOR\%Device%,1,0
 { Serial := A_LoopRegName
   RegRead, PIPrefix, HKLM, SYSTEM\CurrentControlSet\Enum\USBSTOR\%Device%\%Serial%
          , ParentIdPrefix
   If ( PIPrefix = ParentIdPrefixCheck ) {
   RegRead, DeviceFN, HKLM, SYSTEM\CurrentControlSet\Enum\USBSTOR\%Device%\%Serial%
          , FriendlyName
   Return, SubStr( Serial,1,InStr(Serial,"&",0,0)-1 ) " " DeviceFN
}}
}}

:)



Snippet 1: Use a Removable Drive as a Key ( to lock / unlock your computer.. etc. )

DeviceFound := False
DriveFN := "[color=red]GDLL4HW4 JetFlash TS4GJFV30 USB Device[/color]"
DriveGet, Drvs, List, Removable
Loop, Parse, Drvs
 If ( GetDeviceSerialFromUSBdrive( A_LoopField ":" ) == DriveFN ) {
      DeviceFound := True,  Drv := A_LoopField ":"
      Break
   }
If DeviceFound
     MsgBox, 64, USB Device Found, % DriveFN "`nfound in Drive " Drv
Else MsgBox, 16, USB Device Not Found, %DriveFN%
Return

; Copy/Paste GetDeviceSerialFromUSBdrive()

Snippet 2: Force your Compiled script to load only from a particular Removable Drive

SplitPath, A_ScriptFullPath,,,,, Drv
If ! ( GetDeviceSerialFromUSBdrive( Drv ) == "[color=red]GDLL4HW4 JetFlash TS4GJFV30 USB Device[/color]" ) {
  MsgBox, 16, MySofwareName, Software Access Denied!`nThe Application will quit now, 7
  ExitApp
   }
   
; Copy/Paste GetDeviceSerialFromUSBdrive()


SKAN
  • Administrators
  • 9115 posts
  • Last active:
  • Joined: 26 Dec 2005

PixelCheckSum()

Generates a CheckSum for a region of pixels in Screen/Window

Credit: Thanks to Sean. Screen Capture with Transparent Windows and Mouse Cursor

PixelCheckSum( X=0, Y=0, W=3, H=3, Title="" ) {
 hWn := WinExist( Title ), hDC := DllCall( "[color=#D62A00]GetDC[/color]", UInt,hWn )
 mDC := DllCall( "[color=#D62A00]CreateCompatibleDC[/color]", UInt,hDC )
 NumPut( VarSetCapacity(BI,40,0),BI ), NumPut( W,BI,4 ) , NumPut( H,BI,8 )
 NumPut( 32,NumPut( 1,BI,12,"UShort" ),0,"UShort" )     , NumPut( 0,BI,16 )
 hBM := DllCall( "[color=#D62A00]CreateDIBSection[/color]", UInt,mDC, UInt,&BI , Int,0, UIntP,pB, Int,0,Int,0 )
 oBM := DllCall( "[color=#D62A00]SelectObject[/color]", UInt,mDC, UInt,hBM )   , Rop := 0x40000000|0x00CC0020
 DllCall( "[color=#D62A00]BitBlt[/color]", UInt,mDC, Int,0,Int,0, Int,W,Int,H, UInt,hDC, Int,X,Int,Y, UInt,Rop )
 DllCall( "[color=#D62A00]shlwapi\HashData[/color]", UInt,pB, UInt,W*H*4, Int64P,Hash, UInt,8 )
 VarSetCapacity(HH,16,0), DllCall( "[color=#D62A00]msvcrt\sprintf[/color]", Str,HH, Str,"%016I64X",UInt64,Hash )
 DllCall( "[color=#D62A00]DeleteObject[/color]", UInt,hBM ), DllCall( "[color=#D62A00]DeleteObject[/color]", UInt,oBM )
 DllCall( "[color=#D62A00]DeleteDC[/color]", UInt,mDC ), DllCall( "[color=#D62A00]ReleaseDC[/color]", UInt,hWn, UInt,hDC )
Return HH
}

; Example - Wait for a Screen Region to change
ChkSum := PixelChecksum( 0,0,10,10 )
While % ( ChkSum = PixelChecksum( 0,0,10,10 ) )
  Sleep, 100
MsgBox, Screen Region Change Detected!
Return


:)



n-l-i-d
  • Guests
  • Last active:
  • Joined: --
Excellent! (as always)...

8)

SKAN
  • Administrators
  • 9115 posts
  • Last active:
  • Joined: 26 Dec 2005
@daonlyfreez: Thanks friend :D

fragman
  • Members
  • 1591 posts
  • Last active: Nov 12 2012 08:51 PM
  • Joined: 13 Oct 2009
ShellFileOperation doesn't work with FTP servers. Calling it like this:
ShellFileOperation(0x2,"C:\Program Files\AutoHotkey\main.exe","ftp://user@autohotkey.net/",0,0)

Shows a dialog asking if a path "C:\Program Files\AutoHotkey\ftp:\" should be created, and then it either fails with a Cancelled error system code or with a 123 code indicating a path with wrong format.

For now I'm going to avoid that by using a different transfer function for ftp, but it would be nice to see the windows dialogs for it, and I believe it should be possible since explorer can do it.

OceanMachine
  • Members
  • 790 posts
  • Last active: Aug 23 2013 02:10 PM
  • Joined: 15 Oct 2007

ShellFileOperation doesn't work with FTP servers... I believe it should be possible since explorer can do it.


I think that when you put the ftp protocol in the address bar of explorer (i.e. typing <!-- m -->ftp://whatever<!-- m -->), windows actually swiches to using Internet Explorer to do that for you, and not Explorer (the file explorer). So Explorer can't do it... (as far as I am aware). It's not a standard Shell File Operation.

Try something like this WININET wrapper for an FTP solution.

Another alternative is to use this libcURL wrapper.

fragman
  • Members
  • 1591 posts
  • Last active: Nov 12 2012 08:51 PM
  • Joined: 13 Oct 2009
I'm currently transferring files using the wrapper, but I want to show native transfer dialogs, so the user can also get replacement questions, progress etc.

(internet?) Explorer can do the transfer, even with files from clipboard, maybe I can find a way to remote control a hidden explorer window or so.