Write to file as Different User - vba

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.

Related

How to pass arguments to an application that is already running?

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"

In Emacs, is there a way to Call Interactive Function non-interactively from init.el?

Is it possible, in general, to call an interactive function from init.el, if it's parameters are known?
Let me give a concrete example: In the sql package, there is a interactive function sql-connect.
When invoked as
M-x sql-connect
it asks for Connection in the minibuffer. Answering
my-mysql-localhost-connection1
opens an SQL buffer with mysql prompt which it what I want.
I would like to start the connection in a SQL buffer on Emacs startup. But adding, in my init.el:
(sql-connect 'my-mysql-localhost-connection1)
does not do anything. Is what I am trying to achieve possible in this case, and for a general interactive function (which parameters are known)
Thanks
In general:
Yes, and you can use repeat-complex-command (C-xM-:) after the interactive call to find out what the arguments ended up looking like. This is a useful approach to remember, because sometimes there are hidden manipulations in an interactive form which can transform the user's input into something different1.
That doesn't necessarily give you the best arguments to use in a non-interactive call (that will always be dependent on the function in question), but it's probably the best place to start if you're unsure how to translate the one to the other2.
1 align-regexp is a good example of this.
2 Assuming that you've at least read the docstring for the function in question -- it's not uncommon for a given interactive command to be the wrong thing to call in a non-interactive context, and the function help is usually good enough to point this out.
The answer to your general question is yes: you can invoke an interactive function from code, instead of using M-x.
Wrt your more specific question:
You should not need to call the function interactively (i.e., no need to use call-interactively) unless for some reason you really want to invoke it interactively for some reason (e.g., to prompt the user). ;-)
Just call it by supplying the necessary arguments, and you should be OK. IOW this should work:
(sql-connect 'my-mysql-localhost-connection1)
But the doc says that the CONNECTION arg must define actual connection settings, per sql-connection-alist. Check that my-mysql-localhost-connection1 does follow sql-connection-alist in defining connection settings properly so that the user is not prompted for any login parameters.

Replacing a .NET dll

I have a dll which is installed with the initial installation of my app (via an msi file). The dll contains a user key and this is 'demo' for the initial installation. When a user buys a licence he is provided with another dll which contains his name. The second dll is simply the first, rebuilt with a different name so it is the same GUID and file name.
This works fine on my win7 test machine, I can replace the dll in my apps dir and it runs correctly. I have recently provided a user dll to a new client but the replace method doesn't seem to work. He is quite IT literate so I think he is following the emailed instruction (replace the userdata.dll in your app directory with the attached) it does not seem to change the dll. He is using Win8(pro).
I had thought of sending him an Inno setup to copy the user dll into the app dir, Flags:ignorereversion regserver sharedfile
Can anyone suggest a solution or an explanation?
Later...
I have now sent him an Inno setup for the updated dll and this works. If I used the second dll method (a good idea) I would still need to have the user install it.
Rather than replacing the original .dll, why not provide a second .dll with the customer's specific info? The 2nd .dll will unlock features in the original .dll.
For instance, in your original .dll you might check for Customer.dll:
if(TryLoadAssembly("Customer.dll", out assembly)) {
if(Validate(assembly)){
IsUnlocked = true;
}
}
Further recommendations (and untested samples) - have Customer.dll contain a single object implementing an interface:
class Customer : IToken {
GUID Guid {get;}
// other fields
}
To validate:
bool Validate(Assembly assembly){
Type type = assembly.GetType("Customer");
IToken customerToken = (IToken)Activator.CreateInstance(type);
// check some properties
return customerToken.Guid == application.Guid;
}
You say it doesn't appear to be replacing the DLL. Is it UAC redirecting his filecopy into local storage?
If this is the case then the easiest way to deal with it would be to either
1) supply a batch file that can do the file copy, along with instructions to launch the batch file by right clicking on it anc choosing "run as administrator".
2) supply an executable that can do the file copy. You can either include instructions to run the exe as an administrator like the batch file, or you can include a manifest with the application to instruct windows that the file needs to execute as an administrator.
A last option, which might be worth while for troubleshooting would be to get the user to turn off UAC and try the file copy again. If that works then this user will be happy and you know what the problem is and can find an elegant solution for future customers.
I've just looked on my Win 8 laptop and the option for UAC is in Control Panel - User Accounts - User Accounts - Change user account control settings. This will give a slider which can be slid all the way to the bottom to turn off UAC.
(User Accounts really is listed twice.)

