Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to debug PowerShell process whithout error message or exception

I am trying to run the following PowerShell script from within my .NET application:

try {
    Start-Process "C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" -ArgumentList "--headless --disable-gpu --print-to-pdf=c:\myDir\file.pdf https://www.bing.com"
$x = "Complete" 
$x | Out-File C:\myDir\error.txt
}
Catch {
    $_ | Out-File C:\myDir\error.txt
}

Simply, the above will create a pdf based upon bing.com website

In my dev environment it runs fine as a PowerShell script. It also runs fine on the production server (again, as a PowerShell script).

The issue occurs when I invoke this PowerShell script from my web app on the production server. My C# code is

var command = "c:\myDir\ps.ps1";
ProcessStartInfo psi = new ProcessStartInfo();
psi.FileName = "powershell.exe";
psi.Arguments = command;
Process process = new Process();
process.StartInfo = psi;
process.Start();

This works fine on my dev machine. It fails on the production server. The error.txt file is written to disc which suggests it's not a permissions issue. However, the content of the error.txt file always shows "complete". It never errors.

So, it appears that the catch in the PowerShell script is never being hit. As such, no error message. There is no exception thrown in the C# code. Regardless, it isn't working.

How can I debug this?

Or, if easier, I'm happy to run the code directly instead of invoking the PowerShell script file but the following also does 'nothing'.

 var command = $"\"C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe\" -ArgumentList \"--no-sandbox --headless --disable-gpu --print-to-pdf={imagePath} {fullUrl}";
like image 525
MyDaftQuestions Avatar asked Jun 14 '26 00:06

MyDaftQuestions


2 Answers

I was able to reproduce your problem. It is caused by the fact that web application on your production server is running under the user that is not currently logged in. It is running under identity of assigned application pool. Chrome has known issue of not working correctly if it's launched under the user different from currently logged user. If you check that link, you will see that issue was registered in December 2012 and still is not resolved. You could easily reproduce the problem if launch Chrome under the different user ("Run as different user" in shortcut context menu when called with pressed Shift). In this case Chrome will not open any page and will just show gray screen.

The workaround is to launch Chrome with --no-sandbox switch. Google actually does not recomment this. However if you run Chrome in automated way to access trusted source, I believe it's ok.

So to fix the problem modify start-process in the script in the following way:

start-process "C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" -ArgumentList "--no-sandbox --headless --disable-gpu --print-to-pdf=c:\myDir\file.pdf https://www.bing.com"

UPDATE

I have underestimated the problem at first. Now after additional research and many tried approaches I can propose solution that works.

I didn't manage to fix your current approach of direct launch of powershell and chrome from Web Application. Chrome just fails to start and following errors appear in Event log:

Faulting application name: chrome.exe, version: 64.0.3282.186, time stamp: 0x5a8e38d5
Faulting module name: chrome_elf.dll, version: 64.0.3282.186, time stamp: 0x5a8e1e3d
Exception code: 0x80000003
Fault offset: 0x00000000000309b9
Faulting process id: 0x11524
Faulting application start time: 0x01d3bab1a89e3b4f
Faulting application path: C:\Program Files (x86)\Google\Chrome\Application\chrome.exe
Faulting module path: C:\Program Files (x86)\Google\Chrome\Application\64.0.3282.186\chrome_elf.dll
Report Id: e70a5a36-26a4-11e8-ac26-b8ca3a94ba80

This error occurrs even if you configure application pool to use identity of some existing (ordinary) user that could launch the chrome. May be it's possible to configure IIS or application pool to prevent these errors but I have not found the way.

My proposal is to switch from starting powershell process from controller action to scheduling a task with Windows task scheduler.

Here are the steps that should be taken to accomplish this task:

  1. On your production server create a user under which the Chrome will be started. I'll refer to created user as 'testuser'.
  2. Login under testuser, start chrome, open some site. Without this step, the flow was not successfully, probably because of missing chrome user account.
  3. Grant "Log on as a batch job" right for testuser. This step is required for successfull execution of scheduled tasks under testuser. The procedure is described in this answer
  4. Add --no-sandbox argument to the script as I described in my initial answer.
  5. Replace the code of Process.Start() with scheduling of the task job.

The easiest way to schedule a task from .Net is via TaskScheduler NuGet. Install it to your application and add following code:

string powerShellScript = @"c:\myDir\ps.ps1";
string userName = @"YOURCOMP\testuser";
string userPassword = "TestPwd123";

using (TaskService ts = new TaskService())
{
    TaskDefinition td = ts.NewTask();
    td.Triggers.Add(new RegistrationTrigger
    {
        StartBoundary = DateTime.Now,
        EndBoundary = DateTime.Now.AddMinutes(1),
    });
    td.Settings.DeleteExpiredTaskAfter = TimeSpan.FromSeconds(5);
    td.Actions.Add(new ExecAction("powershell.exe", powerShellScript));
    ts.RootFolder.RegisterTaskDefinition($@"Print Pdf - {Guid.NewGuid()}", td, createType: TaskCreation.Create, userId: userName, password: userPassword, logonType: TaskLogonType.Password);
}

In above code snippet change the name and password for testuser.

With this approach your script is successfully executed and pdf is printed successfully.

Update by OP

If the above continues to fail, then again, check the Event Viewer logs. In this case, I had an issues with a message similar to The machine-default permission settings do not grant Local Activation permission for the COM Server application with CLSID {20FD4E26-8E0F-4F73-A0E0-F27B8C57BE6F} and APPID Unavailable but it was resolved by granting permissions for the CLSID. Further, try to run the task in task scheduler by itself, such as create a new task to simply launch notepad or similar to make sure that this is working with the account you want to test. In my case, I had to use the administrator account.

like image 151
CodeFuller Avatar answered Jun 16 '26 14:06

CodeFuller


You have to redirect the stdin and stdout so that it sends it from powershell.exe back to the parent process (your web app). I modified your code sample to do this:

var command = "c:\myDir\ps.ps1";
ProcessStartInfo psi = new ProcessStartInfo();
psi.FileName = "powershell.exe";
psi.Arguments = command;

psi.RedirectStandardOutput = true;
psi.RedirectStandardError = true;

Process process = new Process();
process.StartInfo = psi;
process.Start();

process.WaitForExit();

Console.WriteLine(process.StandardOutput);
Console.WriteLine(process.StandardError);
like image 44
Mike Veazie - MSFT Avatar answered Jun 16 '26 13:06

Mike Veazie - MSFT



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!