吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 1698|回复: 36
收起左侧

[其他原创] Windows右键【复制多行文件完整路径】

  [复制链接]
冥界3大法王 发表于 2026-4-5 09:54
本帖最后由 冥界3大法王 于 2026-4-6 13:30 编辑

尝试了多次,包括VBS、NirCMD、PowerShell都是失败告终:
PixPin_2026-04-05_09-43-18.gif
导入以下注册表:

[Asm] 纯文本查看 复制代码
Windows Registry Editor Version 5.00

[HKEY_CLASSES_ROOT\*\shell\copypath]
@="复制文件完整路径"
"Icon"="D:\\网络相关\\袖珍版IDM.exe,0"

[HKEY_CLASSES_ROOT\*\shell\copypath\command]
@="\"d:\\CopyMultiPath.exe\" \"%1\""


下面是VS2022源码:
[Asm] 纯文本查看 复制代码
#define _CRT_SECURE_NO_WARNINGS
#include <windows.h>
#include <string>
#include <vector>
#include <fstream>
#include <locale>
#include <algorithm> // 必须包含:用于 std::find_if
#include <cwctype>  // 必须包含:用于 iswspace

// 修复后的辅助函数:去掉字符串末尾的所有空白(包括换行符)
void TrimTrailing(std::wstring& s) {
    if (s.empty()) return;
    // 使用 iswspace(不带 std::)处理宽字符空格/换行
    s.erase(std::find_if(s.rbegin(), s.rend(), [](wchar_t ch) {
        return !iswspace(ch);
        }).base(), s.end());
}

// 设置剪贴板(Unicode 支持,防止中文乱码)
void SetClipboardUnicode(const std::wstring& text) {
    if (!OpenClipboard(nullptr)) return;
    EmptyClipboard();
    size_t size = (text.size() + 1) * sizeof(wchar_t);
    HGLOBAL hGlob = GlobalAlloc(GMEM_MOVEABLE, size);
    if (hGlob) {
        memcpy(GlobalLock(hGlob), text.c_str(), size);
        GlobalUnlock(hGlob);
        SetClipboardData(CF_UNICODETEXT, hGlob);
    }
    CloseClipboard();
}

// 使用 wmain 接收宽字符参数,直接获取文件路径
int wmain(int argc, wchar_t* argv[]) {
    if (argc < 2) return 0;

    // 获取系统临时文件夹路径
    wchar_t tempPath[MAX_PATH];
    GetTempPathW(MAX_PATH, tempPath);
    std::wstring tempFile = std::wstring(tempPath) + L"xcopy_paths.tmp";

    // 1. 追加当前进程获取到的路径
    std::wofstream ofs(tempFile, std::ios::app);
    ofs.imbue(std::locale("")); // 适配系统区域设置
    ofs << argv[1] << L"\n";
    ofs.close();

    // 2. 关键等待:给并发进程留出写入时间
    Sleep(250);

    // 3. 读取合并后的路径并处理
    std::wifstream ifs(tempFile);
    ifs.imbue(std::locale(""));
    if (ifs.is_open()) {
        std::wstring allPaths((std::istreambuf_iterator<wchar_t>(ifs)), std::istreambuf_iterator<wchar_t>());
        ifs.close();

        if (!allPaths.empty()) {
            // 修复 Bug:移除末尾多余的换行符
            TrimTrailing(allPaths);

            SetClipboardUnicode(allPaths);

            // 阅后即焚:删除临时文件,防止下次点击时路径重叠
            DeleteFileW(tempFile.c_str());
        }
    }

    return 0;
}

CopyMultiPath.rar (12.59 KB, 下载次数: 80)
编译后的文件送上。

27楼: 最终升级版本,支持 单双文件 或 文件夹的 复制:
【最大化优化生成的 *.exe 仅10K】



免费评分

参与人数 8吾爱币 +13 热心值 +7 收起 理由
evea + 1 + 1 我很赞同!
森岛帆高 + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
pyjiujiu + 1 + 1 用心讨论,共获提升!
xouou + 1 感谢分享, everything就可以呀
GUANylimhs + 1 + 1 我很赞同!
苏紫方璇 + 7 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
gufangkai + 1 + 1 膜拜大法王
520521314 + 1 谢谢@Thanks!

查看全部评分

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

 楼主| 冥界3大法王 发表于 2026-4-6 12:36
lazychen 发表于 2026-4-6 12:21
这个图标icon没有打包过来  我们的电脑上没有  没法显示  注册表里的路径填写规则不清楚   除非把exe放到D  ...

晕死,你直接换成你电脑里的 .ico 不就好了。。。
我又不死心,使用汇编语言搞了一个,编译之后只有4K
[Asm] 纯文本查看 复制代码
.386
.model flat, stdcall
option casemap:none

; ==========================================
; 常量定义
; ==========================================
MAX_PATH          equ 260
FILE_APPEND_DATA  equ 0004h
FILE_SHARE_READ   equ 0001h
FILE_SHARE_WRITE  equ 0002h
OPEN_ALWAYS       equ 4
OPEN_EXISTING     equ 3
FILE_ATTRIBUTE_NORMAL equ 0080h
GMEM_MOVEABLE     equ 0002h
GMEM_ZEROINIT     equ 0040h
CF_UNICODETEXT    equ 13
INVALID_HANDLE_VALUE equ -1
GENERIC_READ      equ 80000000h

