Dan*_*arp 0 c# windows pinvoke winapi
我调用了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;
            }
        }
    }
}
提前致谢!
[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.
但随后你会指示编组人员将参数编组为LPStrANSI字符串.这就是函数总是失败的原因.
正确的p/invoke将是:
[DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
static extern bool CopyFile(string lpExistingFileName, string lpNewFileName,
    bool bFailIfExists);
你绝对不应该p/invoke GetLastError.而是Marshal.GetLastWin32Error出于文档中描述的原因使用.