6

How can I get the number of times a program has previously run in C# without keeping a file and tallying. If it is not possible that way, can it be gotten from the Scheduled Task Manager?

To C. Ross: how would this be done in a registry setting? forgive me. . . what is a registry setting?

Jon Seigel
  • 12,251
  • 8
  • 58
  • 92
  • @"what is a registry setting?" -- the registry is an organized file of information containing program and configuration data for a given installation of Windows. Chesso provides a decent example of how to interact with it below. Don't play around in the registry unless your comfortable though, it can be akin to doing brain surgery on someone that's awake (i.e. very bad). – Hardryv Aug 05 '09 at 17:30
  • @Donta. Cheeso has an excellent answer. I would recommend using theirs. – C. Ross Aug 05 '09 at 20:04

9 Answers9

13

I do this in a registry setting.

static string AppRegyPath = "Software\\Cheeso\\ApplicationName";
static string rvn_Runs = "Runs";

private Microsoft.Win32.RegistryKey _appCuKey;
public Microsoft.Win32.RegistryKey AppCuKey
{
    get
    {
        if (_appCuKey == null)
        {
            _appCuKey = Microsoft.Win32.Registry.CurrentUser.OpenSubKey(AppRegyPath, true);
            if (_appCuKey == null)
                _appCuKey = Microsoft.Win32.Registry.CurrentUser.CreateSubKey(AppRegyPath);
        }
        return _appCuKey;
    }
    set { _appCuKey = null; }
}

public int UpdateRunCount()
{
    int x = (Int32)AppCuKey.GetValue(rvn_Runs, 0);
    x++;
    AppCuKey.SetValue(rvn_Runs, x);
    return x;
}

If it's a WinForms app, you can hook the Form's OnClosing event to run UpdateCount.

Cheeso
  • 189,189
  • 101
  • 473
  • 713
10

To the best of my knowledge Windows does not keep this information for you. You would have to tally the value somewhere (file, database, registry setting). The Windows Task Scheduler is very low functionality.

C. Ross
  • 31,137
  • 42
  • 147
  • 238
  • @wally That doesn't sound like it's safe thing to integrate to. – C. Ross Dec 13 '15 at 13:36
  • @C.Ross I think you to correct this "Windows does not keep this information for you". To my knowledge it is safe (Correct me if I'm wrong). You're not writing to the registry, you're just reading it. – Wally Dec 14 '15 at 12:15
  • @wally I mean it's not safe because it's an OS implementation detail (they even ROT13 it), so they can change it at will and break your stuff. – C. Ross Dec 14 '15 at 12:34
  • @C.Ross Ok. You should still remove "Windows does not keep this information for you" beacuse that is simply not the case. – Wally Dec 14 '15 at 14:22
7

The number of time an app has run is stored in the registry; there are a couple of caveats, though:

  1. It's stored in the user registry (HKCU for instance) [HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\UserAssist]
  2. The path is stored in ROT13 so for instance runme.exe would become ehazr.rkr
  3. The registry actually stores three values in binary form: the last runtime, the run count (which starts at 6 instead of 1, for some reason), and the name of the application.

Don't know if this helps, but there you have it!

Oliver
  • 43,366
  • 8
  • 94
  • 151
Red P.
  • 71
  • 1
  • 1
  • 1
    I really couldn't believe it, but after doing a little search for devenv.exe in ROT13 (which is qrirai.rkr) i really found some interesting entries under `[HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\UserAssist]`. – Oliver May 26 '11 at 07:39
  • Wow, that's pretty bizarre. What do you accomplish by storing it that way? – chaz Jun 19 '12 at 17:08
  • 1
    If you're looking for Open Source projects implementing this look at https://github.com/JockiHendry/ProgramExecutionCounter . It's written in C# – Wally Dec 14 '15 at 12:18
  • @chaz You got it wrong. It's acutally Windows that stores those values. Windows records every program you open in the registry. Some one just found that out and found a way to decrypt the data. – Wally Dec 14 '15 at 12:35
  • @Wally That's quite the old post, but it looks like I just used the word "you" as in an indefinite pronoun, so to re-phrase that sentence it should have been "What does one accomplish by storing it that way?" Sorry for the confusion. – chaz Dec 14 '15 at 21:39
  • @chaz I'm still don't understand what you're saying. Windows stores the values automatically for forensic, spying and accessibility reasons. You don't need to store them. You just read those values from the registry and decrypt them. – Wally Dec 15 '15 at 08:04
4

Here is a tutorial for registry handling -- C# Registry Basics

nik
  • 13,254
  • 3
  • 41
  • 57
1

You could simply create an application setting called Properties.Settings.Default.TimesRun;

Use it like so:

private void Form1_Load( object sender, EventArgs e )
{
   Properties.Settings.Default.TimesRun = timesrun++;
   Properties.Settings.Default.Save();
}
Don Kirkby
  • 53,582
  • 27
  • 205
  • 286
jay_t55
  • 11,362
  • 28
  • 103
  • 174
0

No, task manager does not provide that kind of information. I wouldn't be hard to create a script that would update a tally and then execute the application and then set up the task to call the script.

Andrew Hare
  • 344,730
  • 71
  • 640
  • 635
0

I recommend using the ESENT database that is included with Windows. Software support is easily available with ESENT Managed Interface.

Chris Marisic
  • 32,487
  • 24
  • 164
  • 258
0

@Cheeso,

You don't need the private member variable with that code, one way to slim it down a bit:

using Microsoft.Win32;
public RegistryKey AppCuKey
{
    get
    {
        return Registry.CurrentUser.OpenSubKey(AppRegyPath, true)
            ?? Registry.CurrentUser.CreateSubKey(AppRegyPath);
    }
}

Or, if you like to update the private variable, in order to keep from calling the method (which is a pretty cheap method, anyway), you can still save yourself an if == null check.

Community
  • 1
  • 1
maxwellb
  • 13,366
  • 2
  • 25
  • 35
  • Having a property return something that the caller should dispose is an incredibly bad design. -1 – erikkallen Aug 06 '09 at 08:58
  • I use the property because I refer to other registry settings in other places. @erikkallen, I don't see how it's a bad design to return an IDisposable from a getter. It might be bad design to not Dispose() it. – Cheeso Mar 06 '10 at 13:45
0
int x = Your_Project.Properties.Settings.Default.Counter;
x++;
Your_Project.Properties.Settings.Default.Counter = x;
Your_Project.Properties.Settings.Default.Save();
Tenesi
  • 11
  • 1
  • While this code snippet may solve the question, [including an explanation](//meta.stackexchange.com/questions/114762/explaining-entirely-code-based-answers) really helps to improve the quality of your post. Remember that you are answering the question for readers in the future, and those people might not know the reasons for your code suggestion. Please also try not to crowd your code with explanatory comments, as this reduces the readability of both the code and the explanations! – Blue Aug 05 '16 at 14:13