Windows Service fails to execute mshtml.dll - c#

I have a Windows Application which uses mshtml.dll. It works fine within my Windows Form application.
When I use the same code within my Windows Service app then it fails. My Service runs as an Administrator.
below is the code I use:
private string PrintUsingPrinterExe(string Command)
{
System.Diagnostics.ProcessStartInfo procStartInfo = new System.Diagnostics.ProcessStartInfo("cmd", "/c " + Command);
// The following commands are needed to redirect the standard output.
// This means that it will be redirected to the Process.StandardOutput StreamReader.
procStartInfo.RedirectStandardOutput = true;
procStartInfo.UseShellExecute = false;
// Do not create the black window.
procStartInfo.CreateNoWindow = true;
// Now we create a process, assign its ProcessStartInfo and start it
System.Diagnostics.Process proc = new System.Diagnostics.Process();
proc.StartInfo = procStartInfo;
proc.Start();
//StreamWriter streamWriter = proc.StandardInput;
//StreamReader outputReader = proc.StandardOutput;
//StreamReader errorReader = proc.StandardError;
//while (!outputReader.EndOfStream)
//{
// string text = outputReader.ReadLine();
// streamWriter.WriteLine(text);
//}
//while (!errorReader.EndOfStream)
//{
// string text = errorReader.ReadLine();
// streamWriter.WriteLine(text);
//}
//streamWriter.Close();
proc.WaitForExit(12000);
// Get the output into a string
string result = proc.StandardOutput.ReadToEnd();
if (!proc.HasExited)
{
proc.Kill();
}
// Display the command output.
return result;
}
command is : PRINTHTML.EXE url="http://www.google.com" printername="Brother HL-2270DW series" title="" header="" footer=""
Under event Log I find this:
Faulting module path: C:\Windows\SYSTEM32\mshtml.dll
So, how could it be possible that same DLL works just fine under winForm app and does not work under Windows Service.
BTW, same service runs fine on Windows 7.
so issue is Windows 10 + mshtml.dll + Windows Service

Related

C# RedirectStandardOutput from third party terminal stops at first character

