Skip to content

FBro浏览器独立缓存配置

概述

FBro浏览器支持为每个浏览器实例设置独立的缓存目录,这允许不同的浏览器实例拥有独立的缓存数据、Cookie、本地存储等。通过独立缓存配置,可以实现多账户隔离、数据隔离和更灵活的缓存管理。

核心概念

缓存隔离的重要性

  • 多账户支持:不同浏览器实例可以同时登录不同账户
  • 数据隔离:防止不同任务之间的数据污染
  • Cookie隔离:每个实例拥有独立的Cookie存储
  • 会话管理:独立的会话状态管理

🔧 两种配置层级

1. 框架级配置 - FBroSharpInitSet

全局初始化配置,整个应用程序只设置一次:

csharp
public struct FBroSharpInitSet
{
    public string cache_path;           // 框架缓存目录
    public string user_data_path;       // 框架用户数据目录  
    public string root_cache_path;      // 框架根缓存目录
    // ... 其他全局配置
}

2. 实例级配置 - FBroSharpRequestContextSet

单个浏览器实例配置,每个浏览器实例可以不同:

csharp
public struct FBroSharpRequestContextSet
{
    public string cache_path;                           // 实例缓存路径
    public bool persist_session_cookies;               // 是否持久化会话Cookie
    public bool persist_user_preferences;              // 是否持久化用户首选项  
    public bool ignore_certificate_errors;             // 是否忽略证书错误
    public string accept_language_list;                // 接受语言列表
    public string cookieable_schemes_list;             // 可Cookie的协议列表
    public int cookieable_schemes_exclude_defaults;    // 是否排除默认可Cookie协议
}

关键组件

  • FBroSharpInitSet:框架全局初始化配置
  • FBroSharpRequestContextSet:浏览器实例配置类
  • FBroSharpRequestContext:请求上下文实例
  • FBroSharpWindowsInfo:窗口信息配置

框架初始化配置

🔍 框架级三路径配置详解

FBro框架在应用程序启动时需要配置三个关键的缓存路径,这些路径必须遵循特定的层次关系:

csharp
static void Main()
{
    FBroSharpInitSet set = new FBroSharpInitSet
    {
        //设置缓存目录
        cache_path = Directory.GetCurrentDirectory() + "\\Cache\\CachePath\\",

        //设置用户目录
        user_data_path = Directory.GetCurrentDirectory() + "\\Cache\\UserPath\\",

        //设置根缓存目录,必须是上面缓存目录的父目录,否则采用独立缓存可能会失效
        root_cache_path = Directory.GetCurrentDirectory() + "\\Cache\\",

        //启用事件消息循环
        multi_threaded_message_loop = true,

        //设置执行子进程
        browser_subprocess_path = Directory.GetCurrentDirectory() + "\\FBroSubprocess.exe",

        //本地化语言
        locale = "zh-CN",

        //日志模式
        log_severity = FBroSharpLogSeverity.ERROR
    };

    //创建初始化事件
    InitEvent init_event = new InitEvent();

    //执行框架初始化
    if (!FBroSharpInitControl.InitPro(set, init_event))
        return;

    // ... 应用程序主逻辑
}

🏗️ 框架目录结构层次关系

当前应用程序目录/
└── Cache/                          ← root_cache_path (框架根缓存目录)
    ├── CachePath/                  ← cache_path (框架缓存目录)
    │   ├── HTTP缓存文件
    │   ├── 图片缓存
    │   ├── JavaScript文件缓存
    │   ├── CSS样式缓存
    │   └── 其他临时缓存数据
    └── UserPath/                   ← user_data_path (框架用户数据目录)
        ├── Cookies                 (Cookie存储)
        ├── LocalStorage           (本地存储)
        ├── SessionStorage         (会话存储)
        ├── Preferences            (用户首选项)
        ├── History                (浏览历史)
        ├── Bookmarks             (书签)
        └── Extensions            (扩展程序数据)

⚠️ 重要:这是框架级配置,整个应用程序只需要设置一次,为所有浏览器实例提供基础缓存结构。

🎯 各目录功能详解

路径配置功能作用数据类型重要性清理策略
root_cache_path所有缓存数据的统一根目录容器目录⭐⭐⭐整体管理
cache_path存储临时缓存数据页面缓存、资源文件⭐⭐可定期清理
user_data_path存储用户持久数据Cookie、设置、历史⭐⭐⭐谨慎清理

1. root_cache_path - 根缓存目录

csharp
// 作为所有缓存目录的父容器
root_cache_path = Directory.GetCurrentDirectory() + "\\Cache\\";
  • 🏠 统一管理:作为所有缓存相关目录的父目录
  • 🔒 隔离保证:必须包含下面两个子目录才能确保独立缓存功能正常
  • 📁 批量操作:便于整体缓存清理和备份操作

2. cache_path - 浏览器缓存目录

