MCP

среда, 28 октября 2009 г.

Использование DefaultHttpHandler для отдачи файлов пользователю

Тут на конкурсе задали вопрос: чем отличаются Http Handlers и Http Modules. Ответов полно, дублировать их желания нет.  Всегда можно открыть MSDN и почитать про это.

Вкратце, Handler, это обработчик запроса, например, когда обращаемся на /default.aspx, в web.config ищется подходящий обработчик и ему запрос отдаётся на растерзание. Естественно, если вы поглядите в web.config для вашего приложения, вы там скорее всего такого не найдёте. Но если вспомнить иеархию конфигруационных файлов в .NET, то становится ясно, что нужно искать в базовом web.config файле. У меня он находится тут: C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\CONFIG\web.config.

Этот зверь в 30Кб, полностью описывает стандартные настройки приложения, которые можно заменить в своём. Там как раз и есть обработчик aspx-файлов:

<add path="*.aspx" verb="*" type="System.Web.UI.PageHandlerFactory" validate="true">

Собственно он и говорит рабочему процессу, что все подобные запросы должна обрабатывать фабрика с названием PageHandler (фабрика, это небольшой класс, который позволяет уже самостоятельно выбрать нужный Handler, в зависимости от более тонких условий). Также там можно найти другие интересные строчки:

<add path="*.config" verb="*" type="System.Web.HttpForbiddenHandler" validate="true"/>
...
<add path="*.soap" verb="*" type="System.Runtime.Remoting.Channels.Http.HttpRemotingHandlerFactory, System.Runtime.Remoting, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" validate="false"/>

Например, эти говорят что *.config файлы нельзя показывать (например тот же web.config), а *.soap нужно для Remoting. Естественно, все эти правила можно заменить в своём приложении, да и при этом не забыть, что сам IIS по умолчанию не все расширения отдаёт ASP.NET, и надо добавить соответствующий фильтр в  настройках вашего приложения (ну или глобальный, на все файлы).

Про Http Handler's почему-то не получилось коротко, но это я случайно.   Дальше я расскажу более интересную вещь. А пока немножко про Http Modules.

Собственно, с ними всё просто, поскольку файл мы уже открыли и видим что за httpHandlers идут httpModules. Они-то  и будут будут вызваны HttpApplication во время обработки запроса, при этом они могут сделать что-нибудь полезное не прерывая и не перенаправляя запрос. Например, разобраться с сессией, авторизацией или логгированием. Да мало ли чем, всегда их можно подключить и отключить. Например мы хотим фатальные ошибки приложения сразу отправлять админу по ICQ. Сделали модуль, подключили к нужным приложениям. Всё работает, красота.  


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

Я часто встречал реализацию в виде /getfile.ashx?id=123 — где собственный хендлер как-то пытается отдать файлы. Идея хорошая, но не очень красивая, к тому же приходится рисовать собственный хендлер, отдающий файлы, что как-то неправильно.

Небольшое отсупление, по возможности старайтесь передавать имя файла в запросе, а не через Content-Disposition, иначе будут  проблемы с русскими именами файлов, да и периодические глюки, когда у клиента имя какое-то не такое. Для этого всего-лишь нужно делать запросы вида /getfile.ashx?id=123/requiredFileName немного подправить разбор входящих параметров, а дальше браузер сам придумает как обозвать файл.

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

  • Необходим .NET Framework 3.5 SP1, потому что в предыдущих реализация данного хендлера более примитивная.
  • Файлы должны быть физически доступны из приложения, т.е. пользователь должен иметь теоретическую возможность их скачать (правда имя может быть любое и лежать они могут как хотят. Для запрета прямой скачки, делаем соответствующие правила в web.config)

Теперь, собственно, осталось придумать по какому пути пользователи будут обращаться к файлам и навесить на этот путь свой простенький хендлер, отнаследованный от DefaultHttpHandler. Можете использовать различные url-rewriting решения, или написать своё. Если вам приходится вешаться на aspx файлы, то можете в фабрике возвращать следующий Handler:

PageParser.GetCompiledPageInstance(url, null, context)

Т.е. практически вручную запустить обработку страницы (с некоторым оговорками, но не о них сейчас речь).

