вторник, 24 августа 2010 г.

Отображение непечатаемых символов в SQL Server Management Studio

Чтобы включить в Management Studio отображение непечатаемых символов (пробел, табуляция), нужно присвоить значение 1 следующему ключу реестра:
HKEY_CURRENT_USER\Software\Microsoft\Microsoft SQL Server\xx\Tools\Shell\Text Editor\Visible Whitespace

Здесь xx — версия SSMS. Для 2008-ого SQL сервера имеет значение 100.

В VS, кстати, это делается комбинацией клавиш Ctrl+R, Ctrl+W.

Найдено здесь.

суббота, 21 августа 2010 г.

Visual Studio 2010: Clean command line, переменные среды

При выполнении команды Clean в C++ проекте типа Makefile project команды запускаются в некорректном окружении: cmake ругается на отсутствие необходимых переменных, nmake не доступен в PATH. Проблема известна, но предложенный workaround с ключом useenv не работает, неправильное окружение получают и команды Build и Rebuild.


Update: решение найдено. Необходимо в Clean command line добавить вызов bat-файла, устанавливающего необходимые переменные среды. Этот bat-файл используется в ярлыке Visual Studio Command Prompt (2010).

call "$(VCInstallDir)vcvarsall.bat"

set BUILD_DIR="$(ProjectDir)$(Configuration)"
set PROJECT_DIR="$(ProjectDir)..\..\.."
 
if not exist %BUILD_DIR% mkdir %BUILD_DIR%
cd %BUILD_DIR%
cmake -DCMAKE_BUILD_TYPE=$(ConfigurationName) -G "NMake Makefiles" %PROJECT_DIR%
nmake clean

Сборка log4cxx 0.10.0 в Visual Studio 2010

log4cxx версии 0.10.0, скачанный с сайта Apache, не собирается. Проблема известная и отмечена в issue tracker'е проекта. В талоне указан патч, который вносит необходимые исправления в код. В него входят некоторые лишние, на мой взгляд, файлы (log4cxx.h, log4cxx_private.h и два xml системы сборки), которые патчить не нужно. После внесения модификаций проект скомпилируется, но не слинкуется. Причина в том, что при конвертации файла проекта в новый формат были утеряны сведения о зависимостях log4cxx.dll от других библиотек.

Для конфигурации Release необходимо внести следующие изменения:

log4cxx Properties --> Configuration Properties --> Linker --> General --> Additional Library Directories


log4cxx Properties --> Configuration Properties --> Linker --> Input --> Additional Library Dependencies


Для конфигурации Debug имена директорий LibR нужно поменять на LibD.

PS: Процесс сборки описан здесь.

вторник, 17 августа 2010 г.

CMake, Visual Studio, отладка

Чтобы отлаживать проект CMake'а в студии, необходимо указать следующее в поле Command страницы Debugging свойств проекта:
$(TargetDir)$(ConfigurationName)\$(TargetName)\$(TargetFileName)

Update:Для Visual Studio 2010 путь будет другой.

$(ProjectDir)$(Configuration)\$(ProjectName)\$(ProjectName).exe

Так же имеет смысл указать Working Directory, использовав путь к исполняемому файлу. Для VS 2010:

$(ProjectDir)$(Configuration)\$(ProjectName)\

Update2: эти установки сохраняются не в файле проекта, а файле *.vcxproj.user

пятница, 13 августа 2010 г.

Исправление бага в развернутом ASP.NET приложении

Есть ASP.NET приложение, которое развернуто у заказчика. В приложении баг, развернуть новую версию быстро нельзя. Баг можно обойти, если изменить свойство наследника HttpApplication, которое задается в обработчике события Application.Start.

К счастью, у наследника оказался виртуальный метод, который можно было переопределить:
protected virtual void OnApplicationEnd(object sender, EventArgs e)
{
  Log.Debug("Application End");
}

Для этого нужно отредактировать Global.axax:
<%@ Application Codebehind="Global.asax.cs" Inherits="Triad.Server.QueryService.QueryServiceApplication" Language="C#" %>

<script runat="server">
protected override void OnApplicationStart(object sender, EventArgs e)
{
  base.OnApplicationStart(sender, e);
  // set property
}
</script>

Идея была подсказана на форуме.

вторник, 10 августа 2010 г.

CMake: интеграция с Visual Studio

Есть проект, описанный здесь, нужно интегрировать его с VS.

