EverythingApi.py 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. import zlib
  2. import sys
  3. import ctypes
  4. import datetime
  5. import struct
  6. import re
  7. import os
  8. import platform
  9. # 从文件中读取block_size大小,计算CRC32
  10. def crc32_simple(filepath):
  11. try:
  12. with open(filepath, 'rb') as f:
  13. s = f.read(1024 * 1024)
  14. return zlib.crc32(s, 0)
  15. except Exception as e:
  16. print(str(e))
  17. return 0
  18. # 计算整个文件的crc32
  19. def crc32_file(filepath):
  20. crc = 0
  21. try:
  22. fd = open(filepath, 'rb')
  23. while True:
  24. buffer = fd.read(1024 * 1024)
  25. if len(buffer) == 0: # EOF or file empty. return hashes
  26. fd.close()
  27. if sys.version_info[0] < 3 and crc < 0:
  28. crc += 2 ** 32
  29. return crc # 返回的是十进制的值
  30. crc = zlib.crc32(buffer, crc)
  31. except Exception as e:
  32. if sys.version_info[0] < 3:
  33. error = unicode(e)
  34. else:
  35. error = str(e)
  36. print(error)
  37. return 0
  38. # 根据文件大小 返回合理区间,16473740 bytes--> 15.727 MB
  39. def FormatSize(size):
  40. # 递归实现,精确为最大单位值 + 小数点后三位
  41. def formatsize(integer, remainder, level):
  42. if integer >= 1024:
  43. remainder = integer % 1024
  44. integer //= 1024
  45. level += 1
  46. return formatsize(integer, remainder, level)
  47. else:
  48. return integer, remainder, level
  49. units = ['B', 'KB', 'MB', 'GB', 'TB', 'PB']
  50. integer, remainder, level = formatsize(size, 0, 0)
  51. if level + 1 > len(units):
  52. level = -1
  53. return ('{}.{:>03d} {}'.format(integer, remainder, units[level]))
  54. # 转换时间
  55. def get_time(filetime):
  56. # convert a windows FILETIME to a python datetime
  57. # https://stackoverflow.com/questions/39481221/convert-datetime-back-to-windows-64-bit-filetime
  58. WINDOWS_TICKS = int(1 / 10 ** -7) # 10,000,000 (100 nanoseconds or .1 microseconds)
  59. WINDOWS_EPOCH = datetime.datetime.strptime('1601-01-01 00:00:00', '%Y-%m-%d %H:%M:%S')
  60. POSIX_EPOCH = datetime.datetime.strptime('1970-01-01 00:00:00', '%Y-%m-%d %H:%M:%S')
  61. EPOCH_DIFF = (POSIX_EPOCH - WINDOWS_EPOCH).total_seconds() # 11644473600.0
  62. WINDOWS_TICKS_TO_POSIX_EPOCH = EPOCH_DIFF * WINDOWS_TICKS # 116444736000000000.0
  63. """Convert windows filetime winticks to python datetime.datetime."""
  64. winticks = struct.unpack('<Q', filetime)[0]
  65. microsecs = (winticks - WINDOWS_TICKS_TO_POSIX_EPOCH) / WINDOWS_TICKS
  66. return datetime.datetime.fromtimestamp(microsecs).strftime('%Y-%m-%d %H:%M:%S')
  67. class Everything:
  68. # defines 定义参看Everything.h
  69. EVERYTHING_REQUEST_FILE_NAME = 0x00000001
  70. EVERYTHING_REQUEST_PATH = 0x00000002
  71. EVERYTHING_REQUEST_SIZE = 0x00000010
  72. EVERYTHING_REQUEST_DATE_MODIFIED = 0x00000040
  73. EVERYTHING_SORT_SIZE_DESCENDING = 6
  74. def __init__(self):
  75. # dll imports
  76. pwd = os.path.dirname(__file__)
  77. if platform.architecture()[0] == '32bit':
  78. self.everything_dll = ctypes.WinDLL(os.path.join(pwd, "Everything32.dll"))
  79. else:
  80. self.everything_dll = ctypes.WinDLL(os.path.join(pwd, "Everything64.dll"))
  81. # everything_dll = ctypes.WinDLL(r"E:\\PYProject\\pyqt5\\everything\\Everything64.dll")
  82. self.everything_dll.Everything_GetResultDateModified.argtypes = [ctypes.c_int,
  83. ctypes.POINTER(ctypes.c_ulonglong)]
  84. self.everything_dll.Everything_GetResultSize.argtypes = [ctypes.c_int, ctypes.POINTER(ctypes.c_ulonglong)]
  85. self.everything_dll.Everything_GetResultFileNameW.argtypes = [ctypes.c_int]
  86. self.everything_dll.Everything_GetResultFileNameW.restype = ctypes.c_wchar_p
  87. # 关键词搜索
  88. def searchfile(self, bookName):
  89. recom = re.compile(r'[《》::、;.,,;—— -()()【】\'\"]')
  90. keyword = recom.sub(' ', bookName).strip()
  91. if len(keyword) < 1:
  92. return
  93. # 文件大小倒序
  94. self.everything_dll.Everything_SetSort(self.EVERYTHING_SORT_SIZE_DESCENDING)
  95. self.everything_dll.Everything_SetSearchW(keyword)
  96. self.everything_dll.Everything_SetRequestFlags(
  97. self.EVERYTHING_REQUEST_FILE_NAME | self.EVERYTHING_REQUEST_PATH | self.EVERYTHING_REQUEST_SIZE | self.EVERYTHING_REQUEST_DATE_MODIFIED)
  98. # execute the query
  99. self.everything_dll.Everything_QueryW(1)
  100. # get the number of results
  101. num_results = self.everything_dll.Everything_GetNumResults()
  102. # show the number of results
  103. result = "\nResult Count: {}\n".format(num_results)
  104. print(keyword, result)
  105. # create buffers
  106. file_name = ctypes.create_unicode_buffer(260)
  107. file_modi = ctypes.c_ulonglong(1)
  108. file_size = ctypes.c_ulonglong(1)
  109. # show results
  110. results = [] # 创建一个空列表来保存所有结果
  111. for i in range(num_results):
  112. self.everything_dll.Everything_GetResultFullPathNameW(i, file_name, 260)
  113. self.everything_dll.Everything_GetResultDateModified(i, file_modi)
  114. self.everything_dll.Everything_GetResultSize(i, file_size)
  115. filepath = ctypes.wstring_at(file_name)
  116. if filepath.endswith('.lnk') or filepath.endswith('.txt'):
  117. continue
  118. # 计算文件crc32,格式化为0x1122AAFF
  119. filecrc = hex(crc32_file(filepath)).upper().replace("0X", "0x")
  120. filesize = FormatSize(file_size.value)
  121. modtime = get_time(file_modi)
  122. # strInfo = "\nFilePath: {}\nSize: {} CRC32:{} modtime:{}".format(filepath, filesize, filecrc, modtime)
  123. # print(strInfo)
  124. # 创建一个字典包含文件的所有相关信息
  125. file_info = {
  126. "file_name": os.path.basename(filepath),
  127. "file_path": os.path.dirname(filepath),
  128. "file_size": filesize,
  129. "modified_time": modtime
  130. }
  131. results.append(file_info) # 将字典添加到结果列表中
  132. return results
  133. if __name__ == "__main__":
  134. everythine = Everything()
  135. everythine.searchfile("科大讯飞")