Далее, в своём хендлере делаем следующее:

  • В методе BeginRequest  определяем "настоящий" путь к файлу по запросу. Например, запрос, /123/myfile.jpg меняем на /files/storedFile_123.dat
  • вызываем у контекста (вам его передадут) метод: context.RewritePath с полученным путём.
  • Дальше, чтобы не отдавать запрос IIS (а для оптимизации DefaultHttphandler попробует это сделать), что-нибудь пишем в Response, например context.Response.Write(' '). 
  • Вызываем базовый метод BeginRequest

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

  • Записывает в заголовки Content-Location с настоящим именем файла, т.е. хоть и не страшно, но мы светим то, как у нас хранятся файлы, т.е. неаккуратненько как-то
  • Если он не знает расширения файла, то в целях безопасности может его и не отдать (Свойства сервера, типы MIME — тут указаны расширения, которые IIS знает)

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


Вышесказанное относится к IIS 6.0, в седьмом, возможно всё будет ещё проще, но я с ним мало работал, и в основном в классическом режиме, так что не буду ничего утверждать заранее.

вторник, 27 октября 2009 г.

Калькулятор размеров мониторов

Я как-то давно написал простенькую страничку, которая по введённой диагонали монитора и разрешению выдаёт его физический размер, dpi и соотношение сторон. Вещь на самом деле очень полезная и интересная, можно узнать, например, что:

  1. Монитор в 22" с разрешением 1920х1080 имеет по вертикали практически такой же размер как и обычная 17"-ка (1280х1024)
  2. Sony Vaio P имеет безумное разрешение в 1600x768, что даёт 222 dpi, что в 2.3 раза меньше стандартной точки (!!) Другими словами, в комплект должна идти лупа
  3. Ноутбуки в 15.4" обычно имеют разрешение 1280х800 что близко к классическим 96dpi (98 если точно)
  4. и многое другое

Надеюсь что данный скрипт поможет вам выбрать подходящий размер монитора, да и просто оценить размеры.

Пользуйтесь.

Изменение буквы системного диска в Windows

Раз уж сегодня начал активно писать в блог, то продолжу.  На этот раз не про конкурс, а небольшая заметка про то, как изменить букву диска в Windows, в случаях когда стандартными средствами (Управление Дисками) это не получается (нельзя, запрещено и так далее, в том же духе).

Стандартная ситуация, это когда при установке Windows не на основной диск система оказывается на диске D:, вместо диска C: и изменить это не получается, ибо диск системный и вообще загрузочный. Иногда подобное желание бывает и позднее (например системный диск X: а хочется сделать Y:).

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

Итак, всё просто. Открываем реестр, смотрим следующую ветку:

HKEY_LOCAL_MACHINE\SYSTEM\MountedDevices

Дальше находим ключ \DosDevices\X: — где X, это имя диска, которое нужно сменить. Ну и меняем на то, что нужно.  Потом перегружаемся и наслаждаемся жизнью или ловим проблемы с тем, что ничего не работает.

А теперь информация о том, как быстро сделать бекап, на случай поломки в данном случае. Для этого надо сделать несколько всего действий:

  1. Загрузиться из другой системы. Если её нет под рукой, замечательно подходит установочный диск от Висты или свежее. Вместо установки выбираем Recovery и открываем командную строку. Если у вас есть Far, то можете ж
    80;ть припеваючи на данном шаге.  Если нет, то работайте в консоли.
  2. Копируем все файлы (чтобы проще было) из Windows\System32\Config в любую другую подходящую папку. Там хранится реестр и журнал событий.
  3. Для надёжности копируем Documents And Settings\ntuser.dat — реестр для конкретного пользователя (в Висте и Семерке путь немного другой: Users)

Собственно, на этом всё. Для восстановления нужно проделать те же действия, только скопировать обратно. В частности, этот способ часто помогает, если нужно переустановить Windows на такой же, по причине фатального сбоя. Это поможет восстановить реестр и может быть даже всё заработает. Но очень опасный способ (с другой стороны уже всё сломано, можно и попробовать починить).

GAC

Не выдержал и решил написать ответ на вопрос про GAC для конкурса Гайдара про платформу.

Переписывать MSDN и Рихтера не буду, для разнообразия скажу своё мнение про GAC, чтобы ответ отличался от остальных.   Собственно расскажу, не про то, чем хорош GAC, а чем он плох.

