Cet article décrit comment intégrer un navigateur web dans une application WPF (développée avec Visual Studio 2010 et C#) à l'aide de CefSharp, afin d'ouvrir des pages web tout en respectant deux contraintes :
- L'ordinateur ne doit pouvoir accéder à Internet qu'à travers un serveur proxy spécifique (via le réseau local), et uniquement pour cette application.
- Le code JavaScript de la page web doit pouvoir appeler des méthodes du code C# (passage de données dans les deux sens).
CefSharp est un composant .NET qui fournit un navigateur Chrome embarqué utilisable dans les applications WPF ou WinForms.
- Configuration de l'environnement et installation des packages NuGet
Si vous avez besoin d'une solution simple pour afficher une page web existante, vous pouvez vous référer à d'autres tutoriels. Ici, nous allons au‑delà en intégrant également des interactions JavaScript ⇔ C# et un proxy.
Le gestionnaire de packages NuGet est nécessaire pour charger CefSharp et ses dépendances. Après installation (par exemple NuGet.Tools pour VS2010), ouvrez votre projet dans Visual Studio.
Créez un nouveau projet WPF (par exemple NavigateurEmbarque). Dans le menu Outils, sélectionnez Gestionnaire de packages NuGet → Gérer les packages NuGet pour la solution. Recherchez en ligne CefSharp.Wpf et CefSharp.Common et installez‑les. (Pour WinForms, remplacez par CefSharp.WinForms). L'installation peut prendre un certain temps. Le dossier packages apparaîtra à la racine du projet.
- Configuration du proxy et initialisation du navigateur
Dans le code de la fenêtre principale (MainWindow.xaml et MainWindow.xaml.cs), nous ajoutons une zone de texte pour l'URL et un bouton de navigation. L'essentiel est de configurer le proxy avant d'initialiser CefSharp.
<!-- MainWindow.xaml -->
<Window x:Class="NavigateurEmbarque.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Navigateur Embarqué" Height="350" Width="800"
WindowStartupLocation="CenterScreen" Loaded="Window_Loaded">
<Grid>
<DockPanel>
<StackPanel DockPanel.Dock="Top" Orientation="Horizontal">
<TextBlock Text="Adresse web :" Margin="5"/>
<TextBox x:Name="txtAdresse" Width="350" Margin="5"/>
<Button Content="Ouvrir" Margin="5" Click="OnOuvrirClick" IsDefault="True"/>
</StackPanel>
<Grid x:Name="GrillePrincipale">
</Grid>
</DockPanel>
</Grid>
</Window>
// MainWindow.xaml.cs
using System;
using System.Windows;
using CefSharp;
namespace NavigateurEmbarque
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
// URL par défaut
txtAdresse.Text = "http://www.example.com/";
// Configuration du proxy
var config = new CefSettings();
config.CefCommandLineArgs.Add("--proxy-server", "http://192.168.1.100:3128");
// Initialisation unique de CefSharp
Cef.Initialize(config, true, false);
}
private void OnOuvrirClick(object sender, RoutedEventArgs e)
{
string url = txtAdresse.Text;
if (!string.IsNullOrWhiteSpace(url))
{
var page = new PageAfficheur(url);
GrillePrincipale.Children.Insert(0, page);
}
}
}
}
Remarque importante : La méthode Cef.Initialize ne doit être appelée qu'une seule fois. Placez‑la dans le constructeur de l'application ou dans l'événement Startup du fichier App.xaml.cs. De plus, avant la fermeture de l'application, appelez Cef.Shutdown() pour éviter que le processus reste en arrière‑plan.
- Contrôle utilisateur pour l'affichage de la page web et l'interaction JavaScript
Créez un nouveau contrôle utilisateur PageAfficheur.xaml contenant un masque de chargement et un conteneur pour le navigateur.
<!-- PageAfficheur.xaml -->
<UserControl x:Class="NavigateurEmbarque.PageAfficheur"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Name="ctrlPage">
<Grid x:Name="GrilleConteneur">
<local:MasqueChargement x:Name="masqueAttente"/>
</Grid>
</UserControl>
// PageAfficheur.xaml.cs
using System;
using System.Windows;
using System.Windows.Controls;
using CefSharp;
using CefSharp.Wpf;
namespace NavigateurEmbarque
{
public partial class PageAfficheur : UserControl
{
public PageAfficheur(string url)
{
InitializeComponent();
var navigateur = new ChromiumWebBrowser();
// Enregistrement d'un objet accessible depuis JavaScript
navigateur.RegisterJsObject("pont", new ObjetRappelPourJs());
navigateur.Loaded += (s, e) =>
{
masqueAttente.Visibility = Visibility.Collapsed;
};
GrilleConteneur.Children.Insert(0, navigateur);
navigateur.Address = url;
}
}
// Classe exposée au JavaScript
public class ObjetRappelPourJs
{
public string envoyerMessage(string message)
{
// Exemple : retourner un message à la page web
return "Message reçu depuis C# : " + message;
}
}
}
Notez que l'interface IRequestHandler n'est pas implémentée ici car l'interaction JavaScript ne nécessite pas de gestionnaire de requêtes. Si vous avez besoin de gérer l'authentification proxy, implémentez‑le.
- Interaction avec une page web JavaScript
Créez un fichier HTML test.html (placez‑le dans le dossier de sortie, par exemple bin\Debug) :
<html>
<head><title>Page de test</title></head>
<body>
<h1>Interaction CefSharp</h1>
<button onclick="lancerAppel()">Tester</button>
<p id="resultat"></p>
<script type="text/javascript">
function lancerAppel() {
var reponse = pont.envoyerMessage("123");
document.getElementById("resultat").innerText = reponse;
}
</script>
</body>
</html>
Pour charger cette page locale, modifiez l'URL par défaut dans MainWindow_Loaded :
string chemin = System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName;
chemin = chemin.Replace("NavigateurEmbarque.vshost.exe", "test.html");
txtAdresse.Text = chemin;
- Masque de chargement
Le contrôle MasqueChargement affiche simplement un texte pendant le chargement. Créez MasqueChargement.xaml :
<UserControl x:Class="NavigateurEmbarque.MasqueChargement"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Grid Opacity="0.85">
<TextBlock Text="Chargement de la page..."
VerticalAlignment="Center" HorizontalAlignment="Center"/>
</Grid>
</UserControl>
Le code‑behind est vide, seul le constructeur appelle InitializeComponent().
- Problèmes courants et résoultion
- Erreur « Impossible de charger CefSharp.Core.dll » : installez le runtime Visual C++ 2013 (vcredist_x86.exe pour 32 bits, vcredist_x64.exe pour 64 bits).
- Dans les propriétés du projet, ciblez la plateforme x86 (ou x64 selon l'architecture de votre système).
- Si la compilation échoue, ouvrez le Gestionnaire de configurations (clic droit sur la solution → Propriétés → Configuration) et créez la plateforme x86. Vous devrez peut‑être supprimer une plateforme existante et la recréer.
- Après changement de plateforme, vérifiez le chemin de sortie dans les propriétés du projet : il doit être
bin\Debug(et nonbin\x86\Debug). - Shutdown : ajoutez un gestionnaire d'arrêt de l'application qui appelle
Cef.Shutdown()pour éviter que le processus reste en mémoire.