csharp
// 存储可清理的临时缓存数据
cache_path = Directory.GetCurrentDirectory() + "\\Cache\\CachePath\\";
  • 🚀 性能优化:存储页面缓存、图片缓存、JavaScript文件等
  • 🗑️ 可安全清理:这些数据可以被清理而不影响用户设置
  • 📈 提升浏览体验:减少重复下载,提高页面加载速度

3. user_data_path - 用户数据目录

csharp
// 存储需要持久保存的用户数据
user_data_path = Directory.GetCurrentDirectory() + "\\Cache\\UserPath\\";
  • 👤 用户个性化:存储Cookie、本地存储、用户首选项等
  • 💾 持久保存:这些数据通常需要长期保留
  • 🔐 会话状态:包含登录状态和用户个人信息

⚠️ 关键设计原则

1. 严格的层次关系要求

csharp
// ✅ 正确的层次关系
root_cache_path = "C:\\App\\Cache\\"
cache_path = "C:\\App\\Cache\\CachePath\\"       // cache_path 必须是 root_cache_path 的子目录
user_data_path = "C:\\App\\Cache\\UserPath\\"   // user_data_path 必须是 root_cache_path 的子目录

// ❌ 错误的配置 - 会导致独立缓存失效
root_cache_path = "C:\\App\\Cache\\"
cache_path = "D:\\OtherDrive\\Cache\\"           // 不是root_cache_path的子目录
user_data_path = "C:\\Users\\Data\\"             // 不是root_cache_path的子目录

2. 独立缓存的前提条件

  • 每个浏览器实例必须有自己独立的三路径配置
  • 不同实例的路径不能重叠或共享
  • 必须确保目录的读写权限

3. 数据分离设计思想

  • 临时数据 vs 持久数据:便于选择性清理
  • 缓存数据 vs 用户数据:不同的备份和恢复策略
  • 性能数据 vs 个人数据:不同的安全级别要求

浏览器实例配置

💡 独立缓存实例配置

在框架初始化完成后,每个浏览器实例可以配置自己的独立缓存:

csharp
/// <summary>
/// 创建独立缓存的浏览器实例配置
/// </summary>
/// <param name="instanceName">实例名称(用于区分不同浏览器实例)</param>
/// <returns>配置好的FBroSharpRequestContextSet</returns>
public static FBroSharpRequestContextSet CreateInstanceCacheConfig(string instanceName)
{
    // 为每个实例创建独立的缓存目录
    string baseDirectory = Directory.GetCurrentDirectory();
    string instanceCachePath = Path.Combine(baseDirectory, "BrowserCaches", instanceName);
    
    // 确保目录存在
    if (!Directory.Exists(instanceCachePath))
    {
        Directory.CreateDirectory(instanceCachePath);
        Console.WriteLine($"创建实例缓存目录: {instanceCachePath}");
    }
    
    // 浏览器实例配置(只有cache_path字段)
    var contextSet = new FBroSharpRequestContextSet
    {
        cache_path = instanceCachePath,                    // 实例独立缓存路径
        persist_session_cookies = true,                   // 持久化会话Cookie
        persist_user_preferences = true,                  // 持久化用户首选项
        ignore_certificate_errors = false,               // 不忽略证书错误
        accept_language_list = "zh-CN,zh,en",            // 接受语言列表
        cookieable_schemes_list = "",                     // 默认Cookie协议
        cookieable_schemes_exclude_defaults = 0          // 包含默认协议
    };
    
    Console.WriteLine($"=== 实例缓存配置 [{instanceName}] ===");
    Console.WriteLine($"缓存路径: {contextSet.cache_path}");
    Console.WriteLine($"持久Cookie: {contextSet.persist_session_cookies}");
    Console.WriteLine($"持久首选项: {contextSet.persist_user_preferences}");
    Console.WriteLine("=======================================");
    
    return contextSet;
}

/// <summary>
/// 多实例独立缓存结构示例
/// </summary>
public static void ConfigureMultipleInstances()
{
    // 为不同账户创建独立缓存配置
    var userAConfig = CreateInstanceCacheConfig("UserA");
    var userBConfig = CreateInstanceCacheConfig("UserB");
    var userCConfig = CreateInstanceCacheConfig("UserC");
    
    // 结果目录结构:
    // BrowserCaches/
    // ├── UserA/          ← UserA的独立缓存
    // ├── UserB/          ← UserB的独立缓存
    // └── UserC/          ← UserC的独立缓存
}

🏗️ 完整的缓存架构

应用程序目录/
├── Cache/                          ← 框架级缓存 (FBroSharpInitSet)
│   ├── CachePath/                  
│   └── UserPath/                   
└── BrowserCaches/                  ← 实例级缓存 (FBroSharpRequestContextSet)
    ├── UserA/                      ← 浏览器实例A的独立缓存
    ├── UserB/                      ← 浏览器实例B的独立缓存
    ├── UserC/                      ← 浏览器实例C的独立缓存
    └── TempTask/                   ← 临时任务的独立缓存

🔧 路径验证工具