Gaining Root Access w/ Elevated Helper & SMJobBless

I'm working on something that needs to install files periodically into a folder in /Library.
I understand that in the past I could have used one of the Authenticate methods but those have since been deprecated in 10.7.
What I've understood from my reading so far:
I should create a helper that somehow gets authenticated and have that helper do all of the moving tasks. I've taken a look at some of the sample code, including some involving XPC and one called Elevator but I'm a bit confused.
A lot of it seems to deal with setting up some sort of client / server model but I'm not sure how this would translate into me actually installing my files into the correct directories. Most of the examples are just passing strings.
My question simply: How can I create my folder in /Library programmatically and periodically write files to it while only prompting the user for a password ONCE and never again? I'm really not sure how to approach this and there doesn't seem to be much documentation.
You are correct that there isn't much documentation for this. You'll basically write another app, the helper app, which will get installed with SMJobBless(). Not surprisingly,
the tricky part here is the code signing. The least obvious part for me was that the SMAuthorizedClients and SMPrivilegedExecutables entries in the info plist files of each app are dependent on the identity/certificate that you used to sign the app with. There is also a trick with the compiler/linker to getting the info plist file compiled into the helper tool, which will be a single executable file, rather than a bundle.
Once you get the helper app up and running then you have to devise a way to communicate with it since these are two different processes. XPC is one option, perhaps the easiest. XPC is typically used with server processes, but what you are using here is the communication side of XPC only. Basically it passes dictionaries back and forth between the two apps. Create a standard format for the dictionary. I used #"action", #"source", and #"destination" with 3 different action values, #"filemove", #"filecopy", and #"makedirectory". Those are the 3 things that my helper app can do and I can easily add more if necessary.
The helper app will basically setup the XPC connection and event handler stuff and wait for a connection and commands. The commands will just be a dictionary so you check for the appropriate keys/values and do whatever.
I can provide more details and code if you need more help, but this question is 9 months old so I don't want to waste time giving you details you've already figured out.

Unattended application best practice question

We have an unattended app w/o a user interface that is is periodically run.
It is a VB.NET app. Instead of it being developed as a service, or a formless Windows application, it was developed with a form and all the code was placed in the form_load logic, with an "END" statement as the last line of code to terminate the program.
Other than producing a program that uses unneeded Windows form resources, is there a compelling reason to send this code back for rework to be changed to put the start up logic in a MAIN sub of a BAS file?
If the program is to enter and exit the mix (as opposed to running continuously) is there any point in making it a service?
If the app is developed with a Form do I have to worry about a dialog box being presented that no one will respond to even if there are no MessageBox commands in the app?
I recall there used to be something in VB6 where you could check an app as running unattended, presumably to avoid dialogs.
I don't know whether there are conditions where this will not run.
However, if the code was delivered by someone you will work with going forward, I would look at this as an opportunity to help them understand best practices (which this is not), and to help them understand that you expect best-practice code to be delivered.
First of all, you don't need it to be run in a Form.
Forms are there for Presentation, so it should not be done there.
If you don't want to mess with converting the application a Service (not difficult, but not very easy neither), you shoud create a Console Application, and then, schedule it with Windows Task Scheduler.
This way, you create a Console Application, with a Main function, that does exactly what you need.
Anyway, the programmer could show windows, so there should not be any messagebox. Any communication should be done via Logging to: local files, windows events, database.
If you want more information on any of them, ask me.
If you don't want it to be a service, nothing says that it has to be a windows service. Scheduling it to run via the Task Scheduler or something similar is a valid option.
However, it does sound like the developer should have choose a "Console App" project, instead of a "Windows Forms" project to create this app.
Send it back. The application is bulkier and slower than it needs to be, although that won't be much of an issue. It is somewhat more likely to run out of resources. But the main reason: converting it to a console app is very easy.
If you don't prefer for the Console window to popup, simply do the following.
Create a new class "Program.vb", add a public shared Main() method, and move the "OnLoad" logic from the form to this method.
Next delete the form, and change the project start up object (Available in the project properties window) to use the Program.Main instead of the Form.
This will have the same effect, without the windows forms resources being used. You can then remove the references to System.Windows.Form and System.Drawing.