I have a requirement where application (app1) needs to install / run another application (app2) on user system in non production hours without UAC prompt. I think I can do it with windows service which will elevate my application 1 (app1) which will install my app 2. I worte below code in my console app which will called by windows service :
SecureString ss = ConvertStr.ConvertToSecureString("****");
DirectoryInfo d = new DirectoryInfo(userDownloadFolder);
string[] extensions = new[] { ".bat", ".exe" };
FileInfo[] Files =
d.GetFiles()
.Where(f => extensions.Contains(f.Extension.ToLower()))
.ToArray();
foreach (FileInfo file in Files)
{
if (File.Exists(d.FullName + file.Name))
{
try
{
var proc = new Process();
proc.StartInfo.FileName = d.FullName + file.Name;
proc.StartInfo.Domain = "****";
proc.StartInfo.UserName = "**********";
proc.StartInfo.Password = ss;
proc.StartInfo.Verb = "runas";
proc.StartInfo.UseShellExecute = false;
proc.Start();
proc.WaitForExit();
var exitCode = proc.ExitCode;
proc.Close();
}
catch (Exception ex)
{
Logger.WriteToFile(ex.Message);
}
}
else
{
Logger.WriteToFile("File does not exists");
}
Console application runs but it gives Access is denied. But when I tried to install /run by manually right clicking app with user Id & password in UAC prompt it works. Any idea any other way to implement this.
Related
I am using the mentioned code to run a cmd file. It is working properly in my local machine. However when I am running in a remote machine windows security warning is coming. How can i bypass that security warning. Any help?
string[] newFilePath = Directory.GetFiles(workingDir, "*.cmd");
foreach (var n in newFilePath) {
finishedOld = false;
Process p = new Process();
p.StartInfo.FileName = string.Format("\"" + n + "\"");
p.Start();
p.WaitForExit();
p.Dispose();
finishedOld = true;
}
I am trying to create an application which will install the msi from the c# windows application, here i wanna take the input from user for UserName, Domain and password so that i can run the application in that user account. in the below code if i only give startInfo.Verb = "runas" its working but i want to provide the user name and password of admin and run it. can you guyz help me out.
private void InstallProbe()
{
try
{
bool gdfg= IsRunAsAdmin();
//processObj.InitializeProcess(txtUserName.Text, txtPassword.Text);
string installcmd = "/c msiexec /i \"{0}\" /quiet TARGETDIR=\"{1}\" HOST=\"{2}\" PORT=\"{3}\" USEHTTPS=\"{4}\" STEALTHMODE=\"{5}\" ORGCODE=\"{6}\"";
installcmd = string.Format(installcmd, txtFilePath.Text, #"%PROGRAMFILES%\ProHance Mate", "services.jamochatech.com", "8080", false, 0, "PHSALE");
string uname, domain = string.Empty;
//RunCommand("cmd", installcmd, processObj);
if (txtUserName.Text.IndexOf("\\") > 0)
{
string[] strarr = txtUserName.Text.Split('\\');
uname = strarr[1];
domain = strarr[0];
}
else
{
uname = txtUserName.Text;
domain = ".";
}
Process process = new Process();
ProcessStartInfo startInfo = new ProcessStartInfo();
//startInfo.Verb = "runas";
startInfo.Domain = domain;
startInfo.UserName = uname;
startInfo.Password = ToSecureString(txtPassword.Text);
startInfo.FileName = "cmd";
startInfo.Arguments = installcmd;
startInfo.CreateNoWindow = true;
startInfo.UseShellExecute = false;
startInfo.LoadUserProfile = true;
MessageBox.Show(installcmd);
process.StartInfo = startInfo;
process.Start();
process.WaitForExit(60000);
}
catch (Exception ex)
{
MessageBox.Show("Exception occured while installing the ProHance Mate " + ex.Message);
}
}
Disregarding the MSI context, you are simply trying to launch a new process (msiexec.exe) under a specific user context. Check the thread below and others alike.
In Windows: How do you programatically launch a process in administrator mode under another user context?
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;
}
I want to bind a certificate to the port 0.0.0.0:443.
As parameters for this certificate i have created:
ICertificateBindingConfiguration config = new CertificateBindingConfiguration();
var ipPort = new IPEndPoint(IPAddress.Parse("0.0.0.0"), 443);
var certificateThumbprint = serverCert.X509Certificate.Thumbprint.ToLower();
var appId = Guid.Parse("2f6580e5-a11a-4350-8cc0-47e5e0ac33e6");
But when i execute this code:
config.Bind(new CertificateBinding(certificateThumbprint, StoreName.My, ipPort, appId));
I get an error:
System.ComponentModel.Win32Exception(0x80004005): Access is denied ...
I am not local admin in the machine i am executing it. How could i resolve this problem by executing it as admin?
This happens because you do not have admin rights in you machine. You need to be sure that you have. To check if you have admin rights you could use this sample of code:
static bool IsElevated => new WindowsPrincipal(WindowsIdentity.GetCurrent()).IsInRole(WindowsBuiltInRole.Administrator);
You could just create a sample C# console app and use the line of code above.
You need to use this line of code: using System.Security.Principal;
If it works than it is better to saperate this functionality in another .exe file and create a method like the method below to execute it as Admin:
public static int RunProcessAsAdmin(string exeName, string parameters)
{
try {
System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo();
startInfo.UseShellExecute = true;
startInfo.WorkingDirectory = CurrentDirectory;
startInfo.FileName = Path.Combine(CurrentDirectory, exeName);
startInfo.Verb = "runas";
//MLHIDE
startInfo.Arguments = parameters;
startInfo.ErrorDialog = true;
Process process = System.Diagnostics.Process.Start(startInfo);
process.WaitForExit();
return process.ExitCode;
} catch (Win32Exception ex) {
WriteLog(ex);
switch (ex.NativeErrorCode) {
case 1223:
return ex.NativeErrorCode;
default:
return ErrorReturnInteger;
}
} catch (Exception ex) {
WriteLog(ex);
return ErrorReturnInteger;
}
}
http://www.lansweeper.com/ has features that let user do some actions such as Remote Computer management and etc from web application. I need to deploy it in my Asp.Net c# web application. I do it by the code blow when I build my project it works but when I trying to run it from IIS it doesn't works, just nothing happens.
Any help and idea please. No error encountered
protected void lnkComputermanagement_Click(object sender, EventArgs e)
{
try
{
long InfoID = Convert.ToInt64(txtInfoID.Text);
IBAPanel.NetworkSupport.WMIInfo WMIInfo = new IBAPanel.NetworkSupport.WMIInfo();
WMIInfo = WMIInfo.Get(Convert.ToInt32(InfoID));
string ComName = WMIInfo.ComputerName1;
string Pass = WMIInfo.Password;
if (WMIInfo.UserName != "" && WMIInfo.ComputerName1 != "" && WMIInfo.Password != "")
{
string Usname = WMIInfo.UserName.Substring(2);
ProcessStartInfo startInfo = new ProcessStartInfo();
Process myprocess = new Process();
myprocess.StartInfo.CreateNoWindow = true;
myprocess.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
myprocess.StartInfo.UseShellExecute = false;
myprocess.StartInfo.Verb = "runas";
myprocess.StartInfo.FileName = "cmd.exe";
myprocess.StartInfo.UserName = Usname;
myprocess.StartInfo.Password = MakeSecureString(Pass);
myprocess.StartInfo.Arguments = "/C mmc.exe compmgmt.msc /computer:" + ComName;
myprocess.Start();
myprocess.Close();
}
Response.Redirect("content.aspx?lan=fa&gid=524&InfoID=" + InfoID);
ActionJquery();
}
catch (Exception ex)
{
System.Text.StringBuilder cstext1 = new System.Text.StringBuilder();
cstext1.Append(" $(document).ready(function () {");
cstext1.Append("alert(" + ex.Message + ") ");
cstext1.Append(" }); ");
Page.ClientScript.RegisterStartupScript(typeof(Page), "", cstext1.ToString(), true);
}
}
You are starting the command "mmc.exe" on the webserver and not on the client browsing the website. If you look at the taskmanager on the webserver you will see multiple mmc.exe processes that are running.
To manage Windows Services from Web you need special permission and you can't go through Services.msc, you need to use WMI (Windows management instruments) and you need to give the application pool higher permission but the best way is to impersionate your piece of code where you fetch for sevices information.
A good open source project with full WMI usage is Services+ on codeplex:
Services+ On CodePlex
Thanks