powershell编写一个简易的http服务器httpServer

ops/2025/2/4 21:05:40/
http://www.w3.org/2000/svg" style="display: none;">

文章目录

    • powershell一键启动
      • 检查相关进程
    • 源码

powershell一键启动

一键启动脚本内容(powershell,兼容windows powershell和powershell7+)

irm https://gitee.com/xuchaoxin1375/scripts/raw/main/PS/Tools/Tools.psm1|iex
sleep 0.5
help Start-HTTPServer
#可以指定参数选择服务器根目录和端口
start-httpServer

一键启动依赖于互联网,会从gitee下载代码运行

如果要离线运行,参考最后一节,或者部署上述脚本仓库scripts: 实用脚本集合,以powershell模块为主(针对powershell 7开发) 支持一键部署,改善windows下的shell实用体验


如果部署相关仓库pwsh模块,可以使用Start-HttpserverBG来启动一个后台httpServer进程

可以配合一下方法查询相关进程

检查相关进程

@("*pwsh*","*powershell*")|%{ps -Name $_ } |?{$_.CommandLine -like '*httpServer*'}

例如:

@("*pwsh*","*powershell*")|%{ps -Name $_ } |?{$_.CommandLine -like '*httpServer*'}NPM(K)    PM(M)      WS(M)     CPU(s)      Id  SI ProcessName------    -----      -----     ------      --  -- -----------84    45.52     116.32       1.91   12084   2 pwsh

杀死查询结果

ps -Id 12084 |kill

源码

可以跳过不看,如果源码不可用,则可以将下面代码拷贝到powershell的配置文件或者自动导入模块中,然后用powershell命令行收入Start-HttpServer也能离线(不联网)启动本地服务器

更直接的用法是将内容复制保存到一个.ps1脚本文件中,然后通过右键,选择以powershell方式运行(建议用pwsh而非自带的powershell.exe)即可启动服务

windows powershell.exe对于中文(utf8)编码的脚本可能会乱码报错,因此下面的代码纯英文

