当前位置: 首页 > news >正文

implement copy file content to clipboard on Windows

Linux 有xclip, xsel等程序用来复制内容,我想在Windows也需要,特别是文本内容就行

clipfile.h

#ifndef CLIPFILE_H
#define CLIPFILE_H#include <stdbool.h>
#include <stdio.h>#ifdef __cplusplus
extern "C" {
#endif// 将文本内容复制到剪贴板
bool clipclipfile_copy_text(const char* text);// 将文件内容复制到剪贴板
bool clipfile_copy_file(const char* filename);#ifdef __cplusplus
}
#endif#endif // CLIPFILE_H#ifdef CLIPFILE_IMPLEMENTATION#include <stdlib.h>
#include <string.h>#ifdef _WIN32
#include <windows.h>
#else
#include <unistd.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <fcntl.h>
#endif// 内部函数:获取文件大小
static size_t clipfile_get_file_size(const char* filename) {
#ifdef _WIN32WIN32_FILE_ATTRIBUTE_DATA file_info;if (!GetFileAttributesExA(filename, GetFileExInfoStandard, &file_info)) {return 0;}return (size_t)((file_info.nFileSizeHigh * (MAXDWORD + 1LL)) + file_info.nFileSizeLow);
#elsestruct stat st;if (stat(filename, &st) != 0) {return 0;}return (size_t)st.st_size;
#endif
}// 将文本内容复制到剪贴板
bool clipfile_copy_text(const char* text) {if (!text) return false;#ifdef _WIN32// Windows 实现if (!OpenClipboard(NULL)) return false;if (!EmptyClipboard()) {CloseClipboard();return false;}size_t text_len = strlen(text);HGLOBAL hMem = GlobalAlloc(GMEM_MOVEABLE, text_len + 1);if (!hMem) {CloseClipboard();return false;}char* pMem = (char*)GlobalLock(hMem);if (pMem) {strcpy(pMem, text);GlobalUnlock(hMem);SetClipboardData(CF_TEXT, hMem);} else {GlobalFree(hMem);hMem = NULL;}CloseClipboard();return hMem != NULL;#else// Unix-like 实现const char* cmd;
#ifdef __APPLE__cmd = "pbcopy";
#elsecmd = "xclip -selection clipboard";
#endifFILE* pipe = popen(cmd, "w");if (!pipe) return false;fputs(text, pipe);int ret = pclose(pipe);return ret == 0;
#endif
}// 将文件内容复制到剪贴板
bool clipfile_copy_file(const char* filename) {if (!filename) return false;// 获取文件大小size_t file_size = clipfile_get_file_size(filename);if (file_size == 0) {// 可能是0字节文件或错误,仍尝试读取file_size = 1024; // 初始缓冲区大小}// 分配缓冲区char* buffer = (char*)malloc(file_size + 1);if (!buffer) return false;// 打开文件FILE* file = fopen(filename, "rb");if (!file) {free(buffer);return false;}// 读取文件内容size_t bytes_read = fread(buffer, 1, file_size, file);fclose(file);// 处理实际读取的字节数if (bytes_read == 0) {free(buffer);return false; // 空文件或读取错误}// 确保字符串以null结尾buffer[bytes_read] = '\0';// 复制到剪贴板bool success = clipfile_copy_text(buffer);free(buffer);return success;
}#endif // CLIPFILE_IMPLEMENTATION#ifdef CLIPFILE_MAIN
#include <stdio.h>static void print_usage(const char* prog_name) {fprintf(stderr, "用法: %s [选项] <文件名>\n", prog_name);fprintf(stderr, "将指定文件的内容复制到系统剪贴板\n\n");fprintf(stderr, "选项:\n");fprintf(stderr, "  -h, --help    显示此帮助信息\n");fprintf(stderr, "  -v, --version 显示版本信息\n");
}static void print_version(void) {fprintf(stderr, "clipfile 1.0\n");fprintf(stderr, "跨平台文件内容复制到剪贴板工具\n");
}int main(int argc, char* argv[]) {// 解析命令行参数if (argc < 2) {print_usage(argv[0]);return 1;}const char* filename = NULL;for (int i = 1; i < argc; i++) {if (strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "--help") == 0) {print_usage(argv[0]);return 0;} else if (strcmp(argv[i], "-v") == 0 || strcmp(argv[i], "--version") == 0) {print_version();return 0;} else if (filename == NULL) {filename = argv[i];} else {fprintf(stderr, "错误: 过多的参数\n");print_usage(argv[0]);return 1;}}if (!filename) {fprintf(stderr, "错误: 未指定文件名\n");print_usage(argv[0]);return 1;}// 复制文件内容到剪贴板bool success = clipfile_copy_file(filename);if (success) {printf("成功将文件内容复制到剪贴板: %s\n", filename);return 0;} else {fprintf(stderr, "错误: 无法复制文件内容到剪贴板: %s\n", filename);return 1;}
}#endif // CLIPFILE_MAIN

