We are developing an desktop application based on WPF, which has a feature that user can send feedback to us. We can receive the Name, Email, Body and so on.
For some historical problems we used MSMAPI to help us send mail, as time goes on we found all its function work very well until we did tests on clean machine.
The ActiveX control said, please offer me a license so I can move on, well that's make us quite confused, because that control doesn't have license at all.
Ok, I will talk about the detail now.
In folder C:\Windows\SysWOW64 (On Win7 x64), we have msmapi32.ocx. From MSDN, we have to wrapper it so can be host on a Windows Form. We did it, and got two assemblies: MSMAPI.dll and AxMSMAPI.dll, so we make our application reference these two DLLs.
Here is our code(XAML):
<Window x:Class="WpfApplication14.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:ax="clr-namespace:AxMSMAPI;assembly=AxMSMAPI"
Title="MainWindow"
Width="525"
Height="350">
<StackPanel>
<WindowsFormsHost>
<ax:AxMAPIMessages Name="axMAPIMessage" />
</WindowsFormsHost>
<WindowsFormsHost>
<ax:AxMAPISession Name="axMAPISession" />
</WindowsFormsHost>
</StackPanel>
</Window>
Ofcourse, we have to change our project build target to X86, otherwise it would throw ClassNotDefined exception. Pretty well, press F5, the main window shows successfully.
Then we copy the Debug folder of our demo application, double click, Oops... It said, WpfAPplication14 has stopped work. We captured the exption, here is the stack:
System.Windows.Markup.XamlParseException occurred
_HResult=-2146233087
_message='Initialization of 'AxMSMAPI.AxMAPIMessages' threw an exception.' Line number '-' and line position '-'.
HResult=-2146233087
IsTransient=false
Message='Initialization of 'AxMSMAPI.AxMAPIMessages' threw an exception.' Line number '-' and line position '-'.
Source=PresentationFramework
LineNumber=-
LinePosition=-
StackTrace:
at System.Windows.Markup.WpfXamlLoader.Load(XamlReader xamlReader, IXamlObjectWriterFactory writerFactory, Boolean skipJournaledProperties, Object rootObject, XamlObjectWriterSettings settings, Uri baseUri)
InnerException: System.ComponentModel.LicenseException
_HResult=-2146232063
_message=You must have a license to use this ActiveX control.
HResult=-2146232063
IsTransient=false
Message=You must have a license to use this ActiveX control.
Source=System.Windows.Forms
StackTrace:
at System.Windows.Forms.AxHost.CreateInstance()
at System.Windows.Forms.AxHost.GetOcxCreate()
at System.Windows.Forms.AxHost.TransitionUpTo(Int32 state)
at System.Windows.Forms.AxHost.CreateHandle()
at System.Windows.Forms.Control.CreateControl(Boolean fIgnoreVisible)
at System.Windows.Forms.Control.CreateControl(Boolean fIgnoreVisible)
at System.Windows.Forms.AxHost.EndInit()
at MS.Internal.Xaml.Runtime.ClrObjectRuntime.InitializationGuard(XamlType xamlType, Object obj, Boolean begin)
InnerException:
Then we wrote a Windows Forms application, in the beginning we did excatly the same with WPF demo, reference the two DLLs to project, and even the result is the same. It only can show window in our develpment machine, cannot run on clean Test Machine.
So we followed some steps on MSDN, add the ActiveX control (C:\Windows\SysWOW64\msmapi32.ocx) to Visual Studio Toolbox, and drag them to the surface, and it works very well on Test Machine.
The last try by us is, follow the Windows Forms demo did, we intended to add the ocx to toolbox, but the Visual Studio said it is successfully added to toolbox, but it is not enabled in the active designer due to incompatible with the current designer and .NET framework version (VS2012/.NET 4.0/WPF).
We don'n know what's the reason the demo window thrown exception when parse XAML in Test Machine, it seems we need a license, but does it need a license???
We tried to achieve it follow Windows Forms demo did, but we even cannot add the ocx to toolbox.
So, if you have some advices towards below questions or any of them, please feel free to let us know:
Where does the msmapi32.ocx come from? Does any windows machine has it or only after installed something. By the way, we also tried to install Office 2013 on our Test Machine, it sitll the same exception thrown.
We know our ocx version is 6.0, which released at 2000. So if we would like to use it in our WPF application, any suggestions?
What factors can affect this? we searched the Dev and Test machine, both have the ocx in the folder, and both registry have the MSAPI related item (and the Windows Forms works very well).
So if above questions can be answered, it can help us a lot. From your experience, how can you achieve this feature using WPF, using the native API provided by .NET or some else 3rd party control/plugin? In fact our requirement is so eary that user send feedback to some fixed address. That's all we need to do.
Very appreciate if you have some thoughts about our question, and feel free to ask us questions which puzzled you.
Thanks.
Did you try registering the ocx? (Make sure that a newer ocx is not already registered)
I had used native .NET APIs to send mails in the past. Here is a code snippet:
/// <summary>
///Method to Send an Email informing interested parties about the status of data extraction.
/// INPUTS : int iProcessIsSuccess : int informing about the success of the process. -1 means failure, 0 means partial success, 1 means success.
/// string szLogDataToBeSent : Log data to be sent incase process not successful.
/// OUTPUTS : bool. True if success, else false.
/// </summary>
public bool SendEmailNotification(string szEmailAddressFileName, int iProcessIsSuccess, string szLogDataToBeSent)
{
bool bSuccess = false;
//the the SMTP host.
SmtpClient client = new SmtpClient();
//SMTP Server
client.Host = CommonVariables.EMAIL_SMTP_SERVER;
//SMTP Credentials
client.Credentials = new NetworkCredential(CommonVariables.EMAIL_USERNAME, CommonVariables.EMAIL_PASSWORD);
//Creating a new mail.
MailMessage mail = new MailMessage();
//Filling 'From' Tab.
mail.From = new MailAddress(CommonVariables.EMAIL_SENDERS_ADDRESS, CommonVariables.EMAIL_SENDERS_NAME);
//Filling 'To' tab.
List<EmailAddress> EmailAddressList = new List<EmailAddress>();
try
{
using (System.IO.FileStream fs = new FileStream(szEmailAddressFileName, FileMode.Open))
{
XmlSerializer xs = new XmlSerializer(typeof(List<EmailAddress>));
EmailAddressList = xs.Deserialize(fs) as List<EmailAddress>;
}
foreach (EmailAddress addr in EmailAddressList)
{
mail.To.Add(addr.RecepientEmailAddress);
}
}
catch(Exception Ex)
{
mail.To.Add("somedefaultemail#companyname.com");
}
//Filling mail body.
string szMailBody = "";
string szMailSubject = "";
if (1 == iProcessIsSuccess) //Success
{
szMailSubject = String.Format(CommonVariables.EMAIL_SUBJECT_BOILER_PLATE, "a SUCCESS");
szMailBody = String.Format(CommonVariables.EMAIL_BODY_BOILER_PLATE, DateTime.UtcNow.ToString(), Environment.MachineName);
szMailBody += "\r\n" + szMailSubject + "\r\n";
}
else if (0 == iProcessIsSuccess) //Partially Success
{
szMailSubject = String.Format(CommonVariables.EMAIL_SUBJECT_BOILER_PLATE, "a PARTIAL SUCCESS"); ;
szMailBody = String.Format(CommonVariables.EMAIL_BODY_BOILER_PLATE, DateTime.UtcNow.ToString(), Environment.MachineName);
szMailBody += "\r\n"+ szMailSubject + "\r\n";
szMailBody += "\r\n" + "The Log data is as follows:\r\n";
szMailBody += szLogDataToBeSent;
mail.Priority = MailPriority.High;
}
else //Failed
{
szMailSubject = String.Format(CommonVariables.EMAIL_SUBJECT_BOILER_PLATE, "a FAILURE"); ;
szMailBody = String.Format(CommonVariables.EMAIL_BODY_BOILER_PLATE, DateTime.UtcNow.ToString(), Environment.MachineName);
szMailBody += "\r\n" + szMailSubject + "\r\n";
szMailBody += "\r\n" + "The Log data is as follows:\r\n";
szMailBody += szLogDataToBeSent;
mail.Priority = MailPriority.High;
}
mail.Body = szMailBody;
mail.Subject = szMailSubject;
//Send Email.
try
{
client.Send(mail);
bSuccess = true;
}
catch (Exception Ex)
{
bSuccess = false;
}
// Clean up.
mail.Dispose();
return bSuccess;
}
My post is not an answer to your questions, but provides a solution (if you like it).
In the past I've used this class (mapi compliant).
This class doesn't use native SmtpClient class (that sends an email but doesn't interact with your default mailing app) but is able to invoke your email application and popup email window (filled with every detail you need) so your customer can modify it as needed.
More, email sent remains is "sent email" folder...
enum HowTo { MAPI_ORIG = 0, MAPI_TO, MAPI_CC, MAPI_BCC };
public class MAPI
{
[DllImport("MAPI32.DLL")]
static extern int MAPISendMail(IntPtr sess, IntPtr hwnd, MapiMessage message, int flg, int rsv);
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public class MapiMessage
{
public int reserved;
public string subject;
public string noteText;
public string messageType;
public string dateReceived;
public string conversationID;
public int flags;
public IntPtr originator;
public int recipCount;
public IntPtr recips;
public int fileCount;
public IntPtr files;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public class MapiFileDesc
{
public int reserved;
public int flags;
public int position;
public string path;
public string name;
public IntPtr type;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public class MapiRecipDesc
{
public int reserved;
public int recipClass;
public string name;
public string address;
public int eIDSize;
public IntPtr entryID;
}
List<MapiRecipDesc> m_recipients = new List<MapiRecipDesc>();
List<string> m_attachments = new List<string>();
private int m_lastError = 0;
private const int MAPI_LOGON_UI = 0x00000001;
private const int MAPI_DIALOG = 0x00000008;
private const int maxAttachments = 20;
#region Private methods
private bool AddRecipients(HowTo howTo, params string[] emails)
{
bool ret = true;
foreach (string email in emails)
{
try
{
MapiRecipDesc recipient = new MapiRecipDesc();
recipient.recipClass = (int)howTo;
recipient.name = email;
m_recipients.Add(recipient);
}
catch { ret = false; }
}
return ret;
}
private int SendMail(string strSubject, string strBody, int how)
{
MapiMessage msg = new MapiMessage();
msg.subject = strSubject;
msg.noteText = strBody;
msg.recips = GetRecipients(out msg.recipCount);
msg.files = GetAttachments(out msg.fileCount);
m_lastError = MAPISendMail(new IntPtr(0), new IntPtr(0), msg, how, 0);
if (m_lastError > 1)
MessageBox.Show("MAPISendMail failed! " + LastError, "MAPISendMail");
Cleanup(ref msg);
return m_lastError;
}
private IntPtr GetRecipients(out int recipCount)
{
recipCount = 0;
if (m_recipients.Count == 0)
return IntPtr.Zero;
int size = Marshal.SizeOf(typeof(MapiRecipDesc));
IntPtr intPtr = Marshal.AllocHGlobal(m_recipients.Count * size);
int ptr = (int)intPtr;
foreach (MapiRecipDesc mapiDesc in m_recipients)
{
Marshal.StructureToPtr(mapiDesc, (IntPtr)ptr, false);
ptr += size;
}
recipCount = m_recipients.Count;
return intPtr;
}
private IntPtr GetAttachments(out int fileCount)
{
fileCount = 0;
if (m_attachments == null)
return IntPtr.Zero;
if ((m_attachments.Count <= 0) || (m_attachments.Count > maxAttachments))
return IntPtr.Zero;
int size = Marshal.SizeOf(typeof(MapiFileDesc));
IntPtr intPtr = Marshal.AllocHGlobal(m_attachments.Count * size);
MapiFileDesc mapiFileDesc = new MapiFileDesc();
mapiFileDesc.position = -1;
int ptr = (int)intPtr;
foreach (string strAttachment in m_attachments)
{
mapiFileDesc.name = Path.GetFileName(strAttachment);
mapiFileDesc.path = strAttachment;
Marshal.StructureToPtr(mapiFileDesc, (IntPtr)ptr, false);
ptr += size;
}
fileCount = m_attachments.Count;
return intPtr;
}
private void Cleanup(ref MapiMessage msg)
{
int size = Marshal.SizeOf(typeof(MapiRecipDesc));
int ptr = 0;
if (msg.recips != IntPtr.Zero)
{
ptr = (int)msg.recips;
for (int i = 0; i < msg.recipCount; i++)
{
Marshal.DestroyStructure((IntPtr)ptr, typeof(MapiRecipDesc));
ptr += size;
}
Marshal.FreeHGlobal(msg.recips);
}
if (msg.files != IntPtr.Zero)
{
size = Marshal.SizeOf(typeof(MapiFileDesc));
ptr = (int)msg.files;
for (int i = 0; i < msg.fileCount; i++)
{
Marshal.DestroyStructure((IntPtr)ptr, typeof(MapiFileDesc));
ptr += size;
}
Marshal.FreeHGlobal(msg.files);
}
m_recipients.Clear();
m_attachments.Clear();
m_lastError = 0;
}
#endregion
#region Public methods
public bool AddTo(params string[] emails)
{
return AddRecipients(HowTo.MAPI_TO, emails);
}
public bool AddCC(params string[] emails)
{
return AddRecipients(HowTo.MAPI_CC, emails);
}
public bool AddBCC(params string[] emails)
{
return AddRecipients(HowTo.MAPI_BCC, emails);
}
public void AddAttachment(string strAttachmentFileName)
{
m_attachments.Add(strAttachmentFileName);
}
public int SendMailPopup(string strSubject, string strBody)
{
return SendMail(strSubject, strBody, MAPI_LOGON_UI | MAPI_DIALOG);
}
public int SendMailDirect(string strSubject, string strBody)
{
return SendMail(strSubject, strBody, MAPI_LOGON_UI);
}
public string LastError
{
get
{
switch (m_lastError)
{
case 0: return "OK";
case 1: return "User abort [1]";
case 2: return "General MAPI failure [2]";
case 3: return "MAPI login failure [3]";
case 4: return "Disk full [4]";
case 5: return "Insufficient memory [5]";
case 6: return "Access denied [6]";
case 7: return "-unknown- [7]";
case 8: return "Too many sessions [8]";
case 9: return "Too many files were specified [9]";
case 10: return "Too many recipients were specified [10]";
case 11: return "A specified attachment was not found [11]";
case 12: return "Attachment open failure [12]";
case 13: return "Attachment write failure [13]";
case 14: return "Unknown recipient [14]";
case 15: return "Bad recipient type [15]";
case 16: return "No messages [16]";
case 17: return "Invalid message [17]";
case 18: return "Text too large [18]";
case 19: return "Invalid session [19]";
case 20: return "Type not supported [20]";
case 21: return "A recipient was specified ambiguously [21]";
case 22: return "Message in use [22]";
case 23: return "Network failure [23]";
case 24: return "Invalid edit fields [24]";
case 25: return "Invalid recipients [25]";
case 26: return "Not supported [26]";
default: return String.Format("MAPI error [{0}]", m_lastError);
}
}
}
#endregion
}
Related
I have written a dll which call windows spooler api to get printer name and printer driver name, it works fine in console application. However, I got nothing when I call the dll in windows services application.
Here is my dll source code(i.e. printerUtility):
PRINTER_ENUM_LOCAL = 0x00000002,
PRINTER_ENUM_CONNECTIONS = 0x00000004,
public ArrayList getAllLocalPrinterInfo(LogWriter logger)
{
ArrayList printerInfoList = getAllLocalPrinterInfoV2(PrinterEnumFlags.PRINTER_ENUM_LOCAL | PrinterEnumFlags.PRINTER_ENUM_CONNECTIONS);
foreach (PrinterInfoV2 printerInfo in printerInfoList)
{
logger.write("In dll Printer Name pointer:" + printerInfo.pPrinterName+"\nIn dll Printer Name:" + Marshal.PtrToStringAnsi(printerInfo.pPrinterName));
logger.write("In dll Driver Name pointer:" + printerInfo.pDriverName+"\nIn dll Driver Name:" + Marshal.PtrToStringAnsi(printerInfo.pDriverName));
}
//return allLocalPrinterInfo;
return printerInfoList;
}
public ArrayList getAllLocalPrinterInfoV2(PrinterEnumFlags Flags)
{
return enumPrinters(Flags, 2);
}
private ArrayList enumPrinters(PrinterEnumFlags Flags, UInt32 level)
{
bool result;
ArrayList printerInfo = new ArrayList();
UInt32 returned, needed = 0;
UInt32 flags = Convert.ToUInt32(Flags);
//find required size for the buffer
result = EnumPrinters(flags, null, level, IntPtr.Zero, 0, out needed, out returned);
if (Marshal.GetLastWin32Error() != Convert.ToUInt32(CredUIReturnCodes.ERROR_INSUFFICIENT_BUFFER))
{
throw new Exception("EnumPrinters 1 failure, error code=" + Marshal.GetLastWin32Error());
}
else
{
IntPtr buffer = Marshal.AllocHGlobal((int)needed);
result = EnumPrinters(flags, null, level, buffer, needed, out needed, out returned);
if (result)
{
if ((level > 0) || (level < 5))
{
Type type = typeof(PrinterInfoV1);
switch (level)
{
case 1:
type = typeof(PrinterInfoV1);
break;
case 2:
type = typeof(PrinterInfoV2);
break;
case 3:
type = typeof(PrinterInfoV3);
break;
case 4:
type = typeof(PrinterInfoV4);
break;
}
int offset = buffer.ToInt32();
int increment = Marshal.SizeOf(type);
for (int i = 0; i < returned; i++)
{
printerInfo.Add(Marshal.PtrToStructure(new IntPtr(offset), type));
offset += increment;
}
Marshal.FreeHGlobal(buffer);
return printerInfo;
}
else
{
Marshal.FreeHGlobal(buffer);
throw new Exception("The value of level is out of range");
}
}
else
{
Marshal.FreeHGlobal(buffer);
throw new Exception("EnumPrinters 2 failure, error code=" + Marshal.GetLastWin32Error());
}
}
}
[DllImport("winspool.drv", SetLastError = true)]
static extern bool EnumPrinters([InAttribute()] UInt32 Flags,
[InAttribute()] string pPrinterName,
[InAttribute()] UInt32 Level,
[OutAttribute()] IntPtr pPrinter,
[InAttribute()] UInt32 cbBuf,
[OutAttribute()] out UInt32 pcbNeeded,
[OutAttribute()] out UInt32 pcReturned);
The LogWriter Source code:
public class LogWriter
{
EventLog eventLog = null;
public LogWriter(System.Diagnostics.EventLog elog)
{
this.eventLog = elog;
}
public void write(String msg)
{
if (eventLog != null)
{
eventLog.WriteEntry(msg);
}
}
}
Here is services source code:
protected override void OnStart(string[] args)
{
serviceStatus.dwWaitHint = 100000;
serviceStatus.dwCurrentState = ServiceState.SERVICE_START_PENDING;
SetServiceStatus(this.ServiceHandle, ref serviceStatus);
printerMonitorList = new ArrayList();
try
{
ArrayList printerInfoList = printerUtility.getAllLocalPrinterInfo(logger);
foreach (PrinterInfoV2 printerInfo in printerInfoList)
{
logger.write("In service Printer Name pointer:" + printerInfo.pPrinterName+"\nIn service Printer Name:" + Marshal.PtrToStringAnsi(printerInfo.pPrinterName));
logger.write("In service Driver Name pointer:" + printerInfo.pDriverName+"\nIn service Driver Name:" + Marshal.PtrToStringAnsi(printerInfo.pDriverName));
}
serviceStatus.dwCurrentState = ServiceState.SERVICE_RUNNING;
SetServiceStatus(this.ServiceHandle, ref serviceStatus);
logger.write(this.ServiceName + " Has Been Started");
}
catch (Exception err)
{
logger.write("Print Alert Service cannot be started:"+err.Message);
}
In event viewer, I got an empty string for both printer name and printer driver name.
However, I found that the dll return a pointer for both printer name and printer driver name. Therefore, I suspect whether the Marshal.PtrToStringAnsi function not working in window services environment.
We have a solution running on WM 6.5 that connects to our servers but one of our customers has frequent problems where our software loses its gprs connection and is unable to get a new one until the phone is rebooted.
We know that the phone is in a gprs area as we are able to remote desktop into the phone and browse using internet explorer. Our logs show that although we have specified a 2 minute time out, ConnMgrEstablishConnectionSync returns with a waitingForConnection status. Does anybody have any ideas what could be going wrong? eg Is it possible that some 3rd party software is stealing our connection?
Many Thanks.
private void Connect()
{
if (_connectionHandle != IntPtr.Zero)
{
EventLog.AddLogEntry(LogSeverity.Trace, "connmgr - current handle was:" + _connectionHandle);
CloseConnection();
}
const int connectionTimeout = 120000;
const int CONNMGR_PARAM_GUIDDESTNET = 1;
const int CONNMGR_PRIORITY_USERINTERACTIVE = 0x8000;
const int CONNMGR_FLAG_SUSPEND_AWARE = 0x10; // suspended connections supported
const int CONNMGR_FLAG_NO_ERROR_MSGS = 0x40; // don't show any error messages for failed connections
const int CONNMGR_proxies = 0x3;
const string testUrl = "http://www.bbc.co.uk";
ConnectionInfo info = new ConnectionInfo();
info.cbSize = (uint)Marshal.SizeOf(info);
info.bExclusive = 0;
info.dwFlags = CONNMGR_proxies | CONNMGR_FLAG_NO_ERROR_MSGS | CONNMGR_FLAG_SUSPEND_AWARE;
info.dwPriority = CONNMGR_PRIORITY_USERINTERACTIVE;
Guid networkGuid = Guid.Empty;
int hResult = MobileNativeMethods.ConnMgrMapURL(testUrl, ref networkGuid, IntPtr.Zero);
if (hResult != 0)
{
EventLog.AddLogEntry(LogSeverity.Trace, "<<Dllimport - ConnMgrMapURL (error) " + hResult.ToString());
throw new ConnectionUnavailableException("Unable to open connection");
}
info.guidDestNet = networkGuid;
info.dwParams = CONNMGR_PARAM_GUIDDESTNET;
uint status = 0;
hResult = MobileNativeMethods.ConnMgrEstablishConnectionSync(ref info, out _connectionHandle, (uint)connectionTimeout, out status);
if (hResult != 0)
{
EventLog.AddLogEntry(LogSeverity.Trace, "<<Dllimport - ConnMgrEstablishConnectionSync (error) " + networkGuid.ToString());
throw new ConnectionUnavailableException("Unable to open connection: " + (ConnectionStatus) status);
}
EventLog.AddLogEntry(LogSeverity.Trace, "<<Dllimport - ConnMgrMapURL Connection OK");
}
In the end I found out that setting the AlwaysOn setting in the registry to false fixed the issue. I suspect that there is a deeper problem with Honeywell devices and this setting as Motorola devices seemed to work fine regardless of its value.
I was going to use the following project: https://github.com/scottwis/OpenFileOrFolderDialog
However, there's a problem: it uses the GetOpenFileName function and OPENFILENAME structure. OPENFILENAME has the member named templateID, which is the identifier for dialog template. And the project contains the res1.rc file and the templated dialog init, too. But I couldn't figure out how to attach this file to my C# project.
Is there a better way to use an OpenFileDialog to select folders?
Basically you need the FolderBrowserDialog class:
Prompts the user to select a folder. This class cannot be inherited.
Example:
using(var fbd = new FolderBrowserDialog())
{
DialogResult result = fbd.ShowDialog();
if (result == DialogResult.OK && !string.IsNullOrWhiteSpace(fbd.SelectedPath))
{
string[] files = Directory.GetFiles(fbd.SelectedPath);
System.Windows.Forms.MessageBox.Show("Files found: " + files.Length.ToString(), "Message");
}
}
If you work in WPF you have to add the reference to System.Windows.Forms.
you also have to add using System.IO for Directory class
As a note for future users who would like to avoid using FolderBrowserDialog, Microsoft once released an API called the WindowsAPICodePack that had a helpful dialog called CommonOpenFileDialog, that could be set into a IsFolderPicker mode. The API is available from Microsoft as a NuGet package.
This is all I needed to install and use the CommonOpenFileDialog. (NuGet handled the dependencies)
Install-Package Microsoft.WindowsAPICodePack-Shell
For the include line:
using Microsoft.WindowsAPICodePack.Dialogs;
Usage:
CommonOpenFileDialog dialog = new CommonOpenFileDialog();
dialog.InitialDirectory = "C:\\Users";
dialog.IsFolderPicker = true;
if (dialog.ShowDialog() == CommonFileDialogResult.Ok)
{
MessageBox.Show("You selected: " + dialog.FileName);
}
There is a hackish solution using OpenFileDialog where ValidateNames and CheckFileExists are both set to false and FileName is given a mock value to indicate that a directory is selected.
I say hack because it is confusing to users about how to select a folder. They need to be in the desired folder and then just press Open while file name says "Folder Selection."
This is based on Select file or folder from the same dialog by Denis Stankovski.
OpenFileDialog folderBrowser = new OpenFileDialog();
// Set validate names and check file exists to false otherwise windows will
// not let you select "Folder Selection."
folderBrowser.ValidateNames = false;
folderBrowser.CheckFileExists = false;
folderBrowser.CheckPathExists = true;
// Always default to Folder Selection.
folderBrowser.FileName = "Folder Selection.";
if (folderBrowser.ShowDialog() == DialogResult.OK)
{
string folderPath = Path.GetDirectoryName(folderBrowser.FileName);
// ...
}
Here is a pure C# version, nuget-free, that should work with all versions of .NET (including .NET Core, .NET 5, WPF, Winforms, etc.) and uses Windows Vista (and higher) IFileDialog interface with the FOS_PICKFOLDERS options so it has the nice folder picker Windows standard UI.
I have also added WPF's Window type support but this is optional, the WPF-marked lines can just be removed.
usage:
var dlg = new FolderPicker();
dlg.InputPath = #"c:\windows\system32";
if (dlg.ShowDialog() == true)
{
MessageBox.Show(dlg.ResultPath);
}
code:
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.ComTypes;
using System.Windows; // for WPF support
using System.Windows.Interop; // for WPF support
public class FolderPicker
{
public virtual string ResultPath { get; protected set; }
public virtual string ResultName { get; protected set; }
public virtual string InputPath { get; set; }
public virtual bool ForceFileSystem { get; set; }
public virtual string Title { get; set; }
public virtual string OkButtonLabel { get; set; }
public virtual string FileNameLabel { get; set; }
protected virtual int SetOptions(int options)
{
if (ForceFileSystem)
{
options |= (int)FOS.FOS_FORCEFILESYSTEM;
}
return options;
}
// for WPF support
public bool? ShowDialog(Window owner = null, bool throwOnError = false)
{
owner ??= Application.Current.MainWindow;
return ShowDialog(owner != null ? new WindowInteropHelper(owner).Handle : IntPtr.Zero, throwOnError);
}
// for all .NET
public virtual bool? ShowDialog(IntPtr owner, bool throwOnError = false)
{
var dialog = (IFileOpenDialog)new FileOpenDialog();
if (!string.IsNullOrEmpty(InputPath))
{
if (CheckHr(SHCreateItemFromParsingName(InputPath, null, typeof(IShellItem).GUID, out var item), throwOnError) != 0)
return null;
dialog.SetFolder(item);
}
var options = FOS.FOS_PICKFOLDERS;
options = (FOS)SetOptions((int)options);
dialog.SetOptions(options);
if (Title != null)
{
dialog.SetTitle(Title);
}
if (OkButtonLabel != null)
{
dialog.SetOkButtonLabel(OkButtonLabel);
}
if (FileNameLabel != null)
{
dialog.SetFileName(FileNameLabel);
}
if (owner == IntPtr.Zero)
{
owner = Process.GetCurrentProcess().MainWindowHandle;
if (owner == IntPtr.Zero)
{
owner = GetDesktopWindow();
}
}
var hr = dialog.Show(owner);
if (hr == ERROR_CANCELLED)
return null;
if (CheckHr(hr, throwOnError) != 0)
return null;
if (CheckHr(dialog.GetResult(out var result), throwOnError) != 0)
return null;
if (CheckHr(result.GetDisplayName(SIGDN.SIGDN_DESKTOPABSOLUTEPARSING, out var path), throwOnError) != 0)
return null;
ResultPath = path;
if (CheckHr(result.GetDisplayName(SIGDN.SIGDN_DESKTOPABSOLUTEEDITING, out path), false) == 0)
{
ResultName = path;
}
return true;
}
private static int CheckHr(int hr, bool throwOnError)
{
if (hr != 0)
{
if (throwOnError)
Marshal.ThrowExceptionForHR(hr);
}
return hr;
}
[DllImport("shell32")]
private static extern int SHCreateItemFromParsingName([MarshalAs(UnmanagedType.LPWStr)] string pszPath, IBindCtx pbc, [MarshalAs(UnmanagedType.LPStruct)] Guid riid, out IShellItem ppv);
[DllImport("user32")]
private static extern IntPtr GetDesktopWindow();
#pragma warning disable IDE1006 // Naming Styles
private const int ERROR_CANCELLED = unchecked((int)0x800704C7);
#pragma warning restore IDE1006 // Naming Styles
[ComImport, Guid("DC1C5A9C-E88A-4dde-A5A1-60F82A20AEF7")] // CLSID_FileOpenDialog
private class FileOpenDialog
{
}
[ComImport, Guid("42f85136-db7e-439c-85f1-e4075d135fc8"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
private interface IFileOpenDialog
{
[PreserveSig] int Show(IntPtr parent); // IModalWindow
[PreserveSig] int SetFileTypes(); // not fully defined
[PreserveSig] int SetFileTypeIndex(int iFileType);
[PreserveSig] int GetFileTypeIndex(out int piFileType);
[PreserveSig] int Advise(); // not fully defined
[PreserveSig] int Unadvise();
[PreserveSig] int SetOptions(FOS fos);
[PreserveSig] int GetOptions(out FOS pfos);
[PreserveSig] int SetDefaultFolder(IShellItem psi);
[PreserveSig] int SetFolder(IShellItem psi);
[PreserveSig] int GetFolder(out IShellItem ppsi);
[PreserveSig] int GetCurrentSelection(out IShellItem ppsi);
[PreserveSig] int SetFileName([MarshalAs(UnmanagedType.LPWStr)] string pszName);
[PreserveSig] int GetFileName([MarshalAs(UnmanagedType.LPWStr)] out string pszName);
[PreserveSig] int SetTitle([MarshalAs(UnmanagedType.LPWStr)] string pszTitle);
[PreserveSig] int SetOkButtonLabel([MarshalAs(UnmanagedType.LPWStr)] string pszText);
[PreserveSig] int SetFileNameLabel([MarshalAs(UnmanagedType.LPWStr)] string pszLabel);
[PreserveSig] int GetResult(out IShellItem ppsi);
[PreserveSig] int AddPlace(IShellItem psi, int alignment);
[PreserveSig] int SetDefaultExtension([MarshalAs(UnmanagedType.LPWStr)] string pszDefaultExtension);
[PreserveSig] int Close(int hr);
[PreserveSig] int SetClientGuid(); // not fully defined
[PreserveSig] int ClearClientData();
[PreserveSig] int SetFilter([MarshalAs(UnmanagedType.IUnknown)] object pFilter);
[PreserveSig] int GetResults([MarshalAs(UnmanagedType.IUnknown)] out object ppenum);
[PreserveSig] int GetSelectedItems([MarshalAs(UnmanagedType.IUnknown)] out object ppsai);
}
[ComImport, Guid("43826D1E-E718-42EE-BC55-A1E261C37BFE"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
private interface IShellItem
{
[PreserveSig] int BindToHandler(); // not fully defined
[PreserveSig] int GetParent(); // not fully defined
[PreserveSig] int GetDisplayName(SIGDN sigdnName, [MarshalAs(UnmanagedType.LPWStr)] out string ppszName);
[PreserveSig] int GetAttributes(); // not fully defined
[PreserveSig] int Compare(); // not fully defined
}
#pragma warning disable CA1712 // Do not prefix enum values with type name
private enum SIGDN : uint
{
SIGDN_DESKTOPABSOLUTEEDITING = 0x8004c000,
SIGDN_DESKTOPABSOLUTEPARSING = 0x80028000,
SIGDN_FILESYSPATH = 0x80058000,
SIGDN_NORMALDISPLAY = 0,
SIGDN_PARENTRELATIVE = 0x80080001,
SIGDN_PARENTRELATIVEEDITING = 0x80031001,
SIGDN_PARENTRELATIVEFORADDRESSBAR = 0x8007c001,
SIGDN_PARENTRELATIVEPARSING = 0x80018001,
SIGDN_URL = 0x80068000
}
[Flags]
private enum FOS
{
FOS_OVERWRITEPROMPT = 0x2,
FOS_STRICTFILETYPES = 0x4,
FOS_NOCHANGEDIR = 0x8,
FOS_PICKFOLDERS = 0x20,
FOS_FORCEFILESYSTEM = 0x40,
FOS_ALLNONSTORAGEITEMS = 0x80,
FOS_NOVALIDATE = 0x100,
FOS_ALLOWMULTISELECT = 0x200,
FOS_PATHMUSTEXIST = 0x800,
FOS_FILEMUSTEXIST = 0x1000,
FOS_CREATEPROMPT = 0x2000,
FOS_SHAREAWARE = 0x4000,
FOS_NOREADONLYRETURN = 0x8000,
FOS_NOTESTFILECREATE = 0x10000,
FOS_HIDEMRUPLACES = 0x20000,
FOS_HIDEPINNEDPLACES = 0x40000,
FOS_NODEREFERENCELINKS = 0x100000,
FOS_OKBUTTONNEEDSINTERACTION = 0x200000,
FOS_DONTADDTORECENT = 0x2000000,
FOS_FORCESHOWHIDDEN = 0x10000000,
FOS_DEFAULTNOMINIMODE = 0x20000000,
FOS_FORCEPREVIEWPANEON = 0x40000000,
FOS_SUPPORTSTREAMABLEITEMS = unchecked((int)0x80000000)
}
#pragma warning restore CA1712 // Do not prefix enum values with type name
}
result:
Strange that so much answers/votes, but no one add the following code as an answer:
using (var opnDlg = new OpenFileDialog()) //ANY dialog
{
//opnDlg.Filter = "Png Files (*.png)|*.png";
//opnDlg.Filter = "Excel Files (*.xls, *.xlsx)|*.xls;*.xlsx|CSV Files (*.csv)|*.csv"
if (opnDlg.ShowDialog() == DialogResult.OK)
{
//opnDlg.SelectedPath -- your result
}
}
Sounds to me like you're just after the FolderBrowserDialog.
Here is another solution, that has all the source available in a single, simple ZIP file.
It presents the OpenFileDialog with additional windows flags that makes it work like the Windows 7+ Folder Selection dialog.
Per the website, it is public domain: "There’s no license as such as you are free to take and do with the code what you will."
Article: .NET Win 7-style folder select dialog (http://www.lyquidity.com/devblog/?p=136)
Source code: http://s3downloads.lyquidity.com/FolderSelectDialog/FolderSelectDialog.zip
Archive.org links:
Article: https://web.archive.org/web/20180823181552/http://www.lyquidity.com/devblog/?p=136
Source code: https://web.archive.org/web/20180823181632/http://s3downloads.lyquidity.com/FolderSelectDialog/FolderSelectDialog.zip
Take a look at the Ookii Dialogs libraries which has an implementation of a folder browser dialog for Windows Forms and WPF respectively.
Ookii.Dialogs.WinForms
https://github.com/augustoproiete/ookii-dialogs-winforms
Ookii.Dialogs.Wpf
https://github.com/augustoproiete/ookii-dialogs-wpf
Im new to C# and came across this thread just now.
This might be of interest to those that are new to the language as well.
Change design of FolderBrowserDialog
The answer given by Simon Mourier would be the best answer considering the OP question. It does not involve NuGET package so there will not be any dependency issue in the future for selecting folder method.
If you encountered error related to "...is not available in C# 7.3", just add <LangVersion>8.0</LangVersion> to your .csproj (testing with Visual Studio does not produce any error when build and run)
If you can't change the project language then just replace owner
??= Application.Current.MainWindow
with
owner = owner ?? Application.Current.MainWindow
This is how I use the folder browser dialog in Small Visual Basic. This code solves the non-selected initial folder issue and also selects the folder from the clipboard or the registry (if any), and if the folder is deleted, it goes up through parents until selecting an existing folder. This makes using the dialog very comfortable.
Note that I am sending 4 tabs because I show the Create new folder button, but if you hide it, use two tabs only.
Public Shared Function OpenFolderDialog(initialFolder As String) As String
Dim folder = GetInitialFolder(initialFolder)
If folder = "" Then folder = GetInitialFolder(System.Windows.Clipboard.GetText())
If folder = "" Then folder = GetInitialFolder(GetSetting("sVB", "OpenFolder", "LastFolder", ""))
Dim th As New Threading.Thread(
Sub()
Threading.Thread.Sleep(300)
System.Windows.Forms.SendKeys.SendWait("{TAB}{TAB}{TAB}{TAB}{RIGHT}")
End Sub)
th.Start()
Try
Dim dlg As New System.Windows.Forms.FolderBrowserDialog With {
.Description = "Select a folder:",
.SelectedPath = folder
}
If dlg.ShowDialog() = System.Windows.Forms.DialogResult.OK Then
SaveSetting("sVB", "OpenFolder", "LastFolder", dlg.SelectedPath)
OpenFolderDialog = dlg.SelectedPath
End If
Catch ex As Exception
MsgBox(ex.Message)
End Try
End Function
Private Shared Function GetInitialFolder(folder As String) As String
Try
If folder <> "" Then
If IO.File.Exists(folder) Then
folder = Path.GetDirectoryName(folder)
Else
Do
If Directory.GetDirectoryRoot(folder) = folder OrElse Directory.Exists(folder) Then
Exit Do
End If
folder = Path.GetDirectoryName(folder)
Loop
End If
End If
Catch
folder = ""
End Try
Return folder
End Function
this should be the most obvious and straight forward way
using (var dialog = new System.Windows.Forms.FolderBrowserDialog())
{
System.Windows.Forms.DialogResult result = dialog.ShowDialog();
if(result == System.Windows.Forms.DialogResult.OK)
{
selectedFolder = dialog.SelectedPath;
}
}
I'm an expert programmer, so therefore, I don't have a clue as to WTH I'm doing :)
On a serious note; no, I'm not expert by any means. I do have a problem though, and don't know how to fix it. The good thing is, I (think I) know what the problem is, and I'm hoping someone here can help.
Here's the synopsis of the problem. I am creating a form in C# that will do some server and database administration task for me. I have a button that when clicked is supposed to return the service status of "x" service on "y" server. The status is printed on the screen to a textbox.
Here's my code:
private void button2_Click(object sender, EventArgs e)
{
string fs = "Service X Status = ";
string mr = "Service A Status = ";
string qp = "Service B Status = ";
string sp = "Spooler Service Status = ";
ServiceController fssc = new ServiceController("xService", "yServer");
ServiceController mrsc = new ServiceController("aService", "yServer");
ServiceController qpsc = new ServiceController("bService", "yServer");
ServiceController spsc = new ServiceController("Spooler", "yServer");
try
{
txtGtwySts.AppendText(sp + spsc.Status.ToString());
txtGtwySts.AppendText(Environment.NewLine);
txtGtwySts.AppendText(fs + fssc.Status.ToString());
txtGtwySts.AppendText(Environment.NewLine);
txtGtwySts.AppendText(mr + mrsc.Status.ToString());
txtGtwySts.AppendText(Environment.NewLine);
txtGtwySts.AppendText(qp + qpsc.Status.ToString());
}
catch (Exception crap)
{
string msg = "";
int i;
for (i = 0; i < crap.Message.Count(); i++)
{
msg += "Error # " + i + " Message: " + crap.Message + "\n";
}
MessageBox.Show(msg);
MessageBox.Show(i.ToString());
}
}
I get exceptions, basically saying: Cannot Open "Service" on "Server." Since this is a remote server, I'm assuming this is a credential/security problem. I do NOT, however, have any problems with the Spooler service.
My question is...How can I pass userID and password to this server so that it will authenticate or runas so I can check the status of these services, it that is the problem. If someone doesnt think its the problem, then please inform me where I've went wrong :)
Finally figured it out...
Created a new class, and is shown below:
using System;
using System.Collections.Generic;
using System.Text;
using System.Security.Principal;
using System.Runtime.InteropServices;
using System.Security.Permissions;
public class ImpersonateUser
{
[DllImport("advapi32.dll", SetLastError = true)]
public static extern bool LogonUser(
String lpszUsername,
String lpszDomain,
String lpszPassword,
int dwLogonType,
int dwLogonProvider,
ref IntPtr phToken);
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
public extern static bool CloseHandle(IntPtr handle);
private static IntPtr tokenHandle = new IntPtr(0);
private static WindowsImpersonationContext impersonatedUser;
// If you incorporate this code into a DLL, be sure to demand that it
// runs with FullTrust.
[PermissionSetAttribute(SecurityAction.Demand, Name = "FullTrust")]
public void Impersonate(string domainName, string userName, string password)
{
//try
{
// Use the unmanaged LogonUser function to get the user token for
// the specified user, domain, and password.
const int LOGON32_PROVIDER_DEFAULT = 0;
// Passing this parameter causes LogonUser to create a primary token.
const int LOGON32_LOGON_INTERACTIVE = 2;
tokenHandle = IntPtr.Zero;
// ---- Step - 1
// Call LogonUser to obtain a handle to an access token.
bool returnValue = LogonUser(
userName,
domainName,
password,
LOGON32_LOGON_INTERACTIVE,
LOGON32_PROVIDER_DEFAULT,
ref tokenHandle); // tokenHandle - new security token
if (false == returnValue)
{
int ret = Marshal.GetLastWin32Error();
throw new System.ComponentModel.Win32Exception(ret);
}
// ---- Step - 2
WindowsIdentity newId = new WindowsIdentity(tokenHandle);
// ---- Step - 3
{
impersonatedUser = newId.Impersonate();
}
}
}
// Stops impersonation
public void Undo()
{
impersonatedUser.Undo();
// Free the tokens.
if (tokenHandle != IntPtr.Zero)
{
CloseHandle(tokenHandle);
}
}
}
}
and the original code that I posted is wrapped by:
ImpersonateUser iu = new ImpersonateUser();
iu.Impersonate("[domain]","[username]","[password]");
// code you want to execute as impersonated user.....
iu.Undo();
How to enumerate available database Services(SQL Server or Oracle or MySQL or PostgreSQL, etc) in a network using C#?
I also need to find their port-numbers and service-instance names.
For example:
class Server
{
#region DLL Inports
[DllImport("odbc32.dll")]
private static extern short SQLAllocHandle(short hType, IntPtr inputHandle, out IntPtr outputHandle);
[DllImport("odbc32.dll")]
private static extern short SQLSetEnvAttr(IntPtr henv, int attribute, IntPtr valuePtr, int strLength);
[DllImport("odbc32.dll")]
private static extern short SQLFreeHandle(short hType, IntPtr handle);
[DllImport("odbc32.dll", CharSet = CharSet.Ansi)]
private static extern short SQLBrowseConnect(IntPtr hconn, StringBuilder inString,
short inStringLength, StringBuilder outString, short outStringLength,
out short outLengthNeeded);
#endregion
#region Constants
private const short SQL_HANDLE_ENV = 1;
private const short SQL_HANDLE_DBC = 2;
private const int SQL_ATTR_ODBC_VERSION = 200;
private const int SQL_OV_ODBC3 = 3;
private const short SQL_SUCCESS = 0;
private const short SQL_NEED_DATA = 99;
private const short DEFAULT_RESULT_SIZE = 1024;
private const string SQL_DRIVER_STR = "DRIVER=SQL SERVER";
#endregion
#region static string[] GetServers()
public static string[] GetNames()
{
string[] retval = null;
string txt = string.Empty;
IntPtr henv = IntPtr.Zero;
IntPtr hconn = IntPtr.Zero;
StringBuilder inString = new StringBuilder(SQL_DRIVER_STR);
StringBuilder outString = new StringBuilder(DEFAULT_RESULT_SIZE);
short inStringLength = (short)inString.Length;
short lenNeeded = 0;
try
{
if (SQL_SUCCESS == SQLAllocHandle(SQL_HANDLE_ENV, henv, out henv))
{
if (SQL_SUCCESS == SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, (IntPtr)SQL_OV_ODBC3, 0))
{
if (SQL_SUCCESS == SQLAllocHandle(SQL_HANDLE_DBC, henv, out hconn))
{
if (SQL_NEED_DATA == SQLBrowseConnect(hconn, inString, inStringLength, outString,
DEFAULT_RESULT_SIZE, out lenNeeded))
{
if (DEFAULT_RESULT_SIZE < lenNeeded)
{
outString.Capacity = lenNeeded;
if (SQL_NEED_DATA != SQLBrowseConnect(hconn, inString, inStringLength, outString,
lenNeeded, out lenNeeded))
{
throw new ApplicationException("Unabled to aquire SQL Servers from ODBC driver.");
}
}
txt = outString.ToString();
int start = txt.IndexOf("{") + 1;
int len = txt.IndexOf("}") - start;
if ((start > 0) && (len > 0))
{
txt = txt.Substring(start, len);
}
else
{
txt = string.Empty;
}
}
}
}
}
}
catch (Exception ex)
{
//Throw away any error if we are not in debug mode
//#if (DEBUG)
//MessageBox.Show(ex.Message,"Acquire SQL Servier List Error");
//#endif
txt = string.Empty;
throw ex;
}
finally
{
if (hconn != IntPtr.Zero)
{
SQLFreeHandle(SQL_HANDLE_DBC, hconn);
}
if (henv != IntPtr.Zero)
{
SQLFreeHandle(SQL_HANDLE_ENV, hconn);
}
}
if (txt.Length > 0)
{
retval = txt.Split(",".ToCharArray());
}
return retval;
}
#endregion
}
This code only works for SqlServers and up to WindowsXP.
It doesn't work for other DBMS Servers and on Win7.
I am in need of a canonical solution.
You could use the SqlDataSourceEnumerator class for this as well. Keep in mind, this is MS SQL Server specific...
var results = SqlDataSourceEnumerator.Instance.GetDataSources();
foreach (var row in results.Rows)
{
Console.WriteLine("{0}\{1}", row["ServerName"], row["InstanceName"]);
}
See this link for additional info
Does it work for any RDBMS Server?
Your answer is always going to be "no" here. Every RDBMS lets you set up a custom port - MySQL could be on 1433 or 1434 or 99999. Every RDBMS responds differently from other RDBMSes and even sometimes from previous versions of itself... You'd have to check every networking port possible on every computer for every RDBMS (and every version of that RDBMS if they change response strings often) and HOPE they have them configured with standard plaintext responses instead of being encrypted or whatnot. This is basic networking - first you portscan the IP range, then you can try to appscan on the active ports you've found to see how they respond to various requests, then you use that information to say "these IPs have apps that appear to be databases on the following ports" -- you're still not going to get things like MS Instance Name without going through the proper channels (as listed with code samples above).
Your best bet for understanding where to start is probably - http://www.nmap.org
To combine things said in the previous answers / comments:
Contact your sysadmin, becasue this is undoable. You would need to account for every version of every (R)DBMS out there (or at least the latest ones).
In addition to the other responses:
I have found Oracle.DataAccess.Client.OracleDataSourceEnumerator in the Oracle.DataAccess dll (Oracle.DataAccess.client)
By adding Oracle.managment.omo.dll and DataAccess.dll,you can manipulate Oracle objects like sql;management.SMO in MS SQLSERVER
Resources:
http://msdn.microsoft.com/en-us/library/ms162169.aspx
http://www.microsoft.com/downloads/details.aspx?FamilyId=C6C3E9EF-BA29-4A43-8D69-A2BED18FE73C&displaylang=en
You would want to look into SMO. This requires each client to have the Sql Management Objects and CLR types installed. Below is a code snippet from one of my working applications that does just this.
private void OnClicked_RefreshDataSources(object sender, EventArgs e) {
Cursor = Cursors.WaitCursor;
DataTable dt = SmoApplication.EnumAvailableSqlServers(false);
uxDataSource.Items.Clear();
foreach (DataRow row in dt.Rows) {
uxDataSource.Items.Add(row["Name"]);
}
if (dt.Rows.Count > 0) {
uxDataSource.SelectedIndex = 0;
}
Cursor = Cursors.Default;
}
private void OnSelectedIndexChanged_PopulateDatabases(object sender, EventArgs e) {
ConnectionString.DataSource = uxDataSource.SelectedItem.ToString();
Server server = new Server(uxDataSource.SelectedItem.ToString());
server.ConnectionContext.LoginSecure = false;
server.ConnectionContext.Login = Program.DesktopService.AccountName;
uxInitialCatalog.Items.Clear();
try {
foreach (Database db in server.Databases) {
uxInitialCatalog.Items.Add(db.Name);
}
if (server.Databases.Count > 0) {
uxInitialCatalog.SelectedIndex = 0;
}
}
catch {
MessageBox.Show("You do not have access to this server.", "Sql Connection", MessageBoxButtons.OK,
MessageBoxIcon.Warning);
uxInitialCatalog.Items.Clear();
}
}