Для начала в двух словах про него — это глобальный кеш сборок, и любое приложение, которое использует опредёленную сборку сначала посмотрит на её наличие в GACе, а только потом будет искать в других местах. Т.е. можно считать GAC банальным хранилищем DLLек, как Windows\System32, но с одним важным отличием. Сборки хранятся не по имении библиотеки, а по имени, Strong Name ключу, версии, культуре и платформе (x86, x64). Т.е. можно хранить разные версии сборок и даже умудряться их использовать в одном приложении (хотя лучше постараться не делать так). Т.е. GAC полезная функциональность, но есть несколько НО.

Самое главное, теряется возможность xcopy deployment, необходимо использовать gacutil или делать приличный Installer. Но если подумать, то что нужно класть в GAC? Нужно туда размещать библиотеку, которую будут использовать несколько приложений на компьютере, иначе особого смысла в этом нет. Другими словами, это должен быть конкретный shared-компонент. А кому нужен shared-компонент? Только разработчикам. Для обычных пользователей это в большинстве случаев не нужно. А разработчики очень не любят сложные процессы установки библиотек. Им бы в проект скопировать что надо, и не думать потом о библиотеках. В противном случае получается, что у разработчика может всё работать, ибо сторонняя сборка в GACe, а у клиента уже всё будет падать, ибо разработчик забыл её приложить к приложению.

Например, мой epic fail был с библиотекой Microsoft.mshtml.dll, которая оказалось что ставится со студией, и напрямую в приложении не используется, а используется через третьи библиотеки. В результате, у меня приложение работало на всех компьютерах, а половина клиентов ругалась. Конечно, я уже умный, и подобных вещей стараюсь не допускать, но вот пример как легко можно сломать приложение использованием GACа.

Собственно, если мы планируем использовать сборку в GACе, то у нас сразу усложняется разработка. Необходимо писать скрипты для билда, которые будут выковыривать сборку из GAC, компилировать новую версию и вставлять обратно. Вроде не сложно, но программисты ленивые, и обязательно что-нибудь схалтурят, и при деплое получим проблемы.  Ещё нужно обязательно использовать Strong Name, что на этапе разработки иногда плохо, ибо придётся раздавать ключ всем разработчикам (проблема в секурности), также сразу включается версионирование, которое менять нужно вручную. Иначе получатся две абсолютно разных сборки с версией 1.0.0.0, одна из которых в GAC, а вторая нужна приложению, и это вызовет замечательные проблемы, которые будет очень весело отлаживать.


Собственно, что я хотел сказать:

  • Использовать GAC нужно, когда есть проблемы с версионированием. Это позволит их решить. Например, приложение А использует библиотеки B и С. B использует библиотеку D версии 1.0.0.0, а C использует D версии 1.2.0.0. Как это это необходимо решать. Тут нужен GAC, ибо два файла с одним именем к приложению подцеплять плохо.
  • Использовать GAC нужно, когда есть много приложений, использующих одну сборку. Как вариант — хостинг многих приложений с общим компонентом. И то, может быть проще не использовать GAC, ибо места на диске не так уж и много сэкономится, а если случайно выкинут сборку из GAC, то можно получить проблемы.
  • Хороший пример того, что нужно класть в GAC — системные библиотеки .NET Framework
  • Во всех остальных случаях — не стоит. (Моё личное мнение).

.NET Remoting по протоколу SOAP. Возможно ли?

Тут @gaidar устроил конкурс и задаёт всякие разные вопросы.  В принципе, отвечать на них не планировал, ибо умные ответы писать долго и получится переписывание книжек/MSDN, а глупые можно и в Твиттере

Но, тут задали вопрос про Remoting, а это же моя любимая тема.

Собственно, Remoting может использовать любой канал, хоть голубиную почту, с сообщениями, закодированными морзянкой, этим он и отличается в лучшую сторону, но вопрос именно в том, что можно ли из подобного SOAP/Remoting сделать настоящий Web Service? Ответ сложный, с одной стороны — да, ибо можно использовать SOAP, с другой стороны, эти сообещия будут весьма страшными и заточенными под remoting-клиента, а не обычного Web-Service клиента. Собственно, проблема в том, что для веб-сервисов нужны  WSDL и XSD описания методов, а Remoting хоть и делает WSDL, но делает его для себя, и особо не смотрит на стандартные неймспейсы и типы.