csharp
/// <summary>
/// 验证缓存路径配置是否正确
/// </summary>
/// <param name="contextSet">缓存配置</param>
/// <returns>验证结果</returns>
public static CachePathValidationResult ValidateCachePaths(FBroSharpRequestContextSet contextSet)
{
    var result = new CachePathValidationResult();
    
    // 检查路径是否为空
    if (string.IsNullOrEmpty(contextSet.root_cache_path))
        result.AddError("root_cache_path 不能为空");
    if (string.IsNullOrEmpty(contextSet.cache_path))
        result.AddError("cache_path 不能为空");
    if (string.IsNullOrEmpty(contextSet.user_data_path))
        result.AddError("user_data_path 不能为空");
    
    if (result.HasErrors) return result;
    
    // 标准化路径(处理路径分隔符)
    string rootPath = Path.GetFullPath(contextSet.root_cache_path.TrimEnd('\\'));
    string cachePath = Path.GetFullPath(contextSet.cache_path.TrimEnd('\\'));
    string userPath = Path.GetFullPath(contextSet.user_data_path.TrimEnd('\\'));
    
    // 验证层次关系
    if (!cachePath.StartsWith(rootPath + "\\"))
    {
        result.AddError($"cache_path 必须是 root_cache_path 的子目录\n  Root: {rootPath}\n  Cache: {cachePath}");
    }
    
    if (!userPath.StartsWith(rootPath + "\\"))
    {
        result.AddError($"user_data_path 必须是 root_cache_path 的子目录\n  Root: {rootPath}\n  User: {userPath}");
    }
    
    // 检查路径冲突
    if (cachePath.Equals(userPath, StringComparison.OrdinalIgnoreCase))
    {
        result.AddError("cache_path 和 user_data_path 不能指向同一个目录");
    }
    
    // 检查路径长度(Windows限制)
    if (cachePath.Length > 240) result.AddWarning("cache_path 路径过长,可能在某些系统上出现问题");
    if (userPath.Length > 240) result.AddWarning("user_data_path 路径过长,可能在某些系统上出现问题");
    
    // 权限检查
    try
    {
        Directory.CreateDirectory(rootPath);
        result.AddInfo($"根目录创建/验证成功: {rootPath}");
    }
    catch (Exception ex)
    {
        result.AddError($"无法创建根目录: {ex.Message}");
    }
    
    return result;
}

public class CachePathValidationResult
{
    public List<string> Errors { get; } = new List<string>();
    public List<string> Warnings { get; } = new List<string>();
    public List<string> Info { get; } = new List<string>();
    
    public bool IsValid => Errors.Count == 0;
    public bool HasErrors => Errors.Count > 0;
    public bool HasWarnings => Warnings.Count > 0;
    
    public void AddError(string error) => Errors.Add(error);
    public void AddWarning(string warning) => Warnings.Add(warning);
    public void AddInfo(string info) => Info.Add(info);
    
    public void PrintResults()
    {
        if (HasErrors)
        {
            Console.WriteLine("❌ 配置错误:");
            Errors.ForEach(e => Console.WriteLine($"  • {e}"));
        }
        
        if (HasWarnings)
        {
            Console.WriteLine("⚠️ 配置警告:");
            Warnings.ForEach(w => Console.WriteLine($"  • {w}"));
        }
        
        if (Info.Count > 0)
        {
            Console.WriteLine("ℹ️ 配置信息:");
            Info.ForEach(i => Console.WriteLine($"  • {i}"));
        }
        
        Console.WriteLine($"✅ 配置验证结果: {(IsValid ? "通过" : "失败")}");
    }
}

## 基础配置

### 1. 简单独立缓存配置

