233 lines
7.3 KiB
C#
233 lines
7.3 KiB
C#
using System.IO.Pipes;
|
|
using System.Text;
|
|
using System.Text.Json;
|
|
|
|
namespace PrintServiceCLI;
|
|
|
|
class Program
|
|
{
|
|
private const string PipeName = "PrintServicePipe";
|
|
private const int TimeoutMs = 5000;
|
|
|
|
static async Task<int> Main(string[] args)
|
|
{
|
|
try
|
|
{
|
|
// Handle special --install-service flag (called by elevated process)
|
|
if (args.Contains("--install-service"))
|
|
{
|
|
return ServiceManager.EnsureServiceRunning(silent: false) ? 0 : 1;
|
|
}
|
|
|
|
// Check for skip-service-check flag
|
|
bool skipServiceCheck = args.Contains("--skip-service-check");
|
|
|
|
// Parse arguments
|
|
var command = ParseArguments(args, out bool showHelp);
|
|
if (showHelp || command == null)
|
|
{
|
|
ShowUsage();
|
|
return command == null ? 1 : 0;
|
|
}
|
|
|
|
// Ensure service is running (unless testing)
|
|
if (!skipServiceCheck)
|
|
{
|
|
if (!ServiceManager.EnsureServiceRunning())
|
|
{
|
|
Console.Error.WriteLine("ERROR: Service is not available. Cannot process print request.");
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
var result = await SendCommandToService(command);
|
|
|
|
if (result.Success)
|
|
{
|
|
Console.WriteLine($"SUCCESS: {result.Message}");
|
|
return 0;
|
|
}
|
|
else
|
|
{
|
|
Console.Error.WriteLine($"ERROR: {result.Message}");
|
|
return 1;
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Console.Error.WriteLine($"FATAL ERROR: {ex.Message}");
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Parse command line arguments
|
|
/// </summary>
|
|
static PrintCommand? ParseArguments(string[] args, out bool showHelp)
|
|
{
|
|
showHelp = false;
|
|
string? filePath = null;
|
|
string? documentType = null;
|
|
string? orderNumber = null;
|
|
|
|
for (int i = 0; i < args.Length; i++)
|
|
{
|
|
switch (args[i].ToLower())
|
|
{
|
|
case "-f":
|
|
case "--file":
|
|
if (i + 1 < args.Length)
|
|
{
|
|
filePath = args[++i];
|
|
}
|
|
break;
|
|
|
|
case "-t":
|
|
case "--type":
|
|
if (i + 1 < args.Length)
|
|
{
|
|
documentType = args[++i];
|
|
}
|
|
break;
|
|
|
|
case "-o":
|
|
case "--order":
|
|
if (i + 1 < args.Length)
|
|
{
|
|
orderNumber = args[++i];
|
|
}
|
|
break;
|
|
|
|
case "-h":
|
|
case "--help":
|
|
case "?":
|
|
showHelp = true;
|
|
return null;
|
|
|
|
case "--skip-service-check":
|
|
case "--install-service":
|
|
// These flags are handled in Main, skip here
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Validate required arguments
|
|
if (string.IsNullOrEmpty(filePath))
|
|
{
|
|
Console.Error.WriteLine("Error: File path is required (-f)");
|
|
return null;
|
|
}
|
|
|
|
if (string.IsNullOrEmpty(documentType))
|
|
{
|
|
Console.Error.WriteLine("Error: Document type is required (-t)");
|
|
return null;
|
|
}
|
|
|
|
if (!File.Exists(filePath))
|
|
{
|
|
Console.Error.WriteLine($"Error: File not found: {filePath}");
|
|
return null;
|
|
}
|
|
|
|
return new PrintCommand
|
|
{
|
|
FilePath = Path.GetFullPath(filePath),
|
|
DocumentType = documentType,
|
|
OrderNumber = orderNumber
|
|
};
|
|
}
|
|
|
|
/// <summary>
|
|
/// Send command to service via named pipe
|
|
/// </summary>
|
|
static async Task<PrintResponse> SendCommandToService(PrintCommand command)
|
|
{
|
|
using var pipeClient = new NamedPipeClientStream(
|
|
".",
|
|
PipeName,
|
|
PipeDirection.InOut,
|
|
PipeOptions.Asynchronous);
|
|
|
|
try
|
|
{
|
|
await pipeClient.ConnectAsync(TimeoutMs);
|
|
}
|
|
catch (TimeoutException)
|
|
{
|
|
return new PrintResponse
|
|
{
|
|
Success = false,
|
|
Message = "Service not responding. Is the LAAPC Print Service running?"
|
|
};
|
|
}
|
|
catch (IOException ex)
|
|
{
|
|
return new PrintResponse
|
|
{
|
|
Success = false,
|
|
Message = $"Cannot connect to service: {ex.Message}"
|
|
};
|
|
}
|
|
|
|
// Send command
|
|
var json = JsonSerializer.Serialize(command);
|
|
var bytes = Encoding.UTF8.GetBytes(json);
|
|
await pipeClient.WriteAsync(bytes, 0, bytes.Length);
|
|
await pipeClient.FlushAsync();
|
|
|
|
// Read response
|
|
var buffer = new byte[4096];
|
|
var bytesRead = await pipeClient.ReadAsync(buffer, 0, buffer.Length);
|
|
var responseJson = Encoding.UTF8.GetString(buffer, 0, bytesRead);
|
|
|
|
var response = JsonSerializer.Deserialize<PrintResponse>(responseJson);
|
|
return response ?? new PrintResponse { Success = false, Message = "Invalid response from service" };
|
|
}
|
|
|
|
/// <summary>
|
|
/// Show usage information
|
|
/// </summary>
|
|
static void ShowUsage()
|
|
{
|
|
Console.WriteLine("LAAPC Print Service CLI");
|
|
Console.WriteLine();
|
|
Console.WriteLine("Usage: PrintServiceCLI -f <filepath> -t <doctype> [-o <ordernumber>]");
|
|
Console.WriteLine();
|
|
Console.WriteLine("Options:");
|
|
Console.WriteLine(" -f, --file <path> Path to the capture file to print (required)");
|
|
Console.WriteLine(" -t, --type <type> Document type (required)");
|
|
Console.WriteLine(" Examples: invoice, order, delivery");
|
|
Console.WriteLine(" -o, --order <number> Optional order number");
|
|
Console.WriteLine(" -h, --help Show this help message");
|
|
Console.WriteLine(" --skip-service-check Skip service availability check (for testing)");
|
|
Console.WriteLine();
|
|
Console.WriteLine("Examples:");
|
|
Console.WriteLine(" PrintServiceCLI -f \"C:\\Captures\\file.txt\" -t invoice");
|
|
Console.WriteLine(" PrintServiceCLI -f \"C:\\Captures\\file.txt\" -t order -o 12345");
|
|
Console.WriteLine();
|
|
Console.WriteLine("For Development/Testing:");
|
|
Console.WriteLine(" PrintServiceCLI -f \"file.txt\" -t test --skip-service-check");
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Command to send to service
|
|
/// </summary>
|
|
class PrintCommand
|
|
{
|
|
public string FilePath { get; set; } = string.Empty;
|
|
public string DocumentType { get; set; } = string.Empty;
|
|
public string? OrderNumber { get; set; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// Response from service
|
|
/// </summary>
|
|
class PrintResponse
|
|
{
|
|
public bool Success { get; set; }
|
|
public string Message { get; set; } = string.Empty;
|
|
}
|
|
|