我不是 Windows Server 专业人士,但搜索网络没有给出最新答案。
设置如下:我有一台 Windows Server 2022 计算机。我想通过网络发布请求触发一个程序。用户发送表单数据 f=foo 和 b=bar,服务器应运行带有
myprogram.exe -f foo -b bar
的程序。
我怎样才能做到这一点?安全性无需担心,因为这是一个虚拟服务器,没有已知用户的公共访问权限。
警告,以下内容仅用于概念证明。实际使用时,应根据实际需要进行调整。
浏览器打开https://dotnet.microsoft.com/en-us/download/dotnet/thank-you/sdk-7.0.410-windows-x64-installer
文件浏览器打开目录:下载
点击dotnet-sdk-7.0.410-win-x64.exe
打开CMD.exe
运行命令:添加NuGet源
dotnet nuget add source https://api.nuget.org/v3/index.json -n nuget.org
dotnet nuget list source
接下来我们将创建一个项目目录:
ST_NET7_EXAMPLES
mkdir %USERPROFILE%\Documents\ST_NET7_EXAMPLES
cd %USERPROFILE%\Documents\ST_NET7_EXAMPLES
dotnet new console -n MyProgram
MyProgram\Program.cs
using System;
using System.IO;
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hello, World!");
string fooValue = null;
string barValue = null;
for (int i = 0; i < args.Length; i++)
{
if (args[i] == "-f" && i + 1 < args.Length)
{
fooValue = args[i + 1]; // Get the value after `-f`
}
else if (args[i] == "-b" && i + 1 < args.Length)
{
barValue = args[i + 1]; // Get the value after `-b`
}
}
// Print results
Console.WriteLine($"-f: {fooValue}");
Console.WriteLine($"-b: {barValue}");
// Get the user's home directory
string userHomeDirectory = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile);
// Set the path of the log file
string logFilePath = Path.Combine(userHomeDirectory, "app.log");
// Write to log file
using (StreamWriter writer = new StreamWriter(logFilePath, append: true))
{
writer.WriteLine($"-f: {fooValue}");
writer.WriteLine($"-b: {barValue}");
writer.WriteLine($"Logged at: {DateTime.Now}");
}
Console.WriteLine($"Log written to {logFilePath}");
}
}
cd %USERPROFILE%\Documents\ST_NET7_EXAMPLES\MyProgram
dotnet build
dotnet run -- -f foo -b bar
dotnet publish -c Release -o ..\MyProgramApp
项目1:MyProgram的输出到这里已经完成了。
cd %USERPROFILE%\Documents\ST_NET7_EXAMPLES
dotnet new webapi -n DemoApp
DemoApp
├── DemoApp.csproj
├── appsettings.Development.json
├── appsettings.json
├── Controllers
│ ├── DemoController.cs <Add File>
│ └── WeatherForecastController.cs
├── Models <Create Directory>
│ └── Parameters.cs <Add File>
...
namespace DemoApp.Models
{
public class Parameters
{
public string F { get; set; }
public string B { get; set; }
}
}
using Microsoft.AspNetCore.Mvc;
using System.Diagnostics;
using DemoApp.Models;
namespace DemoApp.Controllers
{
[ApiController]
[Route("api/[controller]")]
public class DemoController : ControllerBase
{
// POST api/demo
[HttpPost]
public IActionResult Post([FromBody] Parameters parameters)
{
if (parameters == null)
{
return BadRequest("Invalid input");
}
// Access the parameters f and b
var f = parameters.F;
var b = parameters.B;
// Print Parameters
Console.WriteLine($"-f: {f}");
Console.WriteLine($"-b: {b}");
// Define the external program path
//Linux
//string programPath = "/home/demo/Desktop/TMP/ST_C_Sharp_X/CODE/myprogram/bin/Debug/net7.0/myprogram";
//Windows
// string programPath = "C:\\Users\\User\\Documents\\ST_C_Sharp_X\\CODE\\myprogram\\bin\\Release\\net7.0\\myprogram.exe";
string programPath = "C:\\TOOLS\\MyProgramApp\\MyProgram.exe";
// Create the process start info
var processStartInfo = new ProcessStartInfo
{
FileName = programPath,
Arguments = $"-f {f} -b {b}", // Pass parameters as command line arguments
RedirectStandardOutput = true, // Capture standard output if needed
RedirectStandardError = true, // Capture standard error if needed
UseShellExecute = false, // Required to redirect output
CreateNoWindow = true // Do not create a console window
};
try
{
// Start the process
using (var process = Process.Start(processStartInfo))
{
if (process == null)
{
return StatusCode(500, "Failed to start the process");
}
// Optionally capture output (if the program writes output)
string output = process.StandardOutput.ReadToEnd();
string error = process.StandardError.ReadToEnd();
// Wait for the process to exit
process.WaitForExit();
// Check if there was any error
if (process.ExitCode != 0)
{
return StatusCode(500, $"Process failed with exit code {process.ExitCode}: {error}");
}
// Return the output or a success message
return Ok(new { message = "Process completed successfully", output });
}
}
catch (Exception ex)
{
return StatusCode(500, $"Error running process: {ex.Message}");
}
return Ok(new { message = $"Received: f = {f}, b = {b}" });
}
}
}
dotnet publish -c Release -o ../publish
ST_NET7_EXAMPLES
├── DemoApp
├── MyProgram
├── MyProgramApp (1)
└── publish (2)
请将目录 (1)
MyProgramApp
(2) publish
复制到您的 Windows Server。
在
Downloads
目录下,点击运行dotnet-hosting-7.0.20-win.exe
MyProgramApp
目录复制
MyProgramApp
至C:\TOOLS
完整路径是
C:\TOOLS\MyProgramApp
publish
目录复制
publish
至C:\
完整路径是
C:\publish
站点 ->
Add Website...
站点名称:
DemoApp
物理路径:C:\publish
点击按钮:
OK
因为我们的设置
*:80
与默认的IIS站点相同,所以会有警告。
点击按钮
Yes
选择
Default Web Site
点击按钮
Stop
选择
DemoApp
点击按钮
Start
打开CMD.exe
运行命令:
curl -X POST ^
"http://localhost/api/demo" ^
-H "Content-Type: application/json" ^
-d "{\"f\":\"IISDemoAppHello\", \"b\":\"IISDemoAppWorld\"}"
返回:
{"message":"Process completed successfully","output":"Hello, World!\r\n-f: IISDemoAppHello\r\n-b: IISDemoAppWorld\r\nLog
written to C:\\Users\\TEMP\\app.log\r\n"}
可以打开
C:\Users\TEMP\app.log
-f: IISDemoAppHello
-b: IISDemoAppWorld
Logged at: 9/19/2024 11:44:58 PM
我没有相应的Windows Server。以上步骤是在Windows 10上开发和测试的。 因此,IIS部署的设置屏幕可能会有所不同。
这不是 CGI 程序。这是部署在 IIS 上的 DotNet 程序。