예제 #1
0
 public int InsertUpdateProjNameMatches(IDEMatch item)
 {
     using (SqlCommand cmd = new SqlCommand("DevTrkr..InsertUpdateProjNameMatches"))
     {
         cmd.Parameters.AddWithValue("@ID", item.ID);
         cmd.Parameters.AddWithValue("@Regex", item.Regex);
         cmd.Parameters.AddWithValue("@RegexGroupName", item.RegexGroupName);
         cmd.Parameters.AddWithValue("@UnknownValue", item.UnknownValue);
         cmd.Parameters.AddWithValue("@AppName", item.AppName);
         cmd.Parameters.AddWithValue("@ProjNameReplaces", item.ProjNameReplaces);
         cmd.Parameters.AddWithValue("@ProjNameConcat", item.ProjNameConcat);
         cmd.Parameters.AddWithValue("@ConcatChar", item.ConcatChar);
         cmd.Parameters.AddWithValue("@IsIde", item.IsIde);
         cmd.Parameters.AddWithValue("@Description", item.Description);
         cmd.Parameters.AddWithValue("@AlternateProjName", item.AlternateProjName);
         cmd.Parameters.AddWithValue("@Sequence", item.Sequence);
         cmd.Parameters.AddWithValue("@IsDBEngine", item.IsDBEngine);
         return(UpdateDatabase(cmd));
     }
 }
        /// <summary>
        /// If log is null do not create a listvieew item, just log to database
        /// </summary>
        /// <param name="p"></param>
        /// <param name="log"></param>
        public WindowEvents(Process p, ListView log)
        {
            try
            {
                var now = DateTime.Now; // time window changed
                Log = log;
                var title = GetActiveWindowTitle();
#if DEBUG
                Debug.WriteLine("**** " + title);
#endif
                if (title == null)
                {
                    return;
                }

                var accessDenied = false;
                var moduleName   = string.Empty;
                try
                {
                    moduleName = p.MainModule.ModuleName;
                }
                catch (Win32Exception ex)
                {
                    // process access denied b/c it is running as admin
                    moduleName   = "Process-Access Denied";
                    accessDenied = true;
                }
                string displayName;
                try
                {
                    displayName = UserPrincipal.Current.DisplayName;
                }
                catch (Exception ex)
                {
                    displayName = Environment.UserName;
                }

                if (Globals.LastWindowEvent == null)
                {
                    Globals.StartTime = now;
                }

                TimeSpan elapsedTime = now - Globals.StartTime;
                Globals.StartTime = now;  // current window change time

                var devPrjName = string.Empty;

                // We set some globals so the file watcher knows who is running
                try
                {
                    _currentApp = Globals.CurrentApp = !accessDenied ? p.ProcessName : AccessDenied;
                }
                catch (Exception ex)
                {
                    Debug.WriteLine(ex.Message);
                    Globals.CurrentApp = "Unknown";
                }

                bool writeDB = false;

                /* make project extraction generic with regex */
                // new code ***** NOTE: THE ideMATCHES TABLE SHOULD ONLY HAVE IDES AND SSMS ****
                // **** WE ARE DOING THIS FOR SSMS THO NOT AN IDE B/C SO MUCH TIME IS SPENT THERE
                // **** AND EVEN GROUPING BY A SERVER.DBNAME MAY GIVE A CLUE TO THE DEV PROJECT
                IDEMatch ideMatchObject = null;

                //new evidence for mulltiple IDEMatch objects for the same IDE i.e., devenv
                // title = "Add New Item - BusinessObjects"
                // title = "Add Existing Item - BusinessObjects"
                // title = "Reference Manager - DevTrkrReports"

                // ssms failing to update project name here and the reason is that ide.DBUnknown is
                //  likely not set b/c ide switches when window changes, .^. some switch must reside in globals
                // that will persist between window changes.. and cache updates
                // i think that is what the index in the match table was
                // about and then I forgot its purpose and removed it

                //NOTE: simplifying problem by updating below for whichever app when we find a new match
                //bool foundIDE = false;
                foreach (var ide in Globals.IDEMatches)
                {
                    if (!accessDenied && _currentApp.ToLower() == ide.AppName)
                    {
                        var pat = ide.Regex;
                        var m   = Regex.Match(title, pat, RegexOptions.IgnoreCase);
                        devPrjName = string.Empty;
                        if (m.Success && m.Groups[ide.RegexGroupName] != null &&
                            !string.IsNullOrWhiteSpace(m.Groups[ide.RegexGroupName].Value))
                        {
#if DEBUG
                            if (ide.AppName == "ssms")
                            {
                                Debug.WriteLine(title);
                            }
#endif
                            // we found the ide match we are looking for
                            ideMatchObject = ide;

                            // if we are concatinating two fields in ssms to get server.dbname
                            if (!string.IsNullOrWhiteSpace(ide.ProjNameConcat))
                            {
                                string[] concats = ide.ProjNameConcat.Split('|');
                                for (var i = 0; i < concats.Length; i++)
                                {
                                    devPrjName += (i > 0 ? ide.ConcatChar : string.Empty) + m.Groups[concats[i]].Value;
                                }
                            }
                            else
                            {
                                devPrjName = m.Groups[ide.RegexGroupName].Value;
                            }


                            if (!string.IsNullOrWhiteSpace(ide.ProjNameReplaces))
                            {
                                string[] replaces = ide.ProjNameReplaces.Split('|');
                                foreach (string s in replaces)
                                {
                                    devPrjName = devPrjName.Replace(s, string.Empty).Trim();
                                }
                            }

                            // NOTE: new logic for IDEMatch objects that have AlternateProjName
                            // if it is not null, replace devPrjName with it b/c altho we found a project name
                            // it is not one we want, so make it what we want (probably the same as the unknown value)
                            // so that it will be updated when we find the projname we want...
                            // e.g., ssms has master set so DBname = Server.master in table but new logic will be correctable
                            // e.g. ssms "not connected" can now have its own match object and will get set to unknow until
                            //       user connects to a database which they will have to do in order to do anything in ssms
                            if (ideMatchObject.AlternateProjName != null)
                            {
                                devPrjName = ideMatchObject.AlternateProjName;
                            }

                            // update project name in windowevents that were written with projname unknown
                            UpdateUnknownProjectNameForIDEMatch(devPrjName, ide.AppName, ide.UnknownValue, Environment.MachineName, Environment.UserName);

                            // since we have found and processed the ide that we wanted, get out
                            writeDB = true;
                            goto EndOfGenericCode;
                        }
                        else /// if (m.Success && string.IsNullOrWhiteSpace(m.Groups["PrjName"].Value))
                        {
                            // ide has no project open yet set as unknown
                            devPrjName = ide.UnknownValue;;
                            //ide.DBUnknown = true;
                            writeDB = true;
                            continue;  // loop to see if another IDEMatch row will get the projectname
                        }
                        // *** removing so we loop to see if another IDEMatch will get the PrjName ...goto EndOfGenericCode;
                    }
                }
                // if at this point we did not find an idematch just an unknown window
EndOfGenericCode:
                // end new code

                #region old code

                /* strt of old cod
                 * if (!accessDenied && Globals.CurrentApp == AppWrapper.AppWrapper.devenv)
                 * {
                 *  var patt = "(?<PrjName>.*?)(?<spacer> - )*Microsoft Visual Studio|Microsoft Visual Studio";
                 *  var m = Regex.Match(title, patt);
                 *  devPrjName = string.Empty;
                 *  if (m.Success && m.Groups["PrjName"] != null && !string.IsNullOrWhiteSpace(m.Groups["PrjName"].Value))
                 *  {
                 *      devPrjName = m.Groups["PrjName"].Value.Replace("(Running)", string.Empty).Replace("(Debugging)", string.Empty).Trim();
                 *      if (Globals.VSUnknowns)
                 *      {
                 *          Globals.VSUnknowns = false;
                 *          UpdateUnknownProjectNameinVSCode(devPrjName, AppWrapper.AppWrapper.devenv, AppWrapper.AppWrapper.VSUnknown);
                 *      }
                 *  }
                 *  else // regex failed to get prjname
                 *  {
                 *      /* this is one place where project name can be set to devenv
                 * and should not be
                 *      //devPrjName = p.ProcessName;
                 *      devPrjName = AppWrapper.AppWrapper.VSUnknown; // "devenvUnKnown";
                 *      Globals.VSUnknowns = true;
                 *  }
                 * }
                 * else if (!accessDenied && Globals.CurrentApp == AppWrapper.AppWrapper.VSCode)
                 * {
                 *  // we are in VSCode
                 *  var pattVSCode = "^(?<FileName>.*?) - (?<PrjName>.*?) - Visual Studio Code|Welcome - Visual Studio Code|Open Folder";
                 *  var m = Regex.Match(title, pattVSCode);
                 *  devPrjName = string.Empty;
                 *  if (m.Success && m.Groups["PrjName"] != null && !string.IsNullOrWhiteSpace(m.Groups["PrjName"].Value))
                 *  {
                 *      devPrjName = m.Groups["PrjName"].Value;
                 *      if (Globals.VSCodeUnknowns)
                 *      {
                 *          Globals.VSCodeUnknowns = false;
                 *          UpdateUnknownProjectNameinVSCode(devPrjName, Globals.CurrentApp, AppWrapper.AppWrapper.VSCodeUnknown);
                 *      }
                 *  }
                 *  else if (m.Success && string.IsNullOrWhiteSpace(m.Groups["PrjName"].Value))
                 *  {
                 *      // in vscode the
                 *      // developer has not opened a folder yet so mark
                 *      // the project name unknown until VSCode opens a folder and then
                 *      // we can update the database records
                 *      devPrjName = AppWrapper.AppWrapper.VSCodeUnknown;
                 *      Globals.VSCodeUnknowns = true;
                 *  }
                 *  else
                 *  {
                 *      devPrjName = AppWrapper.AppWrapper.VSCodeUnknown;
                 *      Globals.VSCodeUnknowns = true;
                 *  }
                 * }
                 * else
                 * {
                 *  // current app is not VS or VSCode we will only be able to determine
                 *  // the project name if this app saves a file to a known project path
                 *  devPrjName = !accessDenied ? p.ProcessName : AccessDenied;
                 *  if (devPrjName == "devenv")
                 *  {
                 *      devPrjName = AppWrapper.AppWrapper.VSUnknown;
                 *      Globals.VSUnknowns = true;
                 *  }
                 * }
                 * end of generic changes */

                //appears to be so FileWatcher can pick it out to use in creating FileAnalyzer
                // could be set in Globals.LastWindowEvent object not in two places
                // below is wrong b/c it is updating the last window that we are no longer in
                //Globals.LastWindowEvent.DevProjectName = devPrjName;

                // in practice, if you do not record all events, you could later want
                // to see some that would not be recorded
                //if (title == "Window Change Log" || title == "Project Description" || p.ProcessName == "DevTracker" || p.ProcessName == "explorer")
                //    return;
                #endregion
                //var currApp = !accessDenied ? p.ProcessName : AccessDenied;

                // see if we are interested in recording this window
                // if writeDB set, then we already know to write this window b/c of ideMatch found
                if (!writeDB)
                {
                    var appConfig = Globals.ConfigOptions.Find(x => x.Name == "RECORDAPPS");
                    if (appConfig != null)
                    {
                        switch (appConfig.Value)
                        {
                        case "A":
                            writeDB = true;
                            break;

                        case "S":
                            var interestingApp = Globals.NotableApplications.Find(o => o.AppName.ToLower() == _currentApp.ToLower());
                            writeDB = (interestingApp != null);
                            break;
                        }
                    }
                }

                if (_currentApp.ToLower() == "explorer")
                {
                    writeDB = false; //  forget
                }
                // if we are writing this window, and devProjectName not set yet
                // see if a known project name is being worked on by a non IDE
                //TODO in a large shop this may be time consuming
                if (writeDB && string.IsNullOrWhiteSpace(devPrjName))
                {
                    devPrjName = IsProjectInNonIDETitle(title);
                }


                WindowEvent item;

                /* there are other threads, FileWatcher, changing this object
                 * and we want no conflict  */
                if (Globals.LastWindowEvent != null)
                {
                    lock (Globals.LastWindowEvent)
                    {
                        item              = Globals.LastWindowEvent;
                        item.EndTime      = now;
                        Globals.StartTime = now;
                        if (writeDB)
                        {
                            var hlpr = new DHWindowEvents(AppWrapper.AppWrapper.DevTrkrConnectionString);
                            if (item.DevProjectName.Equals("devenv"))
                            {
                                Debug.WriteLine(item.DevProjectName);
                            }

                            if (ideMatchObject != null && !ideMatchObject.IsIde && !devPrjName.ToLower().Contains(".sql"))
                            {
                                // if next line true
                                if ((!string.IsNullOrWhiteSpace(ideMatchObject.AlternateProjName) && devPrjName == ideMatchObject.AlternateProjName) || devPrjName == ".")
                                {
                                    Debug.WriteLine(devPrjName);
                                }
                                else
                                {
                                    CheckForInsertingNewProjectPath(devPrjName, ideMatchObject.UnknownValue, Environment.UserName, Environment.MachineName, ideMatchObject.AppName);
                                }
                            }
                            int rows;
                            if (_currentApp.ToLower() == "explorer")
                            {
                                Debug.WriteLine("Dont write explorer");
                            }
                            rows = hlpr.InsertWindowEvent(item);
                        }
                    }
                }

                var appNName = !accessDenied ? p.ProcessName : AccessDenied;
                item = new WindowEvent
                {
                    ID              = Guid.NewGuid().ToString(),
                    StartTime       = now,
                    WindowTitle     = title,
                    AppName         = appNName,
                    ModuleName      = moduleName,
                    EndTime         = DateTime.MinValue,
                    DevProjectName  = devPrjName,
                    ITProjectID     = string.Empty,
                    UserName        = Environment.UserName,
                    MachineName     = Environment.MachineName,
                    UserDisplayName = displayName
                };
                Globals.LastWindowEvent = item;

                const string comma = ",";
#if DEBUG
                Debug.Write("*******" + title + comma +
                            _startTime.ToString("HH:mm:ss") + comma +
                            item.EndTime.ToString("HH:mm:ss") + comma +
                            item.AppName + comma +
                            item.ModuleName + comma +
                            devPrjName + Environment.NewLine);
#endif
            }
            catch (Exception ex)
            {
                Debug.Print(ex.Message);
            }
        }
        //NOTE: new constructor
        public WindowEvents(/* blank constructor to process the queue  WinEventProcesss p, ListView log*/)
        {
            try
            {
                WinEventProcesss wep;

TopOfCode:
                // get a queue item if it exists
                while (true)
                {
                    lock (Globals.WinEventQueue)
                    {
                        if (Globals.WinEventQueue.Count.Equals(0))
                        {
                            Globals.WindowEventThreadRunning = false;
                            return;
                        }

                        wep = Globals.WinEventQueue.Peek();
                        Globals.WinEventQueue.Dequeue();
                        break;
                    }
                }

                var now   = wep.Starttime; // time window changed
                var title = wep.MyWindowEvent.WindowTitle;

#if DEBUG
                Debug.WriteLine("**** " + title);
#endif
                if (title == null)
                {
                    return;
                }

                var    accessDenied = false;
                var    moduleName   = wep.MyWindowEvent.ModuleName;
                string displayName  = wep.MyWindowEvent.UserDisplayName;

                var devPrjName = string.Empty;

                // We set some globals so the file watcher knows who is running
                _currentApp = wep.MyWindowEvent.AppName;

                bool writeDB = false;

                /* make project extraction generic with regex */
                // new code ***** NOTE: THE ideMATCHES TABLE SHOULD ONLY HAVE IDES AND SSMS ****
                // **** WE ARE DOING THIS FOR SSMS THO NOT AN IDE B/C SO MUCH TIME IS SPENT THERE
                // **** AND EVEN GROUPING BY A SERVER.DBNAME MAY GIVE A CLUE TO THE DEV PROJECT
                IDEMatch ideMatchObject = null;

                //new evidence for mulltiple IDEMatch objects for the same IDE i.e., devenv
                // title = "Add New Item - BusinessObjects"
                // title = "Add Existing Item - BusinessObjects"
                // title = "Reference Manager - DevTrkrReports"

                // ssms failing to update project name here and the reason is that ide.DBUnknown is
                //  likely not set b/c ide switches when window changes, .^. some switch must reside in globals
                // that will persist between window changes.. and cache updates
                // i think that is what the index in the match table was
                // about and then I forgot its purpose and removed it

                //NOTE: simplifying problem by updating below for whichever app when we find a new match
                //bool foundIDE = false;
                foreach (var ide in Globals.IDEMatches)
                {
                    if (!accessDenied && _currentApp.ToLower() == ide.AppName)
                    {
                        var pat = ide.Regex;
                        var m   = Regex.Match(title, pat, RegexOptions.IgnoreCase);
                        devPrjName = string.Empty;
                        if (m.Success && m.Groups[ide.RegexGroupName] != null &&
                            !string.IsNullOrWhiteSpace(m.Groups[ide.RegexGroupName].Value))
                        {
#if DEBUG
                            if (ide.AppName == "ssms")
                            {
                                Debug.WriteLine(title);
                            }
#endif
                            // we found the ide match we are looking for
                            ideMatchObject = ide;

                            // if we are concatinating two fields in ssms to get server.dbname
                            if (!string.IsNullOrWhiteSpace(ide.ProjNameConcat))
                            {
                                string[] concats = ide.ProjNameConcat.Split('|');
                                for (var i = 0; i < concats.Length; i++)
                                {
                                    devPrjName += (i > 0 ? ide.ConcatChar : string.Empty) + m.Groups[concats[i]].Value;
                                }
                            }
                            else
                            {
                                devPrjName = m.Groups[ide.RegexGroupName].Value;
                            }


                            if (!string.IsNullOrWhiteSpace(ide.ProjNameReplaces))
                            {
                                string[] replaces = ide.ProjNameReplaces.Split('|');
                                foreach (string s in replaces)
                                {
                                    devPrjName = devPrjName.Replace(s, string.Empty).Trim();
                                }
                            }

                            // NOTE: new logic for IDEMatch objects that have AlternateProjName
                            // if it is not null, replace devPrjName with it b/c altho we found a project name
                            // it is not one we want, so make it what we want (probably the same as the unknown value)
                            // so that it will be updated when we find the projname we want...
                            // e.g., ssms has master set so DBname = Server.master in table but new logic will be correctable
                            // e.g. ssms "not connected" can now have its own match object and will get set to unknow until
                            //       user connects to a database which they will have to do in order to do anything in ssms
                            if (ideMatchObject.AlternateProjName != null)
                            {
                                devPrjName = ideMatchObject.AlternateProjName;
                            }

                            // update project name in windowevents that were written with projname unknown
                            UpdateUnknownProjectNameForIDEMatch(devPrjName, ide.AppName, ide.UnknownValue, Environment.MachineName, Environment.UserName);

                            // since we have found and processed the ide that we wanted, get out
                            writeDB = true;
                            goto EndOfGenericCode;
                        }
                        else /// if (m.Success && string.IsNullOrWhiteSpace(m.Groups["PrjName"].Value))
                        {
                            // ide has no project open yet set as unknown
                            devPrjName = ide.UnknownValue;;
                            //ide.DBUnknown = true;
                            writeDB = true;
                            continue;  // loop to see if another IDEMatch row will get the projectname
                        }
                        // *** removing so we loop to see if another IDEMatch will get the PrjName ...goto EndOfGenericCode;
                    }
                }
                // if at this point we did not find an idematch just an unknown window
EndOfGenericCode:
                // end new code

                // see if we are interested in recording this window
                // NOTE: we may always want to write the window to DB b/c the company may want to know every app being used
                // especially if we want to run the Developer(user) Detail Report
                // if writeDB set, then we already know to write this window b/c of ideMatch found
                if (!writeDB)
                {
                    var appConfig = Globals.ConfigOptions.Find(x => x.Name == "RECORDAPPS");
                    if (appConfig != null)
                    {
                        switch (appConfig.Value)
                        {
                        case "A":
                            writeDB = true;
                            break;

                        case "S":
                            var interestingApp = Globals.NotableApplications.Find(o => o.AppName.ToLower() == _currentApp.ToLower());
                            writeDB = (interestingApp != null);
                            break;
                        }
                    }
                }

                if (_currentApp.ToLower() == "explorer")
                {
                    writeDB = false; //  forget
                }
                // if we are writing this window, and devProjectName not set yet
                // see if a known project name is being worked on by a non IDE
                //TODO in a large shop this may be time consuming
                if (writeDB && string.IsNullOrWhiteSpace(devPrjName))
                {
                    // check to see if the window title contains a known project name
                    devPrjName = IsProjectInNonIDETitle(title);
                }
                else
                {
                    goto TopOfCode;
                }

                WindowEvent item;

                /* Here, we are going to record the window in db
                 * there are other threads, FileWatcher, changing this object
                 * and we want no conflict  */
                if (Globals.LastWindowEvent != null)
                {
                    lock (Globals.LastWindowEvent)
                    {
                        item              = Globals.LastWindowEvent;
                        item.EndTime      = now;
                        Globals.StartTime = now;
                        if (writeDB)
                        {
                            var hlpr = new DHWindowEvents(AppWrapper.AppWrapper.DevTrkrConnectionString);
                            if (item.DevProjectName.Equals("devenv"))
                            {
                                Debug.WriteLine(item.DevProjectName);
                            }

                            if (ideMatchObject != null && !ideMatchObject.IsIde && !devPrjName.ToLower().Contains(".sql"))
                            {
                                // if next line true
                                if ((!string.IsNullOrWhiteSpace(ideMatchObject.AlternateProjName) && devPrjName == ideMatchObject.AlternateProjName) || devPrjName == ".")
                                {
                                    Debug.WriteLine(devPrjName);
                                }
                                else
                                {
                                    if ("Connect.to_Repor._DevTrack.".Contains(devPrjName) || devPrjName.EndsWith("."))
                                    {
                                        Debug.WriteLine("bad project name");
                                    }
                                    else
                                    {
                                        CheckForInsertingNewProjectPath(devPrjName, ideMatchObject.UnknownValue, Environment.UserName, Environment.MachineName, ideMatchObject.AppName);
                                    }
                                }
                            }
                            int rows;
                            if (_currentApp.ToLower() == "explorer")
                            {
                                Debug.WriteLine("Dont write explorer");
                            }
                            rows = hlpr.InsertWindowEvent(item);
                        }
                    }
                }


                const string comma = ",";
#if DEBUG
                Debug.Write("******* " + title + comma +
                            _startTime.ToString("HH:mm:ss") + comma +
                            wep.MyWindowEvent.EndTime.ToString("HH:mm:ss") + comma +
                            wep.MyWindowEvent.AppName + comma +
                            wep.MyWindowEvent.ModuleName + comma +
                            devPrjName + Environment.NewLine);
#endif

                goto TopOfCode; // check for more
            }
            catch (Exception ex)
            {
                Debug.Print(ex.Message);
            }
        }
