📖 Copys 使用说明

Copys 是一款高性能 Windows 文件复制工具,支持右键菜单、命令行和第三方软件调用。

一、安装

  1. 下载 copys_setup.exe,双击运行
  2. 选择安装目录(默认 %LOCALAPPDATA%\CopysC:\Program Files\Copys)
  3. 点击"安装",完成
  4. 重启资源管理器后,右键菜单出现"快速粘贴到此处"
💡 安装完成后,若需命令行全局使用,请手动将安装目录加入系统 PATH(见下文)。

二、图形界面使用(推荐)

快速粘贴

  1. 选中文件/文件夹,按 Ctrl+C(复制)或 Ctrl+X(剪切)
  2. 到目标文件夹,在空白处右键 → 快速粘贴到此处
  3. Copys 窗口弹出,显示进度、速度曲线,完成后自动关闭并显示统计
💡 与系统剪贴板完全互通: Copys 复制的内容可用 Ctrl+V 粘贴,反之亦然。

三、命令行使用

Copys 提供完整命令行工具 copys.exe。若已加入 PATH,可直接使用 copys 命令。

命令总览

命令功能
copys copy <源...> <目标>复制文件/文件夹
copys copy-clipboard <文件...>复制到剪贴板(等价 Ctrl+C)
copys cut <文件...>剪切到剪贴板(等价 Ctrl+X)
copys paste <目标>从剪贴板粘贴
copys path <文件...>复制完整路径到剪贴板
copys stdin -t <目标>从管道(stdin)读取路径列表复制
copys info查看硬盘类型检测结果
copys bench <源> <目标父目录>测速对比
copys update-check检查更新
copys update下载并更新
copys update-set-url <URL>设置更新服务器
💡 更多帮助:copys --help 查看全部命令,copys copy --help 查看某命令的参数,copys --version 查看版本号。

复制文件 copy

copys copy "C:\源文件" "D:\目标目录"
copys copy "C:\源目录" "D:\目标目录"     # 递归复制目录
copys copy "a.txt" "b.txt" "D:\dest"    # 复制多个文件

copy 参数

参数说明示例
--parallel N并行复制文件数--parallel 8
--buffer-size N单次 I/O 缓冲区大小(字节)--buffer-size 4194304
--pipeline N单文件管道深度--pipeline 8
--nvme强制 NVMe 优化配置--nvme
--hdd强制 HDD 优化配置--hdd
--auto自动检测最优配置(默认)--auto
--always总是覆盖已存在文件--always
--skip跳过已存在文件--skip
--rename自动重命名(file (1).txt)--rename
--if-newer仅当源更新时覆盖(默认)--if-newer
--no-preserve不保留文件属性(时间戳等)--no-preserve
-q, --quiet安静模式,不显示进度-q

剪贴板:复制 / 剪切 / 粘贴

copys copy-clipboard "C:\file1.txt" "C:\file2.txt"   # 复制到剪贴板(等价 Ctrl+C)
copys cut "C:\file.txt"                                # 剪切到剪贴板(等价 Ctrl+X)
copys paste "D:\目标目录"                               # 从剪贴板粘贴到目标目录

完整路径与管道输入

# 复制完整路径到剪贴板(右键菜单"复制完整路径"等价命令)
copys path "C:\file.txt"
copys path "C:\a.txt" "D:\b.txt"        # 多路径,每行一个

# 从管道(stdin)读取路径列表复制,可与任何命令配合
dir /b *.log | copys stdin -t "D:\backup"
type list.txt | copys stdin --to "D:\dest" -q
find . -name "*.png" | copys stdin -t "D:\images"
💡 stdin 命令每行读取一个路径,空行和 # 开头的注释行会被跳过;适合脚本批量复制场景。

测速与信息

copys info                            # 查看硬盘类型检测结果
copys bench "C:\源目录" "D:\"        # 测速对比(默认重复 3 次)
copys bench "C:\src" "D:\" --iterations 5   # 测速 5 次取平均

