2022-12-14 수정.
아래로 내려보면 해결법이 있습니다.
c# webview2에서 input file type 버튼을 클릭시 파일 다이얼로그 창이 뜨지 않는 현상이 있어 찾아보니 관리자 권한으로 실행시 다이얼로그 창이 뜨지 않는다고 한다.
링크 : SaveAs functionality · Issue #1090 · MicrosoftEdge/WebView2Feedback (github.com)
현재 (2021-10-20) 기준으로 지원하지 않고 있고 개발중인 것으로 판단된다.
https://github.com/MicrosoftEdge/WebView2Feedback/issues/728#issue-761494788
위와 같은 방법으로 테스트를 진행했다.
[html 파일 내용]
<!DOCTYPE html>
<html lang="ko">
<head> </head>
<body>
<div class="container">
<input type="file" id="file_input" onclick="clickEvent(event)" />
<button type="button" onclick="getFile()"> "window.showOpenFilePicker()" </button>
</div>
</body>
<script>
var nodeId = document.querySelector("#file_input");
function clickEvent(e) {
e.preventDefault();
window.chrome.webview.postMessage("1111");
alert(nodeId);
}
// store a reference to our file handle
let fileHandle;
async function getFile() {
// open file picker
[fileHandle] = await window.showOpenFilePicker();
if (fileHandle.kind === 'file') {
// run file code
} else if (fileHandle.kind === 'directory') {
// run directory code
}
}
</script>
</html>
[C# 코드]
using Microsoft.Web.WebView2.Core;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Text.Json;
using static Microsoft.Web.WebView2.Core.DevToolsProtocolExtension.DOM;
namespace Webview2InputTypeClick
{
public partial class Form1 : Form
{
public string TextBoxURL { get => textBox1.Text; }
public Form1()
{
InitializeComponent();
SetUI();
SetControlEvent();
this.Load += Form1_Load;
}
private void SetUI()
{
textBox1.Text = @"C:\Users\tjdsk\Desktop\Untitled.html";
}
private void SetControlEvent()
{
button1.Click += (s, e) =>
{
if (string.IsNullOrEmpty(TextBoxURL))
textBox1.Text = "https://developer.mozilla.org/ko/docs/Web/HTML/Element/Input/file";
webView21.CoreWebView2.Navigate(TextBoxURL);
};
textBox1.KeyDown += TextBox1_KeyDown;
}
private void TextBox1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode.Equals(Keys.Enter))
{
if (!TextBoxURL.Contains("https://", StringComparison.OrdinalIgnoreCase) || !TextBoxURL.Contains("https://", StringComparison.OrdinalIgnoreCase))
textBox1.Text = "https://" + textBox1.Text;
webView21.CoreWebView2.Navigate(TextBoxURL);
}
}
private async void Form1_Load(object sender, EventArgs e)
{
if (string.IsNullOrEmpty(TextBoxURL))
textBox1.Text = "https://developer.mozilla.org/ko/docs/Web/HTML/Element/Input/file";
CoreWebView2Environment coreWebView2Environment = await CoreWebView2Environment.CreateAsync(null, null, new CoreWebView2EnvironmentOptions("--disable-features=RendererCodeIntegrity,PreloadMediaEngagementData,AutoplayIgnoreWebAudio,MediaEngagementBypassAutoplayPolicies"));
await webView21.EnsureCoreWebView2Async(coreWebView2Environment);
webView21.CoreWebView2.Navigate(TextBoxURL);
webView21.CoreWebView2.DocumentTitleChanged += (s, e) => { this.Text = webView21.CoreWebView2.DocumentTitle; };
webView21.CoreWebView2InitializationCompleted += WebView21_CoreWebView2InitializationCompleted;
webView21.CoreWebView2.WebMessageReceived += CoreWebView2_WebMessageReceived;
//await webView21.CoreWebView2.AddScriptToExecuteOnDocumentCreatedAsync("window.chrome.webview.postMessage(window.document.URL);");
//await webView21.CoreWebView2.AddScriptToExecuteOnDocumentCreatedAsync("window.chrome.webview.addEventListener(\'message\', event => alert(event.data));");
}
private void CoreWebView2_WebMessageReceived(object sender, CoreWebView2WebMessageReceivedEventArgs e)
{
string webMessageAsString = e.TryGetWebMessageAsString();
if (webMessageAsString.Equals("1111")) // html에서 input click 이벤트가 발생해 1111이라는 문자열이 들어왔을때만.
{
textBox2.AppendText($"e.WebMessageAsJson = {e.WebMessageAsJson}{Environment.NewLine}");
textBox2.AppendText($"TryGetWebMessageAsString = {webMessageAsString}{Environment.NewLine}");
ReturnFiles(@"C:\Users\tjdsk\Desktop\fed83f319f334a3b12c992b3813c9fb0 (1).jpg", "file_input");
}
}
private void WebView21_CoreWebView2InitializationCompleted(object sender, CoreWebView2InitializationCompletedEventArgs e)
{
textBox2.AppendText($"e.IsSuccess = {e.IsSuccess}");
}
private async void ReturnFiles(string file, string id)
{
try
{
// get document root
var node = await webView21.CoreWebView2.CallDevToolsProtocolMethodAsync("DOM.getDocument", "{}");
Dictionary<string, object> nodeinfo = JsonSerializer.Deserialize<Dictionary<string, object>>(node);
textBox2.AppendText($"getDocument {node}{Environment.NewLine}");
if (nodeinfo.ContainsKey("root"))
{
var query = JsonSerializer.Serialize(new
{
nodeId = 1, // nodeId 는 int형
selector = id
});
node = await webView21.CoreWebView2.CallDevToolsProtocolMethodAsync("DOM.querySelector", query);
textBox2.AppendText($"querySelector {node}{Environment.NewLine}");
if (!String.IsNullOrEmpty(node))
{
nodeinfo = JsonSerializer.Deserialize<Dictionary<string, object>>(node);
var parameters = JsonSerializer.Serialize(new
{
files = new string[] { file.Replace('\\', '/').Replace(@"\", "/") },
nodeId = 0,
backendNodeId = 0,
objectId = 0
});
// we make it all the way to final step here!
textBox2.AppendText($"parameters {parameters}{Environment.NewLine}");
node = await webView21.CoreWebView2.CallDevToolsProtocolMethodAsync("DOM.setFileInputFiles", parameters);
textBox2.AppendText($"node {node}{Environment.NewLine}");
}
}
}
catch (Exception e)
{
textBox2.AppendText($"Exception DevTools {e.Message}{Environment.NewLine}");
textBox2.AppendText($"Exception DevTools StackTrace {e.StackTrace}{Environment.NewLine}");
}
}
}
}
e.WebMessageAsJson = "1111" TryGetWebMessageAsString = 1111 getDocument {"root":{"backendNodeId":1,"baseURL":"file:///C:/Users/tjdsk/Desktop/Untitled.html","childNodeCount":2,"children":[{"backendNodeId":6,"localName":"","nodeId":2,"nodeName":"html","nodeType":10,"nodeValue":"","parentId":1,"publicId":"","systemId":""},{"attributes":["lang","ko"],"backendNodeId":5,"childNodeCount":2,"children":[{"attributes":[],"backendNodeId":7,"childNodeCount":0,"children":[{"backendNodeId":8,"localName":"","nodeId":5,"nodeName":"#text","nodeType":3,"nodeValue":" ","parentId":4}],"localName":"head","nodeId":4,"nodeName":"HEAD","nodeType":1,"nodeValue":"","parentId":3},{"attributes":[],"backendNodeId":4,"childNodeCount":3,"localName":"body","nodeId":6,"nodeName":"BODY","nodeType":1,"nodeValue":"","parentId":3}],"frameId":"519A21E70341361F8834B07463AEAB31","localName":"html","nodeId":3,"nodeName":"HTML","nodeType":1,"nodeValue":"","parentId":1}],"compatibilityMode":"NoQuirksMode","documentURL":"file:///C:/Users/tjdsk/Desktop/Untitled.html","localName":"","nodeId":1,"nodeName":"#document","nodeType":9,"nodeValue":"","xmlVersion":""}} querySelector {"nodeId":0} parameters {"files":["C:/Users/tjdsk/Desktop/fed83f319f334a3b12c992b3813c9fb0 (1).jpg"],"nodeId":0,"backendNodeId":0,"objectId":0} Exception DevTools Value does not fall within the expected range. Exception DevTools StackTrace at System.Runtime.InteropServices.Marshal.ThrowExceptionForHR(Int32 errorCode) at Microsoft.Web.WebView2.Core.CoreWebView2.CallDevToolsProtocolMethodAsync(String methodName, String parametersAsJson) at Webview2InputTypeClick.Form1.ReturnFiles(String file, String id) in C:\Users\tjdsk\source\repos\WinFormsApp1\Webview2InputTypeClick\Form1.cs:line 184 |
위 페이지와 같은 오류가 발생한다. (Value does not fall within the expected range.)
아직은 무리..
2021-10-22 수정.
- File System Access API 사용했는데도 여전히 관리자 권한으로 응용 프로그램 실행시 웹뷰2에서 파일창이 열리지 않음.
window.showOpenFilePicker();
File System Access API - Web APIs | MDN (mozilla.org)
2022-10-26 수정.
https://github.com/MicrosoftEdge/WebView2Feedback/issues/802#issuecomment-1282930267
108 버전에서 곧 수정된다고 한다.
2022-12-14 수정.
런타임이 108.0.1462.0+버전 이상이며
누겟 패키지 Microsoft.Web.WebView2 1.0.1210.39버전으로 업데이트 후 관리자 권한으로 테스트해보니 파일 선택 창이 떴다..
https://learn.microsoft.com/en-us/deployedge/microsoft-edge-relnote-stable-channel
https://learn.microsoft.com/en-us/microsoft-edge/webview2/release-notes?tabs=dotnetcsharp
'C#' 카테고리의 다른 글
[C#-Linux] 워커 서비스 프로그램 서비스로 등록하기 (0) | 2021.10.21 |
---|---|
[C#-Linux] WSL 및 리눅스 시스템에 .NET 5 설치 (0) | 2021.10.21 |
[C#] Webbrowser - ie 버전 up (0) | 2021.09.02 |
[C#] dll 코드로 등록 방법 (관리자 권한으로 실행해야 함) (0) | 2021.08.31 |
[C#] Webview2 runtime 설치 여부 및 설치 (0) | 2021.08.31 |