我最近开始使用c#进行编码(今年5月份),并且我发现最好通过使用代码来学习。这个应用程序http://www.c-sharpcorner.com/UploadFile/satisharveti/ActiveApplicationWatcher01252007024921AM/ActiveApplicationWatcher.aspx。 我正在尝试重新创建它,但是我将把信息保存到一个sql数据库中(这也是新的)。我有一些编码问题,因为它没有做我期望它做的事情。这是我正在使用的主要代码。
private void GetTotalTimer()
{
//This gets the window that a user has open
SqlConnection RConn = new SqlConnection(@"server=ANDILE-PC;Initial Catalog=Log Records;Integrated Security=SSPI;");
string Connstring = RConn.ToString();
DateTime now = DateTime.Now;
IntPtr hwnd = APIFunc.getforegroundWindow();
Int32 pid = APIFunc.GetWindowProcessID(hwnd);
Process p = Process.GetProcessById(pid);
appName = p.ProcessName;
string time = now.ToString();
const int nChars = 256;
int handle = 0;
StringBuilder Buff = new StringBuilder(nChars);
handle = GetForegroundWindow();
appltitle = APIFunc.ActiveApplTitle().Trim().Replace("\0", "");
string queryString = "Select Top 1[Window Title] FROM [TimerLogs]";
using (RConn)
{
using (SqlCommand command = RConn.CreateCommand())
{
command.CommandText = queryString;
RConn.Open();
using (SqlDataReader reader = command.ExecuteReader())
{
while (reader.Read())
{
string windowtitle = reader["Window Title"].ToString();
if (appltitle != windowtitle)
{
endTime = DateTime.Now;
appduration = endTime.Subtract(startTime);
cmd = new SqlCommand("insert into [TimerLogs] values (@time,@appName,@appltitle,@Elapsed_Time,@userName)", RConn);
cmd.Parameters.AddWithValue("@time", time);
cmd.Parameters.AddWithValue("@appName", appName);
cmd.Parameters.AddWithValue("@appltitle", appltitle);
cmd.Parameters.AddWithValue("@Elapsed_Time", appduration.ToString());
cmd.Parameters.AddWithValue("@userName", userName);
cmd.ExecuteNonQuery();
RConn.Close();
}
}
reader.Close();
}
RConn.Close();
}
}
}
不幸的是这就是结果。 它没有像我期望的那样保存数据。我做错了什么我曾经想过,使用sql阅读器时,它首先会检查一个值,只有在它们不匹配时才会保存,但它会保存是否存在匹配。
我的读者正在返回" {System.Data.SqlClient.SqlDataReader}"而不是表格中的数据
答案 0 :(得分:4)
好的,我们在这里遇到了三个问题。让我们首先关注你的bug:
您使用的是reader.ToString()
,但该方法并非您认为的那样。
在这里查找 - > http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqldatareader.aspx(您可以将光标放在类型名称中,然后按'F1'来访问该页面和类似页面。)
因此,您需要使用reader.GetString(0)
以类型安全的方式访问要比较的字段,而不是“ToString()”。
第二个问题:在else if
块内,您将关闭SqlDataReader两次。这会引发异常。
现在,关于第三个问题:
每个SQL请求始终使用一个连接对象。 SQL连接在.NET中缓存,因此您不必担心时间损失,并且通过这样做您也不必经常检查连接的状态。
为了让事情变得简单,让我向您展示使用陈述的神奇之处:
using (SqlConnection myConn = new SqlConnection(connstring))
{
myConn.Open();
// execute first statement
}
using (SqlConnection myConn2 = new SqlConnection(connstring))
{
myConn2.Open();
// execute second statement
}
using语句的一部分是您要使用的对象的声明。该对象必须是“IDisposable”类型。在using语句中,对象被视为“普通”对象,至少在大多数情况下。你无法改变它的引用(意味着你不能将新的SqlConnection分配给myConn2),但这就是它。
当你离开使用声明时,事情变得更有趣。无论你如何离开它(内部返回语句,发生未处理的异常,或者程序只是在using语句中执行了所有内容后继续),对象将被处理掉。对于SqlConnection或SqlDataReader,它的Close()
方法也将作为Dispose()实现的一部分进行调用。
答案 1 :(得分:0)
问题:您正在将appltitle
(我认为字符串变量)与SqlDataReader对象进行比较。这将总是让你不平等,而且当你反转你的结果时,它总是如此,因此无论情况如何,它都将数据存储到数据中。
解决方案:您需要使用SELECT语句中的正确列检查appltitle
变量。
reader[0]
为您提供数据库中的window title
(在SELECT语句中指定)
替换它:
if (appltitle != reader.ToString())
有了这个:
if (appltitle != reader[0].ToString())