You are doing a Process Start… on a Function server side… that will / should never work. You are running these files on the server. Where do you expect them to be downloading to?
The Process.Start method in C# is used to start a new process or open a file or URL using the default application associated with it in the context . system in which it was invoked. This method is part of the System.Diagnostics namespace. It can be utilized to run executables, open documents, launch websites, or execute commands.
Here’s a brief explanation of some common usages:
Starting a Program:
using System.Diagnostics;
Process.Start("notepad.exe");
This line of code will launch Notepad.
Opening a URL in the Default Browser:
using System.Diagnostics;
Process.Start("http://www.example.com");
This will open the specified URL in the default web browser.
Opening a File with its Associated Program:
using System.Diagnostics;
Process.Start("example.txt");
This will open the example.txt file with the default text editor.
Starting a Process with Specified Arguments:
using System.Diagnostics;
ProcessStartInfo startInfo = new ProcessStartInfo("notepad.exe")
{
Arguments = "example.txt"
};
Process.Start(startInfo);
This will open example.txt in Notepad.
The Process.Start method is quite versatile and provides various overloads for different use cases, allowing for both simple and more advanced process start scenarios.
Like data exfiltration and installing a malicious shell.
For security reasons, the web browser won’t automatically download anything without user permission. If it’s really important then you need a program running locally like the old .NET Client (System Monitor), the Kinetic EdgeClient, or a custom program/service that you write than has access to the local machine.
A function triggered via REST can only return JSON. You could return the file in base64, but that won’t be much use to the user. If you really want to stream to the browser, you have to create your own WebApi and return a FileContentResult
for example:
[ProducesResponseType(typeof(FileContentResult), StatusCodes.Status200OK)]
public async override Task<ActionResult> HandleAsync([FromRoute] Guid sysRowId, CancellationToken cancellationToken = default(CancellationToken))
{
// Get the file
var file = await mErpRestClientFactory.GetService<IAAttachmentFunctions>().Call_GetAttachmentAsync(new GetAttachmentInput { SysRowID = sysRowId }, cancellationToken);
// Get the file in bytes
var bytes = Convert.FromBase64String(file.FileBase64);
// Get content type
var contentType = file.Filename.GetContentType();
// Return file
return new CustomFileResult(bytes, contentType)
{
FileDownloadName = file.Filename,
Inline = true
};
}
public class CustomFileResult : FileContentResult
{
public CustomFileResult(byte[] fileContents, string contentType) : base(fileContents, contentType)
{
}
/// <summary>
/// True to display in browser if possible vs downloading the file
/// </summary>
public bool Inline { get; set; }
public override Task ExecuteResultAsync(ActionContext context)
{
// Check for null
ArgumentNullException.ThrowIfNull(context, nameof(context));
// Set header value
var contentDispositionHeaderValue = new ContentDispositionHeaderValue(Inline ? "inline" : "attachment");
contentDispositionHeaderValue.SetHttpFileName(FileDownloadName);
FileDownloadName = null;
// Add header
context.HttpContext.Response.Headers.Add(HeaderNames.ContentDisposition, contentDispositionHeaderValue.ToString());
// Return completed task
return base.ExecuteResultAsync(context);
}
}