使用File.CopyTo方法时文件被其他进程占用的问题求助
PDF预览后复制提示文件被进程占用的解决方法
这是我的Windows Form项目代码,用于在应用内预览PDF后,通过下拉框选择目标文件夹(代码中用“house”指代)复制文件,简化公司文件整理流程。目前列表框能正常加载所有PDF,axAcroPDF组件预览也正常,但点击发送按钮执行File.CopyTo时,提示文件被其他进程占用。
public partial class Form1 : Form { public Form1() { InitializeComponent(); } string selectedPDF = ""; string selectedHouse = ""; DirectoryInfo currentPDF; private void button1_Click(object sender, EventArgs e) { openFileDialog1.Filter = "PDF Files(*.pdf) |*.pdf;"; openFileDialog1.ShowDialog(); if(openFileDialog1.FileName != null) { axAcroPDF1.LoadFile(openFileDialog1.FileName); } } private void refreshBTN_Click(object sender, EventArgs e) { DirectoryInfo dinfo = new DirectoryInfo(@"C:\Users\bkamide\Desktop\ExamplePDFS"); FileInfo[] smFiles = dinfo.GetFiles("*.pdf"); foreach (FileInfo fi in smFiles) { pdfList.Items.Add(Path.GetFileName(fi.Name)); } } private void pdfList_SelectedIndexChanged(object sender, EventArgs e) { string firstSelectedItem = pdfList.SelectedItem.ToString(); selectedPDF = firstSelectedItem; DirectoryInfo dinfo = new DirectoryInfo(@"C:\Users\bkamide\Desktop\ExamplePDFS\" + firstSelectedItem); currentPDF = dinfo; } private void btnSend_Click(object sender, EventArgs e) { openFileDialog1.Reset(); axAcroPDF1.EndInit(); var sourceFile = new FileInfo(currentPDF.FullName); var dest = Path.Combine(@"C:\Users\bkamide\Desktop\ExamplePDFS\", selectedHouse, sourceFile.FullName); sourceFile.CopyTo(dest, true); } private void cbHouse_SelectedIndex(object sender, EventArgs e) { selectedHouse = cbHouse.SelectedIndex.ToString(); } }
我已尝试:
- 在发送方法中重置
openFileDialog - 调用
axAcroPDF1.EndInit()(不确定用法是否正确) - 重启电脑
- 尝试使用
using语句但不知如何在当前代码中实现
仍未解决问题。
问题根源
axAcroPDF组件加载PDF后会持续占用文件句柄,导致无法直接复制- 代码存在逻辑错误:
pdfList_SelectedIndexChanged中错误地将文件路径实例化为DirectoryInfo,应该用FileInfo- 下拉框事件名称错误(应为
SelectedIndexChanged),且直接存储索引字符串不符合文件夹路径逻辑 - 复制路径拼接错误,
sourceFile.FullName是完整路径,直接拼接会导致目标路径层级混乱
修正后的代码及解决步骤
核心是先释放axAcroPDF对文件的占用,再修正逻辑错误:
public partial class Form1 : Form { public Form1() { InitializeComponent(); } string selectedPDF = ""; string selectedHouseFolder = ""; FileInfo currentPDFInfo; // 修正为FileInfo类型 private void button1_Click(object sender, EventArgs e) { openFileDialog1.Filter = "PDF Files(*.pdf)|*.pdf"; if (openFileDialog1.ShowDialog() == DialogResult.OK) { axAcroPDF1.LoadFile(openFileDialog1.FileName); currentPDFInfo = new FileInfo(openFileDialog1.FileName); selectedPDF = Path.GetFileName(openFileDialog1.FileName); // 同步列表框选中项(可选) if (pdfList.Items.Contains(selectedPDF)) { pdfList.SelectedItem = selectedPDF; } } } private void refreshBTN_Click(object sender, EventArgs e) { pdfList.Items.Clear(); // 清空避免重复加载 DirectoryInfo dinfo = new DirectoryInfo(@"C:\Users\bkamide\Desktop\ExamplePDFS"); FileInfo[] smFiles = dinfo.GetFiles("*.pdf"); foreach (FileInfo fi in smFiles) { pdfList.Items.Add(Path.GetFileName(fi.Name)); } } private void pdfList_SelectedIndexChanged(object sender, EventArgs e) { if (pdfList.SelectedItem == null) return; string selectedFileName = pdfList.SelectedItem.ToString(); selectedPDF = selectedFileName; currentPDFInfo = new FileInfo(Path.Combine(@"C:\Users\bkamide\Desktop\ExamplePDFS", selectedFileName)); axAcroPDF1.LoadFile(currentPDFInfo.FullName); } private void btnSend_Click(object sender, EventArgs e) { if (currentPDFInfo == null || string.IsNullOrEmpty(selectedHouseFolder)) { MessageBox.Show("请选择要复制的PDF和目标文件夹"); return; } // 核心:清空预览组件,释放文件占用 axAcroPDF1.src = ""; // 拼接正确的目标路径:目标文件夹 + 文件名 string destPath = Path.Combine(@"C:\Users\bkamide\Desktop\ExamplePDFS", selectedHouseFolder, currentPDFInfo.Name); try { currentPDFInfo.CopyTo(destPath, true); MessageBox.Show("文件复制成功"); } catch (Exception ex) { MessageBox.Show($"复制失败:{ex.Message}"); } } // 修正事件名称为SelectedIndexChanged private void cbHouse_SelectedIndexChanged(object sender, EventArgs e) { if (cbHouse.SelectedItem != null) { // 存储选中的文件夹名称而非索引 selectedHouseFolder = cbHouse.SelectedItem.ToString(); } } }
关键说明
axAcroPDF1.src = ""会强制组件释放当前加载的文件,这是解决进程占用的核心操作- 若上述方法仍不生效,可以尝试销毁并重新创建
axAcroPDF组件,确保完全释放文件句柄 - 修正了
currentPDF的类型错误,文件必须用FileInfo实例化 - 下拉框事件修正为标准的
SelectedIndexChanged,并存储实际文件夹名称,避免路径拼接错误
内容的提问来源于stack exchange,提问作者Benjamin Kamide
相关产品推荐
相关产品推荐

