我正在尝试创建一个Windows应用程序观察器?

时间:2014-06-13 12:29:25

标签: c# sql winforms

我最近开始使用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();
            }

        }
    }

不幸的是这就是结果。 enter image description here 它没有像我期望的那样保存数据。我做错了什么我曾经想过,使用sql阅读器时,它首先会检查一个值,只有在它们不匹配时才会保存,但它会保存是否存在匹配。

我的读者正在返回" {System.Data.SqlClient.SqlDataReader}"而不是表格中的数据

2 个答案:

答案 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())