매크로

자유
2023.02.23 10:20

Class_FTP.ahk

조회 수 157 추천 0 댓글 0
; ===============================================================================================================================
; AutoHotkey wrapper for FTP Sessions
;
; Author ....: jNizM
; Released ..: 2020-07-26
; Modified ..: 2020-07-31
; Github ....: https://github.com/jNizM/Class_FTP
; Forum .....: https://www.autohotkey.com/boards/viewtopic.php?f=6&t=79142
; ===============================================================================================================================


class FTP
{

static hWININET := DllCall("LoadLibrary", "str", "wininet.dll", "ptr")


; ===== PUBLIC METHODS ======================================================================================================

Close(hInternet)
{
if (hInternet)
if (this.InternetCloseHandle(hInternet))
return true
return false
}


Connect(hInternet, ServerName, Port := 21, UserName := "", Password := "", FTP_PASV := 1)
{
if (hConnect := this.InternetConnect(hInternet, ServerName, Port, UserName, Password, FTP_PASV))
return hConnect
return false
}


CreateDirectory(hConnect, Directory)
{
if (DllCall("wininet\FtpCreateDirectory", "ptr", hConnect, "ptr", &Directory))
return true
return false
}


DeleteFile(hConnect, FileName)
{
if (DllCall("wininet\FtpDeleteFile", "ptr", hConnect, "ptr", &FileName))
return true
return false
}


Disconnect(hConnect)
{
if (hConnect)
if (this.InternetCloseHandle(hConnect))
return true
return false
}


FindFiles(hConnect, SearchFile := "*.*")
{
static FILE_ATTRIBUTE_DIRECTORY := 0x10

Files := []
find := this.FindFirstFile(hConnect, hEnum, SearchFile)
if !(find.FileAttr & FILE_ATTRIBUTE_DIRECTORY)
Files.Push(find)

while (find := this.FindNextFile(hEnum))
if !(find.FileAttr & FILE_ATTRIBUTE_DIRECTORY)
Files.Push(find)
this.Close(hEnum)
return Files
}


FindFolders(hConnect, SubDirectories := "*.*")
{
static FILE_ATTRIBUTE_DIRECTORY := 0x10

Folders := []
find := this.FindFirstFile(hConnect, hEnum, SubDirectories)
if (find.FileAttr & FILE_ATTRIBUTE_DIRECTORY)
Folders.Push(find)
while (find := this.FindNextFile(hEnum))
if (find.FileAttr & FILE_ATTRIBUTE_DIRECTORY)
Folders.Push(find)
this.Close(hEnum)
return Folders
}


GetCurrentDirectory(hConnect)
{
static MAX_PATH := 260 + 8

BUFFER_SIZE := VarSetCapacity(CurrentDirectory, MAX_PATH, 0)
if (DllCall("wininet\FtpGetCurrentDirectory", "ptr", hConnect, "ptr", &CurrentDirectory, "uint*", BUFFER_SIZE))
return StrGet(&CurrentDirectory)
return false
}


GetFile(hConnect, RemoteFile, NewFile, OverWrite := 0, Flags := 0)
{
if (DllCall("wininet\FtpGetFile", "ptr", hConnect, "ptr", &RemoteFile, "ptr", &NewFile, "int", !OverWrite, "uint", 0, "uint", Flags, "uptr", 0))
return true
return false
}


GetFileSize(hConnect, FileName, SizeFormat := "auto", SizeSuffix := false)
{
static GENERIC_READ := 0x80000000

if (hFile := this.OpenFile(hConnect, FileName, GENERIC_READ))
{
VarSetCapacity(FileSizeHigh, 8)
if (FileSizeLow := DllCall("wininet\FtpGetFileSize", "ptr", hFile, "uint*", FileSizeHigh, "uint"))
{
this.InternetCloseHandle(hFile)
return this.FormatBytes(FileSizeLow + (FileSizeHigh << 32), SizeFormat, SizeSuffix)
}
this.InternetCloseHandle(hFile)
}
return false
}


Open(Agent, Proxy := "", ProxyBypass := "")
{
if (hInternet := this.InternetOpen(Agent, Proxy, ProxyBypass))
return hInternet
return false
}


PutFile(hConnect, LocaleFile, RemoteFile, Flags := 0)
{
if (DllCall("wininet\FtpPutFile", "ptr", hConnect, "ptr", &LocaleFile, "ptr", &RemoteFile, "uint", Flags, "uptr", 0))
return true
return false
}


RemoveDirectory(hConnect, Directory)
{
if (DllCall("wininet\FtpRemoveDirectory", "ptr", hConnect, "ptr", &Directory))
return true
return false
}


RenameFile(hConnect, ExistingFile, NewFile)
{
if (DllCall("wininet\FtpRenameFile", "ptr", hConnect, "ptr", &ExistingFile, "ptr", &NewFile))
return true
return false
}


SetCurrentDirectory(hconnect, Directory)
{
if (DllCall("wininet\FtpSetCurrentDirectory", "ptr", hConnect, "ptr", &Directory))
return true
return false
}


; ===== PRIVATE METHODS =====================================================================================================

FileAttributes(Attributes)
{
static FILE_ATTRIBUTE := { 0x1: "READONLY", 0x2: "HIDDEN", 0x4: "SYSTEM", 0x10: "DIRECTORY", 0x20: "ARCHIVE", 0x40: "DEVICE", 0x80: "NORMAL"
, 0x100: "TEMPORARY", 0x200: "SPARSE_FILE", 0x400: "REPARSE_POINT", 0x800: "COMPRESSED", 0x1000: "OFFLINE"
, 0x2000: "NOT_CONTENT_INDEXED", 0x4000: "ENCRYPTED", 0x8000: "INTEGRITY_STREAM", 0x10000: "VIRTUAL"
, 0x20000: "NO_SCRUB_DATA", 0x40000: "RECALL_ON_OPEN", 0x400000: "RECALL_ON_DATA_ACCESS" }
GetFileAttributes := []
for k, v in FILE_ATTRIBUTE
if (k & Attributes)
GetFileAttributes.Push(v)
return GetFileAttributes
}


FindData(ByRef WIN32_FIND_DATA, SizeFormat := "auto", SizeSuffix := false)
{
static MAX_PATH := 260
static MAXDWORD := 0xffffffff

addr := &WIN32_FIND_DATA
FIND_DATA := []
FIND_DATA["FileAttr"]          := NumGet(addr + 0, "uint")
FIND_DATA["FileAttributes"]    := this.FileAttributes(NumGet(addr + 0, "uint"))
FIND_DATA["CreationTime"]      := this.FileTime(NumGet(addr +  4, "uint64"))
FIND_DATA["LastAccessTime"]    := this.FileTime(NumGet(addr + 12, "uint64"))
FIND_DATA["LastWriteTime"]     := this.FileTime(NumGet(addr + 20, "uint64"))
FIND_DATA["FileSize"]          := this.FormatBytes((NumGet(addr + 28, "uint") * (MAXDWORD + 1)) + NumGet(addr + 32, "uint"), SizeFormat, SizeSuffix)
FIND_DATA["FileName"]          := StrGet(addr + 44, "utf-16")
FIND_DATA["AlternateFileName"] := StrGet(addr + 44 + MAX_PATH * (A_IsUnicode ? 2 : 1), "utf-16")
return FIND_DATA
}


FindFirstFile(hConnect, ByRef hFind, SearchFile := "*.*", SizeFormat := "auto", SizeSuffix := false)
{
VarSetCapacity(WIN32_FIND_DATA, (A_IsUnicode ? 592 : 320), 0)
if (hFind := DllCall("wininet\FtpFindFirstFile", "ptr", hConnect, "str", SearchFile, "ptr", &WIN32_FIND_DATA, "uint", 0, "uint*", 0))
return this.FindData(WIN32_FIND_DATA, SizeFormat, SizeSuffix)
VarSetCapacity(WIN32_FIND_DATA, 0)
return false
}


FindNextFile(hFind, SearchFile := "*.*", SizeFormat := "auto", SizeSuffix := false)
{
VarSetCapacity(WIN32_FIND_DATA, (A_IsUnicode ? 592 : 320), 0)
if (DllCall("wininet\InternetFindNextFile", "ptr", hFind, "ptr", &WIN32_FIND_DATA))
return this.FindData(WIN32_FIND_DATA, SizeFormat, SizeSuffix)
VarSetCapacity(WIN32_FIND_DATA, 0)
return false
}


FileTime(addr)
{
this.FileTimeToSystemTime(addr, SystemTime)
this.SystemTimeToTzSpecificLocalTime(&SystemTime, LocalTime)
return Format("{:04}{:02}{:02}{:02}{:02}{:02}"
, NumGet(LocalTime,  0, "ushort")
, NumGet(LocalTime,  2, "ushort")
, NumGet(LocalTime,  6, "ushort")
, NumGet(LocalTime,  8, "ushort")
, NumGet(LocalTime, 10, "ushort")
, NumGet(LocalTime, 12, "ushort"))
}


FileTimeToSystemTime(FileTime, ByRef SystemTime)
{
VarSetCapacity(SystemTime, 16, 0)
if (DllCall("FileTimeToSystemTime", "int64*", FileTime, "ptr", &SystemTime))
return true
return false
}


FormatBytes(bytes, SizeFormat := "auto", suffix := false)
{
static SFBS_FLAGS_ROUND_TO_NEAREST_DISPLAYED_DIGIT    := 0x0001
static SFBS_FLAGS_TRUNCATE_UNDISPLAYED_DECIMAL_DIGITS := 0x0002
static S_OK := 0

if (SizeFormat = "auto")
{
size := VarSetCapacity(buf, 1024, 0)
if (DllCall("shlwapi\StrFormatByteSizeEx", "int64", bytes, "int", SFBS_FLAGS_ROUND_TO_NEAREST_DISPLAYED_DIGIT, "str", buf, "uint", size) = S_OK)
output := buf
}
else if (SizeFormat = "kilobytes" || SizeFormat = "kb")
output := Round(bytes / 1024, 2) . (suffix ? " KB" : "")
else if (SizeFormat = "megabytes" || SizeFormat = "mb")
output := Round(bytes / 1024**2, 2) . (suffix ? " MB" : "")
else if (SizeFormat = "gigabytes" || SizeFormat = "gb")
output := Round(bytes / 1024**3, 2) . (suffix ? " GB" : "")
else if (SizeFormat = "terabytes" || SizeFormat = "tb")
output := Round(bytes / 1024**4, 2) . (suffix ? " TB" : "")
else
output := Round(bytes, 2) . (suffix ? " Bytes" : "")
return output
}


InternetCloseHandle(hInternet)
{
if (DllCall("wininet\InternetCloseHandle", "ptr", hInternet))
return true
return false
}


InternetConnect(hInternet, ServerName, Port := 21, UserName := "", Password := "", FTP_PASV := 1)
{
static INTERNET_DEFAULT_FTP_PORT := 21
static INTERNET_SERVICE_FTP      := 1
static INTERNET_FLAG_PASSIVE     := 0x08000000

if (hConnect := DllCall("wininet\InternetConnect", "ptr",    hInternet
, "ptr",    &ServerName
, "ushort", (Port = 21 ? INTERNET_DEFAULT_FTP_PORT : Port)
, "ptr",    (UserName ? &UserName : 0)
, "ptr",    (Password ? &Password : 0)
, "uint",   INTERNET_SERVICE_FTP
, "uint",   (FTP_PASV ? INTERNET_FLAG_PASSIVE : 0)
, "uptr",   0
, "ptr"))
return hConnect
return false
}


InternetOpen(Agent, Proxy := "", ProxyBypass := "")
{
static INTERNET_OPEN_TYPE_DIRECT := 1
static INTERNET_OPEN_TYPE_PROXY  := 3

if (hInternet := DllCall("wininet\InternetOpen", "ptr",  &Agent
   , "uint", (Proxy ? INTERNET_OPEN_TYPE_PROXY : INTERNET_OPEN_TYPE_DIRECT)
   , "ptr",  (Proxy ? &Proxy : 0)
   , "ptr",  (ProxyBypass ? &ProxyBypass : 0)
   , "uint", 0
   , "ptr"))
return hInternet
return false
}


OpenFile(hConnect, FileName, Access)
{
static FTP_TRANSFER_TYPE_BINARY := 2

if (hFTPSESSION := DllCall("wininet\FtpOpenFile", "ptr", hConnect, "ptr", &FileName, "uint", Access, "uint", FTP_TRANSFER_TYPE_BINARY, "uptr", 0))
return hFTPSESSION
return false
}


SystemTimeToTzSpecificLocalTime(SystemTime, ByRef LocalTime)
{
VarSetCapacity(LocalTime, 16, 0)
if (DllCall("SystemTimeToTzSpecificLocalTime", "ptr", 0, "ptr", SystemTime, "ptr", &LocalTime))
return true
return false
}

}

