I'm attempting to use PowerShell (requirement) to create a WPF window with a WebView2 control such that I can have it open a local XML file with aa local XLST. I got it working in Visual Studio as a proof of concept using this XAML:
<Window x:Class="WepViewTutorial.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:wv2="clr-namespace:Microsoft.Web.WebView2.Wpf;assembly=Microsoft.Web.WebView2.Wpf">
<DockPanel>
<wv2:WebView2 Name="webView"
Source="C:\dev\webview2dev\xmlFile.xml"
/>
</DockPanel>
</Window>
And this works.
When I go to PowerShell, I am finding difficulties. Here's my Script:
Register-PackageSource -provider NuGet -name nugetRepository -location https://www.nuget.org/api/v2 -ErrorAction SilentlyContinue
install-Package -Name Microsoft.Web.WebView2 -SkipDependencies -Scope CurrentUser -ErrorAction SilentlyContinue
$webviewBase = "$(Get-Package *webview* | % source )"| Split-Path -Parent
add-type -LiteralPath "$webviewBase\lib\net45\Microsoft.Web.WebView2.Core.dll"
add-type -LiteralPath "$webviewBase\lib\net45\Microsoft.Web.WebView2.Wpf.dll"
Add-Type -assemblyName PresentationCore
Add-Type -assemblyName PresentationFramework
[xml]$xaml = @"
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:wv2="clr-namespace:Microsoft.Web.WebView2.Wpf;assembly=Microsoft.Web.WebView2.Wpf"
x:Name = "Window">
<DockPanel>
<wv2:WebView2 Name="webView"
Source="C:\dev\webview2dev\xmlFile.xml"
/>
</DockPanel>
</Window>
"@
$reader = (New-Object System.Xml.XmlNodeReader $xaml)
$window = [Windows.Markup.XamlReader]::Load($reader)
$window.ShowDialog()
And this doesn't work. I get an error:
Exception calling "Load" with "1" argument(s): "Cannot create unknown type
'{clr-namespace:Microsoft.Web.WebView2.Wpf;assembly=Microsoft.Web.WebView2.Wpf}WebView2'."
At C:\dev\webview2dev\poc.ps1:30 char:1
+ $window = [Windows.Markup.XamlReader]::Load($reader)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : XamlParseException
If I remove this line from the XAML:
<wv2:WebView2 Name="webView"
Source="C:\dev\webview2dev\xmlFile.xml"
/>
I get the WPF window to generate, so I think I'm missing something specifically related to trying to get WebView2 up and running for the window in PowerShell.
I've read several articles that indicate I need to put the .dlls in the script directory. Tried that, no success. I read something indicating I need to set the User Data Folder, but have thus far been unsuccessful in figuring out how to accomplish that. In any event, I wanted to put this question here to ask for guidance, as I get the feeling I am misunderstanding something fundamental insofar as getting this to work. Any insight/suggestions would be greatly appreciated, thanks.
Here's the working script. I found that the webview2.dlls needed to be in the script directory. I manually dropped them in from where webview2 was installed. Eventually will have the filecopy of the .dlls included in the script after the nuGet package installs:
function New-XamlGui {
[CmdletBinding()]
param (
[parameter(Mandatory,ParameterSetName="String")]
[string]
$XamlXmlString,
[Parameter(Mandatory,ParameterSetName="File")]
[ValidateScript({Test-Path $_})]
[string]
$XamlFile
)
begin {
if (-not ( ([System.Management.Automation.PSTypeName]'windows.markup.xamlreader').type ) ) {
try {
[void][System.Reflection.Assembly]::LoadWithPartialName('presentationframework')
}
catch {
#This looks odd but will stop execution of the rest of the script.
$PSCmdlet.ThrowTerminatingError($_)
}
}
}
process {
if ($PSCmdlet.ParameterSetName -eq "File"){
$XamlXmlString = Get-Content -Raw $XamlFile
if ( -not $XamlXmlString){
$PSCmdlet.ThrowTerminatingError(
( new-object System.Management.Automation.ErrorRecord -ArgumentList @(
[System.Management.Automation.RuntimeException]'EmptyOrMissingFile',
'EasyGUI.UnableToReadFileOrEmpty',
[System.Management.Automation.ErrorCategory]::InvalidData,
$XamlFile
)
)
)
}
}
# fix up xaml from VS:
$XamlXmlString = $XamlXmlString -replace '(x:)?Class=".*?"',''
$XamlXmlString = $XamlXmlString -replace "x:Name=","Name="
$XamlXmlString = $XamlXmlString -replace '(mc:)?Ignorable=".*?"',''
try {
$InputXAML = [xml]$XamlXmlString
} catch {
#This looks odd but will stop execution of the rest of the script.
$PSCmdlet.ThrowTerminatingError($_)
}
$XMLReader = New-Object System.Xml.XmlNodeReader $InputXAML
try {
$XAMLForm = [Windows.Markup.XamlReader]::Load($XMLReader)
}
catch {
$exception = [System.Exception]::new('Failed to load XAML file.'+$_.Exception.tostring(),$_.Exception)
$PSCmdlet.ThrowTerminatingError(
( new-object System.Management.Automation.ErrorRecord -ArgumentList @(
$exception,
'EasyXAML.ReaderLoadError',
[System.Management.Automation.ErrorCategory]::InvalidResult,
$InputXAML
)
)
)
}
$NamedControls = @{}
foreach ($node in ($InputXAML.SelectNodes("//*[@Name]") ) ) {
$NamedControls[$node.name] = $XAMLForm.FindName($node.name)
}
[pscustomobject]@{
Form = $XAMLForm
NamedControls = $NamedControls
}
}
end {
$stop
}
}
if($(Get-Package | ?{$_.Name -Eq 'Microsoft.Web.WebView2'})-eq $null){
if(Get-PackageSource | ?{$_.Name -eq 'nuGet.org'} -eq $null){
Register-PackageSource -provider NuGet -name nugetRepository -location https://www.nuget.org/api/v2 #-ErrorAction SilentlyContinue
}
install-Package -Name Microsoft.Web.WebView2 -Scope CurrentUser #-ErrorAction SilentlyContinue
}
Add-type -LiteralPath "C:\psScriptPath\Microsoft.Web.WebView2.Core.dll"
Add-type -LiteralPath "c:\psScriptPath\Microsoft.Web.WebView2.Wpf.dll"
Add-Type -assemblyName PresentationCore
Add-Type -assemblyName PresentationFramework
$inputXML = Get-content C:\psScriptPath\XAML\window.xaml -Raw
$f = New-XamlGui -XamlXmlString $inputXML
$f.form.showdialog()
and as for the XAML:
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:wv2="clr-namespace:Microsoft.Web.WebView2.Wpf;assembly=Microsoft.Web.WebView2.Wpf"
mc:Ignorable="d"
Title="DCERT Viewer"
Height="800" Width="1200" Topmost="False"
ResizeMode="CanResizeWithGrip" ShowInTaskbar = "True"
WindowStartupLocation = "CenterScreen"
x:Name="MainForm"
Background="AliceBlue" UseLayoutRounding="True"
>
<Grid Background="#FFE5E5E5">
<Grid.RowDefinitions>
<RowDefinition Height="30"/>
<RowDefinition/>
</Grid.RowDefinitions>
<wv2:WebView2 x:Name="_webView2" Grid.Row="1" Visibility="Visible" Source="C:\psScriptpath\xmlFile.xml" >
<wv2:WebView2.CreationProperties>
<wv2:CoreWebView2CreationProperties AdditionalBrowserArguments="--allow-file-access-from-files" UserDataFolder="C:\Temp\Data"/>
</wv2:WebView2.CreationProperties>
</wv2:WebView2>
</Grid>
</Window>