在线升级

copys update-check                          # 检查是否有新版本
copys update                                 # 下载并更新
copys update --yes                           # 跳过确认,直接更新
copys update-set-url https://copys.z.h3hu.com   # 设置更新服务器(首次)
copys update --url https://xxx               # 临时用指定服务器

四、加入系统 PATH(命令行全局使用)

安装目录默认为 %LOCALAPPDATA%\Copys。加入 PATH 后,可在任何位置直接运行 copys 命令。

图形方式

  1. Win + R,输入 sysdm.cpl 回车
  2. "高级" → "环境变量"
  3. 在"系统变量"或"用户变量"中找到 Path,点"编辑"
  4. 点"新建",粘贴 %LOCALAPPDATA%\Copys
  5. 确定,重新打开命令行生效

命令行方式

setx PATH "%PATH%;%LOCALAPPDATA%\Copys"
⚠️ 需要重新打开命令行窗口才能生效。

五、第三方软件调用

Copys 是标准命令行工具,可被脚本、自动化工具或其它软件调用。只需传入 copys copy "源" "目标" [参数],通过退出码判断复制结果。

调用约定

退出码含义
0成功
1失败(复制错误)
💡 建议使用 -q 静默模式(不输出进度),复制结果通过退出码判断。

编程语言调用(点击语言切换示例)

示例均以复制 C:\srcD:\dst覆盖已存在文件演示(--always -q)。已包含 BatchPowerShell 脚本示例。

Python
Rust
Go
C
C++
C# / .NET
Java
PHP
易语言
PowerShell
Node.js
Batch

基本调用

import subprocess
subprocess.run(["copys", "copy", r"C:\src", r"D:\dst"])

带参数 + 退出码判断

import subprocess

result = subprocess.run(
    ["copys", "copy", r"C:\src", r"D:\dst", "--always", "-q"],
    capture_output=True, text=True
)
if result.returncode == 0:
    print("复制成功")
else:
    print(f"复制失败,退出码: {result.returncode}")
    print(result.stderr)

超时保护(防阻塞)

import subprocess

try:
    subprocess.run(
        ["copys", "copy", r"C:\src", r"D:\dst", "-q"],
        timeout=60  # 60秒超时
    )
except subprocess.TimeoutExpired:
    print("复制超时")

基本调用

use std::process::Command;

fn main() {
    let status = Command::new("copys")
        .args(["copy", r"C:\src", r"D:\dst"])
        .status()
        .expect("无法启动 copys");
    println!("退出码: {:?}", status.code());
}

带参数 + 判断结果

use std::process::Command;

fn main() {
    let output = Command::new("copys")
        .args(["copy", r"C:\src", r"D:\dst", "--always", "-q"])
        .output()
        .expect("无法启动 copys");

    if output.status.success() {
        println!("复制成功");
    } else {
        eprintln!("复制失败: {}", String::from_utf8_lossy(&output.stderr));
    }
}

基本调用

package main

import (
    "fmt"
    "os/exec"
)

func main() {
    err := exec.Command("copys", "copy", `C:\src`, `D:\dst`).Run()
    if err != nil {
        fmt.Println("复制失败:", err)
    } else {
        fmt.Println("复制成功")
    }
}

带参数 + 捕获输出

package main

import (
    "fmt"
    "os/exec"
)

func main() {
    out, err := exec.Command(
        "copys", "copy", `C:\src`, `D:\dst`, "--always", "-q",
    ).CombinedOutput()
    if err != nil {
        fmt.Printf("复制失败: %v\n%s\n", err, out)
    } else {
        fmt.Println("复制成功")
    }
}

基本调用

#include <stdio.h>
#include <stdlib.h>

int main(void) {
    int code = system("copys copy \"C:\\src\" \"D:\\dst\"");
    printf("退出码: %d\n", code);
    return 0;
}

带参数 + 判断结果

