I'm trying to do a web api which allows my to start/stop/reset my application pools and sites inside IIS.
Currently, I have tested that running administration level Visual studio allows me to run my code flawlessly. But once I'm not running visual studio with administration level privileged, or even deployed to IIS and run as a test service, my method inside breaks.
A little overview of how it is done is I get a Process to run CMD which utilizes the appcmd to list and reset the iis connections.
private List<SiteModels> GetSiteModels()
{
Process process = new Process();
ProcessStartInfo startInfo = new ProcessStartInfo
{
UseShellExecute = false,
WindowStyle = ProcessWindowStyle.Minimized,
FileName = "cmd.exe",
WorkingDirectory = #"C:\",
Arguments = "/K appcmd list sites & exit",
Verb = "runas",
RedirectStandardOutput = true
};
process.StartInfo = startInfo;
process.EnableRaisingEvents = false;
List<SiteModels> sitesModelList = new List<SiteModels>();
string tempString = process.StandardOutput.ReadToEnd();
process.WaitForExit();
foreach (var line in tempString.Split("\r\n".ToCharArray(), StringSplitOptions.RemoveEmptyEntries))
{
SiteModels sitesModel = new SiteModels();
string pattern = "SITE \"(?<SiteName>.*?)\"[\\s\\S]*?id:(?<Id>.*?),[\\s\\S]*?bindings:(?<Bindings>.*?),[\\s\\S]*?state:(?<State>.*?)\\)";
Regex regexPattern = new Regex(pattern);
Match match = regexPattern.Match(line);
if (match.Success)
{
sitesModel.SiteName = match.Groups["SiteName"].Value.Trim();
sitesModel.Id = int.Parse(match.Groups["Id"].Value.Trim());
sitesModel.Bindings = match.Groups["Bindings"].Value.Trim();
sitesModel.State = match.Groups["State"].Value.Trim();
sitesModelList.Add(sitesModel);
}
}
return sitesModelList;
}
Related
I'm trying to open run a few arguments using cmd.exe from ProcessStartInfo in C#
but my folder navigation needs to include double quotes eg. "C:\this is\my\folder site"
as you see the reason for using double quotes is because the folders have space on their name.
this is my code
var ddd = "\"" + projectPath + "\"";
var strCmdTxt = "/c cd " + ddd + " && code .";
System.Diagnostics.Process process = new System.Diagnostics.Process();
System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo
{
WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden,
FileName = "cmd.exe",
Arguments = strCmdTxt, UseShellExecute = true, CreateNoWindow= true
};
process.StartInfo = startInfo;
process.Start();
BUT, what it runs is something like this
cd\ "C:\this is\my\folder site\"
which, just returns me to C drive
The command should be cd "C:\this is\my\folder site"
Looks like what you're trying to achieve is start VS Code in the specified folder. Consider using the working directory of the process you're starting, instead of trying to navigate to that directory and starting VS Code in there. Here is a method to help with that:
private static void StartVSCodeInFolder(string projectPath)
{
using (System.Diagnostics.Process process = new System.Diagnostics.Process())
{
System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo
{
WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden,
FileName = "C:/Program Files/Microsoft VS Code/Code.exe",
Arguments = ".",
UseShellExecute = false,
CreateNoWindow = true,
WorkingDirectory = projectPath
};
process.StartInfo = startInfo;
process.Start();
}
}
Hope this helps.
Could you not change the working directory using the Environment class and simply using "code.exe".
It seems like it would be a cleaner approach.
Environment.CurrentDirectory = #"C:\Program Files\Microsoft VS Code";
We are writing a Xamarin.Mac application. We need to execute a command like "uptime" and read it's output into an application to parse.
Could this be done? In Swift and Objective-C there is NTask, but I don't seem to be able to find any examples in C#.
Under Mono/Xamarin.Mac, you can the "standard" .Net/C# Process Class as the Process gets mapped to the underlaying OS (OS-X For Mono, MonoMac and Xamarin.Mac, and Mono for *nix).
Process p = new Process();
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.FileName = "Write500Lines.exe";
p.Start();
// To avoid deadlocks, always read the output stream first and then wait.
string output = p.StandardOutput.ReadToEnd();
p.WaitForExit();
Xamarin: https://developer.xamarin.com/api/type/System.Diagnostics.Process/
MSDN: https://msdn.microsoft.com/en-us/library/system.diagnostics.processstartinfo.redirectstandardoutput%28v=vs.110%29.aspx?f=255&MSPPError=-2147217396
Example from my OS-X C# code, but it is cross-platform as it works as is under Windows/OS-X/Linux, just the executable that you are running changes across the platforms.
var startInfo = new ProcessStartInfo () {
FileName = Path.Combine (commandPath, command),
Arguments = arguments,
UseShellExecute = false,
CreateNoWindow = true,
RedirectStandardOutput = true,
RedirectStandardError = true,
RedirectStandardInput = true,
UserName = System.Environment.UserName
};
using (Process process = Process.Start (startInfo)) { // Monitor for exit}
process.WaitForExit ();
using (var output = process.StandardOutput) {
Console.Write ("Results: {0}", output.ReadLine ());
}
}
Here is an example taken from Xamarin forum:
var pipeOut = new NSPipe ();
var t = new NSTask();
t.LaunchPath = launchPath;
t.Arguments = launchArgs;
t.StandardOutput = pipeOut;
t.Launch ();
t.WaitUntilExit ();
t.Release ();
var result = pipeOut.ReadHandle.ReadDataToEndOfFile ().ToString ();
I need to run a command into CMD window and want to get result into a variable.
I used below code to do the same but the out put is incorrect
var proc = new Process
{
StartInfo = new ProcessStartInfo
{
FileName = "cmd.exe",
Arguments = " wmic.exe /node:(computername or ip address) computersystem get username ",
UseShellExecute = false,
RedirectStandardOutput = true,
CreateNoWindow = true
}
};
proc.Start();
string line = "";
while (!proc.StandardOutput.EndOfStream)
{
line += (line.Length > 0 ? "-----" : "") + proc.StandardOutput.ReadLine();
}
proc.WaitForExit();
Out put
Microsoft Windows [Version 6.1.7601]-----Copyright (c) 2009 Microsoft Corporation. All rights reserved.----------C:\Program Files (x86)\Common Files\Microsoft Shared\DevServer\10.0>
But when i run this command into CMD window it shows the current logged in users name.
Can any one help me to solve the issue.
Note :- The given command is used to get the current logged in users
name on network system by using it's IP Address.
What you need is the /c option for cmd
C:\>cmd /?
Starts a new instance of the Windows command interpreter
CMD [/A | /U] [/Q] [/D] [/E:ON | /E:OFF] [/F:ON | /F:OFF] [/V:ON | /V:OFF]
[[/S] [/C | /K] string]
/C Carries out the command specified by string and then terminates
I would question the need for cmd.exe here. You can just invoke wmic directly as below
var proc = new Process {
StartInfo = new ProcessStartInfo {
FileName = "wmic.exe",
Arguments = "/node:localhost computersystem get username ",
UseShellExecute = false,
RedirectStandardOutput = true,
CreateNoWindow = true
}
};
proc.Start();
string line = "";
while (!proc.StandardOutput.EndOfStream) {
line += (line.Length > 0 ? "-----" : "") + proc.StandardOutput.ReadLine();
}
proc.WaitForExit();
Why would you go to the trouble of invoking a commandline tool and parsing its results if System.Management has all the classes you need to obtain the information in-process and managed?
var ip = "127.0.0.1";
var scope = new ManagementScope(
String.Format("\\\\{0}\\root\\cimv2", ip),
new ConnectionOptions { Impersonation = ImpersonationLevel.Impersonate });
scope.Connect();
var users = new ManagementObjectSearcher(
scope,
new ObjectQuery("Select * from Win32_LoggedonUser"))
.Get()
.GetEnumerator();
while(users.MoveNext())
{
var user = users.Current["antecedent"];
var mo = new ManagementObject(new ManagementPath(user.ToString()));
try
{
var username = mo.Properties["name"];
Console.WriteLine("username {0}", username.Value);
}
catch
{
Console.WriteLine(mo);
}
}
All you have to do is create a ManagementScope and then use the ManagementObjectSearcher to run any WMI Query Language statement by using one of the available WMI Classes.
If you have a working wmic call you can always add /TRACE:ON so you can inspect the calls being made. Use wmic /? to see the aliasses.
I have one file which contains a Unix shell script. So now I wanted to
run the same in .NET. But I am unable to execute the same.
So my point is, is it possible to run the Unix program in .NET? Is there any API like NSTask in Objective-C for running Unix shell scripts so any similar API in .NET?
It has been answered before. Just check this out.
By the way, you can use:
Process proc = new Process {
StartInfo = new ProcessStartInfo {
FileName = "program.exe",
Arguments = "command line arguments to your executable",
UseShellExecute = false,
RedirectStandardOutput = true,
CreateNoWindow = true
}
};
After that start the process and read from it:
proc.Start();
while (!proc.StandardOutput.EndOfStream) {
string line = proc.StandardOutput.ReadLine();
// Do something with line
}
ProcessStartInfo frCreationInf = new ProcessStartInfo();
frCreationInf.FileName = #"C:\Program Files\Git\git-bash.exe";
frCreationInf.Arguments = "Test.sh";
frCreationInf.UseShellExecute = false;
var process = new Process();
process.StartInfo = frCreationInf;
process.Start();
process.WaitForExit();
I have run the bat file through dotnet in c# is as below
Process p = new Process();
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.FileName = "d://s.bat";
p.Start();
string output = p.StandardOutput.ReadToEnd();
p.WaitForExit();
it works fine while running through dotnet ide.
But my problem is when ever i run the above code after publishing through IIS it returns me error as
StandardOut-has-not-been-redirected-or-the-process-hasn-t-started-yet.
can you give me some guide lines to solve this problem?
Do this way, to overcome the error:-
StringBuilder content = new StringBuilder();
while ( ! p.HasExited ) {
content.Append(p.StandardOutput.ReadToEnd());
}
string output = content.ToString();
You have to use the RedirectStandardOutput = true.
Link from MSDN
Quote from link:
ProcessStartInfo.RedirectStandardOutput Property
Gets or sets a value that indicates whether the output of an application is written to the Process.StandardOutput stream.
A snippet from my issue to the same problem, when i was making sure our server was starting.
if (IsProcessRunning(ServerProcessName)) { return; }
var p = new Process
{
StartInfo = new ProcessStartInfo
{
FileName = path,
RedirectStandardOutput = true,
UseShellExecute = false
}
};
p.Start();
var a = "";
while (!a.Contains("ServicesStarted"))
{
a = p.StandardOutput.ReadLine();
}