본문 바로가기
C#

[C#] Webview2 - not working Input type when it run as administrator

by Jcoder 2021. 10. 20.

2022-12-14 수정.

아래로 내려보면 해결법이 있습니다.

 

 

<좌측> 그냥 실행, <우측> 관리자 권한으로 실행

 

c# webview2에서 input file type 버튼을 클릭시 파일 다이얼로그 창이 뜨지 않는 현상이 있어 찾아보니 관리자 권한으로 실행시 다이얼로그 창이 뜨지 않는다고 한다.

 

링크 : WebView2 WPF application can't open file dialog when it run as administrator · Issue #734 · MicrosoftEdge/WebView2Feedback (github.com)

 

WebView2 WPF application can't open file dialog when it run as administrator · Issue #734 · MicrosoftEdge/WebView2Feedback

Description WebView2 WPF application can't open file dialog when it run as administrator. When I run the application as user mode, I can open file dialog normally. In my html file, I use <in...< p=""> </in...<>

github.com

링크 : File Open/Save Dialog doesn't show running w/ elevated privileges · Issue #802 · MicrosoftEdge/WebView2Feedback (github.com)

 

File Open/Save Dialog doesn't show running w/ elevated privileges · Issue #802 · MicrosoftEdge/WebView2Feedback

Description When running application "as administrator" (elevated), the File Open dialog will not appear from a file input element. This is presumably because the renderer process is not ...

github.com

 

링크 : SaveAs functionality · Issue #1090 · MicrosoftEdge/WebView2Feedback (github.com)

 

SaveAs functionality · Issue #1090 · MicrosoftEdge/WebView2Feedback

I'm using WebView2 in C++. How can I implement SaveAs option from right click menu? It is supposed to launch SaveAs dialog to save html file. AB#32723386

github.com

 

현재 (2021-10-20) 기준으로 지원하지 않고 있고 개발중인 것으로 판단된다.

 

링크 : Elevating WebView2 from non-admin account creates the msedgewebview2.exe processes as the non-admin user · Issue #932 · MicrosoftEdge/WebView2Feedback (github.com)

 

Elevating WebView2 from non-admin account creates the msedgewebview2.exe processes as the non-admin user · Issue #932 · Micros

Description When using "Runas" and elevating a WebView2 application from non-admin account, there is an issue whereby the msedgewebview2.exe processes are created as the non-admin user Th...

github.com

msedgewebview2.exe가 같이 관리자 권한으로 실행되지 않기 때문

 

https://github.com/MicrosoftEdge/WebView2Feedback/issues/728#issue-761494788

 

Cannot open files dialog · Issue #728 · MicrosoftEdge/WebView2Feedback

In searching for a way to access and upload files through WebView2 I've hit a roadblock. Note, drag-drop of files into webview2 is working great. I can get a filelist this way. But I have no co...

github.com

 

위와 같은 방법으로 테스트를 진행했다.

[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)

 

File System Access API - Web APIs | MDN

The File System Access API allows read, write and file management capabilities.

developer.mozilla.org

 

 

2022-10-26 수정.

https://github.com/MicrosoftEdge/WebView2Feedback/issues/802#issuecomment-1282930267

 

File Open/Save Dialog doesn't show running w/ elevated privileges · Issue #802 · MicrosoftEdge/WebView2Feedback

Description When running application "as administrator" (elevated), the File Open dialog will not appear from a file input element. This is presumably because the renderer process is not ...

github.com

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

 

Microsoft Edge release notes for Stable Channel

Table of contents Release notes for Microsoft Edge Stable Channel Article 12/08/2022 6 minutes to read 6 contributors Feedback In this article --> These release notes provide information about new features and non-security updates that are included in the

learn.microsoft.com

https://learn.microsoft.com/en-us/microsoft-edge/webview2/release-notes?tabs=dotnetcsharp 

 

Release Notes for the WebView2 SDK - Microsoft Edge Development

Release notes for Microsoft Edge WebView2 for Win32, WPF, and WinForms.

learn.microsoft.com