I have a MSI file which I am copying to client machine using WMI Remote Connection. After Copying it to some location , I install it and update status as 'Installation Completed'. But the problem I face is the process of sending status completed is taking place so instantly after the code below that even if it fails the Status would be Completed.
inParams["CommandLine"] = "msiexec.exe /i " + #"""" + #"c:\windows\temp\" + tempFolderName + #"\Agent.msi" + #"""" + " " + String.Format("/q HEARTBEATSERVERIP={0} CONSOLESERVICEURL={1} HEARTBEATSERVERPORT={2} DOMAINACCOUNT={3} DOMAINACCOUNTPASSWORD={4}", this.heartbeatServerIp, this.consoleServiceUrl, this.heartbeatServerPort, this.userName, this.password);
The above line initiates the installation process and the below code determines how I process the whole thing
File.WriteAllText(remoteCopy, cmdFileBuilder.ToString());
Process scriptProc = new Process();
scriptProc.StartInfo.FileName = "cscript";
scriptProc.StartInfo.WorkingDirectory = programDataPath; //<---very important exe location
scriptProc.StartInfo.Arguments = "//B //Nologo remotecopy.vbs";
scriptProc.StartInfo.WindowStyle = ProcessWindowStyle.Hidden; //prevent console window from popping up
scriptProc.Start();
scriptProc.WaitForExit(); // <-- Optional if you want program running until your script exit
scriptProc.Close();
var agentMsiFileName = "\\" + ipAddress + #"\admin$\Temp\" + tempFolderName + #"\Agent.msi";
//remote copy completed...
//remote copy completed...
ProcessStartInfo info = new ProcessStartInfo();
///Start remote execution
///
try
{
var wmiProcess = new ManagementClass(scope, new ManagementPath("Win32_Process"), new ObjectGetOptions());
ManagementBaseObject inParams = wmiProcess.GetMethodParameters("Create");
inParams["CommandLine"] = "msiexec.exe /i " + #"""" + #"c:\windows\temp\" + tempFolderName + #"\Agent.msi" + #"""" + " " + String.Format("/q HEARTBEATSERVERIP={0} CONSOLESERVICEURL={1} HEARTBEATSERVERPORT={2} DOMAINACCOUNT={3} DOMAINACCOUNTPASSWORD={4}", this.heartbeatServerIp, this.consoleServiceUrl, this.heartbeatServerPort, this.userName, this.password);
ManagementBaseObject outParams = wmiProcess.InvokeMethod("Create", inParams, null);
LogUtilities.Info("Creation of the process returned: " + outParams["returnValue"]);
LogUtilities.Info("Process ID: " + outParams["processId"]);
LogUtilities.Info("Installation completed for : " + discoveredMachineId + " " + ipAddress);
SendAgentStatus(discoveredMachineId, "Completed"); //Installation Completed
I know that we can check for the status codes of installer which I used in the code and it returns '0' instantly without waiting for the completion, its for creation of the process completion.
ManagementBaseObject outParams = wmiProcess.InvokeMethod("Create", inParams, null);
LogUtilities.Info("Creation of the process returned: " + outParams["returnValue"]);
Also I could cross-check the registry with
var checkKey = Registry.LocalMachine.OpenSubKey(#"Software\Microsoft\Windows\CurrentVersion\Uninstall\{Product-code}");
but it takes atleast 1-2 minutes or even more than that depending on the system configurations. So, is there a way we can figure this out to perfection?
I want to wait till the installation gets complete and then send the status Completed.
Related
I tried to call a .exe program I have calling cmd from a c# script that generates a command. When I run the code I get the output the process tried to write to a nonexistent pipe. But when I run said command using a cmd open from Windows it runs perfectly. What I am doing wrong? I am using Visual Studio 2022.
SilentMkdir(baseDir + "/00_CameraInit");
string binName =pre + binDir + "\\aliceVision_cameraInit.exe";
string dstDir =pre + baseDir + "/00_CameraInit\\";
string cmdLine = binName;
cmdLine = cmdLine + " --defaultFieldOfView 45.0 --verboseLevel info --sensorDatabase \"\" --allowSingleView 1";
cmdLine = cmdLine + " --imageFolder \"" + pre + srcImageDir + "\"";
cmdLine = cmdLine + " --output \"" + dstDir + "cameraInit.sfm\"";
Console.WriteLine(cmdLine);
var processInfo = new ProcessStartInfo("cmd.exe", cmdLine);
processInfo.UseShellExecute = false;
processInfo.RedirectStandardOutput = true;
processInfo.CreateNoWindow = false;
//processInfo.RedirectStandardOutput = !string.IsNullOrEmpty("output.txt");
int exitCode = -1;
string output = null;
try
{
var process = Process.Start(processInfo);
process.Start();
output = process.StandardOutput.ReadToEnd();
Console.WriteLine(output);
process.WaitForExit();
}
catch (Exception e)
{
Console.WriteLine("Run error" + e.ToString()); // or throw new Exception
}
I have Web,APP,DB Server
App Server which has a Exe it will do some operation .
when I am trying to Trigger a Exe which is in App Server through WMI Connection from Webserver please refer below code
public void RunProcessOnRemoteMachine(string inputFolder, string ProcessName, string AppRun, string isRegression, string TemplateID, string isPreProcess, string UserLoginName, string DocYear,string remoteMachine,string strPathToTheExe)
{
string usernameAndDomain = "";
string password = "";
try
{
ConnectionOptions connOptions = new ConnectionOptions();
connOptions.Impersonation = ImpersonationLevel.Impersonate;
connOptions.EnablePrivileges = true;
if (Environment.MachineName.ToUpper() != remoteMachine.ToUpper())
{
}
ManagementScope manScope = new ManagementScope(String.Format(#"\\{0}\ROOT\CIMV2", remoteMachine), connOptions);
manScope.Connect();
ObjectGetOptions objectGetOptions = new ObjectGetOptions();
ManagementPath managementPath = new ManagementPath("Win32_Process");
ManagementClass processClass = new ManagementClass(manScope, managementPath, objectGetOptions);
ManagementBaseObject inParams = processClass.GetMethodParameters("Create");
inParams["CommandLine"] = strPathToTheExe + " " + "\"" + inputFolder + "\" \"" + ProcessName + "\" \"" + AppRun + "\" \"" + isRegression + "\" \"" + TemplateID + "\" \"" + isPreProcess + "\" \"" + UserLoginName + "\" \"" + DocYear+"\"";
ManagementBaseObject outParams = processClass.InvokeMethod("Create", inParams, null );
Cls_ErrorLog.Writelog("Creation of the process returned: " + outParams["returnValue"]);
Cls_ErrorLog.Writelog("Process ID: " + outParams["processId"]);
}
catch (Exception ex)
{
Cls_ErrorLog.Writelog("Exception occured in method RunProcessOnRemoteMachine : " + ex.Message + " - " + ex.StackTrace);
}
finally
{
}
}
I set Integrated Security=True in my Exe Config and Web config and also i added that user in Sql Server Logins and gave the rights.
After made a Connection that EXe is Running with same Credential(what we set in Identity in IIS) in Appserver But it could not connect a database connection with same credentials
it throws Login failed for user 'NT AUTHORITY\ANONYMOUS LOGON. but when we track the exe which is running with same credentials
when we run a Exe manually in App Server its works
So Please Suggest a Solutions
Thanks in advance
I have a problem with executing the jar file in c#.
This jar file is epubcheck.jar
here is my code to run the file
public string IdpfValidateEpub(string epub)
{
try
{
string result = null;
string epubCheckPath = System.IO.Path.Combine(System.IO.Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "epubcheck.jar");
string arguments = "java -jar" + " \"" + epubCheckPath + "\"" + " \"" + epub + "\"";
System.Diagnostics.Process pProcess = new System.Diagnostics.Process();
//strCommand is path and file name of command to run
pProcess.StartInfo.FileName = #"cmd.exe";
//strCommandParameters are parameters to pass to program
pProcess.StartInfo.Arguments = arguments;
Debug.WriteLine("arguments: " + pProcess.StartInfo.Arguments);
pProcess.StartInfo.UseShellExecute = false;
pProcess.StartInfo.CreateNoWindow = false;
//Set output of program to be written to process output stream
pProcess.StartInfo.RedirectStandardOutput = true;
//Start the process
pProcess.Start();
//Get program output
result = pProcess.StandardOutput.ReadToEnd();
//Wait for process to finish
pProcess.WaitForExit();
return result;
}
catch (Exception ex)
{
Debug.WriteLine(ex.Message);
Debug.WriteLine(ex.StackTrace);
throw ex;
}
}
But the program is not running at all. I also set the property to show the window. So i can see if its running or not. But it only shows the command prompt like this
I also printed the arguments i passed in the System.Diagnostics.Process in order to check if the arguments are correct.
After the program printed the arguments. i just copied it and paste in the command prompt. And the program works as expected. But why does it doesn't work in my c# code?
Thank you so much.
Java is a program in its own right, so you don't actually need cmd.exe to run it.
Change your arguments to the following so that you're passing the arguments for java:
string arguments = "-jar" + " \"" + epubCheckPath + "\"" + " \"" + epub + "\"";
And then simply start java instead of cmd:
pProcess.StartInfo.FileName = #"java";
I'm trying to start Zookeeper and Solr remotely via PowerShell scriptblock.
Then I see that the process is created in the remote machine (by checking the port 2181 of Zookeeper). And on the script completion it is being terminated.
How do I keep this alive even after the completion?
This code below stops the remote process on script completion. The script.ps1 does a lot of things that includes starting Zookeeper and Solr asJob.
int iRemotePort = 5985;
string strShellURI = #"http://schemas.microsoft.com/powershell/Microsoft.PowerShell";
string strAppName = #"/wsman";
WSManConnectionInfo ci = new WSManConnectionInfo(
false,
machineName,
iRemotePort,
strAppName,
strShellURI,
new PSCredential(userName, secure));
Runspace runspace = RunspaceFactory.CreateRunspace(ci);
runspace.Open();
using (PowerShell ps = PowerShell.Create())
{
session.Log(#"c:\temp\script.ps1 -serverID " + counter + " -copySolrConfig $" + status + " -currentHost \"" + machineName + "\" -IP_PORT_List \"" + String.Join(", ", machineWithPort) + "\"");
ps.Runspace = runspace;
ps.AddScript(#"c:\temp\script.ps1 -serverID " + counter + " -copySolrConfig $" + status + " -currentHost \"" + machineName + "\" -IP_PORT_List \"" + String.Join(", ", machineWithPort) + "\"");
var results = ps.Invoke();
foreach (var result in results)
{
session.Log(result.ToString());
}
}
runspace.Close();
So after a long try I came to a conclusion, Using power-shell script alive is not a appropriate way to keep zookeeper and solr running effectively. So moved it as a windows service and installed it on the remote machine via WiX.
I have a remote server name (windows), username and password.
Using C# .Net, I want to run a command on the remote server and get back the console output
Is there a way to do it in C#?
I was able to run the command using WMI with the following code (partial) but with no luck of getting the console output. I could only get back the Process ID.
ObjectGetOptions objectGetOptions = new ObjectGetOptions();
ManagementPath managementPath = new ManagementPath("Win32_Process");
ManagementClass processClass = new ManagementClass(scope, managementPath,objectGetOptions);
ManagementBaseObject inParams = processClass.GetMethodParameters("Create");
inParams["CommandLine"] = "cmd.exe /c "+ mycommand;
ManagementBaseObject outParams = processClass.InvokeMethod("Create", inParams, null);
Any Ideas?
This function is what I came up with after some research. Hope it helps someone else.
public string executeCommand(string serverName, string username, string password, string domain=null, string command)
{
try
{
System.Diagnostics.Process process = new System.Diagnostics.Process();
System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo();
startInfo.RedirectStandardOutput = true;
startInfo.UseShellExecute = false;
startInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
startInfo.FileName = "cmd.exe";
if (null != username)
{
if (null != domain)
{
startInfo.Arguments = "/C \"psexec.exe \\\\" + serverName + " -u " + domain+"\\"+username + " -p " + password + " " + command + "\"";
}
else
{
startInfo.Arguments = "/C \"psexec.exe \\\\" + serverName + " -u " + username + " -p " + password + " " + command + "\"";
}
}
else
{
startInfo.Arguments = "/C \"utils\\psexec.exe "+serverName+" "+ command + "\"";
}
process.StartInfo = startInfo;
process.Start();
process.WaitForExit();
if (process.ExitCode == 0 && null != process && process.HasExited)
{
return process.StandardOutput.ReadToEnd();
}
else
{
return "Error running the command : "+command;
}
}
catch (Exception ex)
{
throw ex;
}
}
You can try executing a command with PsTools. One of many features they offer is PsExec. It allows you to run a command on a remote server. It should also return the results into a console (on local PC where it was run from).