I'm trying to redirect the output from a third party terminal (accoreconsole.exe).
The output is redirected to a richtextbox.
If I manually type in the accoreconsole.exe from cmd I see the whole output but when I try to start it from my project it's stops at the first letter of the first row.
The first row where the output stops at letter R:
Redirect stdout (file: C:\Users\Marcus\AppData\Local\Temp\accc207883).
When I send something like "ipconfig" it work as it should.
I tried to send the output to a .txt file and that worked. But when I tried to apply the text from the .txt file to my textbox it stops at the same letter (R). If I manually opend the .txt file and just save it I can apply it to the textbox.. Wierd?
Any ideas? :) Thanks!
Manually from cmd:
Microsoft Windows [Version 10.0.19043.1348]
(c) Microsoft Corporation. All rights reserved.
C:\Users\Marcus>"C:\Program Files\Autodesk\AutoCAD 2018\accoreconsole.exe"
Redirect stdout (file: C:\Users\Marcus\AppData\Local\Temp\accc207883).
AcCoreConsole: StdOutConsoleMode: processed-output: enabled,auto
AutoCAD Core Engine Console - Copyright 2017 Autodesk, Inc. All rights reserved. (O.72.0.0)
Execution Path:
C:\Program Files\Autodesk\AutoCAD 2018\accoreconsole.exe
Version Number: O.72.0.0 (UNICODE)
Usage:
AcCoreConsole.exe [/i <input dwg>] /s <script>[/product <product>] [/l <language>] [/isolate <userid> <userDataFolder>] [/readonly] [/p[rofile] <profile>]
Example:
AcCoreConsole.exe /i 8th_floor.dwg /s test.scr /l en-US
C:\Users\Marcus>
Output from my project:
Microsoft Windows [Version 10.0.19043.1348]
(c) Microsoft Corporation. All rights reserved.
C:\Users\Marcus\source\repos\Test_Read_Console_Live\Test_Read_Console_Live\bin\Debug>"C:\Program Files\Autodesk\AutoCAD 2018\accoreconsole.exe"
R
My project code:
using System;
using System.Diagnostics;
using System.Windows.Forms;
namespace Test_Read_Console_Live
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
run();
}
public void run()
{
Process cmd = new Process()
{
StartInfo = new ProcessStartInfo("cmd")
{
RedirectStandardInput = true,
RedirectStandardOutput = true,
UseShellExecute = false,
CreateNoWindow = true,
WindowStyle = ProcessWindowStyle.Hidden
}
};
cmd.Start();
cmd.StandardInput.WriteLine(#"""C:\Program Files\Autodesk\AutoCAD 2018\accoreconsole.exe""");
cmd.StandardInput.Flush();
cmd.StandardInput.Close();
string output = cmd.StandardOutput.ReadToEnd();
cmd.WaitForExit();
cmd.Close();
richTextBox1.Text = output;
}
}
}
Here is a snippet of code I had for calling a DOS-based command terminal program.
Whatever the "exeToRun" program is, such as your AcCoreConsole.exe, and
var info = new ProcessStartInfo();
// call the DOS command, ensure the path to
// your exe file being called.
info.FileName = Path.Combine(Environment.CurrentDirectory, exeToRun);
info.Arguments = stringOfCommandArguments;
info.RedirectStandardInput = true;
info.UseShellExecute = false;
info.RedirectStandardOutput = true;
info.RedirectStandardError = true;
// dont "SHOW" the black popup window in background making things look
// like popup, popup, popup for each call going out to device.
info.WindowStyle = ProcessWindowStyle.Hidden;
// the "CreateNoWindow" actually prevents the black DOS window from showing.
info.CreateNoWindow = true;
p.StartInfo = info;
p.Start();
var sb = new StringBuilder();
try
{
while (!p.StandardOutput.EndOfStream)
sb.AppendLine(p.StandardOutput.ReadLine());
while (!p.StandardError.EndOfStream)
sb.AppendLine(p.StandardError.ReadLine());
}
catch
{
sb.AppendLine("Error/Timeout getting results of request.");
}
So, after the process.Start, I did a loop of capturing both standardOutput and standardError streams that are part of the process object. Hopefully this can get you over the hump you are working on.
Now, in the string builder, I can assess, write out and debug for later assessment. You can split into your own capture, but again, hopefully just the piece(s) you may be missing.
One can also use the dedicated event handlers to process the output and error streams asynchronously:
var startInfo = new ProcessStartInfo();
startInfo.FileName = "app.exe";
startInfo.UseShellExecute = false;
var p = new Process();
p.StartInfo = startInfo;
// Gather standard output in a string buffer
var outSb = new StringBuilder();
startInfo.RedirectStandardOutput = true;
p.OutputDataReceived += new DataReceivedEventHandler((sender, e) => { outSb.AppendLine(e.Data); });
// Gather standard error in a string buffer
startInfo.RedirectStandardError = true;
var errSb = new StringBuilder();
p.ErrorDataReceived += new DataReceivedEventHandler((sender, e) => { errSb.AppendLine(e.Data); });
p.Start();
p.BeginOutputReadLine();
p.BeginErrorReadLine();
p.WaitForExit();
var allOutputLines = outSb.ToString();
var allErrorLines = errSb.ToString();

How to stop logcat from logging and close adb programmatically?

