Pull to refresh

Comments 30

Я както натыкался на «обновлялку», внутри которой был завернут GIT-клиент… Это было эпично, но работало великолепно! (Переименованные файлы именно переименовывались, удаленное удалялось, а измененное докачивало лиш измененные части, а не файл целиком).

А ещё советую взглянуть в сторону Torrent-клиента. Можно использовать для более быстрого скачивания обновлений — Клиенты будут делиться друг с другом, снижая нагрузку на ваши сервера.

Я-же писал более сложный алгоритм создания «Патчей»: Архивов, содержащих в себе .diff файлы (для текста и конфигов) и кое-что аналогичное для бинарных данных. Благо файлы на клиенте хранились не единым архивом, а практически в открытую.
Бонусом была кнопочка «Перепроверить всё», заставляющая клиента просчитать CRC для всех файлов и сравнить с данными сервера (И скачивать, в случае различий).

А насколько имеет смысл заморачиваться с diff'ами ради текста и конфигов (я так понимаю ваших, а не тех, что бы изменены пользователем)? Обычно размер подобных файлов достаточно мал и можно скачать целиком

Там были файлы локализации по 10-20 мегабайт. Такчто имело смысл, хотя и небольшой.
Но основная причина — это механизм обновления бинарных файлов кусками, который использовал практически туже механику, что и diff-файлы.
Я както натыкался на «обновлялку», внутри которой был завернут GIT-клиент… а измененное докачивало лиш измененные части, а не файл целиком).

Но основная причина — это механизм обновления бинарных файлов кусками, который использовал практически туже механику, что и diff-файлы.

Я надеюсь, вы в курсе, что Git как раз не докачивает диффы, а делает снепшоты файлов?
А вы сами в курсе, что то что git является snapshot-based а не diff-based VCS не значит что при работе он не использует дельта-компрессию для блобов? И снапшоты в git относятся не к файлам, а к коммитам.
Тогда уж сразу на основе aria2 делать, что не только torrent умеет, но и еще кучу всего.
На ней например DriverPack Solution работает.

С тех пор, как я узнал об SVN, так и не понял, почему люди не встраивают vcs, а продолжают лепить свои поделки.

Потому что у них совершенно разные цели.
Скачать, разместить, проверить достоверность разложенного продукта.
Другая цель только в том, что vcs умеет коммитить обратно.
Это не цели, это функционал. Если часть функционала совпадает, это еще не значит что инструмент подходит.
ещё одна утилита? Всё просто: для обновления файлов игры нужно выполняться с правами администратора.

Программу можно научить перезапускать себя с запросом UAC
Например так
void execAdmin(const wchar_t *path, const wchar_t *params)
{
    SHELLEXECUTEINFOW sei = {0};

    sei.cbSize       = sizeof (sei);
    sei.fMask        = SEE_MASK_NOCLOSEPROCESS;
    sei.hwnd         = 0;
    sei.lpVerb       = L"runas";
    sei.lpFile       = path;
    sei.lpParameters = params;
    sei.lpDirectory  = 0;
    sei.nShow        = SW_SHOW;
    sei.hInstApp     = 0;

    if (ShellExecuteExW (&sei))
    {
        WaitForSingleObject (sei.hProcess, INFINITE);
        CloseHandle (sei.hProcess);
    }
}


Проверка в рантайме, что UAC разрешен
bool isAdmin()
{
    BOOL fRet = FALSE;
    HANDLE hToken = NULL;
    if( OpenProcessToken( GetCurrentProcess( ),TOKEN_QUERY,&hToken ) ) {
        TOKEN_ELEVATION Elevation;
        DWORD cbSize = sizeof( TOKEN_ELEVATION );
        if( GetTokenInformation( hToken, TokenElevation, &Elevation, sizeof( Elevation ), &cbSize ) ) {
            fRet = Elevation.TokenIsElevated;
        }
    }
    if( hToken ) {
        CloseHandle( hToken );
    }
    return fRet;
}

