吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 3678|回复: 69
上一主题 下一主题
收起左侧

[原创工具] 便携工具箱 自动识别文件夹和可执行程序

  [复制链接]
跳转到指定楼层
楼主
暗夜硝烟 发表于 2025-3-22 18:40 回帖奖励
本帖最后由 暗夜硝烟 于 2025-3-23 15:06 编辑


只需要在同目录建立文件夹放入可执行exe、bat、等程序,运行该程序自动识别分类,无需配置文件。

下载地址:
https://wwvl.lanzout.com/iVLxH2rc7nbi
密码:52pj






编译exe用的是:
人懒所以做个python打包exe工具,支持复杂程序打包 1.1
https://www.52pojie.cn/thread-2007933-1-1.html
(出处: 吾爱破解论坛)

[Python] 纯文本查看 复制代码
001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
079
080
081
082
083
084
085
086
087
088
089
090
091
092
093
094
095
096
097
098
099
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
import os
import sys
import tkinter as tk
from tkinter import ttk
import win32ui
import win32gui
from PIL import Image, ImageTk
import subprocess
from win32com.client import Dispatch
 
def get_current_path():
    """自动获取当前程序路径的通用方法"""
    try:
        # 打包后的情况
        if getattr(sys, 'frozen', False):
            return os.path.dirname(sys.executable)  # 返回EXE所在目录
        # 开发环境
        return os.path.dirname(os.path.abspath(__file__))  # 返回脚本所在目录
    except Exception as e:
        print(f"路径获取失败: {e}")
        return os.getcwd()  # 退回当前工作目录
 
def get_exe_icon(exe_path):
    """从exe文件中提取图标"""
    try:
        # 提取图标
        large, small = win32gui.ExtractIconEx(exe_path, 0)
        win32gui.DestroyIcon(small[0])
         
        # 创建设备上下文
        hdc = win32ui.CreateDCFromHandle(win32gui.GetDC(0))
        hbmp = win32ui.CreateBitmap()
        hbmp.CreateCompatibleBitmap(hdc, 32, 32)
         
        # 在设备上下文中绘制图标
        hdc = hdc.CreateCompatibleDC()
        hdc.SelectObject(hbmp)
        hdc.DrawIcon((0, 0), large[0])
         
        # 获取位图信息和位图数据
        bmpinfo = hbmp.GetInfo()
        bmpstr = hbmp.GetBitmapBits(True)
         
        # 创建PIL图像对象
        img = Image.frombuffer(
            'RGBA',
            (bmpinfo['bmWidth'], bmpinfo['bmHeight']),
            bmpstr, 'raw', 'BGRA', 0, 1
        )
         
        return img
    except Exception as e:
        print(f"提取图标失败: {e}")
        return None
 
class UniformButton(tk.Frame):
    """统一尺寸的程序按钮组件"""
    def __init__(self, parent, text, image, command):
        super().__init__(parent, bg="white", highlightthickness=0)
         
        # 固定按钮尺寸
        self.button_width = 70
        self.button_height = 90
        self.max_chars = 10
        self.max_lines = 2
         
        self.config(width=self.button_width, height=self.button_height)
        self.pack_propagate(False)
         
        # 主容器
        self.content_frame = tk.Frame(self, bg="white")
        self.content_frame.pack(fill=tk.BOTH, expand=True)
 
        # 图标区域
        self.icon_label = tk.Label(self.content_frame,
                                 image=image,
                                 bg="white",
                                 borderwidth=0)
        self.icon_label.image = image
        self.icon_label.pack(pady=(5, 2), expand=True)
 
        # 文本区域
        processed_text = self.process_text(text)
        self.text_label = tk.Label(self.content_frame,
                                 text=processed_text,
                                 wraplength=self.button_width-15,
                                 justify="center",
                                 font=("微软雅黑", 8),
                                 bg="white",
                                 borderwidth=0)
        self.text_label.pack(pady=(0, 5))
 
        # 事件绑定
        self.bind_all_children("<Button-1>", lambda e: command())
        self.bind("<Enter>", self.on_enter)
        self.bind("<Leave>", self.on_leave)
 
    def bind_all_children(self, event, handler):
        for child in self.winfo_children():
            child.bind(event, handler)
            if isinstance(child, tk.Frame):
                for subchild in child.winfo_children():
                    subchild.bind(event, handler)
 
    def process_text(self, text):
        text = text[:20]
        words = text.split()
        lines = []
        current_line = []
         
        for word in words:
            if len(word) > self.max_chars:
                chunks = [word[i:i+self.max_chars] for i in range(0, len(word), self.max_chars)]
                current_line.extend(chunks)
            else:
                current_line.append(word)
             
            if sum(len(w) for w in current_line) + (len(current_line)-1) > self.max_chars:
                lines.append(" ".join(current_line[:-1]))
                current_line = [current_line[-1]]
             
            if len(lines) >= self.max_lines:
                break
         
        if current_line and len(lines) < self.max_lines:
            lines.append(" ".join(current_line))
         
        return "\n".join(lines[:self.max_lines]) + ("..." if len(text) > 20 else "")
 
    def on_enter(self, event): 
        # pylint: disable=unused-argument
        self.config(bg="#e0e0e0")
        self.content_frame.config(bg="#e0e0e0")
        for child in self.content_frame.winfo_children():
            child.config(bg="#e0e0e0")
 
    def on_leave(self, event): 
        # pylint: disable=unused-argument
        self.config(bg="white")
        self.content_frame.config(bg="white")
        for child in self.content_frame.winfo_children():
            child.config(bg="white")
 
 