Структура директорий следующая:
C:\DOCUMENTS AND SETTINGS\user\DESKTOP\CMAKE_TEST
│   CMakeLists.txt
│
├───cli
│   │   CMakeLists.txt
│   │
│   └───src
│           main.cpp
│
├───core
│   │   CMakeLists.txt
│   │
│   ├───include
│   │       core.hpp
│   │
│   └───src
│           core.cpp
│           core.hpp
│
└───ide_files
    └───vs
        │   CMake_test.sln
        │
        ├───cli
        │       cli.vcproj
        │
        └───core
                core.vcproj

В студии нужно создать солюшен и добавить в него два проекта, соответствующие подпроектам CMake, подробно это описано здесь. В каждый из проектов нужно добавить соответствующие исходные файлы (правой кнопкой по проекту --> Add --> Existing Item). Но команды для сборки проекта будут другие:
set BUILD_DIR="$(TargetDir)$(ConfigurationName)"
set PROJECT_DIR="$(TargetDir)..\..\.."

if not exist %BUILD_DIR% mkdir %BUILD_DIR%
cd %BUILD_DIR%
cmake -DCMAKE_BUILD_TYPE=$(ConfigurationName) -G "NMake Makefiles" %PROJECT_DIR%
nmake all

set BUILD_DIR="$(TargetDir)$(ConfigurationName)"
set PROJECT_DIR="$(TargetDir)..\..\.."

if not exist %BUILD_DIR% mkdir %BUILD_DIR%
cd %BUILD_DIR%
cmake -DCMAKE_BUILD_TYPE=$(ConfigurationName) -G "NMake Makefiles" %PROJECT_DIR%
nmake clean all

set BUILD_DIR="$(TargetDir)$(ConfigurationName)"
set PROJECT_DIR="$(TargetDir)..\..\.."

if not exist %BUILD_DIR% mkdir %BUILD_DIR%
cd %BUILD_DIR%
cmake -DCMAKE_BUILD_TYPE=$(ConfigurationName) -G "NMake Makefiles" %PROJECT_DIR%
nmake clean

В поле Output должно быть написано core.lib для проекта core и cli.exe для проекта cli.

Исходный код здесь.

Update: Выше указаны команды сборки для проекта cli. Для проекта core необходимо изменить вторую строку:

set PROJECT_DIR="$(TargetDir)..\..\..\core"

Update1: для Visual Studio 2010 первые две и 6-ая строки должны быть другими, поскольку изменились имена встроенных переменных (пример для проекта cli):
set BUILD_DIR="$(ProjectDir)$(Configuration)"
set PROJECT_DIR="$(ProjectDir)..\..\.."
 
if not exist %BUILD_DIR% mkdir %BUILD_DIR%
cd %BUILD_DIR%
cmake -DCMAKE_BUILD_TYPE=$(Configuration) -G "NMake Makefiles" %PROJECT_DIR%
nmake all

понедельник, 9 августа 2010 г.

Как программно отключить bluetooth

rfkill block bluetooth

Управление цветом в KDE

Стандарных средств для настройки яркости и контрастности в KDE нет, поэтому придется использовать гномовский gnome-color-manager, который есть в репозиториях Ubuntu 10.04. После установки программа будет доступна в по адресу K-menu -> Приложения -> Настройка -> Цветовые профили.

Перед запуском необходимо открыть gconf-editor (через меню найти не удалось, можно запустить из командной строки Alt+F2). В нем установить в true ключ /apps/gnome-color-manager/show_fine_tuning. После запуска приложения на вкладке устройства выбрать монитор и открыть группу "Уточнение параметров", там будут ползунки яркости, контрастности и гаммы.


Чтобы восстановить настройки после запуска нового сеанса, необходимо добавить gcm-apply в автозагрузку.

Как в Ubuntu убрать стандартные папки из домашнего каталога

За стандартные папки типа "Загрузки", "Документы" отвечает пакет xdg-user-dirs. Для его настройки необходимо отредактировать файл ~/.config/user-dirs.dirs.

XDG_DESKTOP_DIR="$HOME/Desktop"
XDG_DOWNLOAD_DIR="$HOME/"
XDG_TEMPLATES_DIR="$HOME/"
XDG_PUBLICSHARE_DIR="$HOME/"
XDG_DOCUMENTS_DIR="$HOME/"
XDG_MUSIC_DIR="$HOME/"
XDG_PICTURES_DIR="$HOME/"
XDG_VIDEOS_DIR="$HOME/"

