Running program as admin on startup [duplicate] - c#

This question already has answers here:
How do I force my .NET application to run as administrator?
(12 answers)
Closed 8 years ago.
I am creating an application that monitors another application, if the application get close the former will restart that, and I have to create a folder in c:\ drive , if i simply run the application nothing happens but when i run that as admin it works as required.
What can I do to make this application automatically start as admin without any prompt, as i want to run this application on start up, just like some antivirus programs which do not ever need admin rights.
public bool IsProcessOpen()
{
string name = "aProgram";
foreach (Process clsProcess in Process.GetProcesses())
{
if (clsProcess.ProcessName.Contains(name))
{
return true;
}
}
return false;
}
private void timer1_Tick_1(object sender, EventArgs e)
{
try
{
bool track = false;
track =IsProcessOpen();
if (!track)
{
Process firstProc = new Process();
firstProc.StartInfo.FileName =Application.StartupPath + "\\" + fileName;
firstProc.EnableRaisingEvents = true;
firstProc.Start();
}
}
catch (Exception)
{
}
}
I dont want that the user gets UAC prompt.

in windows there is something called task scheduler, there one can create the task and give the path to any specific program, choose admin rights and when to start etc. attached screenshots for your reference

Related

I am making a quiz game for my alevel software systems developement and my code is fine but I cant run my code

There is nothing wrong in the syntax of my code but whenever I try to run it keeps saying "The process cannot access the file because it is being used by another process". The only way I am running my application is my ending my application from the task manager. Please help me by explaining why this is happening and how to fix it.
private void btnLogin_Click(object sender, EventArgs e)
{
if (File.Exists("users.txt"))
{
string[] users = File.ReadAllLines("users.txt");
bool userFound = false;
foreach (string user in users)
{
string[] splitDetails = user.Split('~');
string username = splitDetails[1];
string password = splitDetails[2];
if ((txtBoxUsername.Text == username) && (txtBoxPassword.Text == password))
{
userFound = true;
break;
}
}
if (userFound)
{
Hide();
HomeForm home = new HomeForm();
home.Show();
}
else
{
MessageBox.Show("User details are incorrect",
"Incorrect details entered");
}
}
else
{
MessageBox.Show("No users have been registered", "No users");
}
}
private void btnRegister_Click(object sender, EventArgs e)
{
Hide();
RegisterForm registerForm = new RegisterForm();
registerForm.Show();
}
This application is for my a level software systems development coursework and I am coding it in c#. I have only been learning c# for the past 5 months so I am still a beginner. I have already tried to find the answer to my problem in stack overflow and other websites.
I am expecting my application to launch when I press run, but instead I get a dialog box saying:
Error Unable to copy file "obj\Debug\SSD AS2 coursework.exe" to "bin\Debug\SSD AS2 coursework.exe". The process cannot access the file 'bin\Debug\SSD AS2 coursework.exe' because it is being used by another process.
SSD AS2 coursework
Check if you are closing all windows of your application when finalizing the app.
You must use Application.Exit() in any events that are going to finalize your application.
You can read more on the Documentation
It seems like the file you are trying to open is being used by another process try to close your text editor or another program writing to that file.
it is still possible to overcome the issue by using FileShare.ReadWrite and use the file from multiple processes, example on the following code:
FileStream fileStream = new FileStream("c:\users.txt", FileMode.Open,
FileAccess.Read, FileShare.ReadWrite);
StreamReader fileReader = new StreamReader(fileStream);
while (!fileReader.EndOfStream)
{
string user = fileReader.ReadLine();
string[] splitDetails = user.Split('~');
// the rest of the user logic in here...
}
fileReader.Close();
fileStream.Close();

Check if process is running for current user in C#