class AppLauncher:
    def __init__(self, root):
        self.root = root
        self.root.title("便携工具箱     by:姬御风")
        self.root.geometry("530x400")
        self.root.resizable(False, False)
        self.icon_size = 32
         
        # 设置窗口图标
        self.set_window_icon()
         
        # 主界面
        self.main_frame = ttk.Frame(root)
        self.main_frame.pack(fill=tk.BOTH, expand=True, padx=5, pady=5)
         
        # 初始化默认图标
        self.default_icon = self.get_default_icon()
         
        # 组件初始化
        self.create_category_panel()
        self.create_program_panel()
         
        # 数据初始化
        self.current_dir = get_current_path()  # 使用通用路径获取方法
        self.scan_directory()
        self.populate_categories()
        self.show_category("所有程序")
 
    def set_window_icon(self):
        """设置窗口图标"""
        try:
            # 使用与编译后的exe相同的图标
            exe_path = sys.executable
            icon_img = get_exe_icon(exe_path)
            if icon_img:
                icon_img.save('temp_icon.ico', 'ICO')
                self.root.iconbitmap('temp_icon.ico')
                os.remove('temp_icon.ico')
            else:
                print("无法提取exe图标,使用默认图标")
                self.root.iconbitmap('icon/app.ico')
        except Exception as e:
            print(f"设置窗口图标失败: {e}")
 
    def resolve_shortcut(self, path):
        """解析快捷方式"""
        try:
            shell = Dispatch('WScript.Shell')
            shortcut = shell.CreateShortCut(path)
            return shortcut.TargetPath
        except Exception as _e:
            print(f"快捷方式解析失败: {path}")
            return None
 
    def get_program_icon(self, path):
        """增强图标获取"""
        try:
            # 处理快捷方式
            if path.lower().endswith('.lnk'):
                target = self.resolve_shortcut(path)
                if target and os.path.exists(target):
                    path = target
             
            # 获取图标
            large, _ = win32gui.ExtractIconEx(path, 0)
            if not large:
                raise Exception("No icons found")
                 
            hicon = large[0]
            hdc = win32ui.CreateDCFromHandle(win32gui.GetDC(0))
            hbmp = win32ui.CreateBitmap()
            hbmp.CreateCompatibleBitmap(hdc, self.icon_size, self.icon_size)
            hdc = hdc.CreateCompatibleDC()
            hdc.SelectObject(hbmp)
            hdc.DrawIcon((0, 0), hicon)
             
            bmpstr = hbmp.GetBitmapBits(True)
            img = Image.frombuffer('RGBA', (self.icon_size, self.icon_size),
                                 bmpstr, 'raw', 'BGRA', 0, 1)
            return ImageTk.PhotoImage(img)
        except Exception as _e: 
            print(f"图标加载失败: {os.path.basename(path)}")
            return self.default_icon
 
    def get_default_icon(self):
        """系统默认图标"""
        try:
            # 使用文件夹图标
            shell32 = "C:\\Windows\\System32\\shell32.dll"
            large, _ = win32gui.ExtractIconEx(shell32, 3)
            hicon = large[0]
             
            hdc = win32ui.CreateDCFromHandle(win32gui.GetDC(0))
            hbmp = win32ui.CreateBitmap()
            hbmp.CreateCompatibleBitmap(hdc, self.icon_size, self.icon_size)
            hdc = hdc.CreateCompatibleDC()
            hdc.SelectObject(hbmp)
            hdc.DrawIcon((0, 0), hicon)
             
            bmpstr = hbmp.GetBitmapBits(True)
            img = Image.frombuffer('RGBA', (self.icon_size, self.icon_size),
                                 bmpstr, 'raw', 'BGRA', 0, 1)
            return ImageTk.PhotoImage(img)
        except Exception as _e: 
            print(f"默认图标加载失败: {_e}")
            return ImageTk.PhotoImage(Image.new('RGBA', (self.icon_size, self.icon_size), (240, 240, 240)))
 
    def create_category_panel(self):
        """分类面板(宽度99)"""
        self.category_frame = ttk.Frame(self.main_frame, width=99)
        self.category_frame.pack(side=tk.LEFT, fill=tk.Y, padx=3)
         
        self.category_canvas = tk.Canvas(self.category_frame,
                                       width=99,
                                       highlightthickness=0)
        scrollbar = ttk.Scrollbar(self.category_frame,
                                orient="vertical",
                                command=self.category_canvas.yview)
        self.category_container = ttk.Frame(self.category_canvas)
         
        self.category_container.bind("<Configure>",
            lambda e: self.category_canvas.configure(
                scrollregion=self.category_canvas.bbox("all"),
                width=99
            ))
         
        self.category_canvas.create_window((0,0),
                                        window=self.category_container,
                                        anchor="nw",
                                        width=99)
        self.category_canvas.configure(yscrollcommand=scrollbar.set)
         
        self.category_canvas.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
        scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
         
        ttk.Label(self.category_container,
                text="应用分类",
                font=("微软雅黑", 9),
                padding=3).pack(pady=5)
 
    def create_program_panel(self):
        """程序显示面板"""
        self.program_frame = ttk.Frame(self.main_frame)
        self.program_frame.pack(side=tk.RIGHT, fill=tk.BOTH, expand=True)
         
        self.program_canvas = tk.Canvas(self.program_frame,
                                     highlightthickness=0)
        scrollbar = ttk.Scrollbar(self.program_frame,
                                orient="vertical",
                                command=self.program_canvas.yview)
        self.program_container = ttk.Frame(self.program_canvas)
         
        self.program_container.bind("<Configure>",
            lambda e: self.program_canvas.configure(
                scrollregion=self.program_canvas.bbox("all")
            ))
         
        self.program_canvas.create_window((0,0),
                                       window=self.program_container,
                                       anchor="nw")
        self.program_canvas.configure(yscrollcommand=scrollbar.set)
         
        self.program_canvas.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
        scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
 
    def scan_directory(self):
        """扫描目录"""
        self.categories = {"所有程序": []}
        executable_ext = ['.exe', '.bat', '.cmd', '.lnk']
         
        for item in os.listdir(self.current_dir):
            path = os.path.join(self.current_dir, item)
             
            if os.path.isdir(path):
                self.categories[item] = []
                for root, _, files in os.walk(path):
                    for file in files:
                        if os.path.splitext(file)[1].lower() in executable_ext:
                            full_path = os.path.join(root, file)
                            self.categories[item].append({
                                "name": os.path.splitext(file)[0],
                                "path": full_path
                            })
                            self.categories["所有程序"].append({
                                "name": os.path.splitext(file)[0],
                                "path": full_path
                            })
            else:
                if os.path.splitext(item)[1].lower() in executable_ext:
                    self.categories["所有程序"].append({
                        "name": os.path.splitext(item)[0],
                        "path": path
                    })
 
    def populate_categories(self):
        """填充分类"""
        for category in self.categories.keys():
            btn = ttk.Button(
                self.category_container,
                text=category,
                command=lambda c=category: self.show_category(c),
                width=12
            )
            btn.pack(fill=tk.X, padx=2, pady=2)
 
    def show_category(self, category):
        """显示分类"""
        for widget in self.program_container.winfo_children():
            widget.destroy()
             
        programs = self.categories.get(category, [])
         
        if not programs:
            ttk.Label(self.program_container, text="该分类暂无应用").pack(pady=50)
            return
         
        max_columns = 5
        row = col = 0
         
        for idx, program in enumerate(programs):
            col = idx % max_columns
            row = idx // max_columns
             
            button = UniformButton(
                parent=self.program_container,
                text=program["name"],
                image=self.get_program_icon(program["path"]),
                command=lambda p=program["path"]: self.launch_program(p)
            )
            button.grid(row=row, column=col, padx=3, pady=3, sticky="nsew")
             
            self.program_container.grid_columnconfigure(col, weight=1)
            self.program_container.grid_rowconfigure(row, weight=1)
 
    def launch_program(self, path):
        """启动程序"""
        try:
            subprocess.Popen(f'"{path}"', shell=True)
        except Exception as _e: 
            print(f"启动失败: {_e}")
 
 