Для того, чтобы папка не создавалась при загрузке, нужно чтобы соответствующая переменная указывала на $HOME. "Desktop" вместо "Рабочий стол" удобнее в консоли. После изменения файла можно удалять папки, больши они появиться не должны.

среда, 4 августа 2010 г.

Простой скрипт для настройки iptables

Создаем файл /etc/network/if-up.d/iptables и назначаем ему права на выполнение. Скрипт рассчитан на машину, подключаемую к сети по локалке и wi-fi.

#!/bin/sh
echo "Setting iptables rules"

IPTABLES="/sbin/iptables"

# delete rules and chains
$IPTABLES -F
$IPTABLES -X

# enable everything on lo
$IPTABLES -A INPUT -i lo -j ACCEPT
$IPTABLES -A OUTPUT -o lo -j ACCEPT

for iface in eth0 wlan0
do
 # enable all established input connections
 $IPTABLES -A INPUT -i $iface -p tcp -m state --state RELATED,ESTABLISHED -j ACCEPT
 $IPTABLES -A INPUT -i $iface -p udp -m state --state RELATED,ESTABLISHED -j ACCEPT
 $IPTABLES -A INPUT -i $iface -p icmp -m state --state RELATED,ESTABLISHED -j ACCEPT

 # enable outgoing traffic
 $IPTABLES -A OUTPUT -o $iface -p tcp -m state --state NEW,RELATED,ESTABLISHED -j ACCEPT
 $IPTABLES -A OUTPUT -o $iface -p udp -m state --state NEW,RELATED,ESTABLISHED -j ACCEPT
 $IPTABLES -A OUTPUT -o $iface -p icmp -m state --state NEW,RELATED,ESTABLISHED -j ACCEPT
done

# block all other input connections
$IPTABLES -A INPUT -p tcp -j REJECT --reject-with tcp-reset
$IPTABLES -A INPUT -p udp -j REJECT --reject-with icmp-port-unreachable
 
# default policies
$IPTABLES -P INPUT DROP
$IPTABLES -P OUTPUT DROP
$IPTABLES -P FORWARD DROP

#protect from spoofing
echo 1 > /proc/sys/net/ipv4/conf/all/rp_filter

вторник, 3 августа 2010 г.

Иерархия директорий для разработки библиотеки на C++

Предположим, мы разрабатываем на C++ библиотеку и программу, ее использующую. Библиотека должна предоставлять заголовочные файлы для использования ее классов, но эти файлы не должны раскрывать внутренней иерархии директорий проекта библиотеки.

Можно использовать следующую структуру папок (проект описан в другом посте):
D:\PROJECTS\SIMPLE-THINGS\TRUNK\CMAKE_TEST
│   CMakeLists.txt
│
├───cli
│   │   CMakeLists.txt
│   │
│   └───src
│           main.cpp
│
└───core
    │   CMakeLists.txt
    │
    ├───include
    │       core.hpp
    │
    └───src
            core.cpp
            core.hpp
Примем соглашение, по которому клиент библиотеки вправе обращаться только к заголовочным файлам из папки include, а файлы в этой папке будут ссылаться на другие файлы из каталога библиотеки. Таким образом поставленная задача инкапсуляции будет решена.

Но возникает другая проблема: include guard в одноименных файлах (core.hpp в примере) может совпадать, в этом случае целевой файл не будет заинклюжен. Для этого придется принять еще одно соглашение, по которому guard во внешних файлах будет называться, например, CLASS_NAME_HPP, а во внутренних _CLASS_NAME_HPP_.

CMake: консольная программа и статическая библиотека

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

Сначала создадим необходимую иерархию директорий:
D:\PROJECTS\SIMPLE-THINGS\TRUNK\CMAKE_TEST
│   CMakeLists.txt
│
├───cli
│   │   CMakeLists.txt
│   │
│   └───src
│           main.cpp
│
└───core
    │   CMakeLists.txt
    │
    ├───include
    │       core.hpp
    │
    └───src
            core.cpp
            core.hpp
CMAKE_TEST - главный каталог проекта. Библиотека находится в папке core, сама программа - в папке cli. В каждой из упомянутых папок есть файл CMakeLists.txt, описывающий их содержимое.