I have a program in which I check if the program is already launched or not.
I use:
if (System.Diagnostics.Process.GetProcessesByName(System.IO.Path.GetFileNameWithoutExtension(System.Reflection.Assembly.GetEntryAssembly().Location)).Count() > 1) return;
The check works but the problem is that this doesn't work on a terminal server.
The reason is, is because I check if the process exist in the existing processes.
Example:
If user A is connected to a terminal server and runs program X, user B won't be able to launch the program (because the program X usage of user A will show up in the list)
My question is, how in C#, can I check if the program is already running under the context of the user?
I have discovered the following WMI-code that works in PowerShell, but the problem is that this doesn't work in C#
$owners = #{ }
gwmi win32_process |% {$owners[$_.handle] = $_.getowner().user}
$ps = get - process | select processname,Id,#{ l = "Owner"; e ={$owners[$_.id.tostring()]} }
foreach ($p in $ps) {
if ($p.Owner - eq $env: USERNAME) {
$p
}
}
Would there be a method by editing my existing method to allow this?
I tried to do:
Process[] runningProcesses = Process.GetProcesses();
var currentSessionID = Process.GetCurrentProcess().SessionId;
Process[] sameAsThisSession =
runningProcesses.Where(p => p.SessionId == currentSessionID).ToArray();
if (sameAsThisSession.Contains(System.Diagnostics.Process.GetCurrentProcess()))
{
MessageBox.Show("Program already running!");
}
But this doesn't work. (It does show the processes of the user only though).

A piece of code working in WindowsFormApplication but not working in windows service, is there any mistake?

Here the code is
protected override void OnStart(string[] args)
{
Thread thr = new Thread(new ThreadStart(run));
thr.Start();
}
static void run()
{
while (true)
{
StreamWriter str = new StreamWriter("D:\\Sarojini.txt", true);
str.WriteLine();
str.WriteLine("**** List of Apllication*********");
str.WriteLine();
str.WriteLine("Service started on:" + DateTime.Now.ToString());
string userName = System.Security.Principal.WindowsIdentity.GetCurrent().Name.ToString();
str.WriteLine();
str.WriteLine("the current user is " + userName);
Process[] processlist = Process.GetProcesses();
foreach (Process process in processlist)
{
if (!String.IsNullOrEmpty(process.MainWindowTitle))
{
str.WriteLine("Process::{0} ID::{1} Title::{2}", process.ProcessName, process.Id, process.MainWindowTitle);
}
}
str.Close();
Thread.Sleep(3600000 / 10);
}
}
protected override void OnStop()
{
StreamWriter str = new StreamWriter("D:\\Sarojini.txt", true);
str.WriteLine();
str.WriteLine("the service has been stopped.");
}
here in this code , a text file is created and first line is written on it but the list of running application is not there , where as when i used this code in in windowsFormApllication it is running perfectly. i dont know what is the problem .
This is most likely due to the account you are running the service under not having the correct permissions to use the Process class. When trying to retrieve process names, IDs etc your application needs to have sufficient rights and the default Local System Account is unlikely to meet this.
When you run this code as a Windows Form Application WindowsIdentity.GetCurrent() will return the user who is currently signed in.
When you run this code as a Windows Service WindowsIdentity.GetCurrent() will return the user who setup under the User Account in the Service Setting.
This will show that they are running with different credentials. So, your service may be running under an account that does not have permission to perform the required actions.
To check this:
Go into Services and double-click your service.
Click on The Log On tab
By default Local System Account is checked but you want to select This Account and set a valid account.

How to close a file in Autocad using C# keeping acad.exe running?