```csharp
/// <summary>
/// 创建具有独立缓存的浏览器实例
/// </summary>
/// <param name="url">初始URL</param>
/// <param name="cacheName">缓存目录名称</param>
/// <param name="parentHandle">父窗口句柄</param>
/// <param name="width">浏览器宽度</param>
/// <param name="height">浏览器高度</param>
/// <returns>浏览器实例</returns>
public IFBroSharpBrowser CreateBrowserWithCache(string url, string cacheName, IntPtr parentHandle, int width, int height)
{
    try
    {
        // 创建浏览器事件处理器
        var browserEvent = new BrowserEvent();
        
        // 配置窗口信息
        var windowInfo = new FBroSharpWindowsInfo
        {
            parent_window = parentHandle,
            width = width,
            height = height,
            x = 0,
            y = 0
        };

        // 使用标准三路径配置创建独立缓存
        var contextSet = CreateStandardCacheConfig(cacheName);

        // 创建请求上下文
        var requestContext = (FBroSharpRequestContext)FBroSharpRequestContext.CreateContext(contextSet);
        
        Console.WriteLine($"缓存目录: {requestContext.GetCachePath()}");

        // 创建浏览器实例
        var browser = FBroSharpControl.CreatBrowser(url, windowInfo, default, requestContext, default, browserEvent, default);
        
        Console.WriteLine($"浏览器创建成功,缓存目录: {cacheName}");
        return browser;
    }
    catch (Exception ex)
    {
        Console.WriteLine($"创建独立缓存浏览器失败: {ex.Message}");
        throw;
    }
}

2. 高级缓存配置

csharp
/// <summary>
/// 创建具有完整配置的独立缓存浏览器
/// </summary>
/// <param name="config">浏览器配置</param>
/// <returns>浏览器实例</returns>
public IFBroSharpBrowser CreateAdvancedCacheBrowser(BrowserCacheConfig config)
{
    try
    {
        var browserEvent = new BrowserEvent();
        
        // 配置窗口信息
        var windowInfo = new FBroSharpWindowsInfo
        {
            parent_window = config.ParentHandle,
            width = config.Width,
            height = config.Height,
            x = config.X,
            y = config.Y
        };

        // 使用标准三路径配置,支持完整的缓存结构
        var contextSet = CreateStandardCacheConfig(config.CacheName);
        
        // 验证配置是否正确
        var validationResult = ValidateCachePaths(contextSet);
        if (!validationResult.IsValid)
        {
            validationResult.PrintResults();
            throw new ArgumentException("缓存路径配置验证失败");
        }

        // 创建请求上下文
        var requestContext = (FBroSharpRequestContext)FBroSharpRequestContext.CreateContext(contextSet);
        
        // 记录配置信息
        LogCacheConfiguration(config.CacheName, requestContext);

        // 创建浏览器
        var browser = FBroSharpControl.CreatBrowser(
            config.InitialUrl, 
            windowInfo, 
            default, 
            requestContext, 
            default, 
            browserEvent, 
            default
        );

        return browser;
    }
    catch (Exception ex)
    {
        Console.WriteLine($"创建高级缓存浏览器失败: {ex.Message}");
        throw;
    }
}

/// <summary>
/// 创建缓存目录
/// </summary>
/// <param name="cacheName">缓存名称</param>
/// <returns>完整缓存路径</returns>
private string CreateCacheDirectory(string cacheName)
{
    string basePath = Directory.GetCurrentDirectory();
    string fullCachePath = Path.Combine(basePath, "Cache", cacheName);
    
    // 确保目录存在
    if (!Directory.Exists(fullCachePath))
    {
        Directory.CreateDirectory(fullCachePath);
        Console.WriteLine($"创建缓存目录: {fullCachePath}");
    }
    else
    {
        Console.WriteLine($"使用现有缓存目录: {fullCachePath}");
    }
    
    return fullCachePath;
}

/// <summary>
/// 记录缓存配置信息
/// </summary>
/// <param name="cacheName">缓存名称</param>
/// <param name="requestContext">请求上下文</param>
private void LogCacheConfiguration(string cacheName, FBroSharpRequestContext requestContext)
{
    Console.WriteLine("=== 缓存配置信息 ===");
    Console.WriteLine($"缓存名称: {cacheName}");
    Console.WriteLine($"缓存路径: {requestContext.GetCachePath()}");
    Console.WriteLine($"配置时间: {DateTime.Now:yyyy-MM-dd HH:mm:ss}");
    Console.WriteLine("===================");
}

配置类定义

BrowserCacheConfig 配置类

csharp
/// <summary>
/// 浏览器缓存配置类
/// </summary>
public class BrowserCacheConfig
{
    /// <summary>
    /// 缓存目录名称
    /// </summary>
    public string CacheName { get; set; }

    /// <summary>
    /// 初始URL
    /// </summary>
    public string InitialUrl { get; set; } = "about:blank";

    /// <summary>
    /// 父窗口句柄
    /// </summary>
    public IntPtr ParentHandle { get; set; } = IntPtr.Zero;

    /// <summary>
    /// 浏览器宽度
    /// </summary>
    public int Width { get; set; } = 1024;

    /// <summary>
    /// 浏览器高度
    /// </summary>
    public int Height { get; set; } = 768;

    /// <summary>
    /// X坐标位置
    /// </summary>
    public int X { get; set; } = 0;

    /// <summary>
    /// Y坐标位置
    /// </summary>
    public int Y { get; set; } = 0;

    /// <summary>
    /// 是否自动创建目录
    /// </summary>
    public bool AutoCreateDirectory { get; set; } = true;

    /// <summary>
    /// 自定义缓存根目录
    /// </summary>
    public string CustomCacheRoot { get; set; } = null;

    /// <summary>
    /// 获取完整缓存路径
    /// </summary>
    /// <returns>完整缓存路径</returns>
    public string GetFullCachePath()
    {
        string baseDirectory = CustomCacheRoot ?? Directory.GetCurrentDirectory();
        return Path.Combine(baseDirectory, "Cache", CacheName);
    }
}

缓存管理器

CacheManager 管理类

csharp
/// <summary>
/// 缓存管理器
/// </summary>
public class CacheManager
{
    private readonly Dictionary<string, IFBroSharpBrowser> _browsers = new Dictionary<string, IFBroSharpBrowser>();
    private readonly Dictionary<string, string> _cachePaths = new Dictionary<string, string>();

    /// <summary>
    /// 创建具有独立缓存的浏览器
    /// </summary>
    /// <param name="browserId">浏览器ID</param>
    /// <param name="config">配置信息</param>
    /// <returns>浏览器实例</returns>
    public IFBroSharpBrowser CreateCachedBrowser(string browserId, BrowserCacheConfig config)
    {
        if (_browsers.ContainsKey(browserId))
        {
            Console.WriteLine($"浏览器 {browserId} 已存在,返回现有实例");
            return _browsers[browserId];
        }

        try
        {
            // 设置缓存名称为浏览器ID(如果未指定)
            if (string.IsNullOrEmpty(config.CacheName))
            {
                config.CacheName = browserId;
            }

            var browser = CreateAdvancedCacheBrowser(config);
            
            // 存储浏览器实例和缓存路径
            _browsers[browserId] = browser;
            _cachePaths[browserId] = config.GetFullCachePath();

            Console.WriteLine($"浏览器 {browserId} 创建成功");
            return browser;
        }
        catch (Exception ex)
        {
            Console.WriteLine($"创建浏览器 {browserId} 失败: {ex.Message}");
            throw;
        }
    }

    /// <summary>
    /// 获取浏览器实例
    /// </summary>
    /// <param name="browserId">浏览器ID</param>
    /// <returns>浏览器实例</returns>
    public IFBroSharpBrowser GetBrowser(string browserId)
    {
        return _browsers.TryGetValue(browserId, out var browser) ? browser : null;
    }

    /// <summary>
    /// 获取缓存路径
    /// </summary>
    /// <param name="browserId">浏览器ID</param>
    /// <returns>缓存路径</returns>
    public string GetCachePath(string browserId)
    {
        return _cachePaths.TryGetValue(browserId, out var path) ? path : null;
    }

    /// <summary>
    /// 清理指定浏览器的缓存
    /// </summary>
    /// <param name="browserId">浏览器ID</param>
    /// <returns>是否成功</returns>
    public bool ClearCache(string browserId)
    {
        try
        {
            if (_cachePaths.TryGetValue(browserId, out var cachePath))
            {
                if (Directory.Exists(cachePath))
                {
                    Directory.Delete(cachePath, true);
                    Console.WriteLine($"缓存清理成功: {cachePath}");
                    return true;
                }
            }

            Console.WriteLine($"缓存路径不存在: {browserId}");
            return false;
        }
        catch (Exception ex)
        {
            Console.WriteLine($"清理缓存失败: {ex.Message}");
            return false;
        }
    }

    /// <summary>
    /// 关闭并清理浏览器
    /// </summary>
    /// <param name="browserId">浏览器ID</param>
    /// <param name="clearCache">是否清理缓存</param>
    public void CloseBrowser(string browserId, bool clearCache = false)
    {
        if (_browsers.TryGetValue(browserId, out var browser))
        {
            browser?.Dispose();
            _browsers.Remove(browserId);

            if (clearCache)
            {
                ClearCache(browserId);
            }

            _cachePaths.Remove(browserId);
            Console.WriteLine($"浏览器 {browserId} 已关闭");
        }
    }

    /// <summary>
    /// 获取所有浏览器信息
    /// </summary>
    /// <returns>浏览器信息列表</returns>
    public List<BrowserInfo> GetAllBrowsers()
    {
        var browserInfos = new List<BrowserInfo>();

        foreach (var kvp in _browsers)
        {
            var info = new BrowserInfo
            {
                BrowserId = kvp.Key,
                CachePath = _cachePaths.GetValueOrDefault(kvp.Key),
                IsValid = kvp.Value != null
            };

            browserInfos.Add(info);
        }

        return browserInfos;
    }

    private IFBroSharpBrowser CreateAdvancedCacheBrowser(BrowserCacheConfig config)
    {
        // 这里复用前面定义的方法
        var browserEvent = new BrowserEvent();
        
        var windowInfo = new FBroSharpWindowsInfo
        {
            parent_window = config.ParentHandle,
            width = config.Width,
            height = config.Height,
            x = config.X,
            y = config.Y
        };

        // 使用标准三路径配置
        var contextSet = CreateStandardCacheConfig(config.CacheName);
        
        // 如果指定了自定义根目录,需要重新配置路径
        if (!string.IsNullOrEmpty(config.CustomCacheRoot))
        {
            string instanceCacheRoot = Path.Combine(config.CustomCacheRoot, "Cache", config.CacheName);
            contextSet = new FBroSharpRequestContextSet
            {
                root_cache_path = instanceCacheRoot + "\\",
                cache_path = Path.Combine(instanceCacheRoot, "CachePath") + "\\",
                user_data_path = Path.Combine(instanceCacheRoot, "UserPath") + "\\"
            };
            
            // 确保自定义路径目录存在
            if (config.AutoCreateDirectory)
            {
                Directory.CreateDirectory(contextSet.root_cache_path);
                Directory.CreateDirectory(contextSet.cache_path);
                Directory.CreateDirectory(contextSet.user_data_path);
            }
        }

        var requestContext = (FBroSharpRequestContext)FBroSharpRequestContext.CreateContext(contextSet);
        
        return FBroSharpControl.CreatBrowser(
            config.InitialUrl, 
            windowInfo, 
            default, 
            requestContext, 
            default, 
            browserEvent, 
            default
        );
    }
}

/// <summary>
/// 浏览器信息类
/// </summary>
public class BrowserInfo
{
    public string BrowserId { get; set; }
    public string CachePath { get; set; }
    public bool IsValid { get; set; }
    public DateTime CreatedTime { get; set; } = DateTime.Now;
}

实际应用示例

🎯 创建独立缓存浏览器实例

csharp
// 1. 首先确保框架已初始化(在应用程序启动时完成)
static void Main()
{
    // ... 前面的框架初始化代码 ...
    
    // 2. 为不同任务创建独立缓存的浏览器实例
    CreateMultipleBrowserInstances();
}

static void CreateMultipleBrowserInstances()
{
    // 创建用户A的浏览器实例(独立缓存)
    CreateBrowserWithCache("UserA", "https://www.google.com");
    
    // 创建用户B的浏览器实例(独立缓存)
    CreateBrowserWithCache("UserB", "https://www.bing.com");
    
    // 创建临时任务的浏览器实例(独立缓存)
    CreateBrowserWithCache("TempTask", "https://www.example.com");
}

static void CreateBrowserWithCache(string instanceName, string url)
{
    // 1. 创建实例级缓存配置
    FBroSharpRequestContextSet contextSet = CreateInstanceCacheConfig(instanceName);
    
    // 2. 创建请求上下文
    FBroSharpRequestContext context = FBroSharpRequestContext.CreateContext(contextSet);
    
    // 3. 窗口配置
    FBroSharpWindowsInfo windowsInfo = new FBroSharpWindowsInfo
    {
        url = url,
        width = 1024,
        height = 768,
        x = 100,
        y = 100
    };
    
    // 4. 创建具有独立缓存的浏览器窗口
    FBroSharpWindows browser = FBroSharpWindows.CreateBrowser(windowsInfo, context);
    
    Console.WriteLine($"创建浏览器实例 [{instanceName}] - URL: {url}");
}

1. 多账户浏览器管理

csharp
public class MultiAccountBrowserManager
{
    private readonly Dictionary<string, FBroSharpWindows> _browsers = new Dictionary<string, FBroSharpWindows>();

    /// <summary>
    /// 为不同账户创建独立浏览器
    /// </summary>
    /// <param name="accounts">账户列表</param>
    /// <returns>创建的浏览器数量</returns>
    public int CreateAccountBrowsers(List<string> accounts)
    {
        int successCount = 0;

        foreach (string account in accounts)
        {
            try
            {
                // 创建实例级独立缓存配置
                var contextSet = CreateInstanceCacheConfig($"account_{account}");
                var context = FBroSharpRequestContext.CreateContext(contextSet);
                
                // 窗口配置
                var windowInfo = new FBroSharpWindowsInfo
                {
                    url = "https://example.com/login",
                    width = 1200,
                    height = 800,
                    x = successCount * 50,  // 错开窗口位置
                    y = successCount * 50
                };

                // 创建浏览器实例
                var browser = FBroSharpWindows.CreateBrowser(windowInfo, context);
                _browsers[account] = browser;
                
                successCount++;
                Console.WriteLine($"账户 {account} 的浏览器创建成功");
            }
            catch (Exception ex)
            {
                Console.WriteLine($"账户 {account} 的浏览器创建失败: {ex.Message}");
            }
        }

        Console.WriteLine($"成功创建 {successCount}/{accounts.Count} 个账户浏览器");
        return successCount;
    }

    /// <summary>
    /// 获取账户浏览器
    /// </summary>
    /// <param name="account">账户名</param>
    /// <returns>浏览器实例</returns>
    public FBroSharpWindows GetAccountBrowser(string account)
    {
        return _browsers.ContainsKey(account) ? _browsers[account] : null;
    }

    /// <summary>
    /// 切换到指定账户浏览器
    /// </summary>
    /// <param name="account">账户名</param>
    /// <param name="url">要访问的URL</param>
    /// <returns>是否成功</returns>
    public bool SwitchToAccount(string account, string url = null)
    {
        var browser = GetAccountBrowser(account);
        if (browser != null)
        {
            if (!string.IsNullOrEmpty(url))
            {
                browser.LoadUrl(url);
            }
            
            // 激活窗口
            browser.ShowWindow();
            Console.WriteLine($"已切换到账户: {account}");
            return true;
        }

        Console.WriteLine($"账户 {account} 的浏览器不存在");
        return false;
    }

    /// <summary>
    /// 关闭账户浏览器
    /// </summary>
    /// <param name="account">账户名</param>
    /// <returns>是否成功</returns>
    public bool CloseAccountBrowser(string account)
    {
        if (_browsers.ContainsKey(account))
        {
            var browser = _browsers[account];
            browser.CloseBrowser();
            _browsers.Remove(account);
            Console.WriteLine($"已关闭账户 {account} 的浏览器");
            return true;
        }
        
        Console.WriteLine($"账户 {account} 的浏览器不存在");
        return false;
    }

    /// <summary>
    /// 关闭所有账户浏览器
    /// </summary>
    public void CloseAllAccountBrowsers()
    {
        foreach (var kvp in _browsers)
        {
            kvp.Value.CloseBrowser();
            Console.WriteLine($"已关闭账户 {kvp.Key} 的浏览器");
        }
        
        _browsers.Clear();
        Console.WriteLine($"已关闭所有账户浏览器");
    }
}

2. 任务隔离浏览器创建

csharp
public class TaskIsolatedBrowserFactory
{
    private readonly Dictionary<string, FBroSharpWindows> _taskBrowsers = new Dictionary<string, FBroSharpWindows>();

    /// <summary>
    /// 为特定任务创建隔离浏览器
    /// </summary>
    /// <param name="taskId">任务ID</param>
    /// <param name="taskType">任务类型</param>
    /// <returns>浏览器实例</returns>
    public FBroSharpWindows CreateTaskBrowser(string taskId, string taskType)
    {
        try
        {
            // 创建任务专用缓存配置
            string cacheName = $"task_{taskType}_{taskId}_{DateTime.Now:yyyyMMdd_HHmmss}";
            var contextSet = CreateInstanceCacheConfig(cacheName);
            var context = FBroSharpRequestContext.CreateContext(contextSet);

            // 窗口配置
            var windowInfo = new FBroSharpWindowsInfo
            {
                url = "about:blank",
                width = 1024,
                height = 768
            };

            // 创建浏览器实例
            var browser = FBroSharpWindows.CreateBrowser(windowInfo, context);
            _taskBrowsers[taskId] = browser;
            
            Console.WriteLine($"任务浏览器创建成功: {taskId} ({taskType})");
            return browser;
        }
        catch (Exception ex)
        {
            Console.WriteLine($"任务浏览器创建失败: {taskId} - {ex.Message}");
            throw;
        }
    }

    /// <summary>
    /// 批量创建任务浏览器
    /// </summary>
    /// <param name="tasks">任务列表</param>
    /// <returns>浏览器实例字典</returns>
    public Dictionary<string, FBroSharpWindows> CreateBatchTaskBrowsers(List<(string taskId, string taskType)> tasks)
    {
        var browsers = new Dictionary<string, FBroSharpWindows>();

        foreach (var (taskId, taskType) in tasks)
        {
            try
            {
                var browser = CreateTaskBrowser(taskId, taskType);
                browsers[taskId] = browser;
            }
            catch (Exception ex)
            {
                Console.WriteLine($"任务浏览器创建失败: {taskId} - {ex.Message}");
            }
        }

        Console.WriteLine($"成功创建 {browsers.Count}/{tasks.Count} 个任务浏览器");
        return browsers;
    }

    /// <summary>
    /// 获取任务浏览器
    /// </summary>
    /// <param name="taskId">任务ID</param>
    /// <returns>浏览器实例</returns>
    public FBroSharpWindows GetTaskBrowser(string taskId)
    {
        return _taskBrowsers.ContainsKey(taskId) ? _taskBrowsers[taskId] : null;
    }

    /// <summary>
    /// 关闭任务浏览器
    /// </summary>
    /// <param name="taskId">任务ID</param>
    /// <returns>是否成功</returns>
    public bool CloseTaskBrowser(string taskId)
    {
        if (_taskBrowsers.ContainsKey(taskId))
        {
            var browser = _taskBrowsers[taskId];
            browser.CloseBrowser();
            _taskBrowsers.Remove(taskId);
            Console.WriteLine($"已关闭任务 {taskId} 的浏览器");
            return true;
        }
        
        Console.WriteLine($"任务 {taskId} 的浏览器不存在");
        return false;
    }
}

最佳实践

1. 缓存目录命名规范

csharp
public static class CacheNamingConvention
{
    /// <summary>
    /// 生成账户缓存名称
    /// </summary>
    /// <param name="account">账户名</param>
    /// <returns>缓存目录名</returns>
    public static string ForAccount(string account)
    {
        return $"account_{SanitizeName(account)}";
    }

    /// <summary>
    /// 生成任务缓存名称
    /// </summary>
    /// <param name="taskType">任务类型</param>
    /// <param name="taskId">任务ID</param>
    /// <returns>缓存目录名</returns>
    public static string ForTask(string taskType, string taskId)
    {
        return $"task_{SanitizeName(taskType)}_{SanitizeName(taskId)}_{DateTime.Now:yyyyMMdd_HHmmss}";
    }

    /// <summary>
    /// 生成临时缓存名称
    /// </summary>
    /// <returns>缓存目录名</returns>
    public static string ForTemporary()
    {
        return $"temp_{Guid.NewGuid():N}";
    }

    /// <summary>
    /// 清理文件名中的非法字符
    /// </summary>
    /// <param name="name">原始名称</param>
    /// <returns>清理后的名称</returns>
    private static string SanitizeName(string name)
    {
        if (string.IsNullOrEmpty(name))
            return "unknown";

        // 移除或替换非法字符
        char[] invalidChars = Path.GetInvalidFileNameChars();
        foreach (char c in invalidChars)
        {
            name = name.Replace(c, '_');
        }

        // 限制长度
        if (name.Length > 50)
            name = name.Substring(0, 50);

        return name;
    }
}

2. 缓存管理建议

✅ 推荐做法

  • 明确分层:区分框架级配置和实例级配置
  • 合理命名:使用有意义的缓存目录名称
  • 适时清理:及时关闭不需要的浏览器实例
  • 错误处理:妥善处理缓存创建失败的情况

❌ 避免做法

  • 混淆配置:不要混淆FBroSharpInitSet和FBroSharpRequestContextSet
  • 路径冲突:避免多个实例使用相同的缓存路径
  • 资源泄漏:未关闭的浏览器实例会占用系统资源
  • 路径过长:避免缓存路径过长导致的系统问题

3. 完整使用流程

csharp
// 1. 应用程序启动时 - 框架初始化(一次性)
static void Main()
{
    // 框架级配置
    FBroSharpInitSet initSet = new FBroSharpInitSet
    {
        cache_path = Directory.GetCurrentDirectory() + "\\Cache\\CachePath\\",
        user_data_path = Directory.GetCurrentDirectory() + "\\Cache\\UserPath\\", 
        root_cache_path = Directory.GetCurrentDirectory() + "\\Cache\\",
        multi_threaded_message_loop = true,
        browser_subprocess_path = Directory.GetCurrentDirectory() + "\\FBroSubprocess.exe",
        locale = "zh-CN"
    };

    InitEvent initEvent = new InitEvent();
    if (!FBroSharpInitControl.InitPro(initSet, initEvent))
    {
        Console.WriteLine("框架初始化失败");
        return;
    }

    // 2. 创建独立缓存的浏览器实例
    CreateIndependentBrowsers();
}

static void CreateIndependentBrowsers()
{
    // 为不同场景创建独立缓存浏览器
    var userA = CreateBrowserInstance("UserA");
    var userB = CreateBrowserInstance("UserB");
    var tempTask = CreateBrowserInstance("TempTask");
    
    // ... 使用浏览器实例 ...
    
    // 3. 清理资源
    userA?.CloseBrowser();
    userB?.CloseBrowser();
    tempTask?.CloseBrowser();
}

static FBroSharpWindows CreateBrowserInstance(string instanceName)
{
    // 实例级配置
    var contextSet = new FBroSharpRequestContextSet
    {
        cache_path = Path.Combine(Directory.GetCurrentDirectory(), "BrowserCaches", instanceName),
        persist_session_cookies = true,
        persist_user_preferences = true
    };

    var context = FBroSharpRequestContext.CreateContext(contextSet);
    var windowInfo = new FBroSharpWindowsInfo
    {
        url = "about:blank",
        width = 1024,
        height = 768
    };

    return FBroSharpWindows.CreateBrowser(windowInfo, context);
}

常见问题

Q1: 如何判断缓存是否独立成功?

A: 检查不同浏览器实例是否可以同时登录不同账户,如果可以则说明缓存已成功隔离。

Q2: 缓存目录会自动创建吗?

A: 是的,FBro会自动创建指定的缓存目录。

Q3: 可以动态修改缓存路径吗?

A: 不可以,缓存路径在浏览器实例创建时确定,无法动态修改。

Q4: 多个实例可以共享同一个缓存目录吗?

A: 不建议,这会导致缓存冲突,失去独立缓存的意义。

Q5: 如何清理缓存?

A: 关闭浏览器实例后,可以直接删除对应的缓存目录。


总结

通过正确区分框架级配置实例级配置,你可以:

  1. 🔧 框架初始化:使用FBroSharpInitSet进行一次性全局配置
  2. 🎯 实例创建:使用FBroSharpRequestContextSet为每个浏览器实例配置独立缓存
  3. 🏗️ 架构清晰:框架缓存为基础,实例缓存实现隔离
  4. ✅ 最佳实践:合理命名、及时清理、错误处理

独立缓存功能让你可以轻松实现多账户管理、任务隔离等高级应用场景。


📚 相关文档

如果文档对您有帮助,欢迎 请喝咖啡 ☕ | 软件发布 | 源码购买