[英]Make HTML file open in default browser instead of text editor in Windows batch file
我有一個生成一些HTML頁面的腳本,完成后,我打開生成的頁面的索引文件。 為此,我有以下代碼:
if exist "generated_pages/index.html" start "" "generated_pages/index.html"
現在,該頁面在.html文件的默認文本編輯器中打開,如何確保它在用戶的默認瀏覽器中打開? 我不想為特定的瀏覽器使用命令,因為我不知道用戶的默認瀏覽器將是什么。
不幸的是,無法使用start
命令指定要start
的程序類型。 它將基於文件的擴展名啟動默認的關聯程序,而您對於用戶對.html文件的文件關聯的可疑選擇感到不滿。 如果要確保僅通過Web瀏覽器而不是通過文本編輯器打開文件,則最好將URL傳遞給start
不是文件系統位置。 使用http地址作為start
參數應確保打開位置的設備將是Web瀏覽器。
無需依賴第三方二進制文件即可通過http服務.html文件。 使用.Net方法創建基本的Web服務器並通過localhost返回網頁並不難。 這樣,您可以start "" "http://localhost:port/"
並且如果您的用戶搞砸了他們的文件關聯,您將有更大的機會避免在文本編輯器中打開文件。
將以下魔術保存為.bat腳本,根據需要調整html文件名和位置,然后嘗試一下。
<# : httptest.bat -- https://stackoverflow.com/a/53689025/1683264
@echo off & setlocal
if exist test.html call :display test.html
goto :EOF
:display <htmlfile>
setlocal
set "infile=%~f1"
powershell -noprofile "iex (${%~f0} | out-string)"
endlocal & exit /b
: end Batch / begin PowerShell polyglot code #>
$tcpClient = new-object Net.Sockets.TcpClient
while ($port = get-random -min 1024 -max 65535) {
try {$tcpClient.Connect("localhost", $port)}
catch {$tcpClient.Dispose(); break}
}
$endpoint = new-object Net.IPEndPoint([Net.IPAddress]::Any, $port)
$listener = new-object Net.Sockets.TcpListener $endpoint
$listener.start()
cmd /c start "" "http://localhost:$($port)/"
$client = $listener.AcceptTcpClient()
$stream = $client.GetStream()
if ($stream.CanRead) {
[void]$stream.read((new-object byte[] 1024), 0, 1024);
}
if ($stream.CanWrite) {
$content = "HTTP/1.1 200 OK`n`n$(gc $env:infile)"
$out = [text.encoding]::UTF8.GetBytes($content)
$stream.write($out, 0, $out.length)
}
$stream.close()
$stream.dispose()
$listener.stop()
作為附帶的好處,通過http提供html可以幫助您避免某些瀏覽器的安全性受到限制,從而禁止JavaScript從file:/// URL執行。
如果要包括其他引用的文件,例如圖像,css文件,源JavaScript文件等,那確實會有些棘手。 這是一個更徹底的示例,它偵聽最初的http請求最多60秒鍾,然后在瀏覽器請求它們時繼續提供相對路徑源文件,直到5秒鍾沒有收到請求為止。 它應該正確聲明圖像和其他源文件的mime類型。 如果您需要更長的超時時間,請更改底部附近的serve-content 5
行。
<# : httptest2.bat -- https://stackoverflow.com/a/53689025/1683264
@echo off & setlocal
if exist "%~1" (call :display "%~1") else goto usage
goto :EOF
:usage
echo Usage: %~nx0 htmlfile
exit /b
:display <htmlfile>
setlocal
set "infile=%~f1"
powershell -noprofile "iex (${%~f0} | out-string)"
endlocal & exit /b
: end Batch / begin PowerShell polyglot code #>
Add-Type -as System.Web
$rootpath = (get-item $env:infile).DirectoryName
$filename = (get-item $env:infile).Name
$webname = [Web.HttpUtility]::UrlEncode($filename)
$tcpClient = new-object Net.Sockets.TcpClient
while ($port = get-random -min 1024 -max 65535) {
try {$tcpClient.Connect("localhost", $port)}
catch {$tcpClient.Dispose(); break}
}
cmd /c start "" "http://localhost:$($port)/$webname"
function log($polarity, $txt) {
$color = (("red","darkgray"),("green","white"))[$polarity]
write-host -nonewline "[" -f $color[1]
write-host -nonewline "*" -f $color[0]
write-host "] $txt" -f $color[1]
}
function serve-content($seconds) {
$timer = (get-date).AddSeconds($seconds)
while (!$listener.Pending()) {
start-sleep -milliseconds 10
if ((get-date) -ge $timer) { return $false }
}
$client = $listener.AcceptTcpClient()
$stream = $client.GetStream()
if ($stream.CanRead) {
$request = new-object byte[] 1024
$size = $stream.read($request, 0, $request.length)
$headers = [text.encoding]::UTF8.GetString($request, 0, $size)
if ($stream.CanWrite) {
$loc = $headers.split("`r?`n")[0] -replace "^\S+\s+|\s+HTTP/\d.+$"
$loc = $loc -replace "^/", "$rootpath/" -replace "/", "\"
$loc = [Web.HttpUtility]::UrlDecode($loc)
if ($loc) {
if (!(test-path $loc -type leaf)) {
$loc = [Web.HttpUtility]::UrlDecode($loc)
}
if (test-path $loc -type leaf) {
$response = ,"HTTP/1.1 200 OK"
$mime = [Web.MimeMapping]::GetMimeMapping($loc)
$response += ,"Content-Type: $mime"
$response += ,"Content-Length: $((gi $loc).length)","",""
$out = [text.encoding]::UTF8.GetBytes(($response -join "`n"))
[byte[]]$body = gc $loc -enc byte
$out += $body
$stream.write($out, 0, $out.length)
log $true $loc
}
else {
$response = "HTTP/1.1 404 Not Found","",@"
<html lang="en">
<head>
<title>Error 404</title>
</head>
<body>
<h3>Not Found</h3>
<p>The requested resource could not be located.</p>
</body>
</html>
"@
$out = [text.encoding]::UTF8.GetBytes(($response -join "`n"))
$stream.write($out, 0, $out.length)
log $false $loc
}
}
}
}
$stream.close()
$stream.dispose()
$client.close()
return $true
}
$endpoint = new-object Net.IPEndPoint([Net.IPAddress]::Any, $port)
$listener = new-object Net.Sockets.TcpListener $endpoint
$listener.start()
[void](serve-content 60)
while ((serve-content 5)) {}
$listener.stop()
我不知道這是否適用於其他瀏覽器,但是對於Chrome瀏覽器來說,這很好。 您可以使用chrome.exe
打開html
文件,如下所示:
if exist "generated_pages/index.html" start "" "full\path\to\chrome.exe" file:///C:/example/generated_pages/index.html
另一種方法是更改Windows帳戶中html
文件的默認處理程序。 ( right-click to file
=> Open With...
=> select your browser
然后option "Open always html files..."
)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.