如何查找当前打开的MS Office文档的名称?

时间:2010-02-06 06:34:22

标签: visual-studio-2005 ms-office c#-2.0

我想查找当前在我的操作系统上打开的office文档的名称(任何类似exel,word,access ...等)。这一切都是通过我的C#代码完成的。

如果有人对此有任何想法,请分享。

我为此创建了共享加载项,并且还记录了该文档的开放,关闭时间以及用户在该文档上花费的时间也被记录并在数据库中进行了输入但只输入并输入了文件名进入数据库。

更新: 我有一个用C#.net开发的基于桌面的应用程序。 我想对我的应用程序做一些事情,这样当我们将这个应用程序安装到客户端系统上并且客户端打开他系统上的任何办公文档时,会在我的数据库中进行背景记录,即当他打开特定文件时,当他关闭时和多少他花在这个文件上的时间以及这个文件在空闲状态下打开的时间(没有工作)和该文件的名称。 这是我的要求。

2 个答案:

答案 0 :(得分:0)

您描述的应用程序听起来有点像与系统安全性相矛盾。该方案实际上类似于在背景中工作的malware,并且在没有用户意识的情况下静默地拦截各种用户的交互等。

无论如何,回到技术解决方案,也许你会根据MS Office在打开/关闭文档时在注册表中留下的曲目来找出一些东西。

MS Office将MRU列表存储在注册表中(有关注册表项的详细信息,请参阅How to clear the Most Recently Used list (MRU) list in Office programs和相关文章。)

因此,您可以定期扫描特定的注册表项,即每分钟扫描一次,然后进行比较(先前与MRU的当前状态),计算一些统计数据等。但这并不理想。

答案 1 :(得分:0)

以下内容改编自:http://pinvoke.net/default.aspx/user32.EnumDesktopWindows

您需要更改EnumWindowsProc过滤条件以满足您的需求。代码查看窗口标题,但如果需要文件路径,可以使用hWnd查找。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
using System.Runtime.InteropServices;

namespace ConsoleApplication5
{
    class Program
    {
    const int MAXTITLE = 255;

    private static ArrayList mTitlesList;

    private delegate bool EnumDelegate(IntPtr hWnd, int lParam);

    [DllImport("user32.dll", EntryPoint="EnumDesktopWindows", ExactSpelling=false, CharSet=CharSet.Auto, SetLastError=true)]
    private static extern bool _EnumDesktopWindows(IntPtr hDesktop, EnumDelegate lpEnumCallbackFunction, IntPtr lParam);

    [DllImport("user32.dll", EntryPoint="GetWindowText", ExactSpelling=false, CharSet=CharSet.Auto, SetLastError=true)]
    private static extern int _GetWindowText(IntPtr hWnd, StringBuilder lpWindowText, int nMaxCount);

    [DllImport("user32.dll", EntryPoint = "GetWindowModuleFileName", ExactSpelling = false, CharSet = CharSet.Auto, SetLastError = true)]
    private static extern int _GetWindowModuleFileName(IntPtr hWnd, StringBuilder lpWindowText, int nMaxCount);

    private static bool EnumWindowsProc(IntPtr hWnd, int lParam)
    {
        string title = GetWindowText(hWnd);

        if (title.Contains("Microsoft Word")   || 
            title.Contains("Microsoft Access") || 
            title.Contains("Microsoft Excel")  ||
            title.Contains("Microsoft Outlook") ||
            title.Contains("Microsoft PowerPoint"))
        {
            mTitlesList.Add(title);
        }

        return true;
    }

    public static string GetWindowText(IntPtr hWnd)
    {
        StringBuilder title = new StringBuilder(MAXTITLE);
        int titleLength = _GetWindowText(hWnd, title, title.Capacity + 1);
        title.Length = titleLength;

        return title.ToString();
    }

    public static string[] GetDesktopWindowsCaptions()
    {
        mTitlesList = new ArrayList();
        EnumDelegate enumfunc = new EnumDelegate(EnumWindowsProc);
        IntPtr hDesktop = IntPtr.Zero; // current desktop
        bool success = _EnumDesktopWindows(hDesktop, enumfunc, IntPtr.Zero);

        if (success)
        {
            string[] titles = new string[mTitlesList.Count];
            mTitlesList.CopyTo(titles);
            return titles;
        }
        else
        {
            int errorCode = Marshal.GetLastWin32Error();
            string errorMessage = String.Format("EnumDesktopWindows failed with code {0}.", errorCode);
            throw new Exception(errorMessage);
        }
    }

    static void Main()
    {
        string[] desktopWindowsCaptions = GetDesktopWindowsCaptions();
        foreach (string caption in desktopWindowsCaptions)
        {
            Console.WriteLine(caption);
        }
    }
}
}