C#Winform程序读取FireFox的Cookie(S...

C#Winform程序读取FireFox的Cookie(Sqlite数据库)http://it.chinawin.net/application/article-ed09.html
首先,介绍一下关于Firefox的配置和Cookie文件:Windows(XP,Server 2003/2008,Vista)下Firefox跟用户相关的配置文件,一般保存在[SystemDisk]:\Documents and Settings\[UserAccountName]\Application Data\Mozilla\Firefox\Profiles\[XXXXXX]文件夹下,[XXXXXX]是一个包含随机字符的字符串,所有可能出现的[XXXXXX]文件夹,均在它们父目录的profiles.ini文件中有记录,[XXXXXX]文件夹下有2个比较重要的文件:
・ prefs.js - 保存了Firefox的当前主页、默认搜索引擎、插件设置情况等配置
・ cookies.sqlite - 保存了所有Firefox当前使用的Cookie值
其他文件诸如:bookmarks.html,blocklist.xml,extensions.ini,search.sqlite等,命名都很直白,因此可以顾名思义知道它们的用途。因为我的项目中没有用到,故本文不做详细描述。特别提到,.sqlite文件是一种开源的轻量级文件数据库,想要了解Sqlite数据库的更多资源,请参考它官方网站:http://www.sqlite.org/。
接下来,就需要在Winform程序里面使用C#代码连接Firefox自带的Sqlite3.dll,并且读取Firefox的cookie文件数据库cookie.sqlite了。这个过程中,有3个主要的问题需要解决:
1. 调用sqlite3.dll中的方法,查询Firefox的cookie.sqlite文件
2. 得到Firefox保存Profile的目录
3. 得到Firefox在当前Windows下的安装情况和安装目录
1需要用到DllImport,.Net程序动态加载Dll的方法,以及调用Sqlite本身的API。2,3相对比较简单,只需要读取注册表某些键值,做出相应的判断就可以了。接下来,就主要介绍一下DllImport,动态加载Dll和Sqlite Wrapper。
DllImport
DllImport是.Net中System.Runtime.InteropServices命名空间下的一个Attribute,即DllImportAttribute,它的主要作用是给 CLR 指示哪个 DLL 导出使用者想要调用的函数。相关 DLL 的名称被作为一个构造函数参数传递给 DllImportAttribute。如果您无法肯定哪个 DLL 定义了您要使用的 Windows API 函数,Platform SDK 文档将为您提供最好的帮助资源。在 Windows API 函数主题文字临近结尾的位置,SDK 文档指定了 C 应用程序要使用该函数必须链接的 .lib 文件。在几乎所有的情况下,该 .lib 文件具有与定义该函数的系统 DLL 文件相同的名称。
百度知道的介绍:http://zhidao.baidu.com/question/59216438.html
MSDN上的介绍:http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.dllimportattribute.aspx
并且,网上已经有达人写了关于C#使用Sqlite数据库的Wrapper功能库,可以从这里下载到源代码和Dll:http://www.codeproject.com/KB/database/cs_sqlitewrapper.aspx
其中一个包装过的Sqlite API声明:
[DllImport("sqlite3")]
private static extern int sqlite3_open(IntPtr fileName, out IntPtr database);
DllImportAttribute默认使用相对路径查询需要Import的Dll,它的查找顺序是:首先会从程序启动目录开始查找相应名称的DLL,如果未找到,则会搜索System目录(Windows XP/2003/Vista/2008为Windows\System32),然后会逐一尝试系统环境变量Path定义的路径。而且DllImportAttribute仅仅支持Const形式的初始化声明,因此由于客户机器上,Firefox安装的路径并不确定,所以在这个项目中就不能使用DllImport的方法来引用Sqlite3.dll,因此并不能直接使用SqliteWrapper。而需要额外配合动态加载非托管Dll技术。
动态加载Dll
仍然是使用DllImportAttribute和Windows API,我们可以构造动态加载非托管Dll功能类DllInvoke:
public class DllInvoke private IntPtr hLib; [DllImport("kernel32.dll")]
public extern static bool FreeLibrary(IntPtr lib);
[DllImport("kernel32.dll")]
public extern static IntPtr LoadLibrary(String path);
[DllImport("kernel32.dll")]
public extern static IntPtr GetProcAddress(IntPtr lib, String funcName);
public DllInvoke(String DllFile) hLib = LoadLibrary(DllFile);
}
~DllInvoke() FreeLibrary(hLib);
public Delegate Invoke(String ApiName, Type t) IntPtr api = GetProcAddress(hLib, ApiName);
return (Delegate)Marshal.GetDelegateForFunctionPointer(api, t); }
其中要注意的是,DllInvoke构造函数中的参数为一个String类型的变量,这个变量就是需要引入的Dll文件的路径,但由于很多Dll是有依赖关系的,因此,如果依赖的Dll并未加入,那么"hLib = LoadLibrary(DllFile);”一句就会返回0,从而导致以后调用DLL中API的时候,出现异常。本例中,sqlite3.dll需要依赖的DLL是Firefox安装目录下的mozcrt19.dll,因此,使用Sqlite3.dll中API之前,要先用LoadLibrary函数加载mozcrt19.dll。
使用动态加载DLL技术后,修正后的Sqlite API调用方式:
delegate int invoke_sqlite3_open(IntPtr fileName, out IntPtr database);
private int sqlite3_open(IntPtr fileName, out IntPtr database) invoke_sqlite3_open invoke = (invoke_sqlite3_open)dllSqlLite.Invoke("sqlite3_open", typeof(invoke_sqlite3_open));
return invoke(fileName, out database);
}
下面给出读取注册表获得FireFox安装和Profile路径,以及读取Cookie的所有代码:
static string ffProfilePath;
static string FfProfilePath get if (string.IsNullOrEmpty(ffProfilePath)) RegistryKey key = Registry.CurrentUser.OpenSubKey(@"Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders");
if (key != null) string ffCfgPath = Path.Combine(key.GetValue("AppData").ToString(), "Mozilla\\Firefox\\Profiles");
if (Directory.Exists(ffCfgPath)) ffProfilePath = ffCfgPath; } return ffProfilePath; }
static string[] ffConfigFiles;
static string[] FfConfigFiles get if (ffConfigFiles == null) ffConfigFiles = Directory.GetFiles(FfProfilePath, "prefs.js", SearchOption.AllDirectories); return ffConfigFiles; }
static string[] ffCookieFiles;
static string[] FfCookieFiles get if (ffCookieFiles == null) ffCookieFiles = Directory.GetFiles(FfProfilePath, "cookies.sqlite", SearchOption.AllDirectories); return ffCookieFiles; }
static string ffInstallFolder;
static string FfInstallFolder get if (string.IsNullOrEmpty(ffInstallFolder)) ffInstallFolder = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles), "Mozilla Firefox");
string ffPath = @"SOFTWARE\Mozilla\Mozilla Firefox";
RegistryKey key = Registry.LocalMachine.OpenSubKey(ffPath);
if (key != null) ffPath += @"\" + key.GetValue("CurrentVersion").ToString() + @"\Main";
RegistryKey keyInstall = Registry.LocalMachine.OpenSubKey(ffPath);
if (keyInstall != null) ffInstallFolder = keyInstall.GetValue("Install Directory").ToString(); } return ffInstallFolder; }
读取Cookie代码片段:
if (Directory.Exists(FfInstallFolder)) string dllMoz = Path.Combine(FfInstallFolder, "mozcrt19.dll");
string dllSqlite = Path.Combine(FfInstallFolder, "sqlite3.dll");
if (File.Exists(dllMoz) && File.Exists(dllSqlite)) DllInvoke.LoadLibrary(dllMoz);
if (FfCookieFiles != null) foreach (string ckFile in FfCookieFiles) SqliteWrapper sqlCookie = new SqliteWrapper(dllSqlite, ckFile);
DataTable dt = sqlCookie.ExecuteQuery(string.Format(defaultCulture, "select * from moz_cookies where name='{0}'", MINIMISE_ME_COOKIE_NAME));
if (dt.Rows.Count > 0) cabId = dt.Rows[0]["value"].ToString(); } }
}
Tags: 

延伸阅读

最新评论

发表评论