I am using visual studio 2010 and I am having a .DWG file which I want to open in autocad. Till now I have used this.
Process p = new Process();
ProcessStartInfo s = new ProcessStartInfo("D:/Test File/" + fileName);
p.StartInfo = s;
p.Start();
But what I want is to close the file inside the Autocad but not the autocad itself. (Means atocad.exe should be kept running).
Till now I hve used this but its closing the acad.exe not the file.
foreach (Process Proc in Process.GetProcesses())
{
if (Proc.ProcessName.Equals("acad"))
{
Proc.CloseMainWindow();
Proc.Kill();
}
}
Take the Autocad .NET libraries from Autodesk Sites (http://usa.autodesk.com/adsk/servlet/index?id=773204&siteID=123112)
Then you will be able to use Application and Document classes.
They will give you full control over opening and closing documents within the application.
You can find many articles on that, and can ask further questions.
AutoCAD does have an api. there are 4 assemblys. Two for in-process and two for COM.
inprocess :
acdbmgd.dll
acmgd.dll
COMInterop :
Autodesk.Autocad.Interop.dll
Autodesk.Autocad.Interop.Common.dll
this is a method that will open a new instance of AutoCAD or it will connect to an existing running instance of AutoCAD.
you will need to load these .dlls into your project references.
using Autodesk.AutoCAD.Interop;
using Autodesk.AutoCAD.Interop.Common;
namespace YourNameSpace {
public class YourClass {
AcadApplication AcApp;
private const string progID = "AutoCAD.Application.18.2";// this is AutoCAD 2012 program id
private string profileName = "<<Unnamed Profile>>";
private const string acadPath = #"C:\Program Files\Autodesk\AutoCAD 2012 - English\acad.exe";
public void GetAcApp()
{
try
{
AcApp = (AcadApplication)Marshal.GetActiveObject(progID);
} catch {
try {
var acadProcess = new Process();
acadProcess.StartInfo.Arguments = string.Format("/nologo /p \"{0}\"", profileName);
acadProcess.StartInfo.FileName = (#acadPath);
acadProcess.Start();
while(AcApp == null)
{
try { AcApp = (AcadApplication)Marshal.GetActiveObject(progID); }
catch { }
}
} catch(COMException) {
MessageBox.Show(String.Format("Cannot create object of type \"{0}\"",progID));
}
}
try {
int i = 0;
var appState = AcApp.GetAcadState();
while (!appState.IsQuiescent)
{
if(i == 120)
{
Application.Exit();
}
// Wait .25s
Thread.Sleep(250);
i++;
}
if(AcApp != null){
// set visibility
AcApp.Visible = true;
}
} catch (COMException err) {
if(err.ErrorCode.ToString() == "-2147417846"){
Thread.Sleep(5000);
}
}
}
}
}
closeing it is as simple as
Application.Exit();
and forgive the code. its atrocious, this was one of my first methods when i just started developing...
I doubt you will be able to do this unless AutoCAD has an API that you can hook into and ask it to close the file for you.
Your c# app can only do things to the process (acad.exe) , it doesn't have access to the internal operations of that process.
Also, you shouldn't use Kill unless the process has become unresponsive and certainly not immediately after CloseMainWindow.
CloseMainWindow is the polite way to ask an application to close itself. Kill is like pulling the power lead from the socket. You aren't giving it the chance to clean up after itself and exit cleanly.
There is one other possibility - this will only work if your C# code is running on the same machine as the AutoCAD process and it is not really recommended, but, if you are really stuck and are prepared to put up with the hassle of window switching you can send key strokes to an application using the SendKeys command.
MSDN articles here:
http://msdn.microsoft.com/EN-US/library/ms171548(v=VS.110,d=hv.2).aspx
http://msdn.microsoft.com/en-us/library/system.windows.forms.sendkeys.send.aspx
Using this you could send the key strokes to simulate the user using the menu commands to close the file.
To perform the closing of file, best way out is to follow the steps at this ObjectARX SDK for c# and change the following code with the below code.
[CommandMethod("CD", CommandFlags.Session)]
static public void CloseDocuments()
{
DocumentCollection docs = Application.DocumentManager;
foreach (Document doc in docs)
{
// First cancel any running command
if (doc.CommandInProgress != "" &&
doc.CommandInProgress != "CD")
{
AcadDocument oDoc =
(AcadDocument)doc.AcadDocument;
oDoc.SendCommand("\x03\x03");
}
if (doc.IsReadOnly)
{
doc.CloseAndDiscard();
}
else
{
// Activate the document, so we can check DBMOD
if (docs.MdiActiveDocument != doc)
{
docs.MdiActiveDocument = doc;
}
int isModified =
System.Convert.ToInt32(
Application.GetSystemVariable("DBMOD")
);
// No need to save if not modified
if (isModified == 0)
{
doc.CloseAndDiscard();
}
else
{
// This may create documents in strange places
doc.CloseAndSave(doc.Name);
}
}
}

Opening a web page in a non-elevated browser from an elevated process C#

I've been trying for a couple weeks now to run a non-elevated web browser from an elevated process, I have tried various things, duplicating the explorer token, using the WinSafer Apis mentioned here and various other techniques that all failed. Finally I decided to use Microsoft's suggestion of using the Task Scheduler to run the application.
I used the Task Scheduler Managed Wrapper, at first I tried running explorer.exe and passing the url as a command but that did not work so I created a dummy executable that'll launch the site using Process.Start.
Here is how I create the task:
public static void LaunchWin8BrowserThroughTaskScheduler(string sURL)
{
String RunAsUserExecPath = AppDomain.CurrentDomain.BaseDirectory + "URLLaunch.exe";
String Command = string.Format("-w \"{0}\"", sURL);
using (TaskService ts = new TaskService())
{
TaskDefinition td = ts.NewTask();
td.RegistrationInfo.Description = "URL Launch";
td.Principal.LogonType = TaskLogonType.InteractiveToken;
TimeTrigger trigger = new TimeTrigger(DateTime.Now.AddSeconds(2))
{
Enabled = true,
EndBoundary = DateTime.Now.AddSeconds(10)
};
td.Triggers.Add(trigger);
td.Actions.Add(new ExecAction( RunAsUserExecPath, Command, null));
td.Settings.StartWhenAvailable = true;
//Delete the task after 30 secs
td.Settings.DeleteExpiredTaskAfter = new TimeSpan(0,0,0,30);
ts.RootFolder.RegisterTaskDefinition("URL Launch", td, TaskCreation.CreateOrUpdate, null, null, TaskLogonType.InteractiveToken);
}
}
and this is the code to my dummy executable:
static void Main(string[] args)
{
if(args.Length<=1)
return;
string sCmd = args[0];
string sArg = args[1];
if(string.IsNullOrEmpty(sCmd)||string.IsNullOrEmpty(sArg))
return;
switch (sCmd)
{
case "-w":
{
Process prs = Process.Start(sArg);
}
break;
}
}
This method is working, and the browser is indeed launched non-elevated and I was able to confirm that by checking the Elevated column in Windows 8's task manager.
The only nuance here is that the browser is not launched as the top most window, it is running in the background and I think its got to do with the fact that its being run through task scheduler.
This is causing me problems especially with Modern UI browsers because Windows does not switch to them when a page is launched. I can see that the page has been successfully launched in Chrome, for example, while running in Windows 8 mode, but the fact that it does not switch to the browser just defies the whole purpose of this workaround.
I thought about using SetForegroundWindow but sadly running a URL like the example above or through explorer.exe, Process.Start returns null.
I was wondering if someone can help me fix this and be able to run the browser in foreground.
Regards
I've been able to solve the issue with a very simplistic method.
Just write a shortcut file to somewhere like the TempFolder and execute it through explorer.exe likes so:
public static void GoURL(string url)
{
string sysPath = Environment.GetFolderPath(Environment.SpecialFolder.System);
string ExplorerPath = Path.Combine(Directory.GetParent(sysPath).FullName,
"explorer.exe");
string TempDir = Environment.GetFolderPath(Environment.SpecialFolder.InternetCache);
string shortcutPath = Path.Combine(TempDir, "Mylink.url");
urlShortcutToTemp(url, shortcutPath);
System.Diagnostics.Process.Start(ExplorerPath, shortcutPath);
}
private static void urlShortcutToTemp(string linkUrl, string shortcutPath)
{
using (StreamWriter writer = new StreamWriter(shortcutPath))
{
writer.WriteLine("[InternetShortcut]");
writer.WriteLine("URL=" + linkUrl);
writer.Flush();
}
}
The same solution can be applied to executables with lnk shortcuts.

Categories

Resources