예제 #4
0
        /// <summary>
        /// NOTE: You can put breakpoints in here, but if you do, then writing becomes iffy in spite of
        /// all that I have done to queue and thread, there are still issues in debugging
        /// b/c stopping in here changes the window event
        /// </summary>
        public WindowEvents()
        {
            WinEventProcesss wep;

TopOfCode:
            try
            {
                // get a queue item if it exists
                while (true)
                {
                    lock (Globals.SyncLockObject)
                    {
                        if (Globals.WinEventQueue.Count.Equals(0))
                        {
                            Globals.WindowEventThreadRunning = false;
                            return;
                        }

                        wep = Globals.WinEventQueue.Peek();
                        Globals.WinEventQueue.Dequeue();
                        break;
                    }
                }

                var now   = wep.Starttime; // time window changed
                var title = wep.MyWindowEvent.WindowTitle;

                if (string.IsNullOrWhiteSpace(title))
                {
                    return;
                }

                var    accessDenied = false;
                var    moduleName   = wep.MyWindowEvent.ModuleName;
                string displayName  = wep.MyWindowEvent.UserDisplayName;

                var devPrjName = string.Empty;
                var syncId     = string.Empty;

                // We set some properties so the file watcher knows who is running
                _currentApp = wep.MyWindowEvent.AppName.ToLower();

                bool writeDB = false;

                /* make project extraction generic with regex */
                // new code ***** NOTE: THE ideMATCHES TABLE SHOULD ONLY HAVE IDES AND SSMS (DBMGRs) ****
                // **** WE ARE DOING THIS FOR SSMS THO NOT AN IDE B/C SO MUCH TIME IS SPENT THERE
                // **** AND EVEN GROUPING BY A SERVER.DBNAME MAY GIVE A CLUE TO THE DEV PROJECT
                IDEMatch ideMatchObject = null;

                // ssms failing to update project name here and the reason is that ide.DBUnknown is
                //  likely not set b/c ide switches when window changes, .^. some switch must reside in globals
                // that will persist between window changes.. and cache updates
                // i think that is what the index in the match table was
                // about and then I forgot its purpose and removed it

                //NOTE: cfp.GetProjectName also sets writeDB base on multiple checks
                // including the config option RECORDAPPS so the decision whether
                // to record this window is made there
                var cfp = new CheckForProjectName();
                Tuple <string, IDEMatch, bool, string> cfpObject = cfp.GetProjectName(title, accessDenied, _currentApp, writeDB);
                devPrjName               = cfpObject.Item1;
                writeDB                  = cfpObject.Item3;
                ideMatchObject           = cfpObject.Item2;
                wep.MyWindowEvent.SyncID = cfpObject.Item4;

                // if we are writing this window, and devProjectName not set yet
                // see if a known project name is being worked on by a non IDE
                if (writeDB)
                {
                    // check to see if the window title contains a known project name
                    if (string.IsNullOrWhiteSpace(devPrjName))
                    {
                        Tuple <string, string> prjObject = cfp.IsProjectInNonIDETitle(title);
                        if (prjObject != null)
                        {
                            devPrjName = prjObject.Item1;
                            wep.MyWindowEvent.SyncID = prjObject.Item2;
                        }
                    }
                }
                else
                {
                    // one or more
                    goto TopOfCode;
                }

                // try to get syncId from DevProjects
                var hlpr = new DHWindowEvents();
                if (/*ideMatchObject != null && !ideMatchObject.IsDBEngine && */ !string.IsNullOrWhiteSpace(devPrjName))
                {
                    MaintainProject mp = new MaintainProject();
                    // bypass next line until we get fw debugged
                    if (string.IsNullOrWhiteSpace(wep.MyWindowEvent.SyncID))
                    {
                        wep.MyWindowEvent.SyncID = mp.GetProjectSyncIDForProjectName(devPrjName); //, _currentApp);
                    }
                    // here we should update any WindowEvents that have been created by this appname
                    // and for this project w/o a syncid
                    if (!string.IsNullOrWhiteSpace(wep.MyWindowEvent.SyncID))
                    {
                        hlpr.UpdateWindowEventsWithSyncID(devPrjName, _currentApp, wep.MyWindowEvent.SyncID);
                    }
                }

                /* Here, we are going to record the window in db
                 * there are other threads, FileWatcher, changing this object
                 * and we want no conflict  */
                WindowEvent item = wep.MyWindowEvent;
                if (item.AppName == "ApplicationFrameHost" && item.WindowTitle.Contains("Solitaire"))
                {
                    item.AppName = item.WindowTitle;
                }

                if (!string.IsNullOrWhiteSpace(item.DevProjectName) && item.DevProjectName.Equals("devenv"))
                {
                    _ = new LogError($"WindowEvent, Bad Project Name of 'devenv' from Title: {item.WindowTitle}", false, "WindowEvents.ctor");
                }

                if (ideMatchObject != null && devPrjName == "DevTracker" && ideMatchObject.AppName == "ssms")
                {
                    _ = new LogError($"WindowEvents, 'Devtracker' should not be the project name for ssms, Title: {item.WindowTitle}", false, "WindowEvent.ctor");
                }

                //NOTE: 4 / 27 / 2020 discontinued this doing anything...except writing bad data notes
                // Window events does not have devpath and therefore is not qualified to insert a project
                if (ideMatchObject != null && !ideMatchObject.IsIde && !devPrjName.ToLower().Contains(".sql"))
                {
                    // if next line true
                    if (/*(!string.IsNullOrWhiteSpace(ideMatchObject.AlternateProjName) && devPrjName == ideMatchObject.AlternateProjName) || */ devPrjName == ".")
                    {
                        _ = new LogError($"WindowEvents, Bad Project Name: {devPrjName} from Title: {item.WindowTitle}", false, "WindowEvents.ctor");
                    }
                    else
                    {
                        // this is a check for convoluted name going to DevProjectName
                        if ("Connect.to_Repor._DevTrack.".Contains(devPrjName) || devPrjName.EndsWith("."))
                        {
                            _ = new LogError($"WindowEvents bad project name = {devPrjName} from Title: {item.WindowTitle}", false, "WindowEvents.ctor");
                        }

                        //NOTE: we should not set an unknown value in the devproject table
                        // the way the sproc is written, this call will insert a new project with unknown path
                        // if the project does not exist, and if it does exist, this call will not update
                        // the path b/c this call is passing xxUnknown as the the path,
                        // if this is the way a project gets created in DevProjects, it will only get the correct path
                        // from the save of a project file, which only get done when a new project is created
                        else if (string.IsNullOrWhiteSpace(devPrjName) || string.IsNullOrWhiteSpace(ideMatchObject.UnknownValue))
                        {
                            _ = new LogError($"WindowEvents, Missing Data, Project: {devPrjName}  Path: {ideMatchObject.UnknownValue} from Title: {item.WindowTitle}", false, "WindowEvents.ctor");
                        }
                        else
                        {
                            // we create projects for database servers here for two reasons
                            // 1) they don't have a path
                            // 2) they will get no files saved  with any relation to a path so FileAnalyzer won't create the project

                            // when development of DevTracker was begun, windowevents
                            // was the only way we had of possibly getting the project
                            // name, but it did not, nor does it now have a way to get
                            // the path.  FileAnalyzer on the other hand has an exact way of
                            // deriving the path to the projectFile .xxproj so Les has made
                            // the decision of stopping what is at best doing half the job
                            // except for database projects
                            //Debug.WriteLine($"**** Would have checked for writing {devPrjName} to DevProjects");

                            if (ideMatchObject != null && ideMatchObject.IsDBEngine && devPrjName != ideMatchObject.AlternateProjName)
                            {
                                var         mp  = new MaintainProject();
                                DevProjPath dpp = new DevProjPath
                                {
                                    DevProjectName  = devPrjName,
                                    DevProjectPath  = ideMatchObject.UnknownValue,
                                    IDEAppName      = item.AppName,
                                    DatabaseProject = ideMatchObject.IsDBEngine,
                                    CountLines      = false,
                                    ProjFileExt     = "sql",
                                    DevSLNPath      = string.Empty,
                                    GitURL          = devPrjName,
                                    Machine         = Environment.MachineName,
                                    UserName        = Environment.UserName,
                                    CreatedDate     = DateTime.Now
                                };
                                item.SyncID = mp.CheckForInsertingNewProjectPath(dpp);
                            }
                        }
                    }
                }

                if (item.AppName == "ssms" && item.DevProjectName == "Microsoft")
                {
                    _ = new LogError($"WindowEvents, Bad Project name 'Microsoft' from Title: {item.WindowTitle}", false, "WindowEvents.ctor");
                }
                item.DevProjectName = devPrjName;
                hlpr = new DHWindowEvents();
                int rows = hlpr.InsertWindowEvent(item);

                goto TopOfCode; // check for more queue entries
            }
            catch (Exception ex)
            {
                _ = new LogError(ex, false, "WindowEvents.ctor");
            }
            goto TopOfCode;
        }