if __name__ == "__main__":
    root_window = tk.Tk() 
    style = ttk.Style()
    style.configure("TButton",
                  padding=3,
                  font=("微软雅黑", 8),
                  width=12)
    style.map("TButton",
            background=[('active', '#f0f0f0')])
    AppLauncher(root_window)
    root_window.mainloop()

免费评分

参与人数 10吾爱币 +14 热心值 +9 收起 理由
webdav01 + 1 + 1 支持,就是体积太大了
suke521 + 1 谢谢@Thanks!
x443681912 + 1 + 1 不但想要你的工具箱,而且想要你的工具。望楼主慷慨解囊忍痛割爱!
wyvern + 1 + 1 热心回复!
viconly + 1 + 1 谢谢@Thanks!
rgyjc + 1 + 1 谢谢@Thanks!
ysxc666 + 1 我很赞同!
Issacclark1 + 1 谢谢@Thanks!
风之暇想 + 7 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
asdskf + 1 + 1 感谢分享~太牛了

查看全部评分

本帖被以下淘专辑推荐:

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

推荐
kboylang 发表于 2025-3-23 09:52
平心而论,工具确实很一般需要进一步优化。但还是很感谢分享,首先不能最大话。其次,但扫描的软件和文件夹只针对这个软件所在的文件夹的范围?其他的也看不见。也有BUG需要处理一下,比如多层文件夹它是识别不了的,点击进去是空白。还有,点击部分已安装软件会被360检测拦截"访问的网站域名:r13850507371.6600.org"?
推荐
 楼主| 暗夜硝烟 发表于 2025-3-23 11:16 |楼主
