Skip to content

Commit f5f3f03

Browse files
committed
添加注释
1 parent 0bddb33 commit f5f3f03

File tree

1 file changed

+42
-0
lines changed

1 file changed

+42
-0
lines changed

src/main/common/windowsClipboard.ts

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,18 @@
11
import { clipboard } from 'electron';
22
import path from 'path';
33

4+
// 仅在 Windows 平台辅助操作剪贴板多文件格式。
45
type ClipboardExModule = typeof import('electron-clipboard-ex');
56

67
const DROPFILES_HEADER_SIZE = 20;
78

89
let clipboardExModule: ClipboardExModule | null = null;
910

11+
/**
12+
* Windows 平台专用:尝试加载第三方库 electron-clipboard-ex。
13+
* 这个库能够调用系统底层接口写入“文件复制”数据,成功率更高。
14+
* 其他系统无需加载它,因此这里做了“按需加载”的处理。
15+
*/
1016
const ensureClipboardEx = (): ClipboardExModule | null => {
1117
if (process.platform !== 'win32') return null;
1218
if (clipboardExModule) return clipboardExModule;
@@ -19,9 +25,20 @@ const ensureClipboardEx = (): ClipboardExModule | null => {
1925
return clipboardExModule;
2026
};
2127

28+
/**
29+
* 把一组文件路径变成 Windows 规定的文本格式。
30+
* 要求:每个路径之间用单个空字符分隔,最后再额外放两个空字符,表示列表结束。
31+
* Windows 资源管理器会按这个格式解析我们复制到剪贴板的文件。
32+
*/
2233
const buildWindowsFileListPayload = (files: string[]): Buffer =>
2334
Buffer.from(`${files.join('\0')}\0\0`, 'utf16le');
2435

36+
/**
37+
* 构造 CF_HDROP 专用的二进制数据。
38+
* 这是 Windows 复制文件时的底层格式,前 20 字节是固定的结构头,
39+
* 后面紧跟着具体的文件路径(由 buildWindowsFileListPayload 生成)。
40+
* 只要把这个内容写入剪贴板,任何支持粘贴文件的程序都能理解。
41+
*/
2542
const buildWindowsFileDropBuffer = (files: string[]): Buffer => {
2643
const payload = buildWindowsFileListPayload(files);
2744
const header = Buffer.alloc(DROPFILES_HEADER_SIZE);
@@ -41,6 +58,11 @@ const buildWindowsFileDropBuffer = (files: string[]): Buffer => {
4158
return result;
4259
};
4360

61+
/**
62+
* 复制/移动/创建快捷方式 等不同操作在 Windows 中对应不同的“意图”值。
63+
* Preferred DropEffect 告诉系统:当前剪贴板数据应该以何种方式处理。
64+
* 我们默认写入“copy”,相当于普通的复制粘贴。
65+
*/
4466
const buildDropEffectBuffer = (effect: 'copy' | 'move' | 'link' = 'copy') => {
4567
const effectMap = {
4668
copy: 1,
@@ -52,6 +74,14 @@ const buildDropEffectBuffer = (effect: 'copy' | 'move' | 'link' = 'copy') => {
5274
return buffer;
5375
};
5476

77+
/**
78+
* 直接使用 Electron 内置 API 写入多种剪贴板格式。
79+
* 步骤:
80+
* 1. 写入二进制的 CF_HDROP(含头部与路径列表)
81+
* 2. 写入纯文本形式的 FileNameW(备选格式)
82+
* 3. 写入 Preferred DropEffect(告诉系统“这是复制”)
83+
* 全部成功后,读取一次 CF_HDROP 的长度,确认剪贴板里确实有内容。
84+
*/
5585
const writeWindowsBuffers = (files: string[]): boolean => {
5686
try {
5787
clipboard.writeBuffer('CF_HDROP', buildWindowsFileDropBuffer(files));
@@ -63,6 +93,11 @@ const writeWindowsBuffers = (files: string[]): boolean => {
6393
}
6494
};
6595

96+
/**
97+
* 如果项目中安装了 electron-clipboard-ex,我们优先使用它。
98+
* 理由:该库通过原生方式与系统交互,兼容性往往优于 Electron 的 JS 层写入。
99+
* 调用成功后,必要时读回文件列表做一次数量校验,确保复制的文件数量正确。
100+
*/
66101
const writeWithClipboardEx = (files: string[]): boolean => {
67102
const clipboardEx = ensureClipboardEx();
68103
if (!clipboardEx) return false;
@@ -78,6 +113,13 @@ const writeWithClipboardEx = (files: string[]): boolean => {
78113
}
79114
};
80115

116+
/**
117+
* 对外暴露的唯一入口。
118+
* 1. 先把所有路径换成 Windows 可识别的标准形式(path.normalize)。
119+
* 2. 尝试使用 electron-clipboard-ex 写入,如果成功就结束。
120+
* 3. 若第三方库不可用或失败,再退回 Electron 原生写入流程。
121+
* 这一层屏蔽了所有细节,外部调用者只需传入字符串数组即可。
122+
*/
81123
export const copyFilesToWindowsClipboard = (files: string[]): boolean => {
82124
const normalizedFiles = files
83125
.map((filePath) => path.normalize(filePath))

0 commit comments

Comments
 (0)