예제 #5
0
        /// <summary>
        /// Get project name from a window title using known IDE regexes
        /// </summary>
        /// <param name="title"></param>
        /// <param name="accessDenied"></param>
        /// <param name="_currentApp"></param>
        /// <param name="writeDB"></param>
        /// <returns>Tuple(devProjName, ideMatchObject, true to write windowevent, possible syncId)</returns>
        public Tuple <string, IDEMatch, bool, string> GetProjectName(string title, bool accessDenied, string _currentApp, bool writeDB)
        {
            IDEMatch foundIde   = null;
            string   devPrjName = string.Empty;
            bool     doWriteDB  = writeDB;
            string   syncId     = string.Empty;

            foreach (var ide in Globals.IDEMatches)
            {
                if (!accessDenied && _currentApp.ToLower() == ide.AppName.ToLower())
                {
                    var pat = ide.Regex;
                    var m   = Regex.Match(title, pat, RegexOptions.IgnoreCase | RegexOptions.ExplicitCapture);
                    devPrjName = string.Empty;
                    if (m.Success && m.Groups[ide.RegexGroupName] != null &&
                        !string.IsNullOrWhiteSpace(m.Groups[ide.RegexGroupName].Value))
                    {
                        // we found the ide match we are looking for
                        foundIde = ide;

                        // if we are concatinating two fields in ssms to get server.dbname
                        if (!string.IsNullOrWhiteSpace(ide.ProjNameConcat))
                        {
                            string[] concats = ide.ProjNameConcat.Split('|');
                            for (var i = 0; i < concats.Length; i++)
                            {
                                if (!string.IsNullOrWhiteSpace(m.Groups[concats[i]].Captures[0].ToString()))
                                {
                                    devPrjName += (i > 0 ? ide.ConcatChar : string.Empty) + m.Groups[concats[i]].Captures[0];
                                }
                            }
                        }
                        else
                        {
                            devPrjName = m.Groups[ide.RegexGroupName].Value;
                        }

                        if (devPrjName.StartsWith("Microsoft") && _currentApp == "ssms")
                        {
                            _ = new LogError($"CheckForProjectName, SSMS Invalid Project: 'Microsoft' from Title: { title}", false, "CheckForProjectName.GetProjectName");
                        }

                        if (!string.IsNullOrWhiteSpace(ide.ProjNameReplaces))
                        {
                            string[] replaces = ide.ProjNameReplaces.Split('|');
                            foreach (string s in replaces)
                            {
                                devPrjName = devPrjName.Replace(s, string.Empty).Trim();
                            }
                        }

                        // how do I know it is not the one we wan
                        // NOTE: new logic for IDEMatch objects that have AlternateProjName
                        // if it is not null, replace devPrjName with it b/c altho we found a project name
                        // it is not one we want, so make it what we want (probably the same as the unknown value)
                        // so that it will be updated when we find the projname we want...
                        // e.g., ssms has master set so DBname = Server.master in table but new logic will be correctable
                        // e.g. ssms "not connected" can now have its own match object and will get set to unknow until
                        //       user connects to a database which they will have to do in order to do anything in ssms
                        // but there is no need to run an update if the devPrjName == AlternateProjName b/c it is already
                        // that in database; we have to wait til we get a valid project name
                        if (!string.IsNullOrWhiteSpace(foundIde.AlternateProjName))
                        {
                            devPrjName = foundIde.AlternateProjName;
                        }
                        else
                        {
                            // update project name in windowevents that were written with projname unknown
                            if (!string.IsNullOrWhiteSpace(devPrjName))
                            {
                                UpdateUnknownProjectNameForIDEMatch(devPrjName, ide.AppName, ide.UnknownValue, Environment.MachineName, Environment.UserName);
                            }
                        }

                        // since we have found and processed the ide that we wanted, get out
                        doWriteDB = true;
                        goto EndOfGenericCode;
                    }
                    else /// if (m.Success && string.IsNullOrWhiteSpace(m.Groups["PrjName"].Value))
                    {
                        // ide has no project open yet set as unknown
                        devPrjName = ide.UnknownValue;
                        doWriteDB  = true;
                        continue;  // loop to see if another IDEMatch row will get the projectname
                    }
                }
            }
            // if at this point we did not find an idematch just an unknown window
EndOfGenericCode:

            // if devProjectName not set yet
            // see if a known project name is being worked on by a non IDE
            // check to see if the window title contains a known project name
            if (string.IsNullOrWhiteSpace(devPrjName))
            {
                Tuple <string, string> prjObject = IsProjectInNonIDETitle(title);
                if (prjObject != null)
                {
                    devPrjName = prjObject.Item1;
                    syncId     = prjObject.Item2;
                }
            }

            // see if we are interested in recording this window
            // NOTE: we may always want to write the window to DB b/c the company may want to know every app being used
            // especially if we want to run the Developer(user) Detail Report
            // if doWriteDB set, then we already know to write this window b/c of ideMatch found
            if (!doWriteDB)
            {
                var appConfig = Globals.ConfigOptions.Find(x => x.Name == "RECORDAPPS");
                if (appConfig != null)
                {
                    switch (appConfig.Value)
                    {
                    case "A":
                        doWriteDB = true;
                        break;

                    case "S":
                        var interestingApp = Globals.NotableApplications.Find(o => o.AppName.ToLower() == _currentApp.ToLower());
                        doWriteDB = (interestingApp != null);
                        break;
                    }
                }
            }

            // explorer is Windows and project explorer but project explorer does not always have a title
            // time spent there is really not interesting so ignore it
            if (_currentApp.ToLower() == "explorer" && string.IsNullOrWhiteSpace(title))
            {
                doWriteDB = false; //  forget
            }
            return(Tuple.Create(devPrjName, foundIde, doWriteDB, syncId));
        }