; ==========================================
; API 声明 (去掉手动加的下划线,让链接器自动处理)
; ==========================================
extern GetCommandLineW@0:ptr
extern CommandLineToArgvW@8:ptr
extern GetTempPathW@8:ptr
extern lstrcatW@8:ptr
extern lstrlenW@4:ptr
extern CreateFileW@28:ptr
extern WriteFile@20:ptr
extern ReadFile@20:ptr
extern CloseHandle@4:ptr
extern Sleep@4:ptr
extern GetFileSize@8:ptr
extern GlobalAlloc@8:ptr
extern GlobalLock@4:ptr
extern GlobalUnlock@4:ptr
extern OpenClipboard@4:ptr
extern EmptyClipboard@0:ptr
extern SetClipboardData@8:ptr
extern CloseClipboard@0:ptr
extern DeleteFileW@4:ptr
extern LocalFree@4:ptr
extern ExitProcess@4:ptr

.data
    szTempName    dw 'x','c','o','p','y','_','p','a','t','h','s','.','t','m','p',0
    szNewLine     dw 0Dh, 0Ah
.data?
    dwArgCount    dd ?
    pArgv         dd ?
    szTempPath    dw MAX_PATH dup(?)
    hFile         dd ?
    dwWritten     dd ?
    hMem          dd ?
    pMem          dd ?
    dwFileSize    dd ?

.code
start:
    ; 1. 获取命令行参数
    call GetCommandLineW@0
    push offset dwArgCount
    push eax
    call CommandLineToArgvW@8
    mov pArgv, eax
    
    cmp dwArgCount, 2
    jl _exit

    ; 2. 构造临时路径
    push MAX_PATH
    push offset szTempPath
    call GetTempPathW@8
    
    push offset szTempName
    push offset szTempPath
    call lstrcatW@8

    ; 3. 写入文件
    push 0
    push FILE_ATTRIBUTE_NORMAL
    push OPEN_ALWAYS
    push 0
    push FILE_SHARE_READ or FILE_SHARE_WRITE
    push FILE_APPEND_DATA
    push offset szTempPath
    call CreateFileW@28
    
    mov hFile, eax
    .if hFile != INVALID_HANDLE_VALUE
        mov eax, pArgv
        mov eax, [eax + 4]
        push eax
        call lstrlenW@4
        
        mov edx, pArgv
        mov edx, [edx + 4]
        shl eax, 1         ; 长度 * 2
        
        push 0
        push offset dwWritten
        push eax
        push edx
        push hFile
        call WriteFile@20
        
        push 0
        push offset dwWritten
        push 4
        push offset szNewLine
        push hFile
        call WriteFile@20
        
        push hFile
        call CloseHandle@4
    .endif

    push 350
    call Sleep@4

    ; 4. 读取合并后的文件
    push 0
    push FILE_ATTRIBUTE_NORMAL
    push OPEN_EXISTING
    push 0
    push FILE_SHARE_READ or FILE_SHARE_WRITE
    push GENERIC_READ
    push offset szTempPath
    call CreateFileW@28
    
    mov hFile, eax
    .if hFile != INVALID_HANDLE_VALUE
        push 0
        push hFile
        call GetFileSize@8
        mov dwFileSize, eax
        
        .if eax > 0
            add eax, 2
            push eax
            push GMEM_MOVEABLE or GMEM_ZEROINIT
            call GlobalAlloc@8
            mov hMem, eax
            
            push eax
            call GlobalLock@4
            mov pMem, eax
            
            push 0
            push offset dwWritten
            push dwFileSize
            push pMem
            push hFile
            call ReadFile@20
            
            ; 简单的 TrimTrailing
            mov ecx, dwFileSize
            shr ecx, 1
            .if ecx > 0
                dec ecx
                mov edi, pMem
                .while ecx > 0
                    movzx eax, word ptr [edi + ecx*2]
                    .if ax == 0Dh || ax == 0Ah || ax == 20h || ax == 0
                        mov word ptr [edi + ecx*2], 0
                        dec ecx
                    .else
                        .break
                    .endif
                .endw
            .endif
            
            push hMem
            call GlobalUnlock@4
            
            push 0
            call OpenClipboard@4
            .if eax
                call EmptyClipboard@0
                push hMem
                push CF_UNICODETEXT
                call SetClipboardData@8
                call CloseClipboard@0
            .endif
        .endif
        push hFile
        call CloseHandle@4
        push offset szTempPath
        call DeleteFileW@4
    .endif

_exit:
    .if pArgv != 0
        push pArgv
        call LocalFree@4
    .endif
    push 0
    call ExitProcess@4
end start

CopyMultiPath_Asm.rar

1.3 KB, 下载次数: 13, 下载积分: 吾爱币 -1 CB

 楼主| 冥界3大法王 发表于 2026-4-6 11:41
本帖最后由 冥界3大法王 于 2026-4-6 11:44 编辑