#include <stdio.h>
#include <stdlib.h>

int main(void) {
    int code = system("copys copy \"C:\\src\" \"D:\\dst\" --always -q");
    if (code == 0) {
        printf("复制成功\n");
    } else {
        printf("复制失败,退出码: %d\n", code);
    }
    return 0;
}

基本调用

#include <iostream>
#include <cstdlib>

int main() {
    int code = std::system("copys copy \"C:\\src\" \"D:\\dst\"");
    std::cout << "退出码: " << code << std::endl;
    return 0;
}

带参数 + 判断结果

#include <iostream>
#include <cstdlib>

int main() {
    int code = std::system(
        "copys copy \"C:\\src\" \"D:\\dst\" --always -q"
    );
    if (code == 0) {
        std::cout << "复制成功" << std::endl;
    } else {
        std::cout << "复制失败,退出码: " << code << std::endl;
    }
    return 0;
}

基本调用

using System.Diagnostics;

Process.Start("copys", "copy \"C:\\src\" \"D:\\dst\"")
    ?.WaitForExit();

带参数 + 读取输出 + 退出码

using System.Diagnostics;

var psi = new ProcessStartInfo {
    FileName = "copys",
    Arguments = "copy \"C:\\src\" \"D:\\dst\" --always -q",
    RedirectStandardOutput = true,
    RedirectStandardError = true,
    UseShellExecute = false,
    CreateNoWindow = true,
};

using var proc = Process.Start(psi);
proc?.WaitForExit();
string stderr = proc?.StandardError.ReadToEnd() ?? "";

if (proc?.ExitCode == 0)
    Console.WriteLine("复制成功");
else
    Console.WriteLine($"复制失败,退出码: {proc?.ExitCode},错误: {stderr}");

基本调用

import java.io.IOException;

public class CopyExample {
    public static void main(String[] args) throws IOException, InterruptedException {
        Process p = new ProcessBuilder("copys", "copy", "C:\\src", "D:\\dst")
            .inheritIO().start();
        int code = p.waitFor();
        System.out.println("退出码: " + code);
    }
}

带参数 + 捕获输出

import java.io.*;

public class CopyExample {
    public static void main(String[] args) throws Exception {
        Process p = new ProcessBuilder(
            "copys", "copy", "C:\\src", "D:\\dst", "--always", "-q")
            .redirectErrorStream(true).start();

        BufferedReader reader = new BufferedReader(
            new InputStreamReader(p.getInputStream()));
        String line;
        while ((line = reader.readLine()) != null)
            System.out.println(line);

        int code = p.waitFor();
        if (code == 0)
            System.out.println("复制成功");
        else
            System.out.println("复制失败,退出码: " + code);
    }
}

基本调用

<?php
// 返回最后一行输出
$output = shell_exec('copys copy "C:\\src" "D:\\dst" 2>&1');
echo $output;
?>

带参数 + 退出码判断

<?php
exec('copys copy "C:\\src" "D:\\dst" --always -q', $output, $code);
if ($code === 0) {
    echo "复制成功\n";
} else {
    echo "复制失败,退出码: $code\n";
    print_r($output);
}
?>

Windows 下注意

💡 PHP 需以 Windows 环境运行;路径含空格时用双引号包裹,如 exec('copys copy "C:\\my dir\\src" "D:\\dst" -q')

基本调用(运行 - 等待完成)

.版本 2

