我调用了Kernel32的复制文件方法:
[DllImport("kernel32.dll",
CharSet = CharSet.Unicode,
CallingConvention = CallingConvention.StdCall,
SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool CopyFile(
[MarshalAs(UnmanagedType.LPStr)] string lpExistingFileName,
[MarshalAs(UnmanagedType.LPStr)] string lpNewFileName,
[MarshalAs(UnmanagedType.Bool)] bool bFailIfExists);
[DllImport("kernel32.dll")]
public static extern uint GetLastError();
然而,当我调用它时,它从GetLastError()返回2,这意味着找不到文件。 路径肯定存在。
string newfile = Environment.CurrentDirectory + "\\temp" + Path.GetExtension(file);
uint i;
if (!CopyFile(file, newfile, true)) i = GetLastError();
我尝试使用此解决方案绕过LongPath异常。但即使使用普通文件,它似乎也无法正常工作。任何帮助将不胜感激。
这里是Form1的完整代码:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using Shell32;
using System.Xml;
using System.Diagnostics;
using word = Microsoft.Office.Interop.Word;
using System.Runtime.InteropServices;
namespace DocumentCrawler
{
public partial class Form1 : Form
{
[DllImport("kernel32.dll",
CharSet = CharSet.Unicode,
CallingConvention = CallingConvention.StdCall,
SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool CopyFile(
[MarshalAs(UnmanagedType.LPStr)] string lpExistingFileName,
[MarshalAs(UnmanagedType.LPStr)] string lpNewFileName,
[MarshalAs(UnmanagedType.Bool)] bool bFailIfExists);
[DllImport("kernel32.dll")]
public static extern uint GetLastError();
public Form1()
{
InitializeComponent();
}
private void btnSearch_Click(object sender, EventArgs e)
{
progressBar.Style = ProgressBarStyle.Marquee;
lbProgress.Text = "Finding Word Documents";
btnSearch.Enabled = false;
lvResults.Clear();
SearchDirectory(tbDirectory.Text, tbField.Text);
btnSearch.Enabled = true;
}
void SearchDirectory(string path, string searchPattern)
{
List<string> docs = new List<string>();
foreach (string d in Directory.GetDirectories(path))
{
SearchDirectory(path + "\\" + d.Remove(0, d.LastIndexOf('\\') + 1), searchPattern);
}
foreach (string f in Directory.GetFiles(path))
{
if (Path.GetExtension(f) == ".docx" || Path.GetExtension(f) == ".doc")
{
docs.Add(f);
}
}
progressBar.Value = 0;
lbProgress.Text = "Processing Word Documents 0%";
progressBar.Maximum = docs.Count;
progressBar.Style = ProgressBarStyle.Blocks;
foreach (string f in docs)
{
string txt = TextFromDocument(f);
if (txt.Contains(searchPattern))
{
lvResults.Items.Add(f);
}
progressBar.Value++;
lbProgress.Text = "Processing Word Documents " + ((int)((float)progressBar.Value / (float)progressBar.Maximum * 100)) + "%";
}
}
string TextFromDocument(string file)
{
string newfile = Environment.CurrentDirectory + "\\temp" + Path.GetExtension(file);
uint i;
if (!CopyFile(file, newfile, true)) i = GetLastError();
object nullobj = System.Reflection.Missing.Value;
word.Application wordApp = new word.Application();
word.Document doc = wordApp.Documents.Open(newfile, false);
doc.ActiveWindow.Selection.WholeStory();
doc.ActiveWindow.Selection.Copy();
string text = doc.Content.Text;
doc.Close(ref nullobj, ref nullobj, ref nullobj);
wordApp.Quit(ref nullobj, ref nullobj, ref nullobj);
File.Delete(newfile);
return text;
}
private void lvResults_DoubleClick(object sender, EventArgs e)
{
Process.Start(lvResults.SelectedItems[0].Text);
lvResults.SelectedItems[0].ForeColor = Color.Purple;
}
private void btnBrowse_Click(object sender, EventArgs e)
{
FolderBrowserDialog fd = new FolderBrowserDialog();
if (fd.ShowDialog() == DialogResult.OK)
{
tbDirectory.Text = fd.SelectedPath;
btnSearch.Enabled = true;
}
}
}
}
提前致谢!
答案 0 :(得分:5)
[DllImport("kernel32.dll",
CharSet = CharSet.Unicode,
CallingConvention = CallingConvention.StdCall,
SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool CopyFile(
[MarshalAs(UnmanagedType.LPStr)] string lpExistingFileName,
[MarshalAs(UnmanagedType.LPStr)] string lpNewFileName,
[MarshalAs(UnmanagedType.Bool)] bool bFailIfExists);
在DllImport
声明中,您选择CharSet.Unicode
字符集。这意味着p / invoke函数将绑定到CopyFileW
。
然后你随后指示编组人员将参数编组为LPStr
,ANSI字符串。这就是函数总是失败的原因。
正确的p / invoke将是:
[DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
static extern bool CopyFile(string lpExistingFileName, string lpNewFileName,
bool bFailIfExists);
你绝对不应该调用GetLastError
。相反,请使用Marshal.GetLastWin32Error
中描述的原因documentation。{/ p>