Open new database connection and query window in SSMS through C# application? - c#

I have a C# application that, when a user clicks a button, will open SQL Server Management Studio query editor with a specified server and database connection. What I would like to do is be able to have this same functionality, but with an already running instance of SSMS (not start a new process).
My code so far:
if (IsProcessOpen("Ssms") == false)
{
Process ssms = new Process();
ssms.StartInfo.FileName = "C:\\Program Files (x86)\\Microsoft SQL Server\\110\\Tools\\Binn\\ManagementStudio\\Ssms.exe";
ssms.StartInfo.Arguments = "-S " + StaticVariables.Getserver + " -d " + StaticVariables.Getdatabase;
ssms.Start();
}
else
{
//In already running SSMS process, open connection to server and database with new query window.
}

As far my research goes, there is no API available to interact with an existing SSMS processs. (http://stackoverflow.com/questions/2334435/how-do-i-programmatically-open-a-new-tab-in-an-open-instance-of-sql-management-s)
You could try doing a hack involving SendKeys, but this would have a downside of not knowing the current state of the SSMS window (if it has any active windows open or anything)
If you could share the original requirement, we may look at some better alternatives.

This problem was driving me crazy, and I finally found that when I changed from logging in as "sa" to using Windows Authentication, the problem was resolved.

Related

C# connect WinForm App running locally via Remote Desktop (or other) to a Database

EDIT
RDP is just the current way I do this, if there is another way to connect to a database in a different environment I will do that. Ideally I want this to connect to the database as it would if the executable was in the RDP environment and show no indication of connecting to the DB via the other environment.
EDIT 2
I have also tried adding a second connection string and opening it then having my current connection string immediately after, that didn't work.
I have a C# Win Forms application which connects to a database, this works fine except I need to RDP into the correct environment and have the executable ran from there to do so.
Is it possible to do the RDP connection inside of the application then connect to the database without having to have the executable inside the RDP.
I have tried to build up a connection string using the MSTSCLib library which I found here however this isn't working at code level anyway.
Code:
private void rdpConnect_Click(object sender, EventArgs e)
{
MSTerminalServiceControl1.Server = rdpServer.Text;
MSTerminalServiceControl1.UserName = rdpUserName.Text;
IMsTscNonScriptable secured = (IMsTscNonScriptable)MSTerminalServiceControl1.GetOcx();
secured.ClearTextPassword = rdpPassword.Text;
MSTerminalServiceControl1.Connect();
}
private void rdpDisconnect_Click(object sender, EventArgs e)
{
MSTerminalServiceControl1.Disconnect();
}
Current Path:
Desired Path:
I'm sure, that can not work, because...
RDP (Remote Desktop Protocol) is a Protocol to connect you from a remote machine to a session on a Terminal Server. That's the purpose. In that session, you can start programs, open documents and do your work. Like you were sitting in front of that machine. The benefit is, this can be done by multiple users, depending only on the number of user licenses and hardware power.
There a some special cases, e.g. you can start a program automatically on start up. Then your session is limited to this program and will end, when the program ends. But this is only a restricting. You will still start a session for that.
Also, there is a small version of Terminal Server build in every windows version, not only servers. This can be used a for a remote connection in the same way.
So, sad that, RDP can not connect to a database. In no way. You need a program for that. You can build a local program with a RDP-Client inside. That can connect to a session on a remote machine and start another program, that connects to the database. But you will have no communication between the to programs by default, so there is no benefit.
I think, like others said, the best is to connect to the database directly.
Looks like you do not have references to the ActiveX Control.
In your Toolbox Choose the COM Component : Microsoft RDP Control - version x
The version here is important it should match the installed RDP version, once you have added this in your tool box drop it on your form, if there is version mismatch it would throw error. I would say start from the latest version of control and go down till you are able to successfully add it to your form. The MSTerminalServiceControl1 in your code is actually the name of this control that you should thus put on your form.
What you need is to Connect multiple sql users to one database and no to use RDP.
you should write a special connection string, for each user something like below:
using System.Data.SqlClient;
SqlConnection conn = new SqlConnection();
conn.ConnectionString =
"Data Source=ServerName;" +
"Initial Catalog=DataBaseName;" +
"User id=" + UserName + ";"
"Password=" + Password + ";";
conn.Open();
Put this in a class that accepts the username and password.
Full example:
class myConnection
{
public static SqlConnection GetConnection(string UserName, string Password)
{
string str = "Data Source=ServerName;Initial Catalog=DataBaseName;User id=" +
UserName + ";Password=" + Password + ";";
SQlConnection con = new SqlConnection(str);
con.Open();
return con;
}
}
Then connect each user to DB directly.
Provided you have app.config file for the executable, update the connection string parameter to point to the ip of rdp server.
Before you do this enable database port on firewall and also enable remote connections to database.
For mssql server.
Run sql server configuration manager.
Select database instance.
Enable tcp/ip under network configuration.
Under io addresses tab.
Set tcp port to 1443.
Restart instance.
Data Source=IP,1443\dbservername;
I hop this can be a starting point.
I've seen a Network Administrator configured our normal winform application to be opened remotely over the Internet using Citrix.
We made no changes to the exectuable file.
It will launch the application in the Citrix Virtual Server.
The problem is that it's a paid software.

SQL Server User Instances error: Existing databases has reached the max number allowed

I'm using C# in Visual Studio 2008 to loop through MDF Files on my PC and extract data from within them. I'm using a Table Adapter to point to the local MDF file.
Recently one of my PC's refuses to let me attach any new Data Source as it says
System.Data.SqlClient.SqlException: Unable to create/attach any new database because the number of existing databases has reached the
maximum number allowed: 32766
Even if I start a fresh Windows application and try to add an MDF file (on my desktop) to it as a Data Source, I get the above error.
Can anyone tell me how to remove/delete the existing connections ?
My code works fine on another PC and I've re-installed Visual Studio on my PC but still get this error.
C# Table adapter code:
tmTableAdapter.Connection.ConnectionString = "Data Source=.\\SQLEXPRESS;AttachDbFilename='" + pathofmdffile + "';Integrated Security=True;Connect Timeout=30;User Instance=True";
tmTableAdapter.Connection.Open();
Reinstalling VS won't help as the error is coming from SQL Server.
Look at these MSDN pages which have lots of good info:
SQL Server Express User Instances
SQL Server 2005 Express Edition User Instances
User Instances for Non-Administrators
Since you are using "User Instances", I guess the DBs won't show up when connecting to the main SQLEXPRESS instance.
Things to check:
In SSMS, connect to your last attached DB by doing the following:
Go to Object Explorer
New Connection to a Database Engine
In the "Connect to Server" popup:
Click the "Options >>" button
Go to the "Additional Connection Properties" tab
Enter in the following in the text area:
User Instance = true
Click the "Connect" button
Expand "Databases" folder. You should see them all, named as the full path to the MDF file
Right-click on a database
Go to "Tasks >"
First option is "Detach"
Obviously this isn't practical for 32,766 databases, but for a few it is the best option.
By default the sqlservr.exe process hangs around for 60 minutes, and any databases you attach prior to it terminating gets added to the list and likely reset the expiration counter. You can end the process immediately by connecting to the most recent attached DB (as noted above; those steps will work for a New Query, or if connecting via Object Explorer, then right-click on the instance name and go to "New Query"), and run the following:
SHUTDOWN;
This will clear out all connected databases in one shot.
Set the timeout to be less than 60 minutes. According to the SQL Server Express User Instances page (same link as above):
A system administrator on the parent instance can set the duration of the time-out period for a user instance by using sp_configure to change the user instance timeout option. The default is 60 minutes.
In SSMS (make sure you are connected to the parent instance):
-- View current setting (in the "run_value" field)
EXEC sp_configure 'user instance timeout'
-- Documentation says default is 60 but mine was 5
-- If you can't see the option, run the following:
EXEC sp_configure 'show advanced options', 1;
RECONFIGURE;
-- To change it, run the following:
EXEC sp_configure 'user instance timeout', 5;
Use the "SQL Server Express Utility" to detach one or more databases:
SSEUtil.exe was written in 2005 and has not been updated since (current version is v1.0.2130)
Download from: https://www.microsoft.com/en-us/download/confirmation.aspx?id=3990
Use the -d[etach] <dbpath[*]>|name=<dbname> command
Look in the following directory which will have the 4 system DBs:
On XP / Vista: C:\Documents and Settings{UserName}\Local Settings\Application Data\Microsoft\Microsoft SQL Server Data\SQLEXPRESS
On Windows 7 and newer: C:\Users{UserName}\AppData\Local\Microsoft\Microsoft SQL Server Data\SQLEXPRESS
This is mostly just informational as these files cannot be deleted so long as the SQL Server process is running.
For an on-going basis, if you will be attaching many DBs in a loop, you can programatically get rid of them in that process by running sp_detach_db when you are done using each DB:
USE [master];
ALTER DATABASE [{DatabaseName}] SET SINGLE_USER WITH ROLLBACK IMMEDIATE;
EXEC sp_detach_db #dbname =N'{DatabaseName}';
And just FYI, "User Instances" are now deprecated. You should look into using SQL Server Express LocalDB.

Error attaching a database (.mdf file) to SQL Server

I'm having trouble attaching a database DBName.mdf to a network SQL Server. The admin can manually attach the database but if I try, I get the following error message.
Database 'DBName' cannot be upgraded because it is read-only, has read-only files or the user does not have permissions to modify some of the files. Make the database or files writeable, and rerun recovery. (Microsoft SQL Server, Error: 3415)
Here is my code:
System.Data.SqlClient.SqlConnection conn = new System.Data.SqlClient.SqlConnection();
conn.ConnectionString = #"Server=" + SQLServerName + ";database=master;User ID=" + UserName + ";Pwd=" + Password; ;
try
{
conn.Open();
System.Data.SqlClient.SqlCommand com = new System.Data.SqlClient.SqlCommand("CREATE DATABASE DBName ON ( FILENAME = '" + #"C:\DBName.mdf" + "' ), ( FILENAME = '" + #"C:\DBName_log.ldf" + "' ) FOR ATTACH", conn);
com.ExecuteScalar();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
finally
{
conn.Close();
}
Here is the details of SQL Server
- Product - Microsoft SQL Server Express Edition (64-bit)
- Version - 11.0.2218.0
I can create a new database just fine but cannot attach an existing database. What am I missing here?
Any help will be appreciated.
I figured out what the problem was.
This link was helpful in figuring out the problem.
http://www.sqlservercentral.com/Forums/FindPost1367859.aspx
The user under which the SQL Service was running didn't have full access permissions to that folder. I gave the user full permission and everything worked fine.
I had the same error trying to attach via SQL server management studio.
Running SQL server Management studio as Administrator solved this problem for me.
Info gleaned from here http://www.nickyvv.com/2013/02/database-databasename-cannot-be.html.
I also faced the similar problems and I resolved it using both approaches listed above by Butters and pblack. To sum up they are:
Go to the system services and find SQL Server Database service.
Right click on the service and select properties
Go to the Log On tab
If the "Log On As" user from your service is a user account, make sure that user account has Full Control on that folder.
If the "Log On As" user from your service is "Network Service" or "Local System" those account should already have access, but go ahead and add them and give them Full Control.
Lastly, RUN SQL Server management studio using Administrative privileges
I also faced similar situation while using T-SQL Script but i choose another way through SSMS. Here are some easy steps that are very helpful to you to attach SQL MDF file through SQL Server Management Studio.
Go through Start Button->All Programs->SQL Server XXXX->SQL Server Management Studio
Login in it
Select Object Explorer enlisted databases
Then Right click on it and Select Attach database
Database Attachment Windows appears on the Screen then click on ADD button
Then you need to select MDF file which you want to attach and click OK
Confirm it and Click OK
Database is successfully attached. You can checkout in the Databases list.

Windows Server 2008 R2 remote service installation: How to execute program after RDP Connection in C#?

I want to remotely start a program on a Win2k8R2 Server, Web Edition, which installs Windows services.
Service installation is afaik only possible if there's a "screen>0" - that means a user must be logged in to do that (I read somewhere that the login dialog window is representing "screen 0", correct me if I'm wrong here).
So to get a screen, I open up a RDP connection and then trigger the setup exe which installs everything silently.
I made it run on Windows Server 2003 already. On 2008 R2 though it doesn't work anymore.
I assume there may be some security policy or even completely other technique to achieve what I want.
Here's the code:
this.axMsRdpClient7 = new AxMSTSCLib.AxMsRdpClient7();
// ... some GUI stuff happens here..
axMsRdpClient7.Server = hostname;
axMsRdpClient7.UserName = username;
axMsRdpClient7.AdvancedSettings.Compress = -1;
axMsRdpClient7.AdvancedSettings2.DisplayConnectionBar = true;
axMsRdpClient7.AdvancedSettings7.ClearTextPassword = userpassword;
axMsRdpClient7.AdvancedSettings2.EncryptionEnabled = -1;
// Set start program information. vvv THIS IS NOT GOING TO BE EXECUTED vvv
axMsRdpClient7.SecuredSettings.StartProgram = executablePath + " " + arguments;
axMsRdpClient7.SecuredSettings.WorkDir = workingDirectory;
// ... here I'm attaching some events like OnDisconnect...
// Start connection
axMsRdpClient7.Connect();
// Now the startprogram should be executed, but doesn't.
// (at this time its ok that I have to manually log off to reach disconnect. Except you have a better idea to disconnect after startprogram finishes)
while (axMsRdpClient7.Connected != 0)
{
Application.DoEvents();
Thread.Sleep(1);
}
// End connection
axMsRdpClient7.Disconnect();
Anyone knows why StartProgram is not being executed? I don't have any error, it just doesn't start.
Or anyone knows a better method to remotely install services?
Thanks in advance!
You should not need to call Disconnect(). When using the StartProgram approach you are using what used to be called the 'Alternate Shell' approach. This means that when the program terminates, the session is automatically closed/disconnected.
See http://msdn.microsoft.com/en-us/library/ms861803.aspx, search for 'AlternateShell'.
I recently wrote an ActiveX library that initiates an Windows 2008 RDS session using the StartProgram parameter. Once the user closes the program that is started automatically when the RDS session starts, the RDS session automatically terminates. So you shouldn't need the looping mechanism nor the call to Disconnect() with your approach.
In my code, for user credentials, I specify the domain as well. Is your user account a Windows Domain account? If so you probably need to specify that as well.
Additionally, I set the following parameters:
// server authentication is required - set Auth level to 2
AdvancedSettings7.AuthenticationLevel := 2;
// use CredSsp if the client supports it.
AdvancedSettings7.EnableCredSspSupport := True;
// setting PublicMode to false allows the saving of credentials, which prevents
// prompting the user to log in
AdvancedSettings7.PublicMode := False;
HTH

c# express back up/restore database

I am completely lost here and I am running out of time. Let me explain my situation:
I have created a software in C# express 2010 and SQL Server Express 2008 R2.
Now in the settings section of my software, the user is supposed to be able to make manual back ups/restores of the database.
Also he is supposed to be able to schedule back ups of the database, which will run at time that he will set.
I do not have a clue on how to get both of these working and I am hoping that someone here may point me in the correct direction.
I need to be able to create a
backup/restore of the database from
the click of a button
I need to be able to schedule backup
processes
Please keep in mind that when the user will install the software on his computer, he will not have sql server installed (I am saying this because I am under the impression that SMO requires sql server to be pre installed on the client machine).
Thank you
You could always try Google.
Backup
Restore
Automate backup scripts using the SQL Job Agent
I'm assuming you can create Windows Forms and wire up OnClick events, and run SqlCommand's against the database. Then it's just a matter of using the documentation above to write the appropriate queries when the user presses the appropriate button.
BTW: This is a Q&A site, not an emergency consultant shop. Don't say things like "I'm running out of time" and don't write up large lists of requirements and say tell me how to do this. You'll get absolutely no help that way. Ask specific questions after demonstrating your effort and specific technical problem.
You could look at this C# example for using SMO to backup the database
http://social.msdn.microsoft.com/forums/en-US/sqlexpress/thread/95750bdf-fcb1-45bf-9247-d7c0e1b9c8d2/
The other option is to run a process and call sqlcmd from code
http://www.sqldbatips.com/showarticle.asp?ID=27
Here is some sample code to execute process
string fileName = #"C:\Backup.sql";
ProcessStartInfo info = new ProcessStartInfo("sqlcmd", #" -S .\SQLExpress -U sa -d mydatabasename -o C:\sqlout.txt -i """ + #fileName + #""" -P");
info.UseShellExecute = false;
info.CreateNoWindow = true;
info.WindowStyle = ProcessWindowStyle.Hidden;
info.RedirectStandardOutput = true;
Process p = new Process();
p.StartInfo = info;
p.Start();

Categories

Resources