我正在创建一个C#程序来帮助我测试我开发的网站,但遇到了一些问题。目标是让程序为我的网站存储不同的帐户及其相关的cookie,这样它就可以自动登录进行测试。现在我正在使用Playwright进行浏览器自动化和cookie存储(这些都没有问题(。然而,我的问题似乎源于FileSystemWatcher在我保存cookie后不会启动的事实。
我的目标是用每次添加新帐户时保存的帐户更新我的程序界面。为此,我使用FileSystemWatcher调用一个函数,该函数从文件中重新加载我的所有用户帐户。
我创建FileSystemWatcher的函数如下:
private string filesPath = @"" + Path.GetDirectoryName(Application.ExecutablePath) + "\inc";
private void CreateFileWatcher()
{
FileSystemWatcher fsWatcher = new FileSystemWatcher(filesPath, "accounts.dat");
fsWatcher.NotifyFilter = NotifyFilters.LastWrite;
fsWatcher.Changed += new FileSystemEventHandler((object s, FileSystemEventArgs e) =>
{
// Load accounts
});
fsWatcher.EnableRaisingEvents = true;
}
我想特别看一下";accounts.dat";文件,所以我添加了它作为过滤器,您可以从我的代码中看到。
对于添加新帐户,我的功能如下:
private void CreateAccount() {
Dictionary<Guid, Account> accounts;
Stream stream = new FileStream(fileName, FileMode.Open, FileAccess.Read);
BinaryFormatter bf = new BinaryFormatter();
try
{
accounts = (Dictionary<Guid, Account>)bf.Deserialize(stream);
accounts.Add(account.UUID, account);
}
catch
{
accounts = new Dictionary<Guid, Account>();
accounts.Add(account.UUID, account);
}
stream.Close();
stream = new FileStream(fileName, FileMode.Truncate, FileAccess.Write);
bf.Serialize(stream, accounts);
stream.Close();
// Then I call my login function that logs the account in and saves the cookies
}
我的登录功能是:
public static Task Login(Account account, string url) {
try
{
using var playwright = await Playwright.CreateAsync();
await using var browser = await playwright.Chromium.LaunchAsync(new()
{
Headless = false,
});
await using var context = await browser.NewContextAsync(new()
{
ViewportSize = new ViewportSize() { Height = 450, Width = 500 }
});
// Create page
var page = await context.NewPageAsync();
await page.GotoAsync(url);
// Sign in
await Login(page, account);
// Save auth state
string cookies = await context.StorageStateAsync();
// Write cookies
await WriteCookies(cookies, account);
}
catch (Exception e)
{
// Log to my logfile
}
}
最后,我保存cookie的功能是:
public static async Task WriteCookies(string cookies, Account account) {
// Create list of accounts
Dictionary<Guid, string> sessions;
Stream stream = new FileStream(sessionsFile, FileMode.Open, FileAccess.Read);
BinaryFormatter bf = new BinaryFormatter();
try
{
sessions = (Dictionary<Guid, string>)bf.Deserialize(stream);
sessions.Add(account.UUID, cookies);
}
catch
{
sessions = new Dictionary<Guid, string>();
sessions.Add(account.UUID, cookies);
}
stream.Close();
stream = new FileStream(sessionsFile, FileMode.Truncate, FileAccess.Write);
bf.Serialize(stream, sessions);
stream.Close();
}
正如您从我的代码中看到的,每个会话都通过帐户Guid
与一个用户帐户相关联,因此我稍后可以轻松访问与该帐户相关的正确会话。我认为这个问题源于我的写cookie功能是异步的,所以它放弃了FileSystemWatcher,所以我试图将会话和帐户分开来解决这个问题,但没有成功。我似乎不知道自己做错了什么,但似乎在第一次创建帐户时事件就会触发,然后一旦我写了cookie,它就再也不会触发,直到我手动重新加载表单。我感谢您的帮助。
此外,现在我正在打开该文件以获取现有数据,关闭它,然后以Truncate
模式重新打开它,因为我想每次都清除该文件,所以如果你推荐一种更好的方式将新对象添加到我的列表中,我很乐意听到。
谢谢!
尝试将FileSystemWatcher创建为程序级变量,而不是方法中的局部变量,看看这是否能解决问题。
即将FileSystemWatcher移动到私有本地变量。