; ===============================================================================================================================

예시

#Include Class_FTP.ahk

hFTP := FTP.Open("ahk-ftp")
hSession := FTP.Connect(hFTP, "아이피", 21, "아이디", "비밀번호")
FTP.GetFile(hSession, "ver.txt", A_WorkingDir "\ver1.txt")
FTP.Disconnect(hSession)
FTP.Close(hFTP)



List of Articles
분류 제목 글쓴이 최근변경 추천
질문 혹시 스크립트 비교 쉽게 해주는프로그램도있나요? 8 튀니지사람들 2015.02.13 0/0
질문 혹시 스크립트 분석해서 최적화해주는 그런 프로그램 ... 7 옥짱 2015.02.05 0/0
질문 혹시 세븐나이츠 녹스에서 돌리시는 분들 중 1 크루세이덩 2016.09.13 0/0
자유 혹시 세나매크로 스크립트 구할 수 없을까요? 10 왜6자냐 2016.05.21 0/0
질문 혹시 세나 매크로 안되시는분? 5 ahura 2015.06.01 0/0
질문 혹시 서머너즈워 오토핫키 or 카카오토 스크립트 공유... 일하면서겜하깃 2019.04.10 0/0
질문 혹시 비활성서치 바람의나라에서 쓸만한 예제 없을까요? 김문기 2017.07.15 0/0
질문 혹시 바람의나라 오핫만드시는분 계신가요? 1 댕댕아씨 2016.09.10 0/0
질문 혹시 미뮤에서 PostMessage 동작하나요? 웃진 2018.06.11 0/0
질문 혹시 뮤오리진 질문이여, 2 사잉다유 2015.10.05 0/0
질문 혹시 모모 앱플레이어 run 으로 실행 명령어가 어떻게 ... 2 wnlf 2017.08.29 0/0
자유 혹시 메이플 사냥매클중에 이런gui보신분 룬오리 2019.04.06 0/0
질문 혹시 멀티스레드로 이미지 서치 돌려본 분 계신가요? 1 sistt 2015.09.01 0/0
질문 혹시 리니지m 지금 되나요? melce1 2019.04.17 0/0
질문 혹시 동시에 여러곳 클릭하는 게 가능한가요? 3 cis105 2017.12.11 0/0
질문 혹시 다른 게임 자동물약 소스 좀 가지고 계시분 있어요? 꿈을낚는아이 2015.09.26 0/0
질문 혹시 PostMessage쓸때 시간 간격 sleep < 문을 쓰나요? 2 꿈을낚는아이 2015.08.15 0/0
질문 혹시 ngs 우회방법이 있나요?? 2 배브아 2020.03.16 0/0
자유 혹시 adb에 대해 배울수잇는 곳 발레리나 2017.07.10 0/0
질문 혹시 1004 매크로 1920 * 1080 해상도를 세나에 맞춰 ... 인사왕바이킹 2014.12.01 0/0
Board Pagination Prev 1 2345678910 ... 209 Next
/ 209

전체 최신 인기글

전체 주간 인기글