I have a problem I start an application with admin rights from this application, another application is started at the end. This then inherits the admin rights. But it should start with normal user rights. Does anyone have a solution for the problem or a tip?
The simplest way is to ask Explorer to start it for you:
Process.Start("explorer.exe", """C:\path to\your.exe""")
You can't pass any arguments to the exe - the exe name is already an argument to explorer and I don't believe there is a way to make explorer interpret the rest of what you give as arguments (to explorer) as "arguments that should be passed to the program being started"..
..but you could create a mini program that passes the relevant arguments and explorer start that mini instead.
'this is literally all the mini program does, then quits:
Process.Start("myactualprogram.exe", "some fixed arguments")
And your main elevated program does:
Process.Start("explorer.exe", """C:\path to\miniprogram.exe""")
--
"But what if the arguments aren't always fixed?" I hear you cry.. "How can I make my mini program do Process.Start("myactualprogram.exe", "varying arguments here") when all I can do is launch it by name?"
Well.. You could either make your actual program contact your first program via TCP sockets or something and ask it for info - interprocess communciation.. Or could write a file with the arguments that your actual program can pick up.. Or if the arguments are simple enough you could just rename (or copy) the mini program so it contains the arguments in its name and when it launches it can parse its own name
'myactualprogram.exe is expecting args of: varying arguments here
'the launcher is a winforms app called 'varying arguments here.exe' that has this code
Dim args = Path.GetFilenameWithoutExtension(Application.ExecutablePath)
Process.Start("myactualprogram", args)
Of course, if your program is expecting args like /out=c:\temp\file.txt then you'll have to get a lot more creative with itbecause you can't put / \ : in filenames.. how about base64 encoding the entire arg string, naming the file that, then having your launcher program decode the b64?
Related
I have an application written in VB.NET and I have a file association that will trigger a specific function if opened from that file type.
The only thing is that If the application is already open and a user clicks on an associated file, it opens another instance of the application.
Basically, I would like to have the currently running instance of the application handle any incoming arguments from a double click on an associated file. Here is some pseudo-code to help understand.
if(application.isAlreadyRunning){
application.doSomething(filePath);
}
else{
proceed normally...
}
I've looked into mutexes, and they allow me to ensure that only one instance of the app is running, but then I need to pass the filename to the currently running instance.
Thanks!
P.S. I forgot to mention that I am using ClickOnce to deploy the app and AppDomain.CurrentDomain.SetupInformation.ActivationArguments.ActivationData to retrieve the "arguments"
I am in the process of making a simple image viewer in VB.NET. I want to be able to open an image with my application. How does VB.NET receive the URL of the file that the user is trying to open?
Seems simple but without knowing key terms, my Google searches are returning completely the wrong things!
You want to inspect the Environment.CommandLine Property
This property provides access to the program name and any arguments specified on the command line when the current process was started.
The program name can include path information, but is not required to do so. Use the GetCommandLineArgs method to retrieve the command-line information parsed and stored in an array of strings.
I am trying to write to a file that my local user account does not have access to, how can I open and write to the file as an administrator?
You need to launch another process that has admin rights. To do that call ShellExecute with 'runas' as the second parameter (this will open a User Account Control dialog). That executable may be separate or may be the same one that is calling ShellExecute.
You might want to look at PSEXEC from Microsoft, it allows you to execute files in elevated mode, and as a different user if desired.
You didn't say how the file is opened for writing, but PSEXEC can be used in conjunction in batch/vbs file to execute another batch/vbs/exe.
A good wrapper class for impersonation in a using block is what I have used with success before:
using (new Impersonation(domain, username, password))
{
// <code that executes under different user context>
}
The Using statement is great for code readability as seen in this example and to ensure that the object used is properly disposed when the final } character is reached (running out of scope). Apparently there is no guarantee of garbage collection though (see first answer).
Two different sources for such a wrapper class:
This stackoverflow solution features good readability and usability.
Here is similar code from CodeProject: A small C# Class for impersonating a User.
See MSDN for more on the Using statement.
My company's main software package includes a hefty configuration library which loads on startup. This config library includes some mandatory settings which, if not supplied (via command line arguments), cause the entire application to exit.
This has never been an issue for our users, who launch the software via scripts which have the needed command line arguments supplied automatically. But sometimes when debugging our software we developers forget to specify the necessary arguments in Visual Studio's debug options; it's then very annoying to be greeted with the message Config specification invalid -- missing required parameters X, Y, and Z -- shutting down (I'm paraphrasing, of course).
It's not really a big deal, just an annoyance. Still, I felt it worthwhile to throw together a little form to make this process a little less painful; it notifies the user which parameters are missing and allows him/her to specify values for those parameters directly on the form, without having to restart the application.
My intentions were good (I think?), but it seems I can't get this solution to actually work. The problem is that after I've launched our software with missing settings, the form pops up and prompts me as expected; but after I've entered the required parameters and it's time for the application to "really" start, I get this InvalidOperationException:
SetCompatibleTextRenderingDefault must
be called before the first
IWin32Window object is created in the
application.
I think I understand what's going on here: the VB.NET project I'm working on is doing something like this "behind the scenes"*:
Sub Main()
Application.EnableVisualStyles()
Application.SetCompatibleTextRenderingDefault(False)
Application.Run(New MainForm)
End Sub
That call to SetCompatibleTextRenderingDefault is, apparently, throwing an exception because a form was already created and displayed prior to its execution.
Is there any way around this? Is there perhaps a more "proper" solution to this problem that I'm not thinking of (i.e., should I not be trying to collect user input via a form at all)?
*This is a best guess based on what I've seen in C# WinForms projects. Strangely, unless I'm missing something, it seems that VB.NET WinForms projects completely hide this from the developer.
Do make sure that you have the application framework option turned off and Sub Main selected as the starting method. Make it look similar to this:
Sub Main(ByVal args() As String)
Application.EnableVisualStyles()
Application.SetCompatibleTextRenderingDefault(False)
If args.Length = 0 Then
Using dlg As New OptionsDialog
If dlg.ShowDialog <> DialogResult.OK Then Return
'' Use dlg result...
End Using
End If
Application.Run(New MainForm)
End Sub
Perhaps you could use the static Debugger.IsAttached (or even a #DEBUG directive) in your program's "main" function that feeds in some input file (say an XML file) into your parsed args collection instead?
Hey Overflow, I have an application which serves as a user interface for a spartan/command line program.
I have the program running on a separate process, and my application monitors it to see if it is responding and how mush CPU it is utilising.
Now I have a list of files in my program (listbox) which are to be sent to the application, which happens fine. But I want to be able to read text from the com-line so as to determine when the first file has been processed.
Com-line says one of "selecting settings", "unsupported format" and "cannot be fixed".
What I want to be able to do is when it says one of these three things, remove item(0) in listbox1.
Is this possible?
I thought of programming an event which handles com_exe.print or something or other, if possible.
Read the standard output from the process.
MSDN Article
Theres an example of synchronous reading from the process in that article.
You might be able to do what you want using the AttachConsole API function as described here. However, maybe an easier alternative would be if you could pipe the output of the command line app to a text file and then your app could just parse the text file (assuming that the command line file wouldn't lock the file completely, I'm not sure about that).
If you don't know how to pipe the output, this page has quite a bit of information.