CHashtag

[C#/WPF] WebView2 사용방법 (WebBrowser 대체, JS통신) 본문

C#/Library 소개

[C#/WPF] WebView2 사용방법 (WebBrowser 대체, JS통신)

HyoSeong 2022. 8. 31. 00:27
반응형

2022년 6월 15일, Internet Explorer가 지원 종료되었습니다.

그에 따른 걱정으로 IE기반 Embedded인 WebBrowser도 지원 중단되는 것이 아닌가 걱정이 되실 것입니다.

 

하지만 그렇지는 않습니다.

자세한 내용은 아래 게시물을 참고해주세요.

 

https://chashtag.tistory.com/147

 

[C#] IE기반 WebBrowser는 지원 중단되나?

결론은 아닙니다. 2022년 6월 15일, Internet Explorer가 지원 종료되었습니다. 그에따른 걱정으로 IE기반 Embedded인 WebBrowser도 지원중단되는것이 아닌가 걱정이 되실텐데요, 다행히 그렇지는 않습니다.

chashtag.tistory.com

 

그럼에도 WebBrowser는 IE기반의 Legacy WebBrowser로, MS에서는 Edge기반의 WebView2 사용을 권하고 있습니다.

 

WebView2는 WebBrowser의 거의 모든 기능을 제공합니다.

 

자 그러면, 코드부터 배포 방법까지 같이 알아보시죠. ㅎㅎ


아래에 나올 코드들은 Github에 전체 코드도 올려두었으니 참고해주세요.

https://github.com/Hyo-Seong/CHashtag/tree/master/WPF_WebView2

 

GitHub - Hyo-Seong/CHashtag: https://chashtag.tistory.com/

https://chashtag.tistory.com/. Contribute to Hyo-Seong/CHashtag development by creating an account on GitHub.

github.com

 

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

 

Navigation events for WebView2 apps - Microsoft Edge Development

Navigation events for WebView2: NavigationStarting, SourceChanged, ContentLoading, HistoryChanged, DOMContentLoaded, and NavigationCompleted.

docs.microsoft.com

 

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 내장하여 사용하는 방법에 대해 알아보도록 하겠습니다.

 

 

 

(해당 내용은 아래 링크를 번역&약간의 노하우를 추가한 것입니다.)

https://docs.microsoft.com/en-us/microsoft-edge/webview2/concepts/distribution#details-about-the-fixed-version-runtime-distribution-mode

 

Distribute your app and the WebView2 Runtime - Microsoft Edge Development

How to distribute the WebView2 Runtime when releasing an app that uses Microsoft Edge WebView2, either by distributing the automatically updated Evergreen Runtime, or distributing a Fixed Version of the WebView2 Runtime.

docs.microsoft.com

 

Runtime Download

https://developer.microsoft.com/microsoft-edge/webview2#download-section

 

WebView2 - Microsoft Edge Developer

When distributing your application, there are a few ways you can ensure the WebView2 Runtime is on client machines. Learn more about those options. For installation issues and error codes see our troubleshooting guide. Evergreen Bootstrapper The Bootstrapp

developer.microsoft.com

위 링크에서 원하는 버전의 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