暴露两个api

// probe.c
#define CLIPFILE_IMPLEMENTATION
#include "clipfile.h"int main(int argc, char** argv) {// 复制文本到剪贴板clipfile_copy_text("Hello, World!");printf("文本形式成功\n");#if 0// 复制文件内容到剪贴板if (clipfile_copy_file("probe.c")) {printf("文件内容已复制到剪贴板\n");} else {printf("复制失败\n");}#endifreturn 0;
}

跨平台支持:

  • Windows 系统:使用 Win32 API 直接操作剪贴板
  • macOS 系统:使用 pbcopy 命令(没测试)
  • Linux 系统:使用 xclip 命令(需要系统已安装)(没测试)

作为命令行工具编译和使用

Windows (MinGW)
gcc -x c -DCLIPFILE_IMPLEMENTATION -DCLIPFILE_MAIN clipfile.h -o clipfile.exe -luser32
Windows (MSVC)
cl /DCLIPFILE_IMPLEMENTATION /DCLIPFILE_MAIN /Tcclipfile.h /Fe:clipfile.exe user32.lib
http://www.lryc.cn/news/622569.html

相关文章:

  • OpenCV 图像处理基础操作指南(二)
  • sqli-labs通关笔记-第52关 GET数值型order by堆叠注入(手工注入+脚本注入两种方法)
  • ComfyUI-3D-Pack:3D创作的AI神器
  • AI 搜索时代:引领变革,重塑您的 SEO 战略
  • Boost搜索引擎项目(详细思路版)
  • AI搜索引擎下的内容优化新范式:GEO的关键技术解析
  • ABM和强化学习-2015年全国大学生数学建模竞赛B题
  • 2025年生成式引擎优化(GEO)服务商技术能力评估报告
  • Linux怎么查看服务器开放和启用的端口
  • 论文学习24:Boundary-Sensitive Segmentation of SmallLiver Lesions
  • [Linux] Linux tar文档管理 系统间复制文档
  • Rust学习笔记(四)|结构体与枚举(面向对象、模式匹配)
  • 头文件包含和前置声明
  • [Linux] Linux网络管理
  • 跨域:浏览器有同源策略,但是为何 cdn 请求资源的时候不会有跨域限制?
  • 【低成本扩容】动态扩容实战指南
  • AMD Ryzen AI Max+ 395四机并联:大语言模型集群推理深度测试
  • 开源 Arkts 鸿蒙应用 开发(十八)通讯--Ble低功耗蓝牙服务器
  • 昇腾AI自学Day2-- 深度学习基础工具与数学
  • 利用cursor+MCP实现浏览器自动化释放双手
  • vscode中使用CMake Tools生成compile_commands.json文件后,如何告诉clangd这个文件在哪里呢?
  • 新手向:Python列表、元组、集合和字典的用法对比
  • JavaScript 核心语法与实战笔记:从基础到面试高频题
  • macOS 中查看当前生效 shell 及配置文件的方法
  • linux网络基础
  • 二叉树的三种遍历方法
  • KVM虚拟化技术解析:从企业应用到个人创新的开源力量
  • 开源 Arkts 鸿蒙应用 开发(十七)通讯--http多文件下载
  • 4.6 Vue 3 中的模板引用 (Template Refs)
  • Vue中的数据渲染【4】