C# windows service is still running but non-responsive - c#

I have c# window service created in server. Which has sqlite database. Client machine uses c# windows form application to connect to server and get data from server db.
So as first thing client application login to server using http request. And server receives the request and send back the data to client.
But sometimes even if the service is running the server is not responsive to the client and client is not able to connect to server. Later i restart the service and then it connects.
System.Data.DataSet rdr = db.ExecuteDataSet(#"
select i.id
from item i,field f
where i.typeid=1 and
f.value like '" + UserName + "' and i.id=f.itemid");
if (rdr.Tables[0].Rows.Count == 0)
{
rdr = null;
return false;
}
public DataSet ExecuteDataSet(String sqlExpr)
{
if (conn.State != ConnectionState.Open)
Open(DataFile);
SQLiteDataAdapter _adapter = new SQLiteDataAdapter(sqlExpr, conn);
DataSet ds = new DataSet();
_adapter.Fill(ds);
return ds;
}
Above is the code for login .Is there something blocking db. Please help me with your valuable answers.
Regards
Sangeetha

I dont have sure, but, if the loggin works well, the problem seems like have a error in the server, when you open the connection with de sqlite you close it after use?
the sqlite have some routine to kill connection in sleep?
Other thing, did you use the component.dispose()? because if you dont dispose the components, they keep use memory.

Related

Can't access my SQL Server without SQL Engine

I have two computers. One is running SQL Server, and I can access the server using SQL authentication from the 2nd PC using SSMS.
I have created a C# Windows Forms application that connects to the database. However, I couldn't access my server from the application.
I disabled the firewall, allowed remote control, and allowed mixed mode authentication. I also forwarded required ports to my IP in my router settings.
I tried both these connecting strings, but they didn't help:
"Persist Security Info = False; User ID = gues; Password=gues;Initial Catalog = CoronaNurse; Server=" + server;
"Data Source=" + server + ";Initial Catalog=CoronaNurse;Integrated Security=false;UID=gues;Password=gues";
(server is a string that have IP of my server)
(gues is a login in my Server)
The weird thing is when I login as gues in SSMS from my 2nd computer I can access the server in the first computer.
The question is, how do I access my server from a computer that doesn't have SSMS or any specific Login?
I need my application to be able to connect to my server without anything else installed, but I can't find where my problem is.
Adding from comments:
Im using the connecting to get a con string from my DB depends on the table i get with my gue.login function SqlDataAdapter
adapter = new SqlDataAdapter("select * from gue.login('" + textBox1.Text.Trim() + "', '" + textBox2.Text.Trim() + "', '" + server + "')", conn);
SqlCommandBuilder cb = new SqlCommandBuilder(adapter);
DataSet ds = new DataSet();
adapter.Fill(ds);
string connection;
connection = ds.Tables[0].Rows[0][0].ToString();
Unless you haven't posted up all of your code, you don't appear to be controlling your SQL connection and I would strongly suggest that you use a parameterised call to protect against SQL injection from using direct text entry field values e.g.:
var dataset = new DataSet();
using (var connection = new SqlConnection(SqlConnectionString))
{
connection.Open();
var command = new SqlCommand("GetAll", connection);
command.CommandType = CommandType.StoredProcedure;
var adapter = new SqlDataAdapter(command);
adapter.Fill(dataset);
...
}
The SQL is wrong, and the connection strings look a little off. You might also need an instance name as part of the server. For example, instead of just localhost or 192.168.0.20, you might need localhost\SQLExpress or 192.168.0.20\..
One way you can find the connection string for sure is to use Visual Studio instead of SSMS to connect to the database. The Visual Studio Database Tools has a similar connection window as SSMS, and you can use it to show you the actual connection string it used.
When you've figured that out, try something more like this:
var connString = $"Server={server};Database=CoronaNurse;User Id=gues;Password=gues";
var sql = "select * from gue.login WHERE username = #username AND pHash = #pHash";
var ds = new DataSet();
using (var conn = new SqlConnection(connString))
using (var cmd = new SqlCommand(sql, conn))
using (var adapter = new SqlDataAdapter(cmd))
{
cmd.Parameters.Add("#username", SqlDbType.NVarChar, 50).Value = textBox1.Text.Trim();
cmd.Parameters.Add("#pHash", SqlDbType.Char, 60).Value = BCrypt.Net.BCrypt.HashPassword(textBox2.Text.Trim());
adapter.Fill(ds);
var connection = ds.Tables[0].Rows[0].Items[0].ToString();
}
Note the use of both parameterized queries and BCrypt (you can add BCrypt via NuGet). There are a few things in database development that are too important to do wrong, even for proof-of-concept and learning projects. One of these is SQL Injection. Another is password handling. What I posted still isn't quite right for password handling (you should instead retrieve the stored hash and use the Verify() method), but it's close enough to set you on the right path.
Someone has told me that I can't access my online SQL Server DB from a client PC that doesn't have a Local DB.
I guess that explains my problem perfectly!
I never knew that, in my case, that is my problem right?

ERROR:There is already an open DataReader associated with this Command which must be closed first. Multiple Users

I have an asp.net C# application (.net 4.0) connected to SQL Server 2012 using ADO.Net and am encountering an error which says:
[InvalidOperationException: There is already an open DataReader associated with this Command which must be closed first.]
I very well know what a DataReader is but, my problem is getting this error in below conditions:
I have not at all used any DataReader in my application, I have only
used DataAdapters everywhere. The code works fine while running in
local environment and there is no errors.
Application works fine even after deployment in IIS7 when used by a
single user.
The error only occurs when multiple users starts using the website hosted in IIS7.
Kindly help, I am also doubting for any problems with my hosting in IIS7
After a lot of trial and error, finally I found out that it's a problem with SqlConnections. What I used to do was open a connection at the instantiation of my DAL layer object. So, whenever two methods from the same DAL object called together, it used to throw the error.
I solved it by opening and closing a connection in every call to the database. Now it all works fine. This also allows max number of users to use the application at a time. Below is my code sample from DAL:-
DataTable dt = new DataTable();
try
{
using (SqlConnection sqlcon = new SqlConnection(ConfigurationManager.ConnectionStrings["MyConnectionString"].ToString()))
{
if (sqlcon.State == ConnectionState.Closed)
sqlcon.Open();
SqlCommand sqlCommand = new SqlCommand
{
Connection = sqlcon,
CommandType = CommandType.StoredProcedure,
CommandText = "MyStoredProc"
};
sqlCommand.Parameters.AddWithValue("#Parameter1", Parameter1);
using (SqlDataAdapter adapter = new SqlDataAdapter(sqlCommand))
{
adapter.Fill(dt);
}
}
return dt;
}
catch (Exception exp)
{
LogHelper.LogError(string.Concat("Exception Details: ", ExceptionFormatter.WriteExceptionDetail(exp)));
throw exp;
}
finally
{
dt.Dispose();
}
Please post a better way of doing it if you know any, thank you.

Is there a way to send OdbcCommand.ExecuteReader-NonQuery commands to execute on an API?

I'm talking about a WinForm application that establishes a connection to a database via Odbc. But sometimes my VPN turns off but I have a server that is on the same network as the database.
Is there a way to override ExecuteReader function so that every OdbcCommand that wants to query is sent to a WebAPI and return the same object to the reader?
For example:
var cmd = new OdbcCommand("SELECT number, text FROM testing", Con);
var reader = cmd.ExecuteReader();
Then the reader obtains its value calling to https://example.com/api/tests/ and the code keeps working without VPN.
Please forget about security.

Gridview Population

I have been looking at this code all weekend. I know there is data and I can pull it through other queries but the GridView will not show and populate. Suggestions?
string sqlSelection =
"SELECT * FROM [COMPANY].[dbo].[parking] ";
SqlConnection cn = new SqlConnection(ConfigurationManager.ConnectionStrings["DATACONNECTION"].ToString());
//This connection works in MSSMS and in other pages I have on the same server
SqlDataAdapter sda = new SqlDataAdapter(sqlSelection, cn);
SqlCommandBuilder scb = new SqlCommandBuilder(sda);
DataTable dTable = new DataTable();
sda.Fill(dTable);
//debug shows: dTable <not set>
GrdDynamic.Visible = true;
GrdDynamic.DataSource = dTable;
GrdDynamic.DataBind();
I have had this behavior when the account in the connection string doesn't have rights to the database because the account the web service doesn't have access to the account. If you are using a machine account (not a sql login) try to create a sql login (if possible) and assign it to the db. Or you can temporarily using the anonymous account to use the login you are using for the management studio (more than likely yourself). I have also had this happen when the web server could not see the SQL server due to routing issues. You can test the last one by going to the server and trying to ping the sql server. The worst one situation is when a firewall has stopped the port from connecting. I am not sure of a sure fire test for this situation because it depends a lot of how your network is configured.

Changing SQL Server settings programmatically

I request you to read my question carefully.
You might know when you install VS2005/2008 with SQL Server Express edition, the SQL Server operates in Windows authentication mode by default. You can use the SQL Server Management Studio to change the mode to Mixed mode (Windows and SQL Server Authentication mode).
Similarly to allow the SQL Server remote connection through TCP/IP, you need to use SQL Server Configuration Manager then select Protocol for SQLEXPRESS and then change the setting for Tcp/IP option.
What i need is to automate this process programmatically using C#. That is, i need to write a c# program to change the mode or change the tcp/ip settings etc.
Can anyone provide me help on this, how could i do that?
Thank you for sharing your valuable time.
You should use SQL Server Management Objects (SMO) - this is an API for managing SQL Server programmatically.
UPDATE:
Proves to be a bit tricky: Server.LoginMode (read/write), Server.TcpEnabled and Server.NamedPipesEnabled (get only, unfortunately). In order to modify protocols, you need to examine Microsoft.SqlServer.Management.Smo.Wmi namespace (hence going from 'the other end'):
ServerProtocol - represents server protocol
ServerProtocolCollection - a collection of all protocols defined on a given server
This function in C# will enable TCP/IP Protocol and set the Login mode to Mixed mode.
See complementary information here.
here is the code:
private static bool SetServerProperties()
{
#region standardize Connection String
string tempCatalog = "master";
string temp = #"Data Source=" + dataSource + ";Initial Catalog=" + tempCatalog + ";Integrated Security=True;MultipleActiveResultSets=True";
#endregion
SqlConnection sqlconnection = new SqlConnection(temp);
SqlCommand cmd = new SqlCommand("select ##ServerName", sqlconnection);
sqlconnection.Open();
string serverName = "";
try
{
SqlDataReader dr = cmd.ExecuteReader();
while (dr.Read())
serverName = dr[0].ToString();
}
catch
{
MessageBox.Show("Failed to Set SQL Server Properties for remote connections.");
}
Server srv = new Server(serverName);
srv.ConnectionContext.Connect();
srv.Settings.LoginMode = ServerLoginMode.Mixed;
ManagedComputer mc = new ManagedComputer();
try
{
Service Mysvc = mc.Services["MSSQL$" + serverName.Split('\\')[1]];
if (Mysvc.ServiceState == ServiceState.Running)
{
Mysvc.Stop();
Mysvc.Alter();
while (!(string.Format("{0}", Mysvc.ServiceState) == "Stopped"))
{
Mysvc.Refresh();
}
}
ServerProtocol srvprcl = mc.ServerInstances[0].ServerProtocols[2];
srvprcl.IsEnabled = true;
srvprcl.Alter();
Mysvc.Start();
Mysvc.Alter();
while (!(string.Format("{0}", Mysvc.ServiceState) == "Running"))
{
Mysvc.Refresh();
}
return true;
}
catch
{
MessageBox.Show("TCP/IP connectin could not be enabled.");
return false;
}
}
What about modifying the registry?
Client Protocol Settings are stored here:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSSQLServer\Client\SNI9.0
Check out ProtocolOrder.
Authentication Mode is stored here:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server\MSSQL.1\MSSQLServer\LoginMode
See:
Authentication Settings
I was able to do this with a small footprint by executing this stored procedure from C#:
USE [master]
EXEC xp_instance_regwrite N'HKEY_LOCAL_MACHINE', N'Software\Microsoft\MSSQLServer\MSSQLServer', N'LoginMode', REG_DWORD, 2
GO
It doesn't look like much but works flawlessly and instantly, without restarting services.
I think you could solve your problem making a silent installation of SQL Server Express edition using a configuration file for the install process.
In this link you can find the command line parameters for the installation.
In this one you can find how to make your configuration file.

Categories