.子程序 _按钮1_被单击
    ' 第2个参数为"真"表示等待程序运行结束
    ' 第3个参数为真时自动隐藏命令行窗口
    运行 (“copys copy ” + #引号 + “C:\src” + #引号 + “ ” + #引号 + “D:\dst” + #引号, 真, 真)
    ' 复制完成后继续执行下面代码
    信息框 (“复制完成”, 0, , )

带参数 + 静默调用

.版本 2

.子程序 复制_静默
    运行 (“copys copy ” + #引号 + “C:\src” + #引号 + “ ” + #引号 + “D:\dst” + #引号 + “ --always -q”, 真, 真)
    ' 等待结束后提示
    信息框 (“复制完成(静默模式)”, 0, , )
💡 易语言中 #引号 表示双引号字符,用于包裹带空格的路径。若需获取退出码,可用"运行并等待"模块或系统 API。

基本调用

& "$env:LOCALAPPDATA\Copys\copys.exe" copy "C:\src" "D:\dst"

带参数 + 退出码

$proc = Start-Process -FilePath "$env:LOCALAPPDATA\Copys\copys.exe" `
    -ArgumentList 'copy', 'C:\src', 'D:\dst', '--always', '-q' `
    -Wait -PassThru -NoNewWindow
if ($proc.ExitCode -eq 0) {
    Write-Host "复制成功"
} else {
    Write-Host "复制失败,退出码: $($proc.ExitCode)"
}

捕获输出

$output = & "$env:LOCALAPPDATA\Copys\copys.exe" copy "C:\src" "D:\dst" 2>&1
$output | ForEach-Object { Write-Host $_ }

基本调用(推荐 execFile,避免命令注入)

const { execFile } = require('child_process');

execFile('copys', ['copy', 'C:\\src', 'D:\\dst'], (err, stdout) => {
    if (err) {
        console.error('复制失败,退出码:', err.code);
        return;
    }
    console.log('复制成功');
    console.log(stdout);
});

带参数 + Promise 化

const { execFile } = require('child_process');
const { promisify } = require('util');
const run = promisify(execFile);

async function copy() {
    try {
        const { stdout } = await run('copys', [
            'copy', 'C:\\src', 'D:\\dst', '--always', '-q'
        ]);
        console.log('复制成功');
    } catch (e) {
        console.error('复制失败,退出码:', e.code);
    }
}
copy();

基本调用

@echo off
copys copy "C:\src" "D:\dst"
echo 退出码: %errorlevel%
pause

带参数 + 判断结果

@echo off
setlocal

copys copy "C:\src" "D:\dst" --always -q
if %errorlevel%==0 (
    echo 复制成功
) else (
    echo 复制失败,退出码: %errorlevel%
)

endlocal
💡 批处理中 %errorlevel% 保存上一条命令的退出码。用 setlocal 可避免污染环境变量。

六、在线升级

  1. Copys 启动时自动检查更新(后台静默)
  2. 发现新版本 → 窗口顶部提示"发现新版本 vX.X.X"
  3. 点击"升级" → 下载更新 → 当前复制完成后自动应用
  4. 或命令行: copys update-check / copys update
💡 复制过程中升级不会中断复制,更新会在复制完成后自动应用。

七、留言反馈

遇到问题、有功能建议或使用感受,欢迎到 留言反馈 页面留言!

  1. 填写昵称(可选)和留言内容,点击提交
  2. 留言会经过审核后公开展示,请勿发布违法违规内容
  3. 看到有用的留言可以点赞(同一留言每人只能赞一次)
  4. 您的声音将汇总到开发者后台,作为下个版本改进的重要参考
💡 建议反馈时描述具体场景(源盘类型、文件大小、操作步骤),更有助于快速定位和优化。

八、常见问题

Q: 复制速度为什么没有宣传的那么快?

实际速度取决于硬盘类型。机械盘(HDD)通常约 80-200 MB/s,固态盘(SSD/NVMe)更高,可接近磁盘瓶颈值。Copys 已自动适配不同硬盘类型,尽量发挥磁盘最大性能。

Q: 报错 "error 123"?

多为目标路径问题(如根目录、特殊字符)。请确认目标目录路径正确。

Q: 无网络时能用吗?

能。Copys 复制功能完全本地运行。仅"检查更新"需要网络,无网络时静默跳过,不影响使用。

Q: 如何彻底卸载?

运行安装目录的 copys_setup.exe → 点"卸载",或通过"控制面板 → 程序"卸载。