Ммм Delphi, приятно видеть что ты не одинок. Как раз кстати обдумывал как реализовать автообновление в проекте.
А как тогда обновлять сам исполняемый файл, если он же и запущен? В линуксе-то это можно сделать, а вот в виндовсе оно же скажет что «не могу записать файл, он занят, попробуйте снова». Поэтому наверное везде где я видел используются все-таки два файла и апдейтер отдельно от основного приложения.
В *nix'ах приложение почти всегда целиком помещается в оперативку и с файлом на диске можно творить всё, что вздумается.
В Винде, по любому, можно провернуть туже операцию. Просто это чуть сложнее.
В апдейтере можно переименовать свой собственный файл и сохранить новый под старым именем.

Причина не в этом. Никсовые файловые системы основаны на inode — запись в каталоге это отдельная сущность от всех прочих данных и метаданных файла. Операция удаления файла удаляет только первую часть, а inode отстается жить, пока на файл есть хотя бы ещё одна ссылка. Открытый файл тоже считается ссылкой. В Винде это не так.

Я вам скажу одну вещь (строго по секрету!): в Windows уже давно можно переименовать запущенный файл (типа game.exe -> game_old.exe), записать на его место новую версию и запустить ее с одновременным выходом из старого экзешника.
А старый либо поставить в очередь на удаление при следующем запуске винды либо удалить из нового экзешника.

Это не отменяет же необходимость получения повышенных прав, отдельный апдейтер нужен прежде всего именно для этого. Но есть и другие причины:


  • так проще переносить апдейтер из проекта в проект;
  • юзеру удобно обновлять игру вручную, достаточно просто запустить GetNewVersion.exe — это весьма полезно на этапе бета-теста, когда в игре часто выкладываются необязательные обновления (багофиксы), и людям, которые ждут эти фиксы, не нужно переустанавливать итгру целиком;
  • у меня в апдейтере GUI сделан на VCL, и мне не хотелось добавлять в игру зависимость от этих библиотек;
  • апдейтер один раз написал, подписал и забыл — больше не нужен сертификат подписи кода (у меня как-раз истёк его срок действия). А игру можно продолжать обновлять :)
UFO just landed and posted this here
Замечу, что для 7z есть обертка для 7z.dll в JCL (JclCompression). Тоже сжимаем файлы для автообоновлений в Delphi
очень напоминает апдейтер от клиентов к «неофициальным» серверам lineage 2, который был распространен в 2008-2009 годах
По ссылке там не процесс повышает права, а запускает новый процесс из того же exe-шника. Это как-раз то, что выше описал Taraflex Годный вариант, но всё же это не elevation самого процесса.
Прошу вас обратить пристальное внимание на третий пункт. Приводится последовательность вызовов:
CredUIPromptForCredentials() или CredUIPromptForWindowsCredentials()
LogonUser()
ImpersonateLoggedOnUser()
RevertToSelf()
CloseHandle()

О запуске нового процесса здесь речи не идет. Магия заключается в том, что полученный в результате LogonUser токен может быть использован не только для запуска процесса но и для процесса имперсонации в текущем контексте выполнения и защиты процесса.
Этот механизм чаще я применял в ASP.NET в случае если web приложение работает от одного пользователя, а действия в БД типа MS SQL нужно выполнить от имени другого, который работает с приложением на данный момент.
.net пример и msdn

Ok, согласен. А как это визуально выглядит для пользователя?
При использовании флага CREDUIWIN_SECURE_PROMPT в функции CredUIPromptForWindowsCredentials, для пользователя, запрос логина с паролем будет производиться в контексте UAC.

А можно с помощью такого обновлятора части пользователей выкатить новую версию, а части оставить старую? Устроить А/В тестирование, так сказать. При запросе обновления передаётся что-то, что позволяет идентифицировать пользователя?
Сейчас не передаётся, но легко добавить параметр. Например, передать ID клиента, который формируется при установке игры и в дальнейшем не меняется. А вот кто именно будет играть с этого клиента — заранее неизвестно, но, наверно, и не нужно. Можно сделать как в Стиме, где пользователь может выбрать тестовый билд игры: добавить соответствующую галочку в настройках, и наличие этой галочки передавать в запросе версии.
Sign up to leave a comment.

Articles