Так что ответ: В принципе да. Но если вы хотите, чтобы клиентами были не только те же .NET приложения, то вам же придётся приложить множество усилий, чтобы использовать только базовые типы, не использовать CAO и эвенты, т.е. сильно урезать функционал Remoting, чтобы свести его к веб-сервисам. А оно вам надо? Гораздо проще тупо и использовать веб-сервисы для тех целей, когда они нужны, это проще и понятнее, а Remoting не использовать вовсе, не нравится он мне. 

пятница, 23 октября 2009 г.

RDC vs RAdmin/VNC

Иногда бывает нужно зайти удалённо на свой компьютер. С одной стороны стандартный RDP рулит, но он обычно создаёт новую сессию, так что получается две запущенные сессии — локальная и удалённая. А это весьма раздражает, ибо заводится весь авторан, да и задача часто бывает именно посмотреть что в конкретно творится, а не просто завести сессию.

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

Но есть простое решение с RDP, которое многие не знают, но тем не менее, оно сделано именно для таких ситуаций — залогиниться именно в локальную сессию удалённо. Делается это просто, запускается клиент с соответствующим ключом:

mstsc /console

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

mstsc /admin

Работает он также как и предыдущий.

Так что пользуйтесь, без всяких дополнительных программ, стандартные средства рулят .

четверг, 3 сентября 2009 г.

Немножко про Reflection

Недавно проверял скорость работы Reflection в плане того, насколько оно медленное. Расписывать все случаи не буду, также не буду утверждать что все замеры корректные, просто немного данных для информации, чтобы вы знали, что ожидать от Reflection:

  • Вызов метода через рефлекшен отличается в зависимости от того, является ли метод public или private
  • Для public вызов метода где-то в 100-150 (!) раз медленнее, чем обычный вызов
  • Для private вызов медленнее где-то раз в 400-500 (!). Выводы делайте сами.
  • Время на вызовы GetMethodInfo относительно невелико, при этом, похоже это всё кешируется. Так что особо оптимизировать вызовы тут смысла нет
  • Если вы точно знаете сигнатуру метода, который берёте через рефлекшен (в качестве варианта, пнуть какой-нибудь приватный метод, или при использовании какого-либо варианта плагинов), то можно воспользоваться Delegate.CreateDelegate с указанием нужного типа, получить правильный делегат и его вызов будет таким же быстрым (возможно даже чуть быстрее, есть подозрение на использование call вместо callvirt), как и прямой вызов
  • Если точно не знаете сигнатуру, то можно использовать Delegate.DynamicInvoke но производительность будет примерно такая же, как и у чистого рефлекшена
  • Если хотите использовать Expression для генерации, в частности LambdaExpression то совет тот же. Используйте чётко типизированный .Compile() и получите почти идеальную производительность (где-то 1.5, но компиляция не очень шустрая). С учётом того, что экспрешены — достаточно могучий механизм, подобное стоит использовать. Есть интересные задачи, где они могут сильно облегчить жизнь, или даже сделать что-то особенное.

Ну вот, в общем и всё. Пока для меня остаётся открытым вопрос: "Как использовать преимущества делегатов без возможности указания нужного типа напрямую", чтобы получить хорошую производительность для рефлешкена. Смотрю в сторону DynamicMethod, но это уж больно серьёзная артиллерия (хотя производительность замечательная). 

среда, 5 августа 2009 г.

Как заполнить поле в базе рандомными значениями

Небольшая напоминалка для себя на будущее, возможно кому и пригодится.

Для тестов иногда бывает необходимо заполнить поле в базе какими-нибудь левыми значениями. Проблема в том, что обычная функция RAND() при апдейте возвращает одно и тоже значение, ибо оптимизатор её оптимизирует. Собственно, из этого есть выход, заключается он в том, что в RAND() надо передавать рандомный seed в качестве параметра. Вариантов несколько, я использую такой:

UPDATE Table SET Field=RAND(abs(convert(varbinary, newid()) % 65536))*1000 

1000 — это максимальное значение в поле (точнее 999). Т.к. точность не требуется, особо над распределением не заморачивался. Пользуйтесь, если вдруг пригодится.

