How to save the input values? - vb.net

Using VB.Net
Database Form
Server Name, Username, Password - textbox
SQL Authentication, windows Authentication - checkbox
I have Database Form, First Time i run my software, I have to give Server Name, Window or SQL Authentication mode, UserName and password. Next Time I run the software, given data's like Server name, username, password, window or sql authentication should appear in the form.
Before I used VB6, I used the ini file for getting the username, password and servername.
vb6 code.
Dim File As String, OFLen As Double, str As String
File = App.Path & "\SQLServer.ini"
OFLen = FileLen(File)
SName = ReadIni(File, "Server", "ServerName")
UName = ReadIni(File, "UserName", "UName")
PWord = ReadIni(File, "Password", "PWord")
Dim ConnectionString As String
Set DLTConn = New ADODB.Connection
ConnectionString = "Provider=SQLOLEDB.1;Integrated Security=SSPI; Persist Security Info=False;Initial Catalog=database1;Data Source=" & SName & ""
DLTConn.Open ConnectionString
There is any option is available in the vb.net for saving the data's or i have to use the same format(ini file) in vb.net
Need vb.net code Help.

These instructions assume VB2008 but I believe that 2010 is similar.
As #treaschf said, right click on your project in the Solution Explorer and select properties. If a window pops up with a title "Solution '...' Property Pages" then you clicked on the solution instead of the project. In the property window click on Settings. In the name column enter "Username", leave the type as String, the scope as User and the value as empty (unless you want to enter a default). Repeat this with each property that you want to store. These steps automatically create variables that you can access using My.Settings..
So in your code-behind you can do:
My.Settings.Username = "bob"
And:
Dim username as String = My.Settings.Username
I believe that settings will automatically be saved on exit but I recommend making an explicit call after updating just in case.
My.Settings.Save()
So that will pretty much do the same as you INI file used to do. But like #treaschf said, you should really encrypt the password when saving to disk. Below is a modified version of the routine found here. http://weblogs.asp.net/jgalloway/archive/2008/04/13/encrypting-passwords-in-a-net-app-config-file.aspx . I removed the System.Security.SecureString because as nice as it is it also makes life more complicated. Change the value of Entropy to anything you want, call Encrypt(string) to encrypt your text and Decrypt(string) to decrypt it. This uses DPAPI so you don't have to worry about messing with the registry, permissions and everything else.
Private Shared entropy As Byte() = System.Text.Encoding.Unicode.GetBytes("Enter some text here for entropy")
Public Shared Function EncryptString(ByVal text As String) As String
Dim data = System.Security.Cryptography.ProtectedData.Protect(System.Text.Encoding.Unicode.GetBytes(text), _
entropy, _
System.Security.Cryptography.DataProtectionScope.CurrentUser)
Return System.Convert.ToBase64String(data)
End Function
Public Shared Function DecryptString(ByVal encryptedData As String) As String
Dim data As Byte() = System.Security.Cryptography.ProtectedData.Unprotect(System.Convert.FromBase64String(encryptedData), _
entropy, _
System.Security.Cryptography.DataProtectionScope.CurrentUser)
Return System.Text.Encoding.Unicode.GetString(data)
End Function
And then to put it all together:
My.Settings.Username = EncryptString("bob")
Dim username As String
If Not String.IsNullOrEmpty(My.Settings.Username) Then
Try
username = DecryptString(My.Settings.Username)
Catch ex As Exception
'There was a problem decrypting the username
End Try
End If
Trace.WriteLine(username)