最终升级版本,支持 单双文件 或 文件夹的 复制: 【最大化优化生成的 *.exe 仅10K】

[Asm] 纯文本查看 复制代码
Windows Registry Editor Version 5.00

[HKEY_CLASSES_ROOT\*\shell\copypath]
@="复制完整路径"
"Icon"="D:\\网络相关\\袖珍版IDM.exe,0"

[HKEY_CLASSES_ROOT\*\shell\copypath\command]
@="\"d:\\CopyMultiPath.exe\" \"%1\""

[HKEY_CLASSES_ROOT\Directory\shell\copypath]
@="复制完整路径"
"Icon"="D:\\网络相关\\袖珍版IDM.exe,0"

[HKEY_CLASSES_ROOT\Directory\shell\copypath\command]
@="\"d:\\CopyMultiPath.exe\" \"%1\""


[Asm] 纯文本查看 复制代码
#define _CRT_SECURE_NO_WARNINGS
#include <windows.h>

// 简单的字符串追加函数
void AppendText(wchar_t* dest, const wchar_t* src) {
    wcscat(dest, src);
}

int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine, int nCmdShow) {
    int argc;
    wchar_t** argv = CommandLineToArgvW(GetCommandLineW(), &argc);
    if (argc < 2) return 0;

    wchar_t tempPath[MAX_PATH];
    GetTempPathW(MAX_PATH, tempPath);
    lstrcatW(tempPath, L"xcopy_paths.tmp");

    // 1. 写入文件 (使用原生 CreateFile)
    HANDLE hFile = CreateFileW(tempPath, FILE_APPEND_DATA, FILE_SHARE_READ | FILE_SHARE_WRITE,
        NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);

    if (hFile != INVALID_HANDLE_VALUE) {
        // 写入路径 + 换行符
        DWORD dwWritten;
        WriteFile(hFile, argv[1], (DWORD)(wcslen(argv[1]) * sizeof(wchar_t)), &dwWritten, NULL);
        WriteFile(hFile, L"\r\n", 4, &dwWritten, NULL);
        CloseHandle(hFile);
    }

    // 2. 等待并发进程
    Sleep(350);

    // 3. 读取并设置剪贴板
    hFile = CreateFileW(tempPath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
        NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);

    if (hFile != INVALID_HANDLE_VALUE) {
        DWORD fileSize = GetFileSize(hFile, NULL);
        if (fileSize > 0) {
            HGLOBAL hMem = GlobalAlloc(GMEM_MOVEABLE, fileSize + sizeof(wchar_t));
            if (hMem) {
                wchar_t* pData = (wchar_t*)GlobalLock(hMem);
                DWORD dwRead;
                ReadFile(hFile, pData, fileSize, &dwRead, NULL);
                pData[fileSize / sizeof(wchar_t)] = L'\0'; // 结束符

                // 移除末尾空白
                int len = (int)wcslen(pData);
                while (len > 0 && (pData[len - 1] == L'\r' || pData[len - 1] == L'\n' || pData[len - 1] == L' ')) {
                    pData[--len] = L'\0';
                }
                GlobalUnlock(hMem);

                if (OpenClipboard(NULL)) {
                    EmptyClipboard();
                    SetClipboardData(CF_UNICODETEXT, hMem);
                    CloseClipboard();
                }
            }
        }
        CloseHandle(hFile);
        DeleteFileW(tempPath); // 阅后即焚
    }

    LocalFree(argv);
    return 0;
}


Release.rar

5.2 KB, 下载次数: 18, 下载积分: 吾爱币 -1 CB

 楼主| 冥界3大法王 发表于 2026-4-5 09:57
最后发现上传时,找不到路径,一琢磨多了一个换行,所以最后有了一个修复版本。
支持单行路径 和 多行路径,这样就无烦恼了。
a2523188267 发表于 2026-4-5 10:21
感谢法王分享,一直只会单行复制,最完美用的是注册表导入的方式增强。你这个多行功能,能用注册表项目导入实现么
 楼主| 冥界3大法王 发表于 2026-4-5 10:29
a2523188267 发表于 2026-4-5 10:21
感谢法王分享,一直只会单行复制,最完美用的是注册表导入的方式增强。你这个多行功能,能用注册表项目导入 ...

。。。最顶上的不就是注册表导入的键值。。。
tshxxst 发表于 2026-4-5 10:30
感谢大佬,又学习到了
jbd0412 发表于 2026-4-5 10:46
啥啊,win10 x64双击没反应,右键没有复制路径
vahkx1113 发表于 2026-4-5 10:54
强,还是c需要实现的
 楼主| 冥界3大法王 发表于 2026-4-5 11:48
jbd0412 发表于 2026-4-5 10:46
啥啊,win10 x64双击没反应,右键没有复制路径
另外路径得改成你自己的。
image.png
image.png
手动创建一个样儿。
djxz 发表于 2026-4-5 12:06
法王出品,必属精品
森岛帆高 发表于 2026-4-5 12:50
本帖最后由 森岛帆高 于 2026-4-5 12:52 编辑

支持大佬
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

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

GMT+8, 2026-7-15 02:26

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

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