EDN Admin
Well-known member
Ive written a Windows Service in C# targeting .NET 4.0 that is useful for system configuration automation. It reads an XML file, performs tasks based on the step currently marked with a progress attribute, and reboots between stages. So far
I am successful in having the service set the Hostname, join a Domain, copy files, and configure the IP address / Subnet Mask / Gateway / DNS of the NICs.
Where Im having trouble is calling an HP utility to team the systems NICs. HP provides a CLI application called CQNICCMD.EXE which can itself import a configuration file and create a NIC team as desired. Ive coded the stage for teaming to
perform a Process.Start() with ProcessStartInfo including the path to the EXE and the switches needed. It works GREAT when run as a CLI application with administrative rights. When run in a Windows Service, the application errors with a message
of "An error occurred when making a call into the Operating System" in its own log file. My return code from the Process is 1, with a message saying "The service did not respond to the start or control request in a timely fashion". This seems odd,
considering the process Im starting is not a service. My service starts up just fine.
I have configured my service to run as the local administrator. This didnt help. LocalSystem and LocalSystem with Desktop Interaction doesnt work either. Im somewhat under the impression it isnt a security issue since the service is
able to change the NIC IP, join a domain, and copy system files.
Ive also separated the services work from the OnStart method. The OnStart method kicks off the XML parsing and appropriate actions on another thread so I dont think its a service start timeout issue.
What could be going on here? The process takes about 7 minutes and succeeds when run from the CLI version. The service version takes about 2 minutes and errors out.
Here is the method Ive written that launches the process:
<pre class="prettyprint private static bool RunCommand(string cmdPath, string cmdArgs, string cmdUser, string cmdPassword, string cmdTimeout)
{
try
{
int timeOut = 720000;
try
{
if (cmdTimeout != "")
{
timeOut = Convert.ToInt32(cmdTimeout);
}
}
catch (Exception ex)
{
timeOut = 720000;
}
ProcessStartInfo procInfo = new ProcessStartInfo();
procInfo.FileName = cmdPath;
procInfo.Arguments = cmdArgs;
procInfo.WorkingDirectory = Path.GetDirectoryName(cmdPath);
procInfo.CreateNoWindow = false;
procInfo.UseShellExecute = false;
procInfo.RedirectStandardError = true;
procInfo.RedirectStandardInput = true;
procInfo.WindowStyle = ProcessWindowStyle.Hidden;
if (cmdUser != "")
{
DataSec myDataSec = new DataSec(myLog);
string myPword = myDataSec.Decrypt(cmdPassword);
var secure = new SecureString();
foreach (var c in myPword.ToCharArray()) secure.AppendChar(c);
procInfo.UserName = cmdUser;
procInfo.Password = secure;
}
Console.WriteLine("Launching process:");
myLog.WriteToLog("Launching process:");
Console.WriteLine(" File: " + cmdPath);
myLog.WriteToLog(" File: " + cmdPath);
Console.WriteLine(" Args: " + cmdArgs);
myLog.WriteToLog(" Args: " + cmdArgs);
myLog.WriteToLog(" User context (if any): " + cmdUser);
Process p = Process.Start(procInfo);
//p.WaitForExit(timeOut);
p.WaitForExit();
if (p.HasExited == false)
if (p.Responding)
{
Console.WriteLine("Process has reached 12 minute timeout. Ending.");
myLog.WriteToLog("Process has reached 12 minute timeout. Ending.");
p.CloseMainWindow();
return false;
}
else
{
Console.WriteLine("Process has reached 12 minute timeout. Terminating.");
myLog.WriteToLog("Process has reached 12 minute timeout. Terminating.");
p.Kill();
return false;
}
Console.WriteLine("Process has exited with ExitCode: " + p.ExitCode.ToString());
myLog.WriteToLog("Process has exited with ExitCode: " + p.ExitCode.ToString());
return true;
}
catch (Exception ex)
{
Console.WriteLine("There was an error running the command: " + ex.Message);
myLog.WriteToLog("There was an error running the command: " + ex.Message);
return false;
}
}
[/code]
Im passing it the path to CQNICCMD.EXE and args of "/C C:HPteamcfg.xml". Ive tried starting the process with and without credentials associated with it. Ive also tried setting the timeout to 20 minutes, setting no timeout, and trying to run
it as the domain admin.
Is there some limitation to starting processes from services that I dont understand? Any help is appreciated!
Thanks,
g
View the full article
I am successful in having the service set the Hostname, join a Domain, copy files, and configure the IP address / Subnet Mask / Gateway / DNS of the NICs.
Where Im having trouble is calling an HP utility to team the systems NICs. HP provides a CLI application called CQNICCMD.EXE which can itself import a configuration file and create a NIC team as desired. Ive coded the stage for teaming to
perform a Process.Start() with ProcessStartInfo including the path to the EXE and the switches needed. It works GREAT when run as a CLI application with administrative rights. When run in a Windows Service, the application errors with a message
of "An error occurred when making a call into the Operating System" in its own log file. My return code from the Process is 1, with a message saying "The service did not respond to the start or control request in a timely fashion". This seems odd,
considering the process Im starting is not a service. My service starts up just fine.
I have configured my service to run as the local administrator. This didnt help. LocalSystem and LocalSystem with Desktop Interaction doesnt work either. Im somewhat under the impression it isnt a security issue since the service is
able to change the NIC IP, join a domain, and copy system files.
Ive also separated the services work from the OnStart method. The OnStart method kicks off the XML parsing and appropriate actions on another thread so I dont think its a service start timeout issue.
What could be going on here? The process takes about 7 minutes and succeeds when run from the CLI version. The service version takes about 2 minutes and errors out.
Here is the method Ive written that launches the process:
<pre class="prettyprint private static bool RunCommand(string cmdPath, string cmdArgs, string cmdUser, string cmdPassword, string cmdTimeout)
{
try
{
int timeOut = 720000;
try
{
if (cmdTimeout != "")
{
timeOut = Convert.ToInt32(cmdTimeout);
}
}
catch (Exception ex)
{
timeOut = 720000;
}
ProcessStartInfo procInfo = new ProcessStartInfo();
procInfo.FileName = cmdPath;
procInfo.Arguments = cmdArgs;
procInfo.WorkingDirectory = Path.GetDirectoryName(cmdPath);
procInfo.CreateNoWindow = false;
procInfo.UseShellExecute = false;
procInfo.RedirectStandardError = true;
procInfo.RedirectStandardInput = true;
procInfo.WindowStyle = ProcessWindowStyle.Hidden;
if (cmdUser != "")
{
DataSec myDataSec = new DataSec(myLog);
string myPword = myDataSec.Decrypt(cmdPassword);
var secure = new SecureString();
foreach (var c in myPword.ToCharArray()) secure.AppendChar(c);
procInfo.UserName = cmdUser;
procInfo.Password = secure;
}
Console.WriteLine("Launching process:");
myLog.WriteToLog("Launching process:");
Console.WriteLine(" File: " + cmdPath);
myLog.WriteToLog(" File: " + cmdPath);
Console.WriteLine(" Args: " + cmdArgs);
myLog.WriteToLog(" Args: " + cmdArgs);
myLog.WriteToLog(" User context (if any): " + cmdUser);
Process p = Process.Start(procInfo);
//p.WaitForExit(timeOut);
p.WaitForExit();
if (p.HasExited == false)
if (p.Responding)
{
Console.WriteLine("Process has reached 12 minute timeout. Ending.");
myLog.WriteToLog("Process has reached 12 minute timeout. Ending.");
p.CloseMainWindow();
return false;
}
else
{
Console.WriteLine("Process has reached 12 minute timeout. Terminating.");
myLog.WriteToLog("Process has reached 12 minute timeout. Terminating.");
p.Kill();
return false;
}
Console.WriteLine("Process has exited with ExitCode: " + p.ExitCode.ToString());
myLog.WriteToLog("Process has exited with ExitCode: " + p.ExitCode.ToString());
return true;
}
catch (Exception ex)
{
Console.WriteLine("There was an error running the command: " + ex.Message);
myLog.WriteToLog("There was an error running the command: " + ex.Message);
return false;
}
}
[/code]
Im passing it the path to CQNICCMD.EXE and args of "/C C:HPteamcfg.xml". Ive tried starting the process with and without credentials associated with it. Ive also tried setting the timeout to 20 minutes, setting no timeout, and trying to run
it as the domain admin.
Is there some limitation to starting processes from services that I dont understand? Any help is appreciated!
Thanks,
g
View the full article