def GetDriveObject(index): """ドライブ情報を調べて、browsableObjectsで返す。Aドライブが0、Zドライブが25。""" letter = chr(index + 65) path = letter + ":\\" type = win32file.GetDriveType(path) f = -1 t = -1 n = "" try: volumeInfo = win32api.GetVolumeInformation(path) n = volumeInfo[0] freeSpace = win32api.GetDiskFreeSpaceEx(path) f = freeSpace[0] t = freeSpace[1] except pywintypes.error as err: pass # エラーは無視 d = browsableObjects.Drive() if type != win32file.DRIVE_REMOTE or t != -1: ret, shfileinfo = shell.SHGetFileInfo(letter + ":\\", 0, shellcon.SHGFI_ICON) d.Initialize(letter, f, t, type, n, shfileinfo[0]) else: d.Initialize(letter, f, t, type, n, -1) return d
def get_icon(PATH, size): SHGFI_ICON = 0x000000100 SHGFI_ICONLOCATION = 0x000001000 if size == "small": SHIL_SIZE = 0x00001 elif size == "large": SHIL_SIZE = 0x00002 else: raise TypeError( "Invalid argument for 'size'. Must be equal to 'small' or 'large'") ret, info = shell.SHGetFileInfo( PATH, 0, SHGFI_ICONLOCATION | SHGFI_ICON | SHIL_SIZE) hIcon, iIcon, dwAttr, name, typeName = info ico_x = win32api.GetSystemMetrics(win32con.SM_CXICON) hdc = win32ui.CreateDCFromHandle(win32gui.GetDC(0)) hbmp = win32ui.CreateBitmap() hbmp.CreateCompatibleBitmap(hdc, ico_x, ico_x) hdc = hdc.CreateCompatibleDC() hdc.SelectObject(hbmp) hdc.DrawIcon((0, 0), hIcon) win32gui.DestroyIcon(hIcon) bmpinfo = hbmp.GetInfo() bmpstr = hbmp.GetBitmapBits(True) img = Image.frombuffer("RGBA", (bmpinfo["bmWidth"], bmpinfo["bmHeight"]), bmpstr, "raw", "BGRA", 0, 1) if size == "small": img = img.resize((16, 16), Image.ANTIALIAS) return img
def _MakeObject(self, objType, fullpath, isDir=False): stat = os.stat(fullpath) ret, shfileinfo = shell.SHGetFileInfo( fullpath, 0, shellcon.SHGFI_ICON | shellcon.SHGFI_TYPENAME) obj = objType() if isDir: size = -1 else: size = stat.st_size # エラー対策 mtime = 0 ctime = 0 if stat.st_mtime <= 32536799999: mtime = stat.st_mtime if stat.st_ctime <= 32536799999: ctime = stat.st_ctime obj.Initialize( os.path.dirname(fullpath), # directory os.path.basename(fullpath), # basename fullpath, size, # size datetime.datetime.fromtimestamp(mtime, datetime.timezone.utc), # modDate win32file.GetFileAttributes(fullpath), # attributes shfileinfo[4], # typeString datetime.datetime.fromtimestamp(ctime, datetime.timezone.utc), # creationDate win32api.GetShortPathName(fullpath), # shortName shfileinfo[0], # hIcon relpath=os.path.relpath(fullpath, self.rootDirectory) ) return obj
def _GetNetworkResources(self): self.log.debug("Getting networkResource list...") try: h = win32wnet.WNetOpenEnum(5, 1, 0, None) #5=RESOURCE_CONTEXT #1=RESOURCETYPE_DISK lst = win32wnet.WNetEnumResource(h, 64) #65以上の指定不可 win32wnet.WNetCloseEnum(h) except win32net.error as er: dialog( _("エラー"), _("ネットワーク上のリソース一覧を取得できませんでした(%(error)s)") % {"error": str(er)}) return #end 情報取得失敗 lst.pop(0) #先頭はドライブではない者が入るので省く for l in lst: ret, shfileinfo = shell.SHGetFileInfo(l.lpRemoteName, 0, shellcon.SHGFI_ICON) s = browsableObjects.NetworkResource() self.log.debug("network resource found and check IP address:" + l.lpRemoteName[2:]) s.Initialize(l.lpRemoteName[2:], l.lpRemoteName, socket.getaddrinfo(l.lpRemoteName[2:], None)[0][4][0], shfileinfo[0]) self.networkResources.append(s)
def GetShellInfo(self, fullpath): """ Cacheを活用し、効率的に画像とファイルタイプを収集する """ if os.path.isfile(fullpath): ext = os.path.splitext(fullpath)[1] else: ext = "/folder/" if ext == "": ret, shfileinfo = shell.SHGetFileInfo( fullpath, 0, shellcon.SHGFI_ICON | shellcon.SHGFI_TYPENAME) return shfileinfo elif ext in self.typeStringCache: return (self.imageCache[ext], None, None, None, self.typeStringCache[ext]) else: ret, shfileinfo = shell.SHGetFileInfo( fullpath, 0, shellcon.SHGFI_ICON | shellcon.SHGFI_TYPENAME) self.typeStringCache[ext] = shfileinfo[4] self.imageCache[ext] = shfileinfo[0] return shfileinfo
def GetAttributesOf(self, pidls, attrFlags): ret_flags = -1 for pidl in pidls: pidl = pidl[0] # ?? typ, name = pidl.split('\0') flags = shellcon.SHGFI_ATTRIBUTES rc, info = shell.SHGetFileInfo(name, 0, flags) hIcon, iIcon, dwAttr, name, typeName = info # All our items, even files, have sub-items extras = shellcon.SFGAO_HASSUBFOLDER | shellcon.SFGAO_FOLDER | shellcon.SFGAO_FILESYSANCESTOR | shellcon.SFGAO_BROWSABLE ret_flags &= (dwAttr | extras) return ret_flags
def _do_get_icon(self): sys_encoded_path = self.path.encode(sys.getfilesystemencoding()) sys_encoded_path = sys_encoded_path.replace('/', '\\') #SHGetFileInfo doesn't work with Unix style paths ret, info = shell.SHGetFileInfo(sys_encoded_path, 0, shellcon.SHGFI_ICONLOCATION, 0) if ret and (info[1] or info[3]): icon = 'gtk-win32-shell-icon;%s;%d' %(info[3], info[1]) else: icon = 'gtk-win32-shell-icon;%s' % sys_encoded_path icon_theme = gtk.icon_theme_get_default() if not icon_theme.has_icon(icon) and not self.__create_builtin_icon(icon, sys_encoded_path): super(Win32File, self)._do_get_icon() else: self._icon = icon
def __create_builtin_icon(self, icon_name, filepath): if not cgtk or not cgdk or not cgdk_pixbuf: return False icon_flags = [shellcon.SHGFI_SMALLICON, shellcon.SHGFI_LARGEICON] for flag in icon_flags: try: ret, info = shell.SHGetFileInfo(filepath, 0, shellcon.SHGFI_ICON|flag, 0) if ret: pixbuf = cgdk.gdk_win32_icon_to_pixbuf_libgtk_only(info[0])#a private function in gdk if pixbuf: cgtk.gtk_icon_theme_add_builtin_icon(icon_name, cgdk_pixbuf.gdk_pixbuf_get_height(pixbuf), pixbuf) return True except: continue return False
def Initialize(self, path, silent=False): """リソースの情報を取得し、リストを初期化する。""" self.log.debug("Getting resources list...") self.rootDirectory = path t = misc.Timer() if isinstance( path, list ): # パラメータがリストなら、browsableObjects のリストとして処理刷る(ファイルリストを取得しないでコピーする) self.resources += path return errorCodes.OK # end copy self.resources.clear() if not silent: globalVars.app.say(path[2:]) # 取得対象を構造体にセット rootResource = win32wnet.NETRESOURCE() rootResource.lpRemoteName = path # リソースリストの取得 try: h = win32wnet.WNetOpenEnum(2, 1, 0, rootResource) # 2=RESOURCE_GLOBALNET # 1=RESOURCETYPE_DISK lst = win32wnet.WNetEnumResource(h, 64) # 65以上の指定不可 win32wnet.WNetCloseEnum(h) except win32wnet.error as er: dialog( _("エラー"), _("ネットワーク上のリソース一覧を取得できませんでした(%(error)s)") % {"error": str(er)}) return errorCodes.ACCESS_DENIED for l in lst: ret, shfileinfo = shell.SHGetFileInfo(l.lpRemoteName, 0, shellcon.SHGFI_ICON) s = browsableObjects.NetworkResource() self.log.debug("network resource found and check IP address:" + l.lpRemoteName[2:]) s.Initialize(l.lpRemoteName[len(path) + 1:], l.lpRemoteName, "", shfileinfo[0]) self.resources.append(s) self.log.debug("Network resource list created in %d seconds." % t.elapsed) self.log.debug(str(len(self.resources)) + " resources found.") return errorCodes.OK
def GetNetworkResources(taskState=None, param=None): # 同期処理でも呼び出し可能。パラメータ無しで呼ぶ。 sync_resources = [] try: h = win32wnet.WNetOpenEnum(5, 1, 0, None) # 5=RESOURCE_CONTEXT # 1=RESOURCETYPE_DISK lst = win32wnet.WNetEnumResource(h, 64) # 65以上の指定不可 win32wnet.WNetCloseEnum(h) except win32net.error as er: if taskState: param["onFinish"](-1) # コールバックに通知 return True else: # 同期処理 raise err return None # end 同期処理 # end 情報取得失敗 if taskState and taskState.canceled: return False lst.pop(0) # 先頭はドライブではない者が入るので省く for l in lst: ret, shfileinfo = shell.SHGetFileInfo( l.lpRemoteName, 0, shellcon.SHGFI_ICON) if taskState and taskState.canceled: return False addr = misc.ResolveLocalIpAddress(l.lpRemoteName[2:]) s = browsableObjects.NetworkResource() s.Initialize(l.lpRemoteName[2:], l.lpRemoteName, addr, shfileinfo[0]) if taskState and taskState.canceled: return False sync_resources.append(s) # end 同期処理 # end 追加ループ if taskState and taskState.canceled: return False if taskState: if taskState: while(not param["isReady"]()): time.sleep(0.3) for s in sync_resources: wx.CallAfter(param["onAppend"], s) wx.CallAfter(param["onFinish"], len(lst)) return True else: return sync_resources
def _performSearchStep(self,taskState): """検索を1ステップ実行する。100県のファイルがヒットするか、リストが終わるまで検索し、終わったら関数から抜ける。途中で EOL に当たったら、検索終了としてTrueを返し、そうでないときにFalseを帰す。また、表示関数に渡しやすいように、今回のステップでヒットした要素のリストも返す。""" ret_list=[] i=self.searched_index eol=False hit=0 while(True): if taskState.canceled: return False, -1#途中でキャンセル path=self.searches[i] if path=="eol":#EOLで検索終了 eol=True self.finished=True globalVars.app.PlaySound("complete.ogg") globalVars.app.say(_("検索終了、%(item)d件ヒットしました。") % {'item': len(self)}) break #end EOL if re.search(self.keyword,path): fullpath=os.path.join(self.rootDirectory,path) stat=os.stat(fullpath) mod=datetime.datetime.fromtimestamp(stat.st_mtime) creation=datetime.datetime.fromtimestamp(stat.st_ctime) ret, shfileinfo=shell.SHGetFileInfo(fullpath,0,shellcon.SHGFI_ICON|shellcon.SHGFI_TYPENAME) if os.path.isfile(fullpath): f=browsableObjects.File() f.Initialize(os.path.dirname(fullpath),os.path.basename(fullpath),fullpath,stat.st_size,mod,win32file.GetFileAttributes(fullpath),shfileinfo[4],creation,win32api.GetShortPathName(fullpath)) self.files.append(f) ret_list.append(f) else: f=browsableObjects.Folder() f.Initialize(os.path.dirname(fullpath),os.path.basename(fullpath),fullpath,-1,mod,win32file.GetFileAttributes(fullpath),shfileinfo[4],creation,win32api.GetShortPathName(fullpath)) self.folders.append(f) ret_list.append(f) #end ファイルかフォルダか hit+=1 if hit==100: self.searched_index=i+1#次の位置をキャッシュ break #end 100県ヒット #end 検索ヒットか i+=1 if i>=len(self.searches):#検索は終わってないが、ファイルリスト取得が追いついてない self.searched_index=len(self.searches) break #end リストが追いついてない #end 検索ループ return eol,ret_list
def get_icon(PATH, size='small', hold_image=False): # Windowsプラットフォームでファイルのアイコン画像を入手する # https://stackoverflow.com/questions/21070423/python-saving-accessing-file-extension-icons-and-using-them-in-a-tkinter-progra SHGFI_ICON = 0x000000100 SHGFI_ICONLOCATION = 0x000001000 if size == 'small': SHIL_SIZE = 0x00001 elif size == 'large': SHIL_SIZE = 0x00002 else: raise TypeError( "Invalid argument for 'size'. Must be equal to 'small' or 'large'") ret, info = shell.SHGetFileInfo( PATH, 0, SHGFI_ICONLOCATION | SHGFI_ICON | SHIL_SIZE) hIcon, iIcon, dwAttr, name, typeName = info if not hIcon: return None ico_x = win32api.GetSystemMetrics(win32con.SM_CXICON) hdc = win32ui.CreateDCFromHandle(win32gui.GetDC(0)) hbmp = win32ui.CreateBitmap() hbmp.CreateCompatibleBitmap(hdc, ico_x, ico_x) hdc = hdc.CreateCompatibleDC() hdc.SelectObject(hbmp) hdc.DrawIcon((0, 0), hIcon) win32gui.DestroyIcon(hIcon) bmpinfo = hbmp.GetInfo() bmpstr = hbmp.GetBitmapBits(True) img = Image.frombuffer('RGBA', (bmpinfo['bmWidth'], bmpinfo['bmHeight']), bmpstr, 'raw', 'BGRA', 0, 1) if size == 'small': img = img.resize((16, 16), Image.ANTIALIAS) ph = ImageTk.PhotoImage(img) ph.image = img if hold_image else None return ph
import win32com from win32com.shell import shell, shellcon s=shell.SHGetFileInfo(r'E:\Users\SUN\Desktop\11122.bmp',0, shellcon.SHGFI_SYSICONINDEX | shellcon.SHGFI_ICON | shellcon.SHGFI_LARGEICON) print('1')
def GetDriveDisplayName(path): return shell.SHGetFileInfo(path, 0, shellcon.SHGFI_DISPLAYNAME)[1][3]
def Initialize(self, dir, silent=False): """ディレクトリからファイル情報を取得し、リストを初期化する。入力は絶対パスでなければならない。情報が取得できなかった場合、errorCodes.OK以外が返る。silentがTrueなら読み上げは行われない。""" if isinstance( dir, list ): #パラメータがリストなら、browsableObjects のリストとして処理刷る(ファイルリストを取得しないでコピーする) self._copyFromList(dir) return errorCodes.OK #end copy self.files.clear() self.folders.clear() dir = dir.rstrip("\\") dir_spl = dir.split("\\") level = len(dir_spl) if not silent: r = [] if globalVars.app.config['on_list_moved'][ 'read_directory_level'] == 'True': r.append("%s%d " % (dir[0], level)) if globalVars.app.config['on_list_moved'][ 'read_directory_name'] == 'True': r.append(dir_spl[level - 1]) if len(r) > 0: globalVars.app.say("".join(r)) #end read self.rootDirectory = dir self.log.debug("Getting file list for %s..." % self.rootDirectory) t = misc.Timer() try: lst = win32api.FindFiles(dir + "\\*") except pywintypes.error as err: self.log.error("Cannot open the directory! {0}".format(err)) if err.winerror == 5: return errorCodes.ACCESS_DENIED dialog(_("エラー"), _("フォルダを開くことができませんでした(%(error)s)") % {"error": str(err)}) return errorCodes.FATAL #end except if "\\" in self.rootDirectory: #ルート以外では余計な.と..がが一番上に入っている del lst[0:2] if len(lst) == 0: self.log.debug("Blank folder.") return errorCodes.OK #end 空のフォルダだったらさっさと帰る for elem in lst: fullpath = dir + "\\" + elem[8] ret, shfileinfo = shell.SHGetFileInfo( fullpath, 0, shellcon.SHGFI_ICON | shellcon.SHGFI_TYPENAME) if os.path.isfile(fullpath): f = browsableObjects.File() f.Initialize(dir, elem[8], fullpath, (elem[4] << 32) + elem[5], elem[3], elem[0], shfileinfo[4], elem[1], elem[9], shfileinfo[0]) self.files.append(f) else: f = browsableObjects.Folder() f.Initialize(dir, elem[8], fullpath, -1, elem[3], elem[0], shfileinfo[4], elem[1], elem[9], shfileinfo[0]) self.folders.append(f) #end どっちについかするか? #end 追加ループ self.log.debug("File list created in %f seconds." % t.elapsed) self.log.debug( str(len(self.folders)) + " directories and " + str(len(self.files)) + " files found.") if self.sortCursor != 0 or self.sortDescending != 0: self.log.debug("Triggering sorting") self.ApplySort() #end ソートが必要ならソート return errorCodes.OK
def _performSearchStep(self, taskState): """検索を1ステップ実行する。100県のヒットが出るまで検索するか、リストが終わるまで検索し、終わったら関数から抜ける。途中で EOL に当たったら、検索終了としてTrueを返し、そうでないときにFalseを帰す。また、表示関数に渡しやすいように、今回のステップでヒットした要素のリストも返す。スレッドからtaskStateを受け取っていて、キャンセルされたら hits を-1にセットして抜ける。""" ret_list = [] i = self.searched_index eol = False total_hits = 0 while (True): if taskState.canceled: return False, -1 #途中でキャンセル path = self.searches[i] if path == "eol": #EOLで検索終了 eol = True self.finished = True globalVars.app.PlaySound("complete.ogg") globalVars.app.say( _("検索終了、%(item)d件ヒットしました。") % {'item': len(self)}) break #end EOL ext = path.split(".")[-1].lower() if misc.isDocumentExt(ext): fullpath = os.path.join(self.rootDirectory, path) content = misc.ExtractText(fullpath).split("\n") fileobj = None #複数ヒットでファイルオブジェクトを生成し続けないようにキャッシュする ln = 1 hitobjects = [] for elem in content: m = re.search(self.keyword, elem) if m: preview_start = m.start() - 10 if preview_start < 0: preview_start = 0 preview = elem[preview_start:preview_start + 20] if not fileobj: stat = os.stat(fullpath) mod = datetime.datetime.fromtimestamp( stat.st_mtime) creation = datetime.datetime.fromtimestamp( stat.st_ctime) ret, shfileinfo = shell.SHGetFileInfo( fullpath, 0, shellcon.SHGFI_ICON | shellcon.SHGFI_TYPENAME) fileobj = browsableObjects.File() fileobj.Initialize( os.path.dirname(fullpath), os.path.basename(fullpath), fullpath, stat.st_size, mod, win32file.GetFileAttributes(fullpath), shfileinfo[4], creation, win32api.GetShortPathName(fullpath)) #end make fileobj obj = browsableObjects.GrepItem() obj.Initialize(ln, preview, fileobj) hitobjects.append(obj) #end ヒット ln += 1 #end 行数ごとに検索 if len(hitobjects) > 0: #このファイルの中でヒットがあった total_hits += len(hitobjects) for elem in hitobjects: hits = len(hitobjects) elem.SetHitCount(hits) #end 最終的なヒットカウントを設定 self.results.extend(hitobjects) ret_list.extend(hitobjects) #end このファイルでヒットがあった #end 対応している拡張子 if total_hits >= 100: self.searched_index = i + 1 #次の位置をキャッシュ break #end 100県検索 i += 1 if i >= len(self.searches): #検索は終わってないが、ファイルリスト取得が追いついてない self.searched_index = len(self.searches) break #end リストが追いついてない #end 検索ループ return eol, ret_list