일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- algorithm
- .net
- tls
- Microsoft
- windows10
- WPF
- Github
- coding-test
- log
- C#
- programmers
- Binding
- IValueConverter
- git
- Process
- commit
- string
- mysql
- windows
- csharp
- convert
- ListView
- dotNET
- Visual Studio
- chashtag
- logging
- nullable
- Coding
- 코딩테스트
- File
- Today
- Total
CHashtag
[C#/WPF] WebView2 사용방법 (WebBrowser 대체, JS통신) 본문
2022년 6월 15일, Internet Explorer가 지원 종료되었습니다.
그에 따른 걱정으로 IE기반 Embedded인 WebBrowser도 지원 중단되는 것이 아닌가 걱정이 되실 것입니다.
하지만 그렇지는 않습니다.
자세한 내용은 아래 게시물을 참고해주세요.
https://chashtag.tistory.com/147
그럼에도 WebBrowser는 IE기반의 Legacy WebBrowser로, MS에서는 Edge기반의 WebView2 사용을 권하고 있습니다.
WebView2는 WebBrowser의 거의 모든 기능을 제공합니다.
자 그러면, 코드부터 배포 방법까지 같이 알아보시죠. ㅎㅎ
아래에 나올 코드들은 Github에 전체 코드도 올려두었으니 참고해주세요.
https://github.com/Hyo-Seong/CHashtag/tree/master/WPF_WebView2
Navigate
WebBrowser의 가장 기본적인 기능이죠.
바로 예제로 알아보시죠.
// Navigate
webView.CoreWebView2.Navigate(Url);
// 혹은 이렇게도 가능합니다.
webView.Source = new Uri(Url);
Navigated
navigated에 대해 배우기 전, WebView2가 페이지를 띄우는 Event Cycle에 대해 이해하여야 합니다.
자 이번에는 사이트를 띄웠을 때 실제로 저 순서대로 나오는지 확인해보겠습니다.
private async void Window_Loaded(object sender, RoutedEventArgs e)
{
await webView.EnsureCoreWebView2Async();
webView.CoreWebView2.NavigationStarting += CoreWebView2_NavigationStarting;
webView.CoreWebView2.SourceChanged += CoreWebView2_SourceChanged;
webView.CoreWebView2.ContentLoading += CoreWebView2_ContentLoading;
webView.CoreWebView2.HistoryChanged += CoreWebView2_HistoryChanged;
webView.CoreWebView2.DOMContentLoaded += CoreWebView2_DOMContentLoaded;
webView.CoreWebView2.NavigationCompleted += CoreWebView2_NavigationCompleted;
}
private void CoreWebView2_NavigationStarting(object sender, Microsoft.Web.WebView2.Core.CoreWebView2NavigationStartingEventArgs e)
{
Console.WriteLine(System.Reflection.MethodBase.GetCurrentMethod().Name);
}
private void CoreWebView2_SourceChanged(object sender, Microsoft.Web.WebView2.Core.CoreWebView2SourceChangedEventArgs e)
{
Console.WriteLine(System.Reflection.MethodBase.GetCurrentMethod().Name);
}
private void CoreWebView2_ContentLoading(object sender, Microsoft.Web.WebView2.Core.CoreWebView2ContentLoadingEventArgs e)
{
Console.WriteLine(System.Reflection.MethodBase.GetCurrentMethod().Name);
}
private void CoreWebView2_HistoryChanged(object sender, object e)
{
Console.WriteLine(System.Reflection.MethodBase.GetCurrentMethod().Name);
}
private void CoreWebView2_DOMContentLoaded(object sender, Microsoft.Web.WebView2.Core.CoreWebView2DOMContentLoadedEventArgs e)
{
Console.WriteLine(System.Reflection.MethodBase.GetCurrentMethod().Name);
}
private void CoreWebView2_NavigationCompleted(object sender, Microsoft.Web.WebView2.Core.CoreWebView2NavigationCompletedEventArgs e)
{
Console.WriteLine(System.Reflection.MethodBase.GetCurrentMethod().Name);
}
결과는 아래와 같습니다.
CoreWebView2_NavigationStarting
CoreWebView2_SourceChanged
CoreWebView2_ContentLoading
CoreWebView2_HistoryChanged
CoreWebView2_DOMContentLoaded
CoreWebView2_NavigationCompleted
각 Event마다 전달되는 값이 다르기 때문에 한번 읽어보시면 좋을 것 같습니다.
이 부분에 대해서는 더 깊이 다루지 않겠습니다만, 상세한 내용은 아래 링크를 참조해주세요.
https://docs.microsoft.com/en-us/microsoft-edge/webview2/concepts/navigation-events
JS와 통신하기
JS -> C#
// cs
private async void Window_Loaded(object sender, RoutedEventArgs e)
{
webView.CoreWebView2.WebMessageReceived += CoreWebView2_WebMessageReceived;
}
private void CoreWebView2_WebMessageReceived(object sender, Microsoft.Web.WebView2.Core.CoreWebView2WebMessageReceivedEventArgs e)
{
Console.WriteLine(e.WebMessageAsJson);
}
// js
chrome.webview.postMessage("hello wpf");
C# -> JS
// cs
webView.CoreWebView2.PostWebMessageAsString("Hello JS");
// js
window.chrome.webview.addEventListener('message', event => {
console.log(event.data);
});
함수 직접 호출
이 방법은 각각의 함수를 직접 호출하고, 값을 return 받는 방법입니다.
C# -> JS
// cs
var result = await webView.CoreWebView2.ExecuteScriptAsync("test()");
// result: "aa"
// js
function test() {
return "aa";
}
JS -> C#
// cs
using System.Runtime.InteropServices;
using Newtonsoft.Json;
private async void Window_Loaded(object sender, RoutedEventArgs e)
{
await webView.EnsureCoreWebView2Async();
webView.CoreWebView2.AddHostObjectToScript("bridge", new Bridge());
}
[ClassInterface(ClassInterfaceType.AutoDual)]
[ComVisible(true)]
public class Bridge
{
public string Func(string param)
{
return JsonConvert.SerializeObject(new
{
result = param + " ended",
success = true
});
}
}
// async
async function asyncCall() {
const bridge = chrome.webview.hostObjects.bridge;
const propValue = await bridge.AnotherObject.Prop;
console.log(propValue);
}
// sync
function syncCall() {
const bridge = chrome.webview.hostObjects.sync.bridge;
var result = bridge.Func("testing...");
console.log(result);
}
Runtime & 배포
자 이렇게 코드를 한번 짜보았는데요,
이제는 배포 방법에 대해 알아보도록 하겠습니다.
WebView2는 Edge 기반 WebBrowser이고, 전용 Runtime이 필요하기 때문에 배포에 유의하여야 합니다.
Edge는 Windows기본 설치 옵션이니 신경 쓰지 않는다 하여도, Runtime이 문제이지요.
Runtime의 경우 최신 Windows에서는 기본 설치가 되나, 아직 설치가 되어있지 않은 PC가 많은 것이 현실입니다.
Runtime은 Evergreen 모드로 한번 설치되면 그 후 업데이트는 MS에서 자체 진행해주는데요,
이것이 양날의 검이 될 수 있습니다.
장점으로는 당연히 버전 관리의 편리성이고요, 단점은 버전이 자동으로 바뀜에 따라 코드 업데이트가 필요할 수 있다는 점입니다.
이 게시글에서는 Evergreen모드가 아닌, Runtime 내장하여 사용하는 방법에 대해 알아보도록 하겠습니다.
(해당 내용은 아래 링크를 번역&약간의 노하우를 추가한 것입니다.)
Runtime Download
https://developer.microsoft.com/microsoft-edge/webview2#download-section
위 링크에서 원하는 버전의 Runtime을 다운로드합니다.
압축 해제
그 후 아래 커맨드를 입력하여 압축을 풀어줍니다.
expand {path to the package} -F:* {path to the destination folder}
코드에서 런타임 경로 지정
기존에는 Windows에 설치된 Runtime을 알아서 감지해줬다면, 이제는 직접 경로를 지정해주어야 합니다.
아래 두 가지 방법 중 한 가지를 선택하시면 됩니다.
다만, Navigate하기 전에(Source가 지정되기 전에) 설정하여야 하기 때문에, 그냥 EnsureCoreWebView2Async에서 지정하는 걸 추천합니다.
// cs
// 절대경로, 상대경로 모두 가능합니다.
webView.CreationProperties.BrowserExecutableFolder = @"C:\Path\to\runtime\path\Microsoft.WebView2.FixedVersionRuntime.104.0.1293.70.x86";
await webView.EnsureCoreWebView2Async(await CoreWebView2Environment.CreateAsync(@"Microsoft.WebView2.FixedVersionRuntime.104.0.1293.70.x86"));
네, 이렇게 WebView2 사용방법에 대해 알아보았습니다.
IE기반의 웹브라우저는 보안에도 취약하기 때문에 이 글 참고하시어 걷어내는 계기가 되었으면 좋겠습니다.
긴 글 읽어주셔서 감사합니다.
'C# > Library 소개' 카테고리의 다른 글
[C#] RestSharp 사용방법(GET, POST) (0) | 2021.12.03 |
---|