# If you need to set the service start path, modify the parameters on the last line.
# By default, the desktop is set as the server directory, and the port is 8080.function Format-FileSize
{param([long]$Size)if ($Size -gt 1GB) { return "{0:N2} GB" -f ($Size / 1GB) }if ($Size -gt 1MB) { return "{0:N2} MB" -f ($Size / 1MB) }if ($Size -gt 1KB) { return "{0:N2} KB" -f ($Size / 1KB) }return "$Size B"
}function Get-MimeType
{param([string]$Extension)$MimeTypes = @{".txt"  = "text/plain; charset=utf-8"".ps1"  = "text/plain; charset=utf-8"".py"   = "text/plain; charset=utf-8"".htm"  = "text/html; charset=utf-8"".html" = "text/html; charset=utf-8"".css"  = "text/css; charset=utf-8"".js"   = "text/javascript; charset=utf-8"".json" = "application/json; charset=utf-8"".jpg"  = "image/jpeg"".jpeg" = "image/jpeg"".png"  = "image/png"".gif"  = "image/gif"".pdf"  = "application/pdf"".xml"  = "application/xml; charset=utf-8"".zip"  = "application/zip"".md"   = "text/markdown; charset=utf-8"".mp4"  = "video/mp4"".mp3"  = "audio/mpeg"".wav"  = "audio/wav"}$key = $Extension.ToLower()if ($MimeTypes.ContainsKey($key)){return $MimeTypes[$key]}return "application/octet-stream"
}function Get-DirectoryListing
{param($RelativePath, $Items)$html = @"
<!DOCTYPE html>
<html>
<head><meta charset="utf-8"><title>Index of /$RelativePath</title><style>body { font-family: Arial, sans-serif; margin: 20px; }table { border-collapse: collapse; width: 100%; }th, td { text-align: left; padding: 8px; border-bottom: 1px solid #ddd; }th { background-color: #f2f2f2; }tr:hover { background-color: #f5f5f5; }a { text-decoration: none; color: #0066cc; }.size { text-align: right; }.date { white-space: nowrap; }</style>
</head>
<body><h1>Index of /$RelativePath</h1><table><tr><th>Name</th><th class="size">Size</th><th class="date">Last Modified</th></tr>
"@if ($RelativePath){$html += "<tr><td><a href='../'>..</a></td><td></td><td></td></tr>"}# Process folders and files separately and sort by name$Folders = $Items | Where-Object { $_.PSIsContainer } | Sort-Object Name$Files = $Items | Where-Object { !$_.PSIsContainer } | Sort-Object Name# Display folders firstforeach ($Item in $Folders){$Name = $Item.Name$LastModified = $Item.LastWriteTime.ToString("yyyy-MM-dd HH:mm:ss")$EncodedName = [System.Web.HttpUtility]::UrlEncode($Name)$html += "<tr><td><a href='$EncodedName/'>$Name/</a></td><td class='size'>-</td><td class='date'>$LastModified</td></tr>"}# Display files nextforeach ($Item in $Files){$Name = $Item.Name$Size = Format-FileSize $Item.Length$LastModified = $Item.LastWriteTime.ToString("yyyy-MM-dd HH:mm:ss")$EncodedName = [System.Web.HttpUtility]::UrlEncode($Name)$html += "<tr><td><a href='$EncodedName'>$Name</a></td><td class='size'>$Size</td><td class='date'>$LastModified</td></tr>"}$html += @"</table><footer style="margin-top: 20px; color: #666; font-size: 12px;">Total $($Folders.Count) folders, $($Files.Count) files</footer>
</body>
</html>
"@return $html
}function Start-HTTPServer
{<#.SYNOPSISStarts a simple HTTP file server..DESCRIPTIONServes a specified local folder as the root directory of an HTTP server, defaulting to port 8080..PARAMETER PathSpecifies the local folder path to be used as the server root directory..PARAMETER PortSpecifies the port number the HTTP server should listen on, defaulting to 8080..EXAMPLEStart-HTTPServer -Path "C:\Share" -Port 8000Serves the C:\Share folder as root at port 8000..EXAMPLEStart-HTTPServerServes the current directory as root at port 8080.#>[CmdletBinding()]param([Parameter(Position = 0)][string]$Path = (Get-Location).Path,[Parameter(Position = 1)][int]$Port = 8080)Add-Type -AssemblyName System.Webtry{# Validate path existsif (-not (Test-Path $Path)){throw "The specified path '$Path' does not exist."}# Create HTTP listener$Listener = New-Object System.Net.HttpListener$Listener.Prefixes.Add("http://+:$Port/")# Try to start the listenertry{$Listener.Start()}catch{throw "Cannot start HTTP server, possibly due to insufficient permissions or port already in use: $_"}Write-Host "HTTP server has started:"Write-Host "Root directory: $Path"Write-Host "Address: http://localhost:$Port/"Write-Host "Press Ctrl+C to stop the server (it may take a few seconds, if you can't wait consider closing the corresponding command line window)"while ($Listener.IsListening){# Wait for request$Context = $Listener.GetContext()$Request = $Context.Request$Response = $Context.Response# URL decode request path$DecodedPath = [System.Web.HttpUtility]::UrlDecode($Request.Url.LocalPath)$LocalPath = Join-Path $Path $DecodedPath.TrimStart('/')# Set response header, support UTF-8$Response.Headers.Add("Content-Type", "text/html; charset=utf-8")# Handle directory requestif ((Test-Path $LocalPath) -and (Get-Item $LocalPath).PSIsContainer){$LocalPath = Join-Path $LocalPath "index.html"if (-not (Test-Path $LocalPath)){# Generate directory listing$Content = Get-DirectoryListing $DecodedPath.TrimStart('/') (Get-ChildItem (Join-Path $Path $DecodedPath.TrimStart('/')))$Buffer = [System.Text.Encoding]::UTF8.GetBytes($Content)$Response.ContentLength64 = $Buffer.Length$Response.OutputStream.Write($Buffer, 0, $Buffer.Length)$Response.Close()continue}}# Handle file requestif (Test-Path $LocalPath){$File = Get-Item $LocalPath$Response.ContentType = Get-MimeType $File.Extension$Response.ContentLength64 = $File.Length# Add filename encoding support$FileName = [System.Web.HttpUtility]::UrlEncode($File.Name)$Response.Headers.Add("Content-Disposition", "inline; filename*=UTF-8''$FileName")$FileStream = [System.IO.File]::OpenRead($File.FullName)$FileStream.CopyTo($Response.OutputStream)$FileStream.Close()}else{# Return 404$Response.StatusCode = 404$Content = "404 - File not found"$Buffer = [System.Text.Encoding]::UTF8.GetBytes($Content)$Response.ContentLength64 = $Buffer.Length$Response.OutputStream.Write($Buffer, 0, $Buffer.Length)}$Response.Close()}}finally{if ($Listener){$Listener.Stop()$Listener.Close()}}
}function Start-HTTPServerBG
{param (# Default shell is Windows PowerShell, if PowerShell 7+ (or pwsh) is installed, use pwsh instead;# By default, need to add Start-HTTPServer to PowerShell configuration file or PowerShell auto-import module, otherwise Start-HTTPServerBG command will not be available, leading to start failure.# $shell = "powershell",$shell = "pwsh", # Personally prefer pwsh$path = "$home\Desktop",$Port = 8080)Write-Verbose "Trying to start HTTP server..." -Verbose# $PSBoundParameters $params = [PSCustomObject]@{shell = $shellpath  = $pathPort  = $Port}Write-Output $params # Cannot directly output literal object with Write-Output, it will be treated as a string# Write-Output $shell, $path, $Port# $exp = "Start-Process -WindowStyle Hidden -FilePath $shell -ArgumentList { {c Start-HTTPServer -path $path -port $Port } -PassThru"# Write-Output $exp# $ps = $exp | Invoke-Expression# $func = ${Function:Start-HTTPServer} # Since the complete code of Start-HTTPServer is too scattered, just writing this way cannot obtain the complete Start-HTTPServer function$ps = Start-Process -FilePath $shell -ArgumentList "-c Start-HTTPServer -path $path -port $Port" -PassThru# Debug start-process syntax# $ps = Start-Process -FilePath pwsh -ArgumentList "-c", "Get-Location;Pause "return $ps}# Modify as needed
Start-HTTPServer -Path "$home\Desktop" -Port 8080

http://www.ppmy.cn/ops/155670.html

相关文章

【漫话机器学习系列】073.黑塞矩阵(Hessian Matrix)

黑塞矩阵&#xff08;Hessian Matrix&#xff09; 黑塞矩阵&#xff08;Hessian Matrix&#xff09;是多变量数学中一个重要的概念&#xff0c;它是一个矩阵&#xff0c;包含了函数的二阶偏导数。黑塞矩阵在优化问题、机器学习以及深度学习中起着至关重要的作用&#xff0c;特…

pytorch深度Q网络

人工智能例子汇总&#xff1a;AI常见的算法和例子-CSDN博客 DQN 引入了深度神经网络来近似Q函数&#xff0c;解决了传统Q-learning在处理高维状态空间时的瓶颈&#xff0c;尤其是在像 Atari 游戏这样的复杂环境中。DQN的核心思想是使用神经网络 Q(s,a;θ)Q(s, a; \theta)Q(s,…

初始JavaEE篇 —— Spring Web MVC入门(上)

找往期文章包括但不限于本期文章中不懂的知识点&#xff1a; 个人主页&#xff1a;我要学编程程(ಥ_ಥ)-CSDN博客 所属专栏&#xff1a;JavaEE 目录 RequestMappingg 注解介绍 Postman的介绍与使用 PostMapping 与 GetMapping 注解 构造并接收请求 接收简单参数 接收对象…

pytorch实现简单的情感分析算法

人工智能例子汇总&#xff1a;AI常见的算法和例子-CSDN博客 在PyTorch中实现中文情感分析算法通常涉及以下几个步骤&#xff1a;数据预处理、模型定义、训练和评估。下面是一个简单的实现示例&#xff0c;使用LSTM模型进行中文情感分析。 1. 数据预处理 首先&#xff0c;我…

8、面向对象:类、封装、构造方法

一、类 1、定义 类&#xff1a;对现实世界中事物的抽象。Student 对象&#xff1a;现实世界中具体的个体。张三、李四 这些具体的学生 面向对象的特征&#xff1a;抽象、封装、继承、多态 OOP: Object Oriented Programming&#xff08;面向对象编程&#xff09; 类和对象…

Paddle和pytorch不可以同时引用

import paddleprint(paddle.utils.run_check())import torch print(torch.version.cuda)print(torch.backends.cudnn.version()) 报错&#xff1a; OSError: [WinError 127] 找不到指定的程序。 Error loading "C:\Program Files\Python311\Lib\site-packages\torch\li…

求职刷题力扣DAY34--贪心算法part05

Definition for a binary tree node. class TreeNode: def init(self, val0, leftNone, rightNone): self.val val self.left left self.right right class Solution: def minCameraCover(self, root: Optional[TreeNode]) -> int: # 三种状态0&#xff1a;没有覆盖…

深度学习编译器的演进:从计算图到跨硬件部署的自动化之路

第一章 问题的诞生——深度学习部署的硬件困境 1.1 计算图的理想化抽象 什么是计算图&#xff1f; 想象你正在组装乐高积木。每个积木块代表一个数学运算&#xff08;如加法、乘法&#xff09;&#xff0c;积木之间的连接代表数据流动。深度学习框架正是用这种"积木拼接…