kboylang 发表于 2025-3-23 09:52
平心而论,工具确实很一般需要进一步优化。但还是很感谢分享,首先不能最大话。其次,但扫描的软件和文件夹 ...


多级目录不会显示子文件夹的,只会显示同目录的文件夹。
能力有限哈,我这个使用AI反复对话写出来的哈,其实我不懂代码,抱歉。
源码已经展示,有想法的朋友可以随意修改编译哈。
转换exe用的是下面的工具,论坛里面下载的,我刚刚找了一下没找到那个帖子。

沙发
myag 发表于 2025-3-22 18:57
3#
realcsnake 发表于 2025-3-22 19:20

感谢大神分享,太牛了
4#
dysunb 发表于 2025-3-22 19:22
这个工具使用率不会太高吧
5#
hubin151587 发表于 2025-3-22 20:43
根据备用很好,使用率不高
6#
lazhou 发表于 2025-3-22 20:45
很好用,谢谢大佬分享!
7#
dsfive 发表于 2025-3-22 21:14

感谢分享!!
8#
xiaochen202411 发表于 2025-3-22 21:38
非常实用,66666
9#
fireflying1984 发表于 2025-3-22 21:59
相当于自己收集的工具软件的整理显示快捷图标?
10#
blhying 发表于 2025-3-22 22:45
看介绍,这个工具放在U盘里用好象很不错的样子!U盘里的东西也可以直接列出来?
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2025-4-7 17:19

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表