I am writing a small C# application to collect logcat files for an app that's running on an Android device connected to the computer.
I can easily start logcat and get it to log the desired lines to a particular text file. But every command that I've tried to stop logcat from logging doesn't work.
I've tried my solutions also when running my app with admin rights.
Here is my code:
static void Main(string[] args)
{
string choice;
string clearLogging = #"adb logcat -c";
string startLogging = #"adb logcat MyApp_LoggingTag:V AndroidRuntime:E *:S > C:\logcat.txt";
string adbDir = #"C:\Users\me\AppData\Local\Android\android-sdk\platform-tools\";
string clearCommand = adbDir + clearLogging;
string startLoggingCommand = adbDir + startLogging;
ProcessStartInfo startInfo = new ProcessStartInfo("cmd.exe", "/K " + clearCommand);
startInfo.CreateNoWindow = true;
startInfo.UseShellExecute = false;
startInfo.RedirectStandardInput = true;
//Tried giving the cmd process elevated rights and then use logcat -c - didn't work
//startInfo.Verb = "runas";
Process logcatRunner = Process.Start(startInfo);
//This works!
logcatRunner.StandardInput.WriteLine(startLoggingCommand);
Console.WriteLine("Logging has started.");
Console.Write("Press Enter to stop logging....");
Console.ReadLine();
//-c doesn't work
//logcatRunner.StandardInput.WriteLine(clearCommand);
//Tried killing adb via the logcatRunner process - doesn't work.
//logcatRunner.StandardInput.WriteLine(#"taskkill -f /im ""adb.exe""");
//Tried killing my process - doesn't work - adb is still running and logcat is still writing logs
//logcatRunner.Kill();
Console.WriteLine("Logging has stopped.");
Console.Write(#"Enter any key");
choice = Console.ReadLine();
}
adb is still running after I close the above application.
So my question is, having started adb and logcat successfully, how do I close both of them programmatically?
Doing this with your approach is complicated. You create cmd process and then start another process (adb) there. To kill adb you need to send CTRL+C to cmd, but it's not that easy because of CreateNoWindow=true. I'd suggest another approach and run adb directly, redirecting its output:
string adbPath = #"G:\Android\android-sdk\platform-tools\adb.exe";
ProcessStartInfo startInfo = new ProcessStartInfo(adbPath, "logcat MyApp_LoggingTag:V AndroidRuntime:E *:S");
startInfo.CreateNoWindow = true;
startInfo.UseShellExecute = false;
startInfo.RedirectStandardOutput = true;
// if you don't want to recreate it each time - choose another file mode, like FileMode.Append
using (var fs = new FileStream(#"C:\logcat.txt", FileMode.Create, FileAccess.Write, FileShare.Read)) {
using (var writer = new StreamWriter(fs)) {
Process logcatRunner = new Process();
logcatRunner.StartInfo = startInfo;
logcatRunner.EnableRaisingEvents = true;
logcatRunner.OutputDataReceived += (sender, args) => {
// Data null indicates end of output stream - don't write it
if (args.Data != null) {
writer.Write(args.Data);
// flush immediately if needed
writer.Flush();
}
};
logcatRunner.Start();
logcatRunner.BeginOutputReadLine();
Console.WriteLine("Logging started, press any key to stop");
Console.ReadKey();
logcatRunner.CancelOutputRead();
logcatRunner.Kill();
logcatRunner.WaitForExit();
}
}

C# Console application not showing console output when starting from different application

I am using a windows application to start a console application for command line parameters configuration.
When I am sending the command line parameters through debug mode, the application is working perfect, and all Console.WriteLine is printing to console, but when am starting the process from windows application of that console application it is not showing console output
the way, am starting the process is
ProcessStartInfo procStartInfo = new ProcessStartInfo();
procStartInfo.FileName = EXEName;
procStartInfo.Arguments = FilePath;
procStartInfo.RedirectStandardOutput = true;
procStartInfo.UseShellExecute = false;
procStartInfo.RedirectStandardOutput = true;
procStartInfo.UseShellExecute = false;
using (Process process = new Process())
{
process.StartInfo = procStartInfo;
process.Start();
}
You need to set ProcessStartInfo.RedirectStandardOutput to false;

C# - Launch application with arguments.

Hello I've to Launch the software CFast for a Parametric Analysis. To do this, I want to create a application in C# that runs the core CFast.exe. If I want run the software from cmd.exe and execute it on the file INPUTFILENAME.in I write in prompt:
CFast.exe INPUTFILENAME
In C# I wrote the following code:
Process firstProc = new Process();
firstProc.StartInfo.FileName = #"C:\Users\Alberto\Desktop\Simulazioni Cfast\D\C\N\A3B1\CFAST.exe";
firstProc.StartInfo.Arguments = #"INPUTFILENAME";
firstProc.EnableRaisingEvents = true;
firstProc.Start();
firstProc.WaitForExit();
With this code CFast run but doesn't analyze anything... Seems like don't accept the argument. Hint for this trouble ?
Solved. Mistake in the filename and in the syntax of the command
// setup cmd process
var command = #"CFAST.exe C:\Users\Alberto\Desktop\Simulazioni_Cfast\D\C\N\A3B1\A3B1";
ProcessStartInfo procStartInfo = new ProcessStartInfo("cmd", "/c " + command);
procStartInfo.RedirectStandardOutput = true;
procStartInfo.UseShellExecute = false;
procStartInfo.RedirectStandardError = true;
procStartInfo.CreateNoWindow = true;
// start process
Process proc = new Process();
proc.StartInfo = procStartInfo;
proc.Start();
proc.WaitForExit();
// read process output
string cmdError = proc.StandardError.ReadToEnd();
string cmdOutput = proc.StandardOutput.ReadToEnd();
where A3B1 is the name of the file .IN

How to pass Ctrl+Enter command to Process when using C# StandardInput redirection

Im trying to make C# application that uses hunpos tagger.
Runing hunpos-tag.exe requires three input arguments: model, inputFile, outputFile
In cmd it would look something like this:
hunpos-tag.exe model <inputFile >outputFile
Although, hunpos-tag.exe can be run with just the model, at that point it'll wait for text input (from cmd) which is processed when the tagger receives Ctrl+Enter as input and the results are displayed through standard output. I've been trying to use StandardInput redirection in C# but I don't know how to send the Ctrl+Enter end command (Or if the redirection works at all). The code:
string inputFilePath = path + "\\CopyFolder\\rr";
string pathToExe = path + "\\CopyFolder\\hunpos-tag.exe";
ProcessStartInfo startInfo = new ProcessStartInfo
{
FileName = pathToExe,
UseShellExecute = false,
RedirectStandardInput = true,
WorkingDirectory = Directory.GetDirectoryRoot(pathToExe),
Arguments = path + "\\CopyFolder\\model.hunpos.mte5.defnpout",
};
try
{
Process _proc = new Process();
_proc.StartInfo.FileName = pathToExe;
_proc.StartInfo.UseShellExecute = false;
_proc.StartInfo.RedirectStandardInput = true;
_proc.StartInfo.Arguments = path + "\\CopyFolder\\model.hunpos.mte5.defnpout";
_proc.Start();
var streamReader = new StreamReader(inputFilePath);
_proc.StandardInput.Write(streamReader.ReadToEnd());
_proc.StandardInput.Flush();
_proc.StandardInput.Close();
_proc.WaitForExit();
}
catch (Exception e)
{
Console.WriteLine(e);
}
When I run the following code the tagger has the following output:
model loaded
tagger compiled
Fatal error: exception Sys_error("Bad file description")
The exception is caused by the .Close() command. The file is valid and works when runned from cmd. Any ideas on how could I send the end command or how to emulate cmd command without using redirection?
It wouldn't work with input redirection so I managed it with running cmd procces and passing it the required command.
using (Process process = new Process())
{
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.RedirectStandardError = true;
process.StartInfo.WorkingDirectory = #"C:\";
process.StartInfo.FileName = Path.Combine(Environment.SystemDirectory, "cmd.exe");
// Redirects the standard input so that commands can be sent to the shell.
process.StartInfo.RedirectStandardInput = true;
// Runs the specified command and exits the shell immediately.
//process.StartInfo.Arguments = #"/c ""dir""";
process.OutputDataReceived += ProcessOutputDataHandler;
process.ErrorDataReceived += ProcessErrorDataHandler;
process.Start();
process.BeginOutputReadLine();
process.BeginErrorReadLine();
// Send a directory command and an exit command to the shell
process.StandardInput.WriteLine(path + "\\CopyFolder\\hunpos-tag.exe " + path + "\\CopyFolder\\model.hunpos.mte5.defnpout <" + path + "\\CopyFolder\\rr >" + path + "\\CopyFolder\\zz");
process.StandardInput.WriteLine("exit");
process.WaitForExit();
}

Categories