вторник, 28 июля 2009 г.

Windows Live Sync

По совету хорошего человека решил попробовать данную программу. Соответственно хочу поделиться краткими впечатлениями о её использовании.

Для начала, что она умеет:

  1. Выбирать папки для синхронизации и синхронизировать их между любым разумным количеством компьютеров. Т.е. вы просто кидаете туда файлы, а через некоторое время на другом компьютере они появляются.
  2. Синхронизировать файлы по запросу. В этом случае на другом компьютере появится заглушка с расширением p2p, при попытке открытия которой, будет скачан файл
  3. Загружать любые файлы с любого вашего компьютера через браузер (если разрешено).  Т.е. если вы дома забыли важный файл, теперь можно просто его снянуть через эту службу (раньше я использовал RDC/VNC для подключения к домашнему, и дальше вытягивал файлы).
  4. Расшаривать некоторые папки между выбранными пользователями. Т.е. нельзя расшарить папку для "всех" или для определённой группы. Можно только ввести email человека, которому нужно дать доступ к папке.

Теперь о том, как она это делает:

  • Необходимо залогиниться в Windows Live
  • Программа попытается открыть какой-нибудь из следующих портов: 80, 443, 6571, 8000 для того, чтобы другие компьютеры подключались напрямую к этому и забирали файлы
  • Используется шифрованное peer-to-peer соединение. Т.е. ваши файлы никуда не уходят. Сервер используется только как главное звено для обнаружения соседей.
  • Как я понял, если программа н;е смогла открыть порты, то синхронизация будет работать только в одну сторону, или же очень плохо.
  • Детали синхронизации не выяснял. Похоже файлы синхронизируются целиком. Коллизии тоже пока не рассматривал, не думаю что это очень принципиально для простого использования. Я для сложного всегда лучше самому всё протестировать, а не слушать чужое мнение.  

В общем, весьма неплохо. Конечно, хотелось бы ручного выбора портов, ибо у меня есть некоторое количество компьютеров за NAT-ом, и хотелось бы использовать синхронизацию между ними. А с учётом того, что практически доступно всего 2 порта (вы думаете у программиста есть бездействующие 80-ый и 443-ий порт? ). Так что для этого она не очень хорошо подходит.

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

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

Также, очень смущает то, что нет привязки к SkyDrive, хотя дизайн на сайтах похож, и вообще, это очень хорошо напрашивается в качестве онлайн-службы для бекапов. Ладно, можно и поискать программы, делающие из SkyDrive виртуальный локальный диск,  возможно Gladinet хорошо подойдет для этого. Кроме того, не рекомендуется синхронизировать pst-файлы и базы данных, ибо они хорошо меняются и обещают ошибки из-за этого.

Теперь о других подобных службах, я нашёл DropBox и Syncplicity. Как я понял, они пускают синхронизацию через свой сервер и хранят там файлы. Т.е. могут использоваться в качестве простенького Source Control'а, да и пофункциональнее будут. Но в них есть ограничение на объем доступной шары. после этого хотят абонентскую плату. Тут же никаких ограничений нет и файлы никуда не ходят. Да и в плане безопасности Майкрософту можно доверять (тапками не кидаться, но Майкрософту в этом плане я доверяю гораздо больше чем большинству других сервисов).

Ну, в общем-то и всё. Собственно писать про этот сервис особо нечего, он работает или не работает, никаких сложностей. Весит установочный файл всего 1.4 Мегабайта, берётся с соответствующего сайта и в принципе, может использоваться on-demand. Т.е. поставили на одном компьютере и забыли. Потом вспомнили, поставили на другом, настроили всё в браузере и давай синхронизировать. Теперь даже не нужна флешка для того, чтобы всё своё носить с собой. Можно выложить в папку и иметь на всех компьютерах одно и тоже. Лишь бы был интернет.

понедельник, 6 июля 2009 г.

Очередное российское интернет-издевательство

МОСКВА, 19 июня. /ПРАЙМ-ТАСС/. Регистрация доменных имен в зонах RU и РФ при обязательном предоставлении паспорта начнется с 1 октября 2009 г. Об этом сообщила пресс-служба регистратора RU-CENTER.

