Как написать код для запуска один раз и только один раз - PullRequest
3 голосов
/ 22 декабря 2010

Я ищу способ написания кода, чтобы при первом запуске программы этот сегмент кода выполнялся один и только один раз. Если программа закрывается и запускается снова, код больше не будет запускаться. Он запустится снова, если все приложение будет удалено и установлено с нуля.

Файл конфигурации или флаг в базе данных не являются решением этой проблемы.

Я где-то читал (что, похоже, не могу найти) о каком-то способе запустить что-то один раз, и тогда он может скомпилировать переменную в двоичный файл, который будет использоваться всегда и всегда.

Спасибо за любую помощь, которую я могу получить в этом!

Ответы [ 8 ]

7 голосов
/ 22 декабря 2010

Вы собираетесь где-то хранить состояние. Есть много и много мест, где вы можете сделать это, и техника, используемая в каждом случае, отличается:

  1. В конфигурационном файле (который вы специально отключили)

  2. В реестре, который некоторые могут считать устаревшим, но, безусловно, вариант.

  3. На веб-сайте вне компьютера, на сервере, который вы пишете, или на веб-сайте, или что-то в этом роде, однако для этого требуется инфраструктура и сетевой пинг.

  4. Вы можете сделать что-то, как вы предлагаете, где вы динамически перекомпилируете DLL или программу и корректируете исходный код. Это не сильно отличается от файла конфигурации - за исключением того, что файл конфигурации является исполняемым файлом - он также имеет недостаток, заключающийся в том, что многие пользователи с ограниченными правами не могут этого сделать, и могут не иметь разрешения на запись в том месте, где вы хотите его сохранить. (в Program Files например.)

Я уверен, что есть и другие способы. Однако, как и большинство проблем программирования, вы должны учитывать компромиссы и определять, что подходит именно вам.

Если вы можете предложить больше информации и контекста (например, почему вы не можете просто записать это в файл конфигурации), возможно, мы поможем вам лучше судить.

Если это работает для вас, одним из простых решений может быть добавление установщиком фиктивного файла с именем, например, neverrun.txt. При запуске проверьте наличие файла. Если он есть, выполните код, затем удалите файл. Таким образом, для выполнения этого кода требуется переустановка.

Однако есть ряд проблем с этим подходом. Он не является надежно защищенным (легко установить начальное состояние и воссоздать файл), и ваши пользователи могут не иметь возможности удалить файл в Program Files или в том месте, где вы его выгружаете. Нам нужно больше контекста, чтобы понять основные цели, которые у вас есть.

4 голосов
/ 22 декабря 2010

Ладно, не удержался, вот версия, которая пишет в поток ADS.

using System;

namespace ConsoleApplication1
{
    class Program
    {
        private static string ADS_Part = "RunOnceFlag";
        private static uint FILE_FLAG_BACKUP_SEMANTICS = 0x2000000;
        private static uint CREATE_ALWAYS = 2;
        private static uint OPEN_EXISTING = 3;
        private static uint FILE_SHARE_READ = 0x1;
        private static uint GENERIC_READ = 0x80000000;

        static void Main(string[] args)
        {
            if (IsFirstEverRun())
            {
                System.Diagnostics.Trace.WriteLine("First run");
                SetRunOnce();
            }
            else
            {
                System.Diagnostics.Trace.WriteLine("I've been run at least once!");
            }
        }
        private static bool IsFirstEverRun()
        {
            //Current running EXE (assumes not being loaded from another program)
            string P = System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName;
            string ADSFile = P + ":" + ADS_Part;

            //Try opening the ADS
            using (var FH = CreateFile(ADSFile, GENERIC_READ, FILE_SHARE_READ, IntPtr.Zero, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, IntPtr.Zero))
            {
                //Return whether its a valid handle or not
                return FH.IsInvalid;
            }

        }
        private static void SetRunOnce()
        {
            //Current running EXE (assumes not being loaded from another program)
            string P = System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName;
            string ADSFile = P + ":" + ADS_Part;

            //Create the ADS. We could write additional information here such as date/time first run or run counts, too
            using (var FH = CreateFile(ADSFile, GENERIC_READ, FILE_SHARE_READ, IntPtr.Zero, CREATE_ALWAYS, FILE_FLAG_BACKUP_SEMANTICS, IntPtr.Zero)){}
        }


