dotnet C# 使用 SHFileOperation 调用 Win32 的文件复制对话框

news/2024/11/16 21:43:32/文章来源:https://www.cnblogs.com/lindexi/p/18351897

本文将和大家介绍如何在 dotnet C# 里面使用 SHFileOperation 调用 Windows 自带的文件复制对话框进行文件复制

本文核心代码拷贝自 C#中使用SHFileOperation调用Windows的复制文件对话框 - 季风哥 - 博客园 文章,特别感谢大佬提供的方法

实现的效果图如下

详细实现逻辑还请大家参阅: C#中使用SHFileOperation调用Windows的复制文件对话框 - 季风哥 - 博客园

其中我遇到的坑是多个文件之间需要使用 \0 字符分割,我使用了 dotnet 新 API 对其进行更新,代码如下

        pm.pFrom = string.Join(FILE_SPLITER, sourceFiles) + $"{FILE_SPLITER}{FILE_SPLITER}";pm.pTo = string.Join(FILE_SPLITER, targetFiles) + $"{FILE_SPLITER}{FILE_SPLITER}";

上述代码的 FILE_SPLITERpm 都是从 C#中使用SHFileOperation调用Windows的复制文件对话框 博客里面抄的

所有代码如下

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;namespace KachelearnemChurjawenikall;
internal class Program
{[SkipLocalsInit]static void Main(string[] args){var sourceFile = @"F:\temp\1";var targetFile = @"F:\temp\2";if (!File.Exists(sourceFile)){var buffer = new byte[1024 * 1024];for (int i = 0; i < 1000; i++){Random.Shared.NextBytes(buffer);File.AppendAllBytes(sourceFile, buffer);}}string[] sourceFiles = [sourceFile];string[] targetFiles = [targetFile];SHFILEOPSTRUCT pm = new SHFILEOPSTRUCT();pm.wFunc = wFunc.FO_COPY;//设置对话框标题,在win7中无效pm.lpszProgressTitle = "复制文件";pm.pFrom = string.Join(FILE_SPLITER, sourceFiles) + $"{FILE_SPLITER}{FILE_SPLITER}";pm.pTo = string.Join(FILE_SPLITER, targetFiles) + $"{FILE_SPLITER}{FILE_SPLITER}";pm.fFlags = FILEOP_FLAGS.FOF_NOCONFIRMATION | FILEOP_FLAGS.FOF_MULTIDESTFILES | FILEOP_FLAGS.FOF_ALLOWUNDO;SHFileOperation(pm);}/// <summary>/// 映射API方法/// </summary>/// <param name="lpFileOp"></param>/// <returns></returns>[DllImport("shell32.dll", SetLastError = true, CharSet = CharSet.Unicode)]private static extern int SHFileOperation(SHFILEOPSTRUCT lpFileOp);/// <summary>/// 多个文件路径的分隔符/// </summary>private const string FILE_SPLITER = "\0";/// <summary>/// Shell文件操作数据类型/// </summary>[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]private class SHFILEOPSTRUCT{public IntPtr hwnd;/// <summary>/// 设置操作方式/// </summary>public wFunc wFunc;/// <summary>/// 源文件路径/// </summary>public string pFrom;/// <summary>/// 目标文件路径/// </summary>public string pTo;/// <summary>/// 允许恢复/// </summary>public FILEOP_FLAGS fFlags;/// <summary>/// 监测有无中止/// </summary>public bool fAnyOperationsAborted;public IntPtr hNameMappings;/// <summary>/// 设置标题/// </summary>public string lpszProgressTitle;}/// <summary>/// 文件操作方式/// </summary>private enum wFunc{/// <summary>/// 移动/// </summary>FO_MOVE = 0x0001,/// <summary>/// 复制/// </summary>FO_COPY = 0x0002,/// <summary>/// 删除/// </summary>FO_DELETE = 0x0003,/// <summary>/// 重命名/// </summary>FO_RENAME = 0x0004}/// <summary>/// fFlags枚举值,/// 参见:http://msdn.microsoft.com/zh-cn/library/bb759795(v=vs.85).aspx/// </summary>private enum FILEOP_FLAGS{///<summary>///pTo 指定了多个目标文件,而不是单个目录///The pTo member specifies multiple destination files (one for each source file) rather than one directory where all source files are to be deposited.///</summary>FOF_MULTIDESTFILES = 0x1,///<summary>///不再使用///Not currently used.///</summary>FOF_CONFIRMMOUSE = 0x2,///<summary>///不显示一个进度对话框///Do not display a progress dialog box.///</summary>FOF_SILENT = 0x4,///<summary>///碰到有抵触的名字时,自动分配前缀///Give the file being operated on a new name in a move, copy, or rename operation if a file with the target name already exists.///</summary>FOF_RENAMEONCOLLISION = 0x8,///<summary>///不对用户显示提示///Respond with "Yes to All" for any dialog box that is displayed.///</summary>FOF_NOCONFIRMATION = 0x10,///<summary>///填充 hNameMappings 字段,必须使用 SHFreeNameMappings 释放///If FOF_RENAMEONCOLLISION is specified and any files were renamed, assign a name mapping object containing their old and new names to the hNameMappings member.///</summary>FOF_WANTMAPPINGHANDLE = 0x20,///<summary>///允许撤销///Preserve Undo information, if possible. If pFrom does not contain fully qualified path and file names, this flag is ignored.///</summary>FOF_ALLOWUNDO = 0x40,///<summary>///使用 *.* 时, 只对文件操作///Perform the operation on files only if a wildcard file name (*.*) is specified.///</summary>FOF_FILESONLY = 0x80,///<summary>///简单进度条,意味着不显示文件名。///Display a progress dialog box but do not show the file names.///</summary>FOF_SIMPLEPROGRESS = 0x100,///<summary>///建新目录时不需要用户确定///Do not confirm the creation of a new directory if the operation requires one to be created.///</summary>FOF_NOCONFIRMMKDIR = 0x200,///<summary>///不显示出错用户界面///Do not display a user interface if an error occurs.///</summary>FOF_NOERRORUI = 0x400,///<summary>/// 不复制 NT 文件的安全属性///Do not copy the security attributes of the file.///</summary>FOF_NOCOPYSECURITYATTRIBS = 0x800,///<summary>/// 不递归目录///Only operate in the local directory. Don't operate recursively into subdirectories.///</summary>FOF_NORECURSION = 0x1000,///<summary>///Do not move connected files as a group. Only move the specified files.///</summary>FOF_NO_CONNECTED_ELEMENTS = 0x2000,///<summary>///Send a warning if a file is being destroyed during a delete operation rather than recycled. This flag partially overrides FOF_NOCONFIRMATION.///</summary>FOF_WANTNUKEWARNING = 0x4000,///<summary>///Treat reparse points as objects, not containers.///</summary>FOF_NORECURSEREPARSE = 0x8000,}
}

本文代码放在 github 和 gitee 上,可以使用如下命令行拉取代码。我整个代码仓库比较庞大,使用以下命令行可以进行部分拉取,拉取速度比较快

先创建一个空文件夹,接着使用命令行 cd 命令进入此空文件夹,在命令行里面输入以下代码,即可获取到本文的代码

git init
git remote add origin https://gitee.com/lindexi/lindexi_gd.git
git pull origin 9685aaf325b6d7deee15fd6488cd7533f7052ea2

以上使用的是国内的 gitee 的源,如果 gitee 不能访问,请替换为 github 的源。请在命令行继续输入以下代码,将 gitee 源换成 github 源进行拉取代码。如果依然拉取不到代码,可以发邮件向我要代码

git remote remove origin
git remote add origin https://github.com/lindexi/lindexi_gd.git
git pull origin 9685aaf325b6d7deee15fd6488cd7533f7052ea2

获取代码之后,进入 Workbench/KachelearnemChurjawenikall 文件夹,即可获取到源代码

更多技术博客,请参阅 博客导航

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/780673.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Avalonia 11.1 已知问题 应用启动时 PointToScreen 无法获取正确坐标

本文记录 Avalonia 11.1 版本的已知问题,在 Linux 上使用 X11 时,在应用启动时,即使在 Loaded 或 Activated 事件里,都无法使用 PointToScreen 获取到正确的屏幕坐标,只会将传入的点作为返回值此问题已经报告给 Avalonia 官方,请看 https://github.com/AvaloniaUI/Avalon…

乌龟对对碰开局应该抽几只?

结论:30只以上为佳,3的倍数 https://www.bilibili.com/video/BV17nYVekEWU/?vd_source=9b97428fe30142d2bb4f9bab6ef082a4# Import necessary libraries import numpy as np import random from collections import defaultdict import matplotlib.pyplot as plt# Function …

写一个cpp uos系统

#include <iostream>int main() {std::cout << "Hello, UOS!" << std::endl;return 0; }创建一个test.cpp文件, 在当前目录打开终端, 把上面代码内容写里面, 输入g++ test.cpp, 生成了一个a.out文件, ./a.out 输出 Hello, UOS!

C#项目—彩票选号

C#彩票选号软件 今天做了一个彩票选号的小软件,将学到的知识点总结如下; 1.写程序的思路实体类(属性、方法) 主程序调用类方法2.学到的知识点判断、循环 文件的操作(保存、打开) 集合、数组(增加-AddRange、删除-RemoveAt、排序-Reverse) 关键字:Random(随机数-Next)…

C#学习——彩票选号软件

C#彩票选号软件 今天做了一个彩票选号的小软件,将学到的知识点总结如下; 1.写程序的思路实体类(属性、方法) 主程序调用类方法2.学到的知识点判断、循环 文件的操作(保存、打开) 集合、数组(增加-AddRange、删除-RemoveAt、排序-Reverse) 关键字:Random(随机数-Next)…

探究grid_sample函数

一、函数介绍torch.nn.functional.grid_sample(input, grid, mode=bilinear, padding_mode=zeros, align_corners=None)对于4D输入,input维度为 \((N,C,H_{in},W_{in})\), grid维度为 \((N,H_{out},W_{out},2)\) ,则output维度为 \((N,C,H_{out},W_{out})\)对于5D输入,input…

036.CI4框架CodeIgniter,VUE+CI4互通,VUE通过伪静态地址访问,内容为调用的CI4的API

CI4和VUE前端代码,可以看我在https://www.cnblogs.com/tianpan2019写的前2篇运行CI4能正常打开 使用npm run dev 也可以正常打开VUE 根据https://www.cnblogs.com/tianpan2019前1篇把根目录设置成CI4的publi目录 把伪静态内容也写上,内容如下:location / { if (!-e $reques…

2024年1000个计算机毕业设计项目源码(源码+论文【万字】)

【计算机毕设项目】2025级100个热门项目推荐 (前后端Web项目) 以下项目选题适合计算机专业大部分专业,技术栈主要为:Java语言,SpringBoot+Vue框架,MySQL数据库以下项目选题适合计算机专业大部分专业,技术栈主要为:Java语言,SpringBoot+Vue框架,MySQL数据库 ①后台免费获…

035.CI4框架CodeIgniter,安装前端VUE并执行

安装node22.5 选择路径 安装完成 装好后使用cmd查看node -v和 npm -v,看一下就知道有没有装好了 nodejs的安装目录,需要完全授权才可以,不然后面会报错 在网站的根目录,打开Powershell 显示权限不足的错误 管理员模式打开系统的Powershell 输入set-ExecutionPolicy RemoteS…

7月编程心得

7 月份非常忙碌,想系统性的写一篇文章,好几次不知道如何下手,后来想想还不如顺其自然,写一点自己的学习心得体会。 这篇文章,聊聊 7月份笔者的编程心得 ,希望对大家有所帮助。 1 IntelliJ IDEA 社区版 工欲善其事,必先利其器。 笔者的 Mac 电脑安装了 IntelliJ IDEA Ult…

三分钟对可视化表单设计器开源优点做简单介绍

为了帮助大家了解可视化表单设计器开源的多个优势特点,本文将为大家做一个系统介绍。想要实现流程化办公,需要了解低代码技术平台、可视化表单设计器开源在现代化办公中的作用和价值。为了帮助大家了解可视化表单设计器开源的多个优势特点,本文将为大家做一个系统介绍。 要了…

校园集市小程序开发-系统架构与Django后端

引子: 烂尾就烂尾吧,大不了以后自己创业。唉,也算给自己一个警戒。E-R模型接口设计数据模型设计 基本模型放在models.py中 class School(models.Model):id = models.AutoField(primary_key=True)name = models.CharField(max_length=100, verbose_name=学校名称) # 学校校区 …