На заседании совета Координационного центра домена RU (http://cctld.ru/ru/), состоявшемся 17 июня, было принято окончательное решение о так называемой "паспортизации Рунета": теперь при регистрации доменных имен в зонах RU и РФ пользователь обязан предоставлять регистратору паспорт.

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

пятница, 19 июня 2009 г.

Прокачиваем мышь 3

Продолжение. вторая часть, первая часть.

Решил всё-таки довести затею до конца, и доделать программу, хоть до какого-то состояния.

За прошедшее с последнего поста время, я умудрился придумать куда запихать пятую кнопку ("а чо она без дела?"), и поправить некоторые неоднозначные ситуации с управлением окнами до состояния, как мне больше нравится (всякие MDI, беззаголовочные и прочие специфические окна). Про четвёртую кнопку я вроде бы всё расписал. Так что, распишу про пятую, которую я приспособил для управления музыкой (эмулируются мультимедийные кнопки клавиатуры, на которые должен уметь вешаться любой уважающий себя Winamp).


  • Нажать пятую и покрутить колесо — изменить громкость

  • Нажать пятую и среднюю — пуск/пауза

  • Нажать пятую и левую — предыдущая песня

  • Нажать пятую и правую — следующая песня


Это как бы наиболее понятные и очевидные вещи, но осталось незадействованным движение, но что туда повесить? У меня мыслей хватило только на простенькие Gestures, которые тоже эмулируют соответствующие кнопки:

  • Нажать пятую и сдвинуть влево — назад (например для браузера)

  • Нажать пятую и сдвинуть вправо — вперед

  • Нажать пятую и сдвинуть вверх — стоп (для браузера)

  • Нажать пятую и сдвинуть вниз — обновить (для браузера)


Т.е. простенькое управление браузером, для того, чтобы можно было безболезненно отказаться от четвёртой и пятой кнопки для тех, кто использует их в качестве Back/Forward в браузере. Теперь это можно делать с помощью gestures .

На этом я планирую всё-таки успокоиться и прекратить мучать мышь . Соответственно для всех желающих даю ссылку:
mouseExtender

В архиве есть версия для 64-х бит, есть версия которая изменяет только логику скролла без всех остальных действий, и версия которая использует вместо четвёртой — правую кнопку мышки + Ctrl (но она только для когда посмотреть хочется, а четвёртой кнопки нету, качество работы не гарантируется).



ЗЫ: Постепенно буду доводить до относительного ума остальные проекты, которые в полуподвешенном состоянии и которыми пользуется 3-4 человека и выкладывать их сюда, чтобы пользовалось ими 5-6 .

пятница, 24 апреля 2009 г.

Прокачиваем мышь 2

Продолжение предыдущего поста.

Креатив продолжился, и я понял, что незадействованы было движение мыши, при нажатой четвёртой кнопке. После небольшого brainstorm'а, оказалось что это действие замечательно подходит для перетаскивания окон. За любую часть! Без захвата фокуса!

Другими словами, сидите вы работаете, сзади торчит окно, и хотите вы его подвинуть, чтобы увидеть нужную информацию, но переключаться с текущего не хочется. Зажимаете четвёртую кнопку на том окне, и тащите его куда надо. Красота.

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

Из интересных моментов при написании данной программы, было замечено, что некоторые программы не реагируют на команду закрытия (WM_CLOSE), зато реагируют на команду вида "тебе на крестик нажали" (WM_SYSCOMMAND), даже если у них нет крестика.


Пока креатив иссяк, вроде бы всю кнопку замучал, и сделал всё необходимое для управления окон. Но кто его знает... Вдруг он опять появится, и я ещё что-нить придумаю. 

среда, 22 апреля 2009 г.

Прокачиваем мышь

Давно я не писал тут, ну да ладно. Не до умных технических постов было. А тут появился повод.

Повод случился вчера, когда я решил поправить функциональность стандартных драйверов Майкрософта для мышки. Вообще, на это всё меня натолкнула программа моего коллеги Vista Keys Extender. Программа весьма интересная, наверняка кому-нить будет полезная, ибо позволяет управлять окнами с клавиатуры "как в семёрке".

Но я для управления окнами уже давно использую мышку. А именно, одну из боковых кнопок (которая по дефолту "Back") переназначаю на сворачивание окна. Весьма удобная вещь для меня, — посмотрел окно, мгновенно свернул, пошёл работать дальше. Очень полезно для всякой почты/миранды и прочего, чего не требуется для постоянной работы, а является своего рода "попапами".

В стандартных драйверах мне сильно не нравились две вещи:

  • Сворачивается активное окно, а не то, над которым мышка
  • Проблемы с программами, написанными на Delphi (там очень оригинальная концепция окон, из-за чего они сворачиваются совершенно безумно, как MDI).

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

  • Отпустить: свернётся окно, находящееся под курсором
  • Покрутить колесо вниз: развёрнутое окно станет нормальным, нормальное — свернётся.
  • Покрутить колесо вверх: нормальное — развёрнется. Логично продолжить про свёрнутое, но его ведь нет . Так что нечему разворачиваться. Хотя в определённых ситуациях всё будет. Я постарался.
  • Нажать правую кнопку: свернутся все окна
  • Нажать левую: закроется текущее
  • Нажать среднюю: компьютер заблокируется

Дальше я ещё не придумал, завёл практически всё что можно на данную функцию. Конечно, остался ещё горизонтальный скроллинг, который можно завести на сдвиг окон, но он встроен только в Висту. А в XP он эмулируется драйверами. Т.е. работать будет не везде. Правда лучше чем ничего, надо будет это ещё обдумать.  

К чему я написал весь этот пост? Ну конечно же, похвастаться, как же без этого. Но также хочу обратить внимание на то, что была бы идея, а реализовать её можно просто и получить от этого удовольствие и удобство. Да и то, что мышка совершенно не используется по максимуму. На всё это у меня ушло всего пара часов, не больше. Часть времени при этом я просто потратил на идеи, а не на написание кода. Но за два часа сделать полезную, хотя бы для себя, вещь — это уже хорошо.


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

суббота, 28 марта 2009 г.

Обновление сайта с градусником

Прошло достаточно много времени с моего последнего поста про градусник. С технической точки зрения за это время ничего не изменилось, но появились некоторые усовершенствования на его сайте.

1. Добавлен график изменения температуры за месяц. 
Точнее не за месяц, а за 24 дня, но существенной разницы в этом нет. Просто ширина поля графика 576 пикселей, т.е. 24 часа * 24 дня. По пикселу на час. 

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

2. Дополнительная информация о текущей температуре.

Тут она фиолетового цвета. График весь из себя плавный и красивый. Это я ради интереса добавил текущую погоду с Гисметео, чтобы можно было убедиться в том, что мой градусник так же невероятно точен, как и у продвинутых систем (на самом деле он ещё точнее , Гисметео слишком оптимистичны).  Хотя тут видны сразу две проблемы с моим градусником. В 05:50 — тепмература сильно опустилась и градусник начал глючить (об этом уже написано). А в 9:20 — Солнце аккуратно попало на градусник и температура поехала. Надо будет собраться и попробовать перевесить его чуть правее, чтобы его получше закрывало от солнца. Хотя после перевода часов, проблема уедет на час, так что будет не так критично .
Хотя чего я всё заладил про Гисметео. Буквально с сегодняшнего дня данные идут от HMN, ибо они обновляются чаще и оперативнее. Но это уже детали, погоду, по идее, они берут из одних источников.

3. Web Slices.
Ну и напоследок маленькая фишка для пользователей восьмого Интернет Эксплорера. Теперь есть поддержка Веб-Слайсов, и можно добавить на панель браузера "обновлябельный" погодный сайт. Если вы уже пользуетесь восьмеркой — рекомендую добавить . А если нет, то рекомендую поставить, ибо браузер весьма и весьма симпатичный (хотя отмечу, что у некоторых людей он конкретно глючит, причём не ясно от чего).

пятница, 20 марта 2009 г.

Немного расчётов про Оперу

По статистике в мире доля Оперы 0.7%. В России 31%.

Берём калькулятор в руки и считаем. Получаем, что если Оперой пользуются только в России, то в России находится всего 2.2% пользователей всего интернета.

Берём статистику, например из Википедии. Получаем, что пользователей интернета в России 2.4% от общего количества. Получаем маленькую нестыковочку. 

Ещё раз в цифрах. В России пользуются Оперой 38 000 000 * 31% = 12 920 000 человек. В мире же пользуются Оперой "всего" 1 581 571 589 * 0.7% = 11 071 000.

Другими словами, в России есть почти 2 млн. человек, которые пользуются двумя Операми, и это с учётом того, что больше в мире ей никто не пользуется.

Сдаётся мне, что кто-то пизд лукавит в статистике. И я очень сомневаюсь, что это делают в России.

среда, 18 марта 2009 г.

Opera Turbo

Ну вот, стоило сделать свою версию сжимающей прокси (кстати, большинство удалось побороть за 10 минут, оказалось, что была бага, которую я правил-правил и не доправил), как норвежцы прочитали мой пост и сделали Opera Turbo.

В общем, идея та же самая, но на более глобальном уровне, со сжатием картинок, блекджеком и шлюхами. Благодаря тому, что это напрямую встроили в браузер, сразу же появятся вкусные фишки (например, релоад картинки загрузит её уже в хорошем качестве).

Вообще, думаю что в Опере нашли ту самую killing-feature, которая позволит им прорекламироваться. Не думаю, что кто-то ещё сможет провернуть подобное. Возможно только Гугл с хромом, но не думаю, что им это нужно будет.




Эх, чтобы ещё такого сделать, чтобы в Опере тут же реализовали в 10 раз лучше...

пятница, 6 марта 2009 г.

Proxy

Жизнь течёт, изменяется, но по-прежнему сохраняется потребность в проксе, хотя казалось бы, интернет шустреет, и зачем оно таки надо?  

Достаточно давно, когда интернет у меня был практически только по диалапу (на работе, правда более или менее приличный, но не шустрый), я написал какую-то безумную проксю с совершенно извращённым кешированием. А именно, она кешировала все картинки намертво, CSS и JavaScript, вроде бы тоже. Страничики тоже кешировались, но слава богу обновлялись, иногда.  Как результат, было удобно смотреть сайты в браузере без интернета (ибо раз нельзя достучаться, результат выдавался из кеша), да и трафик был слегка меньше.

Естественно, всё слегка глючило, кеш портился, да много чего было. Но тогда я разобрался в принципах работы HTTP через прокси, написал свою файловую систему для кеша, проработал механизмы блокировки URL'ов с баннерами. Часть из всего этого пригодилась в дальнейших проектах. Да и урощённый движок прокси тоже активно использовался в одном из них.

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

Потом, конечно, пошли доработки, в которых я выяснил, что встроенное в .NET сжатие GZip — это унылое говно, которое использовать нужно только по необходимости. В других же случаях гораздо лучше использовать #ziplib, мало того, что жмёт на порядок лучше, так ещё и работает быстрее! Кто там говорил, что в Майкрософте воруют код? Да ничего подобного! Если бы они это делали, они бы не написали такой отстой. Сжатие BZip2 было реализовано, но исключено по причине того, что оно раз в 10 медленнее GZip (точнее Deflate, но это уже тонкости структуры результирующего потока), а результаты в большинстве случаев не лучше. LZMA (7z) — результаты давал ненамного лучше, то скорость у него вообще отвратительная. Были ещё варианты сжатия по заранее заданному словарю, но пока на них забил из-за сложностей в реализации (хотя прирост сжатия должен быть весьма и весьма хорош). Добавил простенькое кеширование, чтобы не перегружать заново некоторые страницы (они реально перегружаются, но если результат такой же, то он не отправляется). Также сделал повторное использование TCP-соединений, чтобы уменьшить их количество и соответственно трафик.

Результаты оказались в принципе достаточно неплохие. Сжатие в зависимости от условий использования вполне может составлять 50% (в принципе, при некоторых сценариях и все 35% от исходного объёма). Заодно выяснил, что некоторые серверы плюют на робкие попытки прокси попросить закрывать соединение после отсылки данных (пришлось закрывать самостоятельно). Ну и конечно, всё периодически глючит, как же без этого.

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

Конечно же, можно было бы взять что-нибудь готовое, но это совершенно неинтересно. Написать что-нибудь самому, очень полезно для развития. При этом, как я уже писал, с оценкой времени всё туманно, так что как оценить пользу/вред от этого совершенно непонятно.