예제 #6
0
        private void Locked()
        {
            LockStartTime = DateTime.Now;
            var      accessDenied   = false;
            var      _currentApp    = Globals.LastWindowEvent.AppName;
            IDEMatch ideMatchObject = null;
            bool     writeDB        = false;

            //_locked = true;

            // turn off polling while locked, so we will not see any window change while locked
            // therefore LastWindowEvent should be the one created below when we detect unlock
            WindowPolling.SuspendWindowPolling();

            // Try to get the project name for the Globals.LastWindowEvent
            var cfp = new CheckForProjectName();
            Tuple <string, IDEMatch, bool, string> cfpObject = cfp.GetProjectName(Globals.LastWindowEvent.WindowTitle, accessDenied, Globals.LastWindowEvent.AppName, writeDB);
            string devProjectName = cfpObject.Item1;

            ideMatchObject = cfpObject.Item2;
            writeDB        = cfpObject.Item3;
            if (string.IsNullOrWhiteSpace(Globals.LastWindowEvent.DevProjectName))
            {
                Globals.LastWindowEvent.DevProjectName = devProjectName;
            }

            var hlpr = new DHWindowEvents(AppWrapper.AppWrapper.DevTrkrConnectionString);

            lock (Globals.SyncLockObject)
            {
                // now, make it look like the current window when the lock occurs is being moved away from
                // by writing it to database
                Globals.LastWindowEvent.EndTime = LockStartTime;
                hlpr.InsertWindowEvent(Globals.LastWindowEvent);

                // next, start a new LastWindowEvent called ComputerLocked
                // and put it in Globals.LastWindowEvent
                string displayName;
                try
                {
                    displayName = UserPrincipal.Current.DisplayName;
                }
                catch (Exception ex)
                {
                    displayName = Environment.UserName;
                }

                var item = new WindowEvent
                {
                    ID              = Guid.NewGuid().ToString(),
                    StartTime       = LockStartTime,
                    WindowTitle     = locked,
                    AppName         = locked,
                    ModuleName      = locked,
                    EndTime         = LockEndTime,
                    DevProjectName  = locked,
                    ITProjectID     = string.Empty,
                    UserName        = Environment.UserName,
                    MachineName     = Environment.MachineName,
                    UserDisplayName = displayName
                };
                Globals.LastWindowEvent = item;
            }
        }