Prompt for user input during installation - vb.net

I have developed a vb.net desktop app that connects and interacts with a database. Ideally, I would like to set up the publication project to prompt for user input during installation of the app (when running the *.msi file). Then, this input could be used as constants within the application. This way, the admins can enter the connection info during install rather than managing through config files, etc.
Prompts would include Username, Password, Database name.
Is this possible or is there a better way of implementing this functionality?

Not during install but this is how I accomplish a similar task.
Add a setting to your application called IsUpgrade and set it to true.
Create a settings form to set all of the values you need.
Once the application is installed, have the admin launch it.
Check for IsUpgrade in your starting form load event.
If IsUpgrade then
FormSettings.Show()
'Save settings in FormSettings closing event
My.Settings.IsUpgrade = False
End If

Related

How can I change the VB.NET application connection string after deployment?

I have written a VB.NET application and created a setup file to install the same on the target machine. An ODBC connection is used to connect to SQL Server instance through a DSN.
My development computer used Integrated Security whereas the target computer uses SQL Authentication which requires me to hard code the credentials in the connection string while building the setup file.
I have previously looked up for solutions, but they require one to define the credentials every time the application is run. I have seen an application that requests the credentials the first time it is run or if the connection is unsuccessful, but unfortunately could not retrieve the source code for the same.
Any guidance on similar lines would be helpful.
Add application settings of string type with user scope for the user name and password, lets say username & userpass. Let the User save these values the first time they run your app. Then just incorporate the My.Settings.username and My.Settings.userpass into your connection string.
To save the settings:
My.Settings.username = txt_user.text
My.Settings.Save()
This way the user can change the username & password if required without you having to update your code.

Copy file with elevated privileges; prompt is fine [duplicate]

