如何在紧凑框架中记录操作?
我正在使用紧凑框架开发Windows Mobile项目。
我需要做的一件事就是记录用户执行操作的时间,这可能意味着从按下按钮到使用条形码扫描器的任何操作。 它发生的时间也需要记录。
我的计划是重写所有控件以包含内置的日志记录功能,但这可能不是正确的方式,似乎是一件非常乏味的事情。
有没有更好的办法?
我会和IL Weaving一起去的。 这里是我会推荐的一个库:http://www.sharpcrafters.com/aop.net/msil-injection它的作用是用一个属性标记你的类,你可以拦截所有的函数调用。 在这个拦截过程中,你会放入你的日志逻辑。
我认为这很大程度上取决于“行动”的定义。 我非常希望看到(未记录的) QASetWindowsJournalHook
API是否可以工作。 它可能会抓住你想要的大部分,而不需要很多代码。 在这里可以在Codeproject上找到一个本地的使用示例。
使用WH_JOURNALRECORD
SetWindowsHook也值得一看。 是的,我知道它是“不受支持的”,但它工作得很好,它不可能从你已经部署的设备中删除(加上它已经在操作系统中至少10年)。
一些P / Invoke声明,都是从pwinuser.h派生的,对它们来说都是这样的:
[StructLayout(LayoutKind.Sequential)]
public struct JournalHookStruct
{
public int message { get; set; }
public int paramL { get; set; }
public int paramH { get; set; }
public int time { get; set; }
public IntPtr hwnd { get; set; }
}
internal enum HookType
{
JournalRecord = 0,
JournalPlayback = 1,
KeyboardLowLevel = 20
}
internal enum HookCode
{
Action = 0,
GetNext = 1,
Skip = 2,
NoRemove = 3,
SystemModalOn = 4,
SystemModalOff = 5
}
public const int HC_ACTION = 0;
public const int LLKHF_EXTENDED = 0x1;
public const int LLKHF_INJECTED = 0x10;
public const int LLKHF_ALTDOWN = 0x20;
public const int LLKHF_UP = 0x80;
public const int VK_TAB = 0x9;
public const int VK_CONTROL = 0x11;
public const int VK_ESCAPE = 0x1B;
public const int VK_DELETE = 0x2E;
[DllImport("coredll.dll", SetLastError = true)]
public static extern IntPtr SetWindowsHookEx(HookType idHook, HookProc lpfn, IntPtr hMod, int
[DllImport("coredll.dll", SetLastError = true)]
public static extern bool UnhookWindowsHookEx(IntPtr hhk);
[DllImport("coredll.dll", SetLastError = true)]
public static extern int CallNextHookEx(IntPtr hhk, HookCode nCode, IntPtr wParam, IntPtr
[DllImport("coredll.dll", SetLastError = true)]
public static extern IntPtr QASetWindowsJournalHook(HookType nFilterType, HookProc pfnFilterProc, ref JournalHookStruct pfnEventMsg);
将这些消息写入日志文件不能解决您的问题吗?
#if PocketPC
private static string _appPath = Environment.GetFolderPath(Environment.SpecialFolder.Personal);
#else
private static string _appPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData), Application.CompanyName);
#endif
public const int KILOBYTE = 1024;
public static string ErrorFile { get { return _appPath + @"error.log"; } }
public static void Log(string message)
{
if (String.IsNullOrEmpty(message)) return;
using (FileStream stream = File.Open(ErrorFile, FileMode.Append, FileAccess.Write))
{
using (StreamWriter sw = new StreamWriter(stream, Encoding.UTF8, KILOBYTE))
{
sw.WriteLine(string.Format("{0:MM/dd/yyyy HH:mm:ss} - {1}", DateTime.Now, message));
}
}
}
如果你正在进行线程化并且多个例程试图同时写入,你可能会遇到问题。 在这种情况下,您可以添加额外的逻辑来锁定正在使用的例程。
无论如何,我就是这么做的。
#if
区域,你可以看到这也是我的Windows PC应用程序使用。
上一篇: How to log actions in compact framework?
下一篇: Convert byte array to structure in the Compact Framework