Donate
Donate / 打赏
如果 SyncClipboard 对你有帮助,欢迎打赏支持项目持续维护。
If SyncClipboard helps you, donations are welcome to support ongoing maintenance.
Notes / 说明
- issue 是否能被快速解决,主要取决于问题描述是否详细、是否容易复现、是否对功能有重大影响、作者空闲时间等因素。
Issue resolution speed mainly depends on whether the report is detailed, reproducible, has significant impact on core functionality, and on the author's available time.
- 请在打赏时备注名字、网络 ID 或其他用户标识。
Please leave your name, online ID, or other user identifier when donating.
Alipay / 支付宝
WeChat Pay / 微信支付
Hash
Profile Hash 计算方法
概述
所有 Profile 类型的 Hash 基于 SHA256 算法,涉及文本的使用 UTF-8 编码。
Hash 值通常以大写十六进制字符串形式表示,实际使用时应该对大小写不敏感。
1. TextProfile (纯文本)
将文本进行UTF8编码后计算SHA256
2. FileProfile 和 ImageProfile (单个文件或图片)
- 计算文件内容的 SHA256 哈希值并转换为大写十六进制字符串
- 获取文件名(不含路径)
- 构造字符串:
文件名|文件内容SHA256字符串 - 对该字符串进行 UTF-8 编码后再次计算 SHA256
伪代码
ContentHash = SHA256(FileContent)
CombinedString = "FileName|" + ToUpperCase(ContentHash)
Hash = SHA256(UTF8(CombinedString))3. GroupProfile (多文件或文件夹)
计算方法
对所有文件和目录排序后,按特定格式和顺序拼接成完整字符串计算 SHA256
详细说明
3.1 Entry 收集
- 收集所有输入文件/目录及其子文件/子目录,每一条作为一个 entry
- 每个 entry 以输入文件的父目录为根,取相对路径作为 EntryName
- EntryName 中的路径分隔符统一为
/ - 目录的 EntryName 以
/结尾
3.2 排序
- 取 EntryName 按 UTF-8 编码后的byte数组,以字典序升序排序
3.3 Entry 的 Hash 输入字符串格式
- 目录:
D|{entryName}\0 - 文件:
F|{entryName}|{length}|{contentHash}\0
其中:
{entryName}:相对路径名{length}:文件字节长度{contentHash}:文件内容的 SHA256 哈希值(大写十六进制)- 每条 entry 的 hash 输入字符串以
\0结尾
3.4 哈希计算
- 将所有 entry hash 输入字符串按序拼接成一个字符串,UTF8 编码后计算 SHA256
示例
假设有以下文件结构:
folder/
├── a.txt (100 bytes, hash: abc...123)
└── subdir/
└── b.txt (200 bytes, hash: def...456)排序、拼接所有 Entry hash 输入字符串,得到最终的输入字符串(这里将\0显示为换行):
D|folder/
F|folder/a.txt|100|ABC...123
D|folder/subdir/
F|folder/subdir/b.txt|200|DEF...456将上述字符串使用UTF8编码转换为 byte 数组,对此 byte 数组进行 SHA256 计算得到最终的hash
README EN
SyncClipboard
中文 | English
Contents
- Features
- Breaking Changes
- v3.1.1
- Server
- Standalone Server
- Server Configuration
- Docker
- Arch Linux
- Desktop Client Built-in Server
- WebDAV Server
- S3 Server
- Client
- Windows
- Installer
- Portable Version
- Troubleshooting
- macOS
- Manual Installation
- Troubleshooting
- Linux
- Manual Installation
- Arch Linux
- Troubleshooting
- Desktop Client Command Line Arguments
- --shutdown-previous
- --command-{command-name}
- IOS
- Use Shortcuts
- Android
- Use SyncClipboard Mobile
- HarmonyOS Next
- Use ClipLink
- Notes for Clients
- API
- Get Clipboard
- Upload Clipboard
- SyncClipboard.json
- S3 Sync Protocol Specification
- Open Source Dependencies
- Donate
Features
- Cross-platform (Windows/macOS/Linux) real-time clipboard syncing, clipboard history management, and history syncing.
- Supports desktop client built-in server, Docker-deployed server, or storage services compatible with WebDAV/S3 APIs.
- Mobile clipboard syncing based on third-party tools.
- Optimize image type clipboard:
- Paste image to a textbox directly after copying a image file from file system, and vice versa.
- Download the original file and copy it after copying a image in web browser. This is helpful for copying an animated image in browser. Web sites always prevent downloads from non-browser, so this feature isn't always usable.
- Copy the transcoded temporary image file (jpg or gif) after copying a modern image file type (heic, webp, etc.).
[!WARNING]
The clipboard history feature is in its early stages. Please be prepared for the possibility of losing all information. Do not rely solely on this tool to save important information.
Breaking Changes
[v3.1.1](https://github.com/Jeric-X/SyncClipboard/issues/286)
Clients and servers v3.1.1 and above are incompatible with previous versions. All clients, servers, and third-party clients in the sync network need to be upgraded together.
Server
Standalone Server
SyncClipboard.Server is cross-platform, depends on ASP.NET Core 8.0. Run with:
dotnet /path/to/SyncClipboard.Server.dll --contentRoot ./Content root folder is SyncClipboard.Server.dll's parent folder. Writing permission is needed. Choosing a different content root folder is possible. Copy a new appsettings.json to the folder and run with:
dotnet /path/to/SyncClipboard.Server.dll --contentRoot /path/to/contentRootServer Configuration
appsettings.json is the config file.
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*",
"Kestrel": {
"Endpoints": {
"http": {
"Url": "http://*:5033"
},
//"https": {
// "Url": "https://*:5033"
//}
},
//"Certificates": {
// "Default": {
// "Path": "/path/to/pem",
// "KeyPath": "/path/to/pem_key"
// }
//}
},
"AppSettings": {
"UserName": "your_username",
"Password": "your_password",
"MaxSavedHistoryCount": 1000
}
}For more information, please refer to the official Microsoft documentation.
Username and password can be set by environment variables. When the environment variables SYNCCLIPBOARD_USERNAME and SYNCCLIPBOARD_PASSWORD are both set, they will be used as the username and password.
ASPNETCORE_hostBuilder__reloadConfigOnChange is used to configure whether to automatically detect changes in appsettings.json and reload the configuration. The default value is false. Changing it to any value other than false will enable this feature.
[!WARNING]
HTTP transmits data in plaintext. When deploying the server on a public network, please enable HTTPS or configure HTTPS using a reverse proxy tool. If obtaining a certificate from a certificate authority is not possible, it is recommended to use the open-source tool mkcert or other methods to generate a self-signed certificate.
Docker
# docker
docker run -d \
--name=syncclipboard-server \
-p 5033:5033 \
-e SYNCCLIPBOARD_USERNAME=your_username \
-e SYNCCLIPBOARD_PASSWORD=your_password \
-v /data/syncclipboard-server:/app/data \
--restart unless-stopped \
jericx/syncclipboard-server:latest
# docker compose
curl -sL https://github.com/Jeric-X/SyncClipboard/raw/master/src/SyncClipboard.Server/docker-compose.yml >> docker-compose.yml
docker compose up -dAfter the container starts for the first time, a default appsettings.json will be automatically created in the container directory /app/data (which corresponds to the host directory /data/syncclipboard-server).
When modifying appsettings.json, pay attention to the file path mapping between the container and the host.
Arch Linux
You can install it directly from AUR (maintained by @devome):
paru -Sy syncclipboard-serverThe configuration file path is /etc/syncclipboard/appsettings.json. After modifying the configuration, you can start the service using systemctl command:
sudo systemctl enable --now syncclipboard.serviceDesktop Client Built-in Server
Desktop client (Windows/Linux/macOS) has a built-in server, can be configured with GUI.
WebDAV Server
Tested server:
- [x] Nextcloud
- [x] AList
- [x] InfiniCLOUD
- [x] aliyundrive-webdav
S3 Server
The desktop client supports AWS S3 via the official AWS SDK, and also supports OSS providers that expose an S3-compatible API.
When adding an account, choose S3 and configure:
Server Address: Optional. Leave empty for AWS; set your endpoint for S3-compatible providers.Region: Signing region, for exampleus-east-1.Bucket Name: Bucket used to storeSyncClipboard.jsonandfile/objects.Object Prefix: Optional. Recommended to isolate data with a dedicated prefix (for examplesyncclipboard).Force Path-Style Addressing: Recommended for many S3-compatible providers.Access Key ID/Secret Access Key: Access credentials.
Client
Clipboard is auto-synced between desktop clients running on Windows/Linux/macOS.
Screenshots
Windows
Installer
Download the exe installer starting with SyncClipboard_win_ from the Release page. Double-click to run the installer and it will be ready to use.
Portable Version
Download the zip file starting with SyncClipboard_win_ from the Release page. Extract it and run SyncClipboard.exe.
Troubleshooting
- The minimum supported OS version is Windows 10 2004.
- If the interface icons are displayed incorrectly on Windows 10, download and install the Microsoft Segoe Fluent Icons font.
macOS
Manual Installation
Download the installation package starting with SyncClipboard_macos_ from the Release page. Double-click it and drag the SyncClipboard icon to the Applications folder.
Troubleshooting
- System prompts
“SyncClipboard” cannot be opened because the developer cannot be verified: Go toSettings->Privacy & Securityon macOS, and clickOpen Anyway. - System prompts
"SyncClipboard" is damaged, can't be opened: Run the following command in the terminal:sudo xattr -d com.apple.quarantine /Applications/SyncClipboard.app - Some features require simulating keyboard input to perform copy or paste operations, which depend on Accessibility permissions. SyncClipboard will prompt for authorization when needed.
Linux
Manual Installation
Download the installation package starting with SyncClipboard_linux_ from the Release page.
Arch Linux
Arch Linux users can directly install from AUR (maintained by @devome):
paru -Sy syncclipboard-desktopAfter installation, you can launch it from the menu. If launching via the command syncclipboard-desktop results in an error, set the environment variable LANG to en_US.UTF-8 or just start it using LANG=en_US.UTF-8 syncclipboard-desktop.
Troubleshooting
- Clipboard sync is delayed, fails, or uploads garbled text: It is recommended to install
xclip(for X11) orwl-clipboard(for Wayland) on your system. SyncClipboard will use these tools to help access the clipboard and improve stability. Use the commandsxclip -versionorwl-paste -versionto check if they are installed. - When upgrading using
deborrpminstallation packages, if the upgrade fails, please uninstall the old version before installing the new one. - When using the
AppImagepackage, please ensure that the AppImage file has executable permissions. - Hotkeys may not work on Wayland.
- The language cannot be auto-detected and defaults to English. You can change the language in SyncClipboard's settings after launching.
[!NOTE]
To completely remove SyncClipboard, manually delete the configuration and temporary file directories:%AppData%\SyncClipboard\(Windows),~/Library/Application Support/SyncClipboard/(macOS),~/.config/SyncClipboard/(Linux)
Desktop Client Command Line Arguments
--shutdown-previous
Closes any running instance of SyncClipboard and starts a new one.
--command-{command-name}
Executes the specified command, where {command-name} is the name of the command. After setting a shortcut key, you can view the corresponding command name in the configuration file. Even if the shortcut key configuration is cleared, the command line argument remains valid.
If a SyncClipboard instance is already running, it will not start a new instance but will instruct the running SyncClipboard to execute the command. If no instance is running, the command will be executed immediately after startup.
Multiple --command-{command-name} arguments are supported, multiple commands are executed simultaneously.
[!NOTE]
When using command line arguments on macOS, please use the full path to the executable:/Applications/SyncClipboard.app/Contents/MacOS/SyncClipboard.Desktop.MacOS
IOS
Use [Shortcuts](https://apps.apple.com/us/app/shortcuts/id1462947752)
- Sync manually, import this Shortcut
- Sync Automatically, import this Shortcut. This shortcut keeps running in the background forever, you need to stop it manually. You can also change whether to send notifications and querying interval time manullay.
Android
Use [SyncClipboard Mobile](https://github.com/Jeric-X/syncclipboard-mobile)
- Quick manual trigger from notification center, home screen shortcut, and share menu
- Limited background sync capability
- Clipboard history and history sync
- Auto-upload SMS verification codes
HarmonyOS Next
Use [ClipLink](https://github.com/xiebaiyuan/ClipLink)
A HarmonyOS Next client. Download the .hap file from Releases and install via auto-installer or hdc install (sideloading required due to HarmonyOS restrictions).
Notes for Clients
There are three necessery config(maybe different words, same uses).
- username
- password
- url, format is
http://ip(or domain name):port. When using a WebDav server, url needs to be pointed to a specific existing folder as the working folder, likehttps://domain.com/dav/folder1/working%20folder. File name is the best not to contain any special characters or spaces, or you'll have to URL encode it. And do not use this folder to do anything else. If not using a desktop client(Windows/Linux/macOS), create a folder namedfilein the working folder to sync files. Desktop clients create this folder automatically. Make sure no slash(/) at the end of url.
API
In a standalone server environment, set the environment variable ASPNETCORE_ENVIRONMENT to Development before running the server, or open the server in the desktop client and enable diagnostic mode in settings.
Then visit http://ip:port/swagger/index.html to access the API description page.
APIs that do not start with /api/ are WebDAV-compatible APIs. When implementing clients, calling these APIs can support clipboard synchronization based on both WebDAV servers and official SyncClipboard servers. The key APIs are described below.
Get Clipboard
GET /SyncClipboard.json
GET /file/dataName # optionalUpload Clipboard
PUT /file/dataName # optional
PUT /SyncClipboard.jsonSyncClipboard.json
{
"type": "Text", // or Image/File/Group, required
"hash": "string", // optional, empty string is treated as null
"text": "string", // required
"hasData": true, // or false, required
"dataName": "string", // if hasData is true, required
"size": 0 // optional
}- All API fields are case-sensitive
textstores the clipboard preview string, or the complete content of Text type clipboardhasDataindicates whether an additional file is used to store the complete clipboard information
- For Image/File/Group types, hasData is always true
- For Text type, depending on the original string length, you can optionally use an additional UTF8-encoded .txt file to store the complete string. If so, the text field only stores the beginning part of the complete string
hashvalue is a unique identifier of the clipboard content. For the calculation method, please refer to docs/Hash.md
- The sender should provide hash information whenever possible
- When the hash value exists, the receiver should verify the consistency between the hash information and the clipboard content, and execute the error handling process when inconsistent
- When hash is empty, or in an environment where hash cannot be calculated, you can use the combination of type/text to simply determine the equality of clipboard content
sizeindicates the total byte size of the copied file, or the length of the complete string for Text type clipboard
S3 Sync Protocol Specification
For protocol and data format specifications when using S3-compatible object storage as sync backend, please refer to S3 Adapter Design.
Open Source Dependencies
NativeNotification
Magick.NET
.NET Community Toolkit
H.NotifyIcon
WinUIEx
moq
Avalonia
FluentAvalonia.BreadcrumbBar
FluentAvalonia
AsyncImageLoader.Avalonia
Vanara
Tmds.DBus
SharpHook
Quartz.NET
Donate
If SyncClipboard helps you, donations are welcome to support ongoing maintenance. View donation details here.
S3 Adapter Design
SyncClipboard S3 同步协议规范
本文档描述 SyncClipboard 使用 S3 兼容对象存储作为同步后端的存储布局约定以及相关开发指南。
1. S3 专有配置项
以下配置项为 S3 服务器依赖。
| 参数 | 说明 | 必填 | 默认值 |
|---|---|---|---|
ServiceURL |
S3 兼容端点 URL。使用 AWS 原生服务时留空 | 否 | 空 |
| Region | AWS 区域标识(如 us-east-1、ap-northeast-1) | 否 | us-east-1 |
| BucketName | 存储桶名称 | 是 | — |
| ObjectPrefix | 所有对象 key 的统一前缀,用于隔离多客户端或多用途 | 否 | 空 |
| ForcePathStyle | 是否使用路径风格寻址(endpoint/bucket/key),大多数 S3 兼容服务需要开启 | 否 | false |
| AccessKeyId | 访问密钥 ID | 是 | — |
| SecretAccessKey | 访问密钥 Secret | 是 | — |
端点选择规则
- AWS 原生:
ServiceURL留空,SDK 根据Region自动解析标准 AWS S3 端点。 - S3 兼容服务(MinIO / Cloudflare R2 / 阿里云 OSS 等):填写
ServiceURL(如https://s3.example.com),一般同时启用ForcePathStyle = true。
认证方式
使用 AWS Signature V4 签名。
2. 对象存储布局
所有对象 key 的格式为 {ObjectPrefix}/{相对路径}。前缀的首尾 / 会被 trim。
{BucketName}/
└── {ObjectPrefix}/ # 为空时没有此级
├── SyncClipboard.json # 剪贴板 Profile 元数据文件
└── file/ # 附件目录(零或多个数据文件)
├── {dataName1} # 例如 "Text_2025-04-15_08-45-23_abc12345.tmp.txt"
└── {dataName2} # 例如 "screenshot.png"3. Profile 元数据格式(`SyncClipboard.json`)
参照 API 说明。
4. S3 API 调用约定
以下按操作列出具体的 S3 API 调用。所有操作均使用 AWS Signature V4 认证。
4.1 连接测试
| S3 操作 | ListObjectsV2 |
|---|---|
| Bucket |
{BucketName} |
| Prefix | {ObjectPrefix} |
| MaxKeys | 1 |
成功返回即说明凭据和桶可用。
4.2 初始化(确保目录结构)
检查 file/ 目录标记是否存在:
| S3 操作 | HeadObject(GetObjectMetadata) |
|---|---|
| Key |
{prefix}/file/ |
如果返回 404 / NoSuchKey,则创建目录标记:
| S3 操作 | PutObject |
|---|---|
| Key |
{prefix}/file/ |
| Body | 空字符串 |
| Content-Type | application/x-directory |
4.3 读取 Profile
| S3 操作 | GetObject |
|---|---|
| Key |
{prefix}/SyncClipboard.json |
- 成功:读取响应体 → JSON 反序列化为 ProfileDto
- 404 / NoSuchKey:返回空(首次使用,尚无 Profile)
4.4 写入 Profile
| S3 操作 | PutObject |
|---|---|
| Key |
{prefix}/SyncClipboard.json |
| Body | JSON 序列化的 ProfileDto |
| Content-Type | application/json; charset=utf-8 |
4.5 上传数据文件
| S3 操作 | PutObject |
|---|---|
| Key |
{prefix}/file/{fileName} |
| Body | 文件二进制内容 |
fileName 即 ProfileDto 中的 dataName 字段值。
4.6 下载数据文件
| S3 操作 | GetObject |
|---|---|
| Key |
{prefix}/file/{dataName} |
dataName 来自 ProfileDto 的 dataName 字段。
4.7 清理旧文件
分页列出 file/ 目录下所有对象并批量删除:
第一步:列出对象
| S3 操作 | ListObjectsV2 |
|---|---|
| Prefix |
{prefix}/file/ |
| MaxKeys | 1000 |
使用 ContinuationToken 分页直到全部列出。
第二步:批量删除
| S3 操作 | DeleteObjects |
|---|---|
| Objects |
上一步列出的所有 key |
5. S3 兼容服务注意事项
5.1 签名与编码
对于非 AWS 的 S3 兼容服务,在 PUT 请求时应注意:
| 设置 | 说明 |
|---|---|
| 禁用 Chunked Transfer Encoding |
不使用 Transfer-Encoding: chunked |
| 禁用 Payload Signing | 不在请求体上计算 SHA-256 签名(使用 UNSIGNED-PAYLOAD) |
| 禁用 Trailer Checksum | 不追加 x-amz-checksum-* trailer |
许多 S3 兼容网关(R2、MinIO、OSS gateway 等)不支持 AWS SDK v3+ 默认启用的流式 Trailer 签名。
5.2 路径风格 vs 虚拟主机风格
- AWS 标准:虚拟主机风格
{bucket}.s3.{region}.amazonaws.com/{key} - 兼容服务:通常需要路径风格
{endpoint}/{bucket}/{key}(开启ForcePathStyle)
5.3 协议选择
- 如果
ServiceURL以http://开头,使用 HTTP;否则使用 HTTPS - AWS 原生始终使用 HTTPS