My requirement is to read the content from the file and send it to the chrome browser extension. I am using native messaging. I did all the configuration for native messaging but failed to send messages from the native messaging host to the extension. I am getting error like "Error when communicating with the native messaging host". I got to know that it was due to the wrong implementation of the native messaging protocol.
The Actual protocol from native messaging is : "The same format is used to send messages in both directions: each message is serialized using JSON, UTF-8 encoded and is preceded with 32-bit message length in native byte order. The maximum size of a single message from the native messaging host is 1 MB, mainly to protect Chrome from misbehaving native applications. The maximum size of the message sent to the native messaging host is 4 GB."
My code is as below: native-messaging-example-host.ps1:
$file = "D:\temp\test\test.txt"
$data = Get-content $file -Raw
$Objectdata = $data |ConvertFrom-Json
$formatedData = $Objectdata |Select-Object -Property message |ConvertTo-Json -Depth 1 -Compress
$encconsumerkey= [System.Text.UTF8Encoding]::new().GetBytes($formatedData)
$Writer = New-Object System.IO.BinaryWriter([System.Console]::OpenStandardOutput());
$Writer.Write([Int32]$encconsumerkey.length)
$Writer.Write($encconsumerkey)
$Writer
$Writer.Flush()
$Writer.Close()
My Batch Script which calls the above PowerShell script
MyExample1.bat
@echo off
color 1F
echo.
C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -ExecutionPolicy Bypass -File "D:\projects-repo\CromeNativeMessaging\NativeHost\native-messaging-example-host.ps1"
:EOF
echo Waiting seconds
timeout /t 10 /nobreak > NUL
NativeMessageHello.json
{
"name": "native.messaging.trail.example",
"description": "My Example1",
"path": "D:/projects-repo/CromeNativeMessaging/NativeHost/MyExample1.bat",
"type": "stdio",
"allowed_origins": [
"chrome-extension://lknkdjfamgnamaeaebinefklcobjpphm/"
]
}
Someone please help me where I am doing wrong.
CodePudding user response:
I'm assuming that your script is being called from outside PowerShell via the PowerShell CLI (powershell.exe
for Windows PowerShell, pwsh
for PowerShell (Core) 7 ).
There are two problems with your script, one potential, the other definite - I am not certain that fixing them is enough to solve your problem:
A potential problem is that the
[System.Text.Encoding]::UTF8
encoding is an encoding with BOM,[1] whereas it's safe to assume that Chrome does not expect your data to have a BOM in this scenario and may fail on encountering one.- To obtain a BOM-less UTF-8 encoding, use
New-Object System.Text.UTF8Encoding
instead, or, in PowerShell v4 and above,[System.Text.UTF8Encoding]::new()
.
- To obtain a BOM-less UTF-8 encoding, use
A definite problem is the
$Writer
statement (the line containing only$Writer
) in your code, which causes implicit output[2] to PowerShell's success output stream, which is relayed via stdout to an outside caller, in the form of a formatted representation of the$Writer
object (that is invariably text).That is, this statement "pollutes" the binary data you're sending to stdout.
- In general, prepending
$null =
suppresses unwanted implicit output;[3] here, it seems you can simply remove the statement.
- In general, prepending
The same goes for the batch file that wraps your PowerShell command: it too mustn't produce its own stdout output, so you must either remove the
echo
commands or redirect their output to stderr, with>&2
[1] in .NET Framework and as of .NET 6; changing this is being discussed for a future .NET version.
[2] See this answer for more information about PowerShell's implicit output behavior.
[3] See this answer form more information about output suppression.