        [System.Runtime.InteropServices.DllImport("kernel32.dll", SetLastError = true, CharSet = System.Runtime.InteropServices.CharSet.Auto)]
        public static extern Microsoft.Win32.SafeHandles.SafeFileHandle CreateFile(string lpFileName,
            uint dwDesiredAccess,
            uint dwShareMode,
            IntPtr lpSecurityAttributes,
            uint dwCreationDisposition,
            uint dwFlagsAndAttributes,
            IntPtr hTemplateFile);
    }
}
1 голос
/ 02 марта 2012

Пока не встречается в ответах, и хотя это старый вопрос, позвольте мне добавить еще один вариант в ваш список:

  • Обман с помощью службы Windows.Каждый раз, когда ваше приложение запускается, оно пытается установить сервис.Если служба уже установлена, она не будет снова установлена.Теперь вы можете добавить дополнительные функции в саму службу (запускать ее при запуске системы, требовать, чтобы она запускалась вашим приложением, или даже изменять программу для запуска из службы, а не из исходного ярлыка).

В зависимости от ваших потребностей, это может быть жизнеспособным решением.То, что вы на самом деле делаете здесь, это изменение состояния вашей программы при первом запуске и при последующих запусках, вы запускаете другой код:

if(!serviceInstalled)
{
    CodeThatRunsOnceAndOnlyOnce();
    InstallService();
}

Но, если вы не добавите функциональность через сервис, более простое решениеде-факто решение, на мой взгляд, заключается в сохранении состояния в реестре.Если вы хотите скрыть это от удаления, запутайте запись в реестре.

1 голос
/ 22 декабря 2010

Вам нужно будет хранить ресурс, например, файл или значение реестра, чтобы указать вашей программе, что код уже был запущен и не должен быть перезапущен.Затем вы можете проверить этот файл / значение при запуске, и всякий раз, когда вы захотите снова запустить код, удалите файл / значение.

Примеры:

  • Временный файл в вашемкаталог настроек приложения.(Примечание: ваш деинсталлятор должен будет это почистить)
  • Настройка реестра в HKLM / HKCU.(Примечание: еще раз, очищено реестром)
  • Измените на app.config или web.config (Примечание: это не потребует очистки удаления, так как обычный процесс удаления должен удалить файл конфигурации тоже, можетпережить грязную деинсталляцию пользователя, просто удаляющего файлы).

Но это, вероятно, следует сделать на этапе установки / удаления.

0 голосов
/ 23 октября 2013

Вы можете записать его в сценарии, поэтому после установки приложения сценарий запускается, а затем удаляется. или иметь мини-приложение, которое вы запускаете вручную, либо после первой установки, либо всякий раз, когда вы хотите повторно инициализировать свое приложение. таким образом, вы можете восстановить новую установку, запустив мини-приложение.

0 голосов
/ 14 ноября 2012

Настройка параметров проекта и установка переменной в качестве флага ...

Вы можете сделать это, щелкнув правой кнопкой мыши на узле проекта и перейдя в раздел свойств и настроек, добавив новую строковую переменную

и получить к нему доступ: .setting.defaults.я думаю ...

, а также установить его, после установки вашей переменной, вам нужно вызвать save ()

0 голосов
/ 22 декабря 2010

В приложении WinForms вызовите код из кода запуска вашего приложения, в приложении ASP.NET вызовите его из обработчика Application_Start() в Global.asax.(Я понятия не имею, как ваше приложение может быть и то и другое.)

0 голосов
/ 22 декабря 2010

Я заметил, что ваш тег предназначен как для Asp.Net, так и для Winforms, довольно странно иметь что-то подобное в Asp.Net, но почему бы просто не добавить это в ваш установочный пакет?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...