When a user saves a file from my application, they currently can't save to restricted locations (like C:). I think this is a good restriction, but I would like to provide a UAC prompt to elevate privileges and allow a user to save in a restricted area.
I've seen lots of answers around this topic that involve spawning a new process with elevated privileges using 'runas'. Also, it seems like this can be done by impersonating another user. From what I understand, both of those methods require a user to provide user credentials.
What I'm wanting to do is basically what Windows itself does. When you try to copy a file to C:\ in Windows 7 (assuming you've got UAC set to its default level), you get the following prompt:
Once you click the Continue button with the UAC shield, the file is copied to C:\ with no prompt for credentials (assuming you're logged on with admin privileges).
How can I replicate this behavior in my application for admin users? They shouldn't have to impersonate any other user because they already have admin privileges. Can anyone provide details on what Windows is doing during this process? Are they spawning a new explorer.exe process with elevated privileges?
You need to do what Windows does. And spawn a new process which will run with elevated rights. There are no shortcuts here. The token that is allocated when a process starts is what determines what rights the process has. That token cannot be changed after the process has started. If you need to elevate, you need a new process.
I've seen lots of answers around this topic that involve spawning a new process with elevated privileges using 'runas'. Also, it seems like this can be done by impersonating another user. From what I understand, both of those methods require a user to provide user credentials.
No that's not the case. If the current user is not an admin, then the UAC dialog will prompt for new credentials of a user that does have admin rights. That's the over-the-shoulder UAC dialog. On the other hand, if the current user is an admin then they just get the consent dialog. That's the dialog that's shown on the secure desktop and just asks for you to click Continue.
The one thing that Windows components can do that you cannot is start a process elevated without showing you the consent dialog. That happens on Windows 7 only (not on Vista), and only if you have the UAC setting at the new Default setting that was added in Windows 7. That's how Explorer is able to show the dialog that you included in the question and then start an elevated process to do the copying without showing the consent UAC dialog. Only Windows components are granted that ability.
But the bottom line is that you need to start a new process that runs elevated. Using the runas verb is the canonical way to do it.
Programming Elevated Privilege/UAC
Running applications with more privileges than required is against the
principle of least privilege, and may have potential security
vulnerability. To defend this, Windows Vista introduces User Account
Control (UAC), to protect operating system by running applications
with reduced privileges (as a normal user), even the current user is
signed in as an administrator. More and more XP/2K users are also use
normal user account for daily use. Read UAC Demystified first to fully
understand UAC.
There are two common mistakes that developers tend to make:
Request the end-user to run an application with administrator privilege even
though this is not necessary, most of the time because of bad design
practices. These applications either scare away end-users, or
potentially have security vulnerability.
Do not request the end-user
to run the application elevated but try to perform operations that
require administrator privilege. These applications simply break under
Windows Vista or Windows XP/2K normal user account.
The downloadable sample code demonstrates how to programming elevated
privilege/UAC. Both WPF and Windows Forms sample applications are
provided. Run the application for the following scenarios to see the
difference:
Normal user, Windows XP/Windows Vista: the UAC shield icon
is displayed. Clicking “Save to C:\” displays “Run As” dialog, asking
user to enter administrator password to continue;
Administrator, Windows XP/Windows Vista with UAC disabled: the UAC shield icon is
hidden. Clicking “Save to C:\” completed without any dialog;
Administrator, Windows Vista with UAC enabled: the UAC shield icon is
displayed. Clicking “Save to C:\” displays dialog asking user’s
permission to continue.
Link to Download
Calling the elevated execute (testing for admin first):
private void SaveToRootFolder_Click(object sender, EventArgs e)
{
string fileName = #"C:\Test.txt";
if (App.IsAdmin)
DoSaveFile(textBox1.Text, textBox2.Text, fileName);
else
{
NameValueCollection parameters = new NameValueCollection();
parameters.Add("Text1", textBox1.Text);
parameters.Add("Text2", textBox2.Text);
parameters.Add("FileName", fileName);
string result = Program.ElevatedExecute(parameters);
if (!string.IsNullOrEmpty(result))
MessageBox.Show(result);
}
}
Elevated Executes:
internal static string ElevatedExecute(NameValueCollection parameters)
{
string tempFile = Path.GetTempFileName();
File.WriteAllText(tempFile, ConstructQueryString(parameters));
try
{
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.UseShellExecute = true;
startInfo.WorkingDirectory = Environment.CurrentDirectory;
Uri uri = new Uri(Assembly.GetExecutingAssembly().GetName().CodeBase);
startInfo.FileName = uri.LocalPath;
startInfo.Arguments = "\"" + tempFile + "\"";
startInfo.Verb = "runas";
Process p = Process.Start(startInfo);
p.WaitForExit();
return File.ReadAllText(tempFile);
}
catch (Win32Exception exception)
{
return exception.Message;
}
finally
{
File.Delete(tempFile);
}
}
A limited option, useful only when Moving, Renaming, Copying, and Deleting files:
SHFileOperation
If you attempt to perform a file operation via this function, Windows will provide the elevation prompt to the user.
Note there are some drawbacks for this:
This only works for Moving, Renaming, Copying, and Deleting. Saving a new file this way would require saving to a temp directory, then Moving it to the desired location. This does not solve the problem of the Save File Dialog not allowing you to select a UAC protected location as a target.
If the target directory doesn't exist (for a Move or Copy), SHFileOperation can prompt the user if the target directory should be created. However, it will NOT ask for elevated privileges to do so, and so will fail under a UAC protected location. The workaround for this is to manually create the non-existent directories in a temporary location, then Move/Copy them to the target location. This WILL provide the UAC prompt.
You need to have contingency plans in place for if the user selects 'Skip' or 'Cancel' to the Move/Copy dialog, or if the user selects 'No' at the UAC prompt.

OSP Control Automatic Logon Feature Fail

I have an Okuma OSP Machine Controller running Windows XP.
By default it attempts to automatically log on when the machine is turned on.
We have changed the default administrator password and now the auto-log on fails every time.
How can I turn off this feature or update the password so that it succeeds?
Machine Types Effected: Any machine with P200 or P300 control running Windows-XP
4/1/2014: Confirmed the same applies to new OSP-300 Windows 7 controls
2/1/2015: There is another (easier) way to accomplish this on Okuma controls.
This can be done using a utility in the TOOLS directory called the "Auto Logon Setting Tool". This is perfect for anyone uncomfortable with editing the registry.
Tool location:
The utility:
Just choose the user you wish to to be logged on automatically, and click the "Register auto log-on" button.
This feature is enabled from the factory to allow users to get up and running quickly while still having the machine password protected. Because it is recommended to change the default password this is most likely a very common situation.
The automatic login behavior can be changed by editing registry settings.
Click Start, type "regedit" (sans-quotes) in the run box, and press enter.
In the folder structure in the left pane, navigate to the following folder:
> HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon
To turn the feature OFF, change the key value of "AutoAdminLogon" to '0'
Similarly, the default user name and password can be changed by editing the appropriate keys to restore the functionality of the auto login feature.
Reference Microsoft Support article here.

Word Automation : could not open macro storage

My application (vb.net windows application deployed via ClickOnce) uses Word to open and fill .dot templates to create new Word documents. I reference Microsoft Word 14 Object Library and uses this code :
Dim oWord As Word.Application = Nothing
Dim oDoc As Word.Document = Nothing
Try
oWord = New Word.Application
Dim strFileName As String = ""
Select Case strType
Case "LettreReception"
strFileName = Path.Combine(GetParam(1), "Template_LettreReception.dot")
If File.Exists(strFileName) Then
oDoc = oWord.Documents.Add(strFileName)
On the last line I receive "could not open macro storage" error on deployed machines (not on my development machine).
I develop with Windows 7 - Office 2010 - VS 2010 (.Net 3.5). My deployment machine is also a Windows 7 with Office 2010 installed.
I tried to remove normal.dotm (I found some links advicing it) without success. The .dot template used contains no macro.
Check the properties of the word document and make sure the files are unblocked. Sometimes when you get the documents from a different computer or download them from the internet they will be blocked which will cause the the throwing of this exception "could not open macro storage"
Because Word Interop is actually running behind the scenes as if it was running in an interactive session, certain permissions are required of the account used during execution.
Are you using Windows Authentication and impersonation in you web app? If so, the user being impersonated must have local log on rights to the server to run Word... In addition, you must actually log on to the server with that account at least once so that a profile exists on that machine for that user so the registry hive can be loaded. I've also found that you may need to actually run Word at least once as that user (to make sure any first-time initialization messages get taken care of before trying to run Word from code).
If not, then the service account that the application is running under (usually NETWORK SERVICE) requires the aforementioned permissions (which I will describe shortly) and you'll have to do something fancy like loading a registry hive dynamically at run-time. Personally, I prefer implementing an in-code temporary impersonation with a user account that has local log on permissions on the server in question.
Local log on permissions can be a bit tricky depending on your network and group policy configurations (if you want to be somewhat secure and not just use a Domain Admin account).
The reason everything works on your computer running in VS is because the context of the web application is YOUR user account - which, of course, has local log on permissions on your machine with a registry hive that can be loaded.
Now for the permissions:
First, you must run "dcomcnfg" on the server and make the following configuration change:
Right click on Component Services\computers\My Computer\DCOM Config\Microsoft Word 97 - 2003 Document and go to Properties
In the Properties screen, go to the Security tab and change the "Launch and Activation Permissions" to Customize.
Click the Edit button and add the local computer NETWORK SERVICE account (If not using impersonation... If using impersonation, add the appropriate user or group) to the list of users and check "Local Launch" and "Local Activation"
Make sure that the local computer NETWORK SERVICE account (If not using impersonation... If using impersonation, then the appropriate user or group) has appropriate read/modify permissions on the folder(s)and file(s) that you will be opening and/or saving to.
Create a "Desktop" directory under: C:\Windows\System32\config\systemprofile\ and give Full permissions to the local NETWORK SERVICE account (or the account that your ASP .NET application is running under) [NOTE: I believe this and the next step only apply if NOT using impersonation]
Give Modify/Read/Execute permissions on the C:\Windows\System32\config\systemprofile folder
Hope that helps some and wasn't too confusing...
Right click on the file that is opened -> Click the Unblock tick box -> Apply
Worked for me at least.
"could not open macro storage" is telling you that VBA is looking for a particular structured storage file such as a .DOT or .DOC, and looking for the storage (a kind of stream within the file) in that file that contains the VBA code. If it can't open it, possible reasons include:
the container (the .doc/.dot) isn't there
the container cannot be opened with the caller's permissions
the container is there but the storage isn't there (e.g. on the target system there is a container with the expected name, but it contains no macros)
the container is there and the storage is there but cannot be opened with the caller's permissions
So one thing to do is to look through your project looking for anything it references (perhaps even other objects or DLLs that you specified via Tools->References) that is not also being delivered with your template.
Go to the Word document (if it's a template, be sure to open it, not create a new document with it) and disable Protected View:
https://casecomplete.zendesk.com/hc/en-us/articles/200685047-Could-not-open-macro-storage

Logoff script to change user

Using Windows 2003, I'm look for a way to create a "logoff script" that will continue with the current logoff then immediately login another user. So, "UserA" logs off. Script fires to login "UserB".
This is part of an application upgrade for a computer where we have written the 'shell'; similar to a kiosk application. For the upgrade we need to logon as 'Adminstrator' then, when the upgrade has completed, logoff 'Administrator' and logon as 'sample_user'. We would like to accomplish this WITHOUT rebooting.
Note, I do not want a script that will initiate the logoff (i.e. "shutdown"). I'm looking for a script that will run upon the user logging off (set via Group Policies). As above, the script should log a different user on.
Thanks.
Don't think it's possible in the stated way (script at logoff).
You'd have to set the machine to logon automatically as a specified account and then log off (having it log on automatically for you) and then you'd have to disable that feature again afterwards, by placing a temporary logon script... generally sounds messy.
The actual setting can be made using tools like Microsofts Shared Computer Toolkit or similar (not so sure how the "normal" registry auto-login behaves at manual logout but I've had an XP kiosk that would automatically log on instantly, even if you logged out manually - you had to override it using some key like shift+logoff to be able to manually specify the login again, so somehow it can be made).
The "easiest" way might be to replace msgina.dll with someone of your own making...
But why are you doing this? Just use runas and start whatever you need to do as that other user without logging off the console user - it's a multi-user system afterall? The desktop is just fluff ^^
(This will anyhow require that the user credentials are available to your script, which kind of makes it redundant as you compromise the security of that account - defying the purpose of having that second account in the first place, for whatever purpose it exists?)
I would try setting the registry to autologon with the user you want, and then simply logging off the admin user. That should log your kiosk-user right back on.
Not sure how to login another user once the current user logs off (not sure if windows would let you...)
But you can use shutdown to logoff:
shutdown /?
Here's some ideas that probaly fall into the "cheap hack" category:
How about logging in at UserB in the first place, and then using runas /user:userA <cmd> to run the first part of the install process?
If that's unacceptable, I know there's a way to make Windows workstations (those that aren't part of a Domain) automatically log in into a certain user account after a restart. Perhaps if you looked into which Registry changes happen, and duplicated them, a reboot would automatically log in that user. (Of course, as a final stage, after userB logs in, you would have to revert those changes :-)
It also occurs to me to wonder if perhaps there's a way for a service to force an open "login screen" to log in as a certain user. Maybe using some method like the way the Remote Desktop does it remotely... If that's possible, then you could create a service that you install before logoff of userA, that would trigger the login of userB.
You can script it with VNC (there are many free versions, take your pick). Set up a VNC server process on the machine to listen on localhost. When the user logs off, your logoff script will connect to the machine using VNC and send the keystrokes necessary to log on the next user. VNC uses the RFB (remote framebuffer) protocol; there are libraries for most popular languages, so you should be able to get something working quickly. Or there are related tools that might help.
If you were to run something like this as a normal script in a given language, it would most likely not work as when you log out of your account, all processes should be killed along with your running script.
You might be able to create some sort of 'service' that would run on a service account (i.e. always active) that would automatically do this user switching for you.
My bets are on Windows Powershell, although I'm not entirely sure what functionality it has as far as actually creating a service.
A quick search brings up the following (The second link is to a forum but it mentions running Powershell as a service and sending that service a parameter which would be the path to your user switching script)
How to Create a Windows Service using Powershel
Powershell Script as a Windows Service
I don't have a Windows 2003 server or a system with a "Group Policies" setup to test my hunch but you could take a look at SU ("switch user") for Windows. Originally part of the Resource Toolkit this has been extended to a new SUperior SU. Do post the results/script if this works.
You could approach this from the perspective of building a remote control utility (like VNC, etc). The big thing here is that if you want access to the Logon screen (i.e. the CTRL + ALT + DEL / username/password) part, the only kicker is that a Windows Service is the only component that can access this, so you'd have to create one.
The only problem I see with this technique as a whole is that even if you spent a great deal of effort getting it to work (and it would be a pretty big effort), the chances of this working successfully with the whole thing originating from a logoff script (i.e. when stuff is shutting down) are low even due to the number of things that can go wrong when logging back on as Administrator.
Just remember that for anything you need to run as an Administrator, there are easier ways in Windows to make that happen (such as Run As, changing the user permissions on the items that need to update, etc).