CMakeLists.txt в корневой директории проекта:
cmake_minimum_required(VERSION 2.6)
project(CMAKE_TEST)

add_subdirectory(core)
add_subdirectory(cli)
Минимально необходимой для сборки проекта версией CMake является 2.6, проект называется CMAKE_TEST, это имя будет использоваться для обращения к корневой папке из подпроектов. Две команды add_subdirectory, аргументом которых являются имена папок, необходимы для указания подпроектов.

Библиотека core состоит из единственного класса, имеющего следующий вид:
#ifndef _CORE_HPP_
#define _CORE_HPP_

class Core
{
public:
  const char * say();
};

#endif

##include "Core.hpp"

const char * Core::say()
{
  return "hello";
}

Файл проекта библиотеки такой:
set(SRC src/core.cpp)
add_library(core ${SRC})

Первая строка — список исходников, вторая строка — команда на обработку библиотеки под названием core.

Основной класс библиотеки доступен с помощью заголовочного файла:
#ifndef CORE_HPP
#define CORE_HPP

#include "../src/core.hpp"

#endif

Код самой программы предельно прост:
#include <iostream>
#include "core.hpp"

int main(int argc, char **argv)
{
  Core core;
  std::cout << core.say() << std::endl;

  return 0;
}

Особый интерес представляет CMakeLists.txt этого подпроекта:
include_directories(${CMAKE_TEST_SOURCE_DIR}/core/include)
link_directories(${CMAKE_TEST_BINARY_DIR}/core)

set(SRC src/main.cpp)

add_executable(cli ${SRC})
target_link_libraries(cli core)
Команда include_directories определяет папку, где компилятор будет искать заголовочные файлы, подключаемые с помощью include, при этом переменная CMAKE_TEST_SOURCE_DIR указывает на корневую папку проекта. link_directories определяет, где искать библиотеки для линковки, CMAKE_TEST_BINARY_DIR - директория для сборки проекта. 4-ая строка задает список исходников, add_executable говорит, что будет собираться приложение cli.exe, target_link_libraries перечисляет библиотеки, с которым его нужно слинковать. Библиотека core по умолчанию будет статической.

Для сборки в корневой папки проекта необходимо создать директорию build и в ней отдать следующие команды:
cmake ..
msbuild CMAKE_TEST.sln /t:Rebuild /p:Configuration=Release

Исходный код здесь.

Установка Ubuntu 10.04 на LVM

В CD версиях дистрибутива отсутствует поддержка LVM, поэтому для установки необходим ряд дополнительных действий.

После загрузки с LiveCD необходимо установить соответствующий пакет:
sudo aptitude update
sudo aptitude install lvm2

Затем необходимо активировать группу томов (vg00):
sudo vgchange -a y vg00
Если диск не размечен под LVM, придется использовать утилиты vgcreate, lvcreate и т.д., поскольку установщик не поддерживает управление томами LVM.

После активации группы томов необходимо установить дистрибутив. Тома LVM будут доступны под именами вида /dev/<имя группы томов>/<имя тома> (например, /dev/vg00/lvhome). При этом для каталога /boot необходимо создать отдельный раздел, не находящийся под управлением LVM, иначе система на сможет загрузиться. Предположим, что этим разделом будет /dev/sda5.

В установленной на жесткий диск системе пакет LVM отсутствует, его необходимо поставить в chroot'е. Для этого необходимо подмонтировать соответствующие разделы (будем считать, что / находится на разделе /dev/vg00/lvroot)
sudo mkdir /mnt/target
sudo mount /dev/vg00/lvroot /mnt/target
sudo mount /dev/sda5 /mnt/target/boot
sudo mount -o bind /dev /mnt/target/dev
sudo mount -o bind /dev/pts /mnt/target/dev/pts
sudo mount -o bind /dev/shm /mnt/target/dev/shm
sudo mount -o bind /proc /mnt/target/proc
sudo mount -o bind /sys /mnt/target/sys

После установить пакет:
sudo chroot /mnt/target
sudo aptitude update
sudo aptitude install lvm2

Затем необходимо отмонтировать разделы в порядке, обратном порядку монтирования:
sudo umount /mnt/target/sys
sudo umount /mnt/target/proc
sudo umount /mnt/target/dev/shm
sudo umount /mnt/target/dev/pts
sudo umount /mnt/target/dev
sudo umount /mnt/target/boot
sudo umount /mnt/target/

После этого установленная система должна загружаться.