If you right-click on your project in Solution Explorer, and chose Properties, on the properties page there will be a Settings tab, in which you define the settings of your application.
These settings will be stored in an XML file, near the executable of your application. (Or in case of user-settings, in the C:\Users\username... directory.
If you name your connection string setting as DbConnectionString, you will be able to access it from code like this:
My.Settings.DbConnectionString
However if you need to store user names and passwords, I would recommend you to store the settings in the Windows registry, and encrypt them with the System.Security.Cryptography.ProtectedData class. (Storing the password unencrypted is not recommended.)

Related

Is it posible to use System.Configuration to Write to a Network Location

due to our applications being moved onto a Citrix VM platform I need to move our application settings config files from C:\ProgramData to an alternative location. With this particular application each user has their own config file, which is effectively a clone of the app.config file but with just user specific content, for example encrypted authentication credentials.
With this in mind, I modified the code to save the config files to a mapped network drive. Using system.configuration I am able to read content without any issues from the networked drive but when I attempt to write changes I get the following error message:
*"Attempted to perform an unauthorized operation."
The following is the function which generates the error:
Public Shared Function WriteSettingUser(ByVal configPath As String, ByVal userName As String, ByVal sectionName As String, ByVal setting As String, ByVal value As String) As String
Dim result As Boolean = False
Dim filemap As New ExeConfigurationFileMap
Dim config As Configuration
Dim section As AppSettingsSection
Try
filemap.ExeConfigFilename = configPath & userName & ".config"
config = ConfigurationManager.OpenMappedExeConfiguration(filemap, ConfigurationUserLevel.None)
section = config.GetSection(sectionName)
section.Settings(setting).Value = value
config.Save()
result = True
Catch ex As Exception
Throw
result = False
Finally
End Try
Return result
The error is generated at the 'config.save' line.
Would appreciate any insight into this issue.
Kind Regards
Paul J.

Get Account management - Display Name - Vb.net

This little piece of code gets the system current logged in user's Display name
Imports System.DirectoryServices.AccountManagement
Dim userFullName As String = UserPrincipal.Current.DisplayName
Label1.Text = "Hi " & userFullName & ", Welcome !!"
The above code works fine when i connected the LAN to the computer. but when LAN is removed and WIFI is connected it doesn't work .. Can someone guide the workaround for this?
This method only works as long as the directory server can be contacted.
Otherwise you get a PrincipalServerDownException.
As a workaround you could cache the displayname while the server is reachable.
You can cache it for example inside My.Settings.
Create a user scoped setting named cachedDisplayname and use the following method:
Function GetUserDisplayName() As String
Dim userFullName As String
Try
'Reading the displayname from the directory
userFullName = UserPrincipal.Current.DisplayName
'Saving the displayname in My.Settings
My.Settings.cachedDisplayname = userFullName
My.Settings.Save()
Catch ex As PrincipalServerDownException
If String.IsNullOrWhiteSpace(My.Settings.cachedDisplayname) Then
'displayname has not been cached yet, use Username as compromise solution
userFullName = Environment.UserName
Else
'read the cached displayname from My.Settings
userFullName = My.Settings.cachedDisplayname
End If
End Try
Return userFullName
End Function
Setting the label-text:
Label1.Text = String.Format("{0}, Welcome !!", GetUserDisplayName())

Using DirectoryEntry.Invoke("SetPassword", ...) to set initial AD account password, I get "RPC server is unavailable" error

The company I'm working in has a web service that can create new Active Directory accounts based on information that is typed in e.g. username, firstname, lastname, OU1, OU2, etc.
This web service has been working fine on Windows Server 2003. Now I'm working on moving the web service to 2008 R2 servers. However a certain functionality doesn't work anymore, which is when it tries to set a random initial password to the newly created account.
The exception that is thrown is a TargetInvocationException containing an inner exception of COMException with a message of "The RPC Server is unavailable".
Imports System.DirectoryServices
Dim ldapPath As String = "..." 'assume valid LDAP path
Dim objContainer As DirectoryEntry = New DirectoryEntry(ldapPath, vbNullString, vbNullString, AuthenticationTypes.Secure)
objUser = objContainer.Children.Add("cn=" & Username.Trim, "user")
'sets objUser.Properties e.g. givenName, displayName, userPrincipalName, samAccountName, etc. Not important...
objUser.CommitChanges()
strPassword = RandomPassword() 'function that generates random password
objUser.Invoke("SetPassword", New Object() {strPassword})
objUser.Properties("useraccountcontrol").Value = "512" ' set as normal account
objUser.CommitChanges()
'and so on...
The error happens on the line that says:
objUser.Invoke("SetPassword", New Object() {strPassword})
Strangely the account creation itself works and I can see the new user from Active Directory Users and Computers.
I have consulted a few different people who manage the security of the DCs and the web servers, they don't really know why...
In the end I figured out a different way of setting the password, which is using the System.DirectoryServices.AccountManagement library.
So the code becomes something like this:
Imports System.DirectoryServices
Imports System.DirectoryServices.AccountManagement
Dim ldapPath As String = "..." 'assume valid LDAP path
Dim objContainer As DirectoryEntry = New DirectoryEntry(ldapPath, vbNullString, vbNullString, AuthenticationTypes.Secure)
Dim objUser As DirectoryEntry = objContainer.Children.Add("cn=" & Username.Trim, "user")
'sets objUser.Properties e.g. givenName, displayName, userPrincipalName, samAccountName, etc. Not important...
objUser.CommitChanges()
Dim domainContext As PrincipalContext = New PrincipalContext(ContextType.Domain, ...)
Dim user As UserPrincipal = UserPrincipal.FindByIdentity(domainContext, IdentityType.SamAccountName, Trim(Username))
strPassword = RandomPassword() 'function that generates random password
user.SetPassword(strPassword)
user.Enabled = True 'setting these two properties
user.PasswordNotRequired = False 'result in useraccountcontrol value = 512 (normal account)
user.Save()
'and so on...
I'm mixing old code with new code in this one, but it appears to be working really well on the new servers. One thing to note is that sometimes the UserPrincipal.FindByIdentity call initially returns Nothing, I believe due to delay in the account creation or with the replication. So I have to make sure that the user object is not Nothing by trying FindByIdentity multiple times until I get the object.
Despite finding a solution (more like a way around) to the problem, still I'm confused as to why the old code does not work on the new servers, but the new one does. The error is very generic and searching the internet for clues have resulted in nothing but more confusion.
Would really appreciate if experts out there can shed some lights or even comment on the way my new code looks, any problems?
Thanks in advance.

Accessing Files On Server By Specifying Credentials

Our company has a share point document server where the UNC looks something like this: \\theserver.ourdomain.com\rootdirectory
Currently this drive is mapped to the Z:\ on my local computer. To access the Z:\ you have to specify (each time you login) credentials (in our case is it our username and password we logged on with) to access the folders and files in the rootdirectory.
I am in a situation where I need to copy files onto the share point server. I want to be able to copy files onto the server without using the mapped network drive (not have to specify Z:\ in the path). How can I supply credentials so that I can perform basic IO functions like GetDirectories(), GetFiles(), IO.File.Copy() etc...?
I have looked into the following things but was unsuccessful in making them work:
LogonUser API call by specifying plain text user name and password, then taking the token from that call and impersonating that user using a new instance of the WindowsIdentity class. Was able to get the token, but the impersonation didn't seem to work. Kept getting access denied errors.
CredUIPromptForCredentials/CredUIPromptForWindowsCredentials API calls, but I realize these are just for a fancy Windows UI where you can enter your credentials into and actually don't do anything.
<DllImport("advapi32.dll", SetLastError:=True)> _
Private Shared Function LogonUser(lpszUsername As String, lpszDomain As String, _
lpszPassword As String, dwLogonType As Integer, _
dwLogonProvider As Integer, ByRef phToken As IntPtr) As Boolean
End Function
<DllImport("kernel32.dll", CharSet:=CharSet.Auto)> _
Private Shared Function CloseHandle(handle As IntPtr) As Boolean
End Function
'// logon types
Public Const LOGON32_LOGON_NETWORK As Integer = 3
Public Const LOGON32_LOGON_NEW_CREDENTIALS As Integer = 9
'// logon providers
Public Const LOGON32_PROVIDER_WINNT50 As Integer = 3
Public Const LOGON32_PROVIDER_WINNT40 As Integer = 2
Public Const LOGON32_PROVIDER_WINNT35 As Integer = 1
Public Const LOGON32_PROVIDER_DEFAULT As Integer = 0
Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
Dim token = IntPtr.Zero
Dim success = LogonUser("username", "domain", "password", _
LOGON32_LOGON_NEW_CREDENTIALS, _
LOGON32_PROVIDER_DEFAULT, token)
If Not success Then
Me.RaiseLastWin32Error()
End If
Using identity = New WindowsIdentity(token)
Using impersonated = identity.Impersonate()
Try
Dim info = New DirectoryInfo("\\theserver.ourdomain.com\rootdirectory\")
Dim files = info.GetDirectories()
Catch ex As Exception
Finally
impersonated.Undo()
End Try
If Not CloseHandle(token) Then
Me.RaiseLastWin32Error()
End If
End Using
End Using
End Sub
Private Sub RaiseLastWin32Error()
Dim hr = Marshal.GetLastWin32Error()
Dim ex = Marshal.GetExceptionForHR(hr)
If ex IsNot Nothing Then
Throw ex
End If
Throw New SystemException(String.Format("Call resulted in error code {0}", hr))
End Sub
This isn't a direct answer to your question as it is a wildly different approach. If it doesn't work for your situation sorry to bother, but have you considered using the SharePoint web services to load the files and retrieve information?
I suggest this approach for a few reasons:
The issue you are experiencing may be occurring because SharePoint implements WebDav which might not be 100% compatible with System.IO. I'm not an expert on the innards here, I don't know about the compatibility for sure, but it seems plausible.
The UNC location you have could easily be massaged into a URL that the web service requires.
You can set the credentials directly on the proxy and might have an easier time. (though we make these calls from another web server and so the app pool credentials in the example are good enough for us)
Here's some sanitized and simplified code just in case:
// location takes the form http://server.name.com/site/library/folder/document.ext
public string UploadDocument(string location, byte[] fileContents)
{
var result = String.empty;
var destination = new string[1];
destination[0] = location;
var fileName = Path.GetFileName(location);
var fieldInfo = new FieldInformation[0];
CopyResult[] copyResults;
_copyService.Url = "http://server.name.com/_vti_bin/Copy.asmx";
_copyService.Credentials = CredentialCache.DefaultCredentials;
_copyService.CopyIntoItems(fileName, destination, fieldInfo, fileContents, out copyResults);
var errorCode = copyResults[0].ErrorCode;
if (errorCode != CopyErrorCode.Success)
{
if (errorCode == CopyErrorCode.DestinationCheckedOut)
result = "File is currently checked out. Please try again later.";
else
result = "Error uploading content.";
}
return result;
}
_copyService is a dependency we inject where the run-time implementation is the proxy generated by Visual Studio tools from the Copy.asmx SharePoint web service.
You can also get folder contents and document metadata using the Lists.asmx web service. The biggest downsides to this approach are that querying the information requires some CAML knowledge and processing the results is not as easy. But the services are reasonably documented on MSDN and the operations are all working in our application.
Well, I was able to solve this with the help of the WNetAddConnection2 API. This API is used for mapping network drives as well, however you can call this method without specifying a drive letter so that it just adds the connection.
Say for example you had drive X: mapped to \\server\share
Lets also say that it requires username & password to access the files on the server. When you restart Windows 7, you will probably lose that connection (you will get a notification saying that Windows was unable to reconnect some of the network drives). If you have an application that requires access to that server's files and you attempt to access it without supplying your credentials you will get access denied exceptions. If you do a successful call to WNetAddConnection2, not only will it fix your unmapped network drive, you will also be able to access the files/directories via the System.IO namespace.
We use Sharepoint and this worked for me. Thanks to the other guys for replying also.

FtpWebRequest.GetRequestStream hang up and fails.

I have wrote a web service, in a nutshell it uses openpop to get email messages does stuff with the content to insert into databases and saves attachments which are images. That works fine when i save images locally, it does exactley what it is suppose to. Now an added requirment was to save images to an FTP directory, so i can create my folders dynamically (they are created based upon timestamp) and that works well. My problem comes from when i try to save them to the ftp. Yes my user name and password are correct, otherwise i wouldn't be creating the directory.
Private Sub UploadFile(ByVal fileToSave As FileInfo, ByVal path As String)
Dim UploadRequest As FtpWebRequest = DirectCast(WebRequest.Create("ftp://UserName:Passowrd#999.99.999.9" & path), FtpWebRequest)
UploadRequest.Credentials = New NetworkCredential("PicService", "grean.matching18")
UploadRequest.Method = System.Net.WebRequestMethods.Ftp.UploadFile
UploadRequest.UseBinary = True
UploadRequest.UsePassive = True
' Const BufferSize As Integer = 2048
' Dim content(BufferSize - 1) As Byte, dataRead As Integer
Dim bFile() As Byte = System.IO.File.ReadAllBytes(fileToSave.ToString)
'UploadRequest.ContentLength = content.Length
Using FileStream1 As FileStream = fileToSave.OpenRead()
Try
'open request to send
Using RequestStream As Stream = UploadRequest.GetRequestStream
End Using
Catch ex As Exception
Finally
'ensure file closed
FileStream1.Close()
End Try
End Using
End Sub
I have tried using Passive False and Binary False as well, i did more research on my stack trace.
And found this article but no solution as of yet. Any input would be appreciated, i am also posting another question on windows services for different issue. If you would like to take a shot at it, the other question isnt about ftp but permissions for a service on windows server 2003
This may not be the solution but I've found that the URI string has to be 'just right' and that what is 'just right' varies by the ftp server.
So ftp://server/directory/file works on some servers but needs to be ftp://server//directory/file to work on others (note the double slash after the server name)
Aso, your URI has 'password' spelled incorrectly: ftp://UserName:Passowrd#999.99.999.9 and you are supplying the credentials in a separate code line as well.