Комментарии 58
все гениальное просто :)
спасибо, возьму на заметку
спасибо, возьму на заметку
0
а что будет, если файл создан, но продолжает, скажем, загружаться?
+7
Хороший вопрос. Я это предусмотрел — в обработчике FileSystemWatcher файл пытается открыться на чтение. Если он еще загружается — получаем эксепшен(виндовая ошибка ERROR_SHARING_VIOLATION). Прога уходить в слип на секунду, после чего пытается еще раз открыть ну и т.д. Если за установленое количество попыток ничего не получилось — оставляем архив в покое, пусть кто-нибудь другой разбирается. Для себя количество попыток я установил до дури(int.MaxValue), вы можете поставить другое значение.
Собственно код вы можете найти в функции WatcherHandler
И в утилитном класс IOUtils, там, правда, немного мутно из-за необходимости отличать ERROR_SHARING_VIOLATION в IOException от остальных ошибок доступа.
Собственно код вы можете найти в функции WatcherHandler
IOUtils.WrapSharingViolations(() => { using (File.OpenRead(file));}, null, int.MaxValue, 1000);
* This source code was highlighted with Source Code Highlighter.
И в утилитном класс IOUtils, там, правда, немного мутно из-за необходимости отличать ERROR_SHARING_VIOLATION в IOException от остальных ошибок доступа.
+6
Там бы еще неплохо многопоточную обработку вотчера прикрутить, чтобы не подвисало в ожидании закачки, но пока пользователей(а пока пользователь только я=)) все и так устраивает.
+1
А вызовы раз в секунду не слишком грузят компьютер?
И еще: с запароленными архивами проблем нет?
И еще: с запароленными архивами проблем нет?
0
как происходит распаковка, когда в архиве запакована папка?
папки в папке не будет?
папки в папке не будет?
0
как происходит распаковка, когда в архиве запакована папка?
Ну если в архиве лежит папка, то будет в результате папка с подпапкой — имя_архива/имя_подпапки. Так же, как если через контекстное меню распаковать.
+1
Надо еще сделать так, чтобы он удалял архив после распаковки. Т.е. запаковываешь что-нибудь в архив, а оно распаковывает обратно, да еще и архив сносит)) Прекрасное издевательство над пользователями.
+1
Надо еще сделать так, чтобы он удалял архив после распаковки.
Я думал над этим, но с другой стороны кому-то может понадобиться сохранить архив. Например я скачал архив с исходниками, поковырялся с ними и грохнул папку, а архив остался на всякий случай, если снова к ним вернусь. Думаю, может вынести это опцией, но по умолчанию лучше оставлять — удаление операция опасная ввиду нетранзакционности файловой системы на большинстве десктопов.
+2
главное не скачивать рекурсивные архивы
или предусмотрена какая-нибудь защита?
или предусмотрена какая-нибудь защита?
+3
Боюсь, что защиты нет. Я думал над этим — можно считать хэш-архива и запрещать повторную распаковку, но в некоторых случаях это будет багом для пользователя. Еще можно проанализировать структуру архива на предмет наличия таких бомб, но это уже совсем другой уровень сложности, может позже, когда будет время и желание покопаться в разных форматах архивов. Ну или отказаться от автораспаковки вложенных архивов.
0
распаковка во вложенную папку? во вложенных папках архивы не распаковывать?
После распаковки в альтернативный поток добавлять метку о том что файл распакован автоматом и больше не распаковывать
После распаковки в альтернативный поток добавлять метку о том что файл распакован автоматом и больше не распаковывать
0
во вложенных папках архивы не распаковывать?
Ну я об этом и написал «Ну или отказаться от автораспаковки вложенных архивов.». Но опять же, в нормальной работе(где мы не скачиваем рекурсивные архивы), это может считаться недостатком.
После распаковки в альтернативный поток добавлять метку о том что файл распакован автоматом и больше не распаковывать
Хм. Так я же и написал про «запрещать повторную распаковку». Это может быть плохой вариант — например, я скачал архив, он распаковался, все хорошо. Прошло полгода, я обо всем забыл, заново качаю архив, но в другую папку(которая тоже мониторится). У меня ничего не распаковалось — я пишу разработчику багу. Можно, конечно, ограничить время жизнь хранения хэша архива — например один час. Но все равно, потенциально проблема есть.
0
Я слишком поздно понимаю, чем мне знакомо это разноцветье.
Глубина-глубина…
Слишком поздно.
Дип-программа накрывает меня, и увернуться нет сил.
Глубина-глубина…
А полотнище все полыхает, не собираясь гаснуть, как положено честной, законопослушной дип-программе…
Глубина-глубина…
Я ныряю все глубже, я падаю в эту цветную пропасть, в бесконечную череду фальшивых отражений, в цветной лабиринт, в безумие и беспамятство.
На моей машине нет таймера, и никто не придет к моей двери со своим ключом.
Глубина-глубина…
Я не могу выныривать с такой скоростью, с какой затягивает цветной водоворот!
Глубина-глубина...
+1
В ОС основанных на ядре Linux это делается так:
1. Устанавливаем unp и убеждаемся в наличии inotify.
2. Запускаем из необходимых каталогов следующий скрипт (не тестировалось):
while true; do
inotifywait -e modify -e moved_to -e create "`pwd`"
unp *
sleep 10 # Во избежание убивания процессра постоянной попыткой распаковать качающийся файл.
done
В других *nix inotify заменяется на имеющееся средство, либо на кроссплатформенную обёртку FAM.
1. Устанавливаем unp и убеждаемся в наличии inotify.
2. Запускаем из необходимых каталогов следующий скрипт (не тестировалось):
while true; do
inotifywait -e modify -e moved_to -e create "`pwd`"
unp *
sleep 10 # Во избежание убивания процессра постоянной попыткой распаковать качающийся файл.
done
В других *nix inotify заменяется на имеющееся средство, либо на кроссплатформенную обёртку FAM.
+2
Плюс сервиса в автозагрузке и подъеме системой в случае падения. Ну и к сессии пользователя они не привязаны. Я конечно еще тот знаток никсов, но мне казалось, что если проводить аналогию, это должен быть демон, прописанный в /etc/rc.local и кроновская таска, которая будем за ним следить, поднимая когда он упадет, разве нет? Ну и с точке зрения использования, мне было бы удобнее прописать пути в одном конфиге, чем запускать скрипт из нескольких папок.
Опять же, возможно я не прав, но разве эта команда — unp * — не будет каждый раз, когда мы скачаем новый архив, перераспаковывать заново все уже существующие архивы в папке?
Опять же, возможно я не прав, но разве эта команда — unp * — не будет каждый раз, когда мы скачаем новый архив, перераспаковывать заново все уже существующие архивы в папке?
+1
«Плюс сервиса в автозагрузке и подъеме системой в случае падения.»
Что-то я не замечал за windows-сервисами подобного. Обычно если он лег, то он лег, и система его не перезапускает.
Что-то я не замечал за windows-сервисами подобного. Обычно если он лег, то он лег, и система его не перезапускает.
-1
Я же говорю — не тестировалось. :)
Возможно надо делать так:
files="*.{zip,rar,tar*, и т.д.}
unp $files
rm $files # или mv $files unpacked/
> если проводить аналогию
Зачем делать сложно если ту же задачу можно решить просто? Да, я понимаю что автру возможно захотелось поупражняться в написании служб на C#.
Возможно надо делать так:
files="*.{zip,rar,tar*, и т.д.}
unp $files
rm $files # или mv $files unpacked/
> если проводить аналогию
Зачем делать сложно если ту же задачу можно решить просто? Да, я понимаю что автру возможно захотелось поупражняться в написании служб на C#.
0
По поводу простоты — там в проекте лежит и консольное приложение — запускай и все. А если начать вешать доп. требования — автозапуск, настройка из одного места, параллельная распаковка, защита от рекурсивных архивов — то решение сразу усложнится и возможно написать его на том же питоне/C#/Lisp/ваш_любимый_язык_программирования и оформить демоном будет проще.
0
Я тут еще подумал
Вот эта штука будет реагировать на создание/изменению любых файлов, что не очень хорошо: я создал текстовый файл — у меня пошли распаковываться все архивы в папке. А еще в скрипте вложенные архивы не обрабатываются.
inotifywait -e modify -e moved_to -e create "`pwd`"
Вот эта штука будет реагировать на создание/изменению любых файлов, что не очень хорошо: я создал текстовый файл — у меня пошли распаковываться все архивы в папке. А еще в скрипте вложенные архивы не обрабатываются.
0
Вообще замечательная вещь, как правило во время закачки архвам присваивается временное расширение типа *.!ut так что использование его не так страшно, но все таки хотелось бы защиты от ошибок.
Будет ли данный сервис дорабатываться? Хотелось бы еще опцию автоудаления (если ее нет).
Удачи автору в начинании :)
Будет ли данный сервис дорабатываться? Хотелось бы еще опцию автоудаления (если ее нет).
Удачи автору в начинании :)
0
Будет ли данный сервис дорабатываться?Будет, если это будет кому-то нужно.
Хотелось бы еще опцию автоудаления (если ее нет).Сейчас залил новую версию и исходники по мотивам(ссылка в статье):
- Добавлена опция автоудаления. По умолчанию автоудаление отключено.
[Options]
Autodelete = yes - Сделана многопоточная обработка — если скачалось много архивов, они начинают распаковывать параллельно.
- Сделана простая защита от рекурсивных архивов — если архив распакован, повторная распаковка может быть запущена только через 10 минут.
+1
По-хорошему бы батник копировал файлы куда надо еще… а то я вижу что он сейчас только устанавливает сервис из текущей папки
0
А куда надо? Я могу и инсталлятор сделать, если нужно.
Мне кажется это лишним. Программа должна работать незаметно для пользователя. Я скачал архив — пошел в папку — посмотрел содержимое. А так, что-то всплывает, мигает, рассказывает о своих ошибках и успехах, забирает фокус — мне такие программы не очень нравятся.
Ну это можно =) Изначально параметры не стал выносить, т.к. хотелось сделать конфиг простым.
Прогресс бар бы все таки не помешал, или хоть какоето оповещение: Началась распаковка, Успешно распакован, Ошибка, и т.д.
Мне кажется это лишним. Программа должна работать незаметно для пользователя. Я скачал архив — пошел в папку — посмотрел содержимое. А так, что-то всплывает, мигает, рассказывает о своих ошибках и успехах, забирает фокус — мне такие программы не очень нравятся.
И да, еще, [WinRar] это както не правильно :) Заменить бы на [Архиватор] и в том же разделе указывать параметры было бы неплохо
Ну это можно =) Изначально параметры не стал выносить, т.к. хотелось сделать конфиг простым.
+1
Ну хотя бы ведение лога опять же опционально, вместо оповещения…
И в том архиве что поставляется хорошо бы указать все возможные параметры с комментариями. Не нашел где указать Extentions в Options?
И почемуто с 7zip не работает на Win 7 x64
И в том архиве что поставляется хорошо бы указать все возможные параметры с комментариями. Не нашел где указать Extentions в Options?
И почемуто с 7zip не работает на Win 7 x64
0
Extentions указывается так
Но вы правы, перенесу в Options.
Все замечания завтра постараюсь поправить.
[Extentions]
rar,zip,7z
Но вы правы, перенесу в Options.
И в том архиве что поставляется хорошо бы указать все возможные параметры с комментариями.ok
И почемуто с 7zip не работает на Win 7 x64Ну наверно потому, что параметры командной строки не подходят. Секция называлась [WinRar] не спроста — я, ибо ленивый, дал возможность только указать место, где лежит winrar.
Все замечания завтра постараюсь поправить.
+1
Прогресс бар бы все таки не помешал, или хоть какоето оповещение: Началась распаковка, Успешно распакован, Ошибка, и т.д.
0
«кстати, кто-нибудь может мне ответить, почему я могу создавать/удалять сервисы только через командную строку?»
Никто не может вам ответить, потому что это неправда. В .net есть специальный компонент для этого, который автоматически создается в проекте при создании проекта сервиса. И в msdn про это написано.
Никто не может вам ответить, потому что это неправда. В .net есть специальный компонент для этого, который автоматически создается в проекте при создании проекта сервиса. И в msdn про это написано.
0
В .net есть специальный компонент для этого, который автоматически создается в проекте при создании проекта сервиса
Вы не правильно поняли вопрос. Я спрашиваю почему в консоли services.msc я не могу создать или удалить сервис, хотя могу сделать это через командную строку.
0
Потому что незачем, если коротко. Установить сервис — задача того, кто его поставляет.
+1
Надеюсь, что уловил суть вопроса. Возможно, нужно только дописать класс инсталлера. Если хотите создать установшик — вот руководство: wladm.narod.ru/C_Sharp/services.html
Кратко: в проект дописать класс инсталлера
добавить к решению проект типа Setup Project, контекстное->View->Custom Actions; для Install и Uninstall через их контекстное меню выполняем пункт Add Custom Action и указываем System Folder, проследить, чтобы свойство Installer Class у этих Custom Action было выставлено в True.
Кратко: в проект дописать класс инсталлера
using System.ComponentModel;
using System.Configuration.Install;
using System.ServiceProcess;
namespace AE.Service
{
[RunInstaller(true)]
public partial class ExtractorServiceInstaller : Installer
{
public ExtractorServiceInstaller()
{
var serviceProcessInstaller =
new ServiceProcessInstaller
{
Account = ServiceAccount.LocalSystem,
Username = null,
Password = null
};
var serviceInstaller =
new ServiceInstaller
{
ServiceName = "My Windows Service",
DisplayName = "My New C# Windows Service",
StartType = ServiceStartMode.Automatic
};
Installers.AddRange(new Installer[] { serviceProcessInstaller, serviceInstaller });
}
}
}
* This source code was highlighted with Source Code Highlighter.
добавить к решению проект типа Setup Project, контекстное->View->Custom Actions; для Install и Uninstall через их контекстное меню выполняем пункт Add Custom Action и указываем System Folder, проследить, чтобы свойство Installer Class у этих Custom Action было выставлено в True.
0
Да нет, я знаю как сделать установщик. Батник я сделал потому что:
1) Так было проще
2) Хотел показать(может кто не знает), как пользоваться sc.
А вопрос был про то, как мне уже существующие сервисы, как админу, удалить с компа.
Ну во-первых раз у меня возник этот вопрос, значит case есть. Во-вторых, если «задача того, кто его поставляет», чего же тогда в sc у меня есть возможность снести или добавить любой сервис, который мне не нравится? По сути я говорю об отсутствии UI к команде sc(вернее к тому API, который она дергает).
1) Так было проще
2) Хотел показать(может кто не знает), как пользоваться sc.
А вопрос был про то, как мне уже существующие сервисы, как админу, удалить с компа.
Потому что незачем, если коротко. Установить сервис — задача того, кто его поставляет.
Ну во-первых раз у меня возник этот вопрос, значит case есть. Во-вторых, если «задача того, кто его поставляет», чего же тогда в sc у меня есть возможность снести или добавить любой сервис, который мне не нравится? По сути я говорю об отсутствии UI к команде sc(вернее к тому API, который она дергает).
0
Ну так через установщик можно и удалить.
+1
«Ну во-первых раз у меня возник этот вопрос, значит case есть.»
0
«Ну во-первых раз у меня возник этот вопрос, значит case есть.»
Вот для него и есть sc.
«По сути я говорю об отсутствии UI к команде sc(вернее к тому API, который она дергает). „
Не на всякую чисто административную (и редко используемую) команду есть UI. Это, в среднем, нормально (да, даже в Windows).
Типовое поведение: поставить сервис через инсталлятор, снести через деинсталлятор. Если по типовому сценарию не прошло — тогда есть sc.
Вот для него и есть sc.
«По сути я говорю об отсутствии UI к команде sc(вернее к тому API, который она дергает). „
Не на всякую чисто административную (и редко используемую) команду есть UI. Это, в среднем, нормально (да, даже в Windows).
Типовое поведение: поставить сервис через инсталлятор, снести через деинсталлятор. Если по типовому сценарию не прошло — тогда есть sc.
0
Не на всякую чисто административную (и редко используемую) команду есть UI. Это, в среднем, нормально (да, даже в Windows).Я считаю это вопрос концептуальной целостности. Через services.msc я могу остановить сервис, я могу изменить ему права, я могу сделать так, чтобы он никогда больше не запустился. Вроде как центральная точка управления службами. Но для удаления я должен пользоваться деинсталятором(который мне снесет весь пакет продукта, а не только сервис) либо лезть в командную строку.
0
«Вроде как центральная точка управления службами. „
Установленными.
“Но для удаления я должен пользоваться деинсталятором(который мне снесет весь пакет продукта, а не только сервис)»
Да, именно так. Потому что только деинсталлятор знает, что будет, если вы снесете только сервис, а все остальное оставите.
Установленными.
“Но для удаления я должен пользоваться деинсталятором(который мне снесет весь пакет продукта, а не только сервис)»
Да, именно так. Потому что только деинсталлятор знает, что будет, если вы снесете только сервис, а все остальное оставите.
0
Выслал пример вам личкой
0
А как решена проблема setup.exe и других подобных имен файлов, часто встречающихся в архивах?
0
Простите, о какой проблеме идет речь?
0
Наверное речь идет о том, что в папке распаковки может оказаться два архива, в которых могут лежать файлы с одинаковым именем и расширением, но реально содержащих разные данные.
Ну и при автоматической распаковке файл из одного архива будет затерт файлом из другого.
Ну и при автоматической распаковке файл из одного архива будет затерт файлом из другого.
0
Хм. А зачем понадобились ini-файлы в 2011 году? Чем стандартный App.config не устроил? :)
0
Когда же обновление? :)
0
Зарегистрируйтесь на Хабре, чтобы оставить комментарий
Упрощаем жизнь: сервис автораспаковки архивов на C#