Tkabber Wiki

Config dir
Login

Config dir

Материал из Tkabber Wiki

Внимание! реализация механизмов, обсуждаемых здесь, интегрирована в транк Ткаббера начиная с ревизии 859 (05 янв 2007). Реализованный механизм изложен ниже.

Также был обновлён раздел #4 "Configuration" документации Ткаббера — читайте tkabber.html на своей системе.

Содержание

Введение

Обсуждение новой схемы поддержки каталога конфигурации Ткаббера.

Идея: отказаться от схемы ~/.tkabber в Windows по причине того, что при существующей схеме каталог конфигурации на любой Windows-системе оказывается не там, где предполагается хранить конфигурацию на данной системе.

Конкретно нас интересует т.н. каталог "application data" ("appdata"). Предполагается хранить настройки Ткаббера в подкаталоге "Tkabber" этого каталога.

Получить путь каталога "appdata" можно тремя способами:

Инфа по системам

(TODO): 95? ME?

Проблемы

Наиболее разумным представляется вызов SHGetSpecialFolderPath, однако это не самый простой путь:

Путь с реестром и окружением не имеет такой "идеологической чистоты", как вызов SHGetSpecialFolderPath.

Рабочий вариант

При старте:

Вопросы:

Juriks, посовещавшись с kostix, предлагает: Запускать несколько Ткабберов с разными настройками с помощью таких вот скриптов:

@echo off
set TKABBER_HOME=c:\home\vasya_pupkin
start tkabber.exe

То есть искать папку с конфигами в таком порядке:

  1. переменная окружения TKABBER_HOME
  2. реестр
  3. прочие переменные оружения

kostix комментирует: реализованный в альфе Ткаббера вариант сначала ищет переменную окружения APPDATA, и только в случае неудачи смотрит реестр. Причины простые:

Добавка про SHGetSpecialFolderPath

SHGetSpecialFolderPath «замещена» процедурой SHGetFolderPath начиная с w2k, хотя и доступна на всех системах. Для нас это ничего не значит, так как нам для совместимости со старыми OS необходимо использовать старую версию.

На современных системах SHGetSpecialFolderPath реализована в shell32.dll. Также эта функция содержится в redistributable library SHFolder.dll, которая может включаться в поставку продукта и худо-бедно работать на любой OS. Starpack это, пожалуй, не спасёт, а вот Pack и выше может спокойно её использовать.

Тестовая реализация SHGetSpecialFolderPath через Ffidl

Скрипт

Скрипт, печатающий путевое имя каталога "application data" в Windows.

Создаваемая команда Tcl "SHGetSpecialFolderPath" способна возвращать имя любого стандартного каталога Windows (заданного соотв. ключом "CSIDL_...").

В случае неуспеха команда возвращает пустую строку.

#! /usr/bin/tclsh

package require Ffidl

ffidl::callout dll_SHGetSpecialFolderPath \
  {int pointer-utf16 int int} int \
  [ffidl::symbol shell32.dll SHGetSpecialFolderPathW]

proc SHGetSpecialFolderPath {what create} {
  array set CSIDL {
    CSIDL_DESKTOP	0
    CSIDL_INTERNET  1
    CSIDL_PROGRAMS	2
    CSIDL_CONTROLS	3
    CSIDL_PRINTERS	4
    CSIDL_PERSONAL	5
    CSIDL_FAVORITES	6
    CSIDL_STARTUP	7
    CSIDL_RECENT	8
    CSIDL_SENDTO	9
    CSIDL_BITBUCKET	10
    CSIDL_STARTMENU	11
    CSIDL_DESKTOPDIRECTORY	16
    CSIDL_DRIVES	17
    CSIDL_NETWORK	18
    CSIDL_NETHOOD	19
    CSIDL_FONTS	20
    CSIDL_TEMPLATES	21
    CSIDL_COMMON_STARTMENU	22
    CSIDL_COMMON_PROGRAMS	23
    CSIDL_COMMON_STARTUP	24
    CSIDL_COMMON_DESKTOPDIRECTORY	25
    CSIDL_APPDATA   26
    CSIDL_PRINTHOOD 27
    CSIDL_LOCAL_APPDATA 28
    CSIDL_ALTSTARTUP    29
    CSIDL_COMMON_ALTSTARTUP	30
    CSIDL_COMMON_FAVORITES	31
    CSIDL_INTERNET_CACHE   32
    CSIDL_COOKIES	33
    СSIDL_HISTORY	34
    CSIDL_COMMON_APPDATA	35
    CSIDL_WINDOWS	36
    CSIDL_SYSTEM	37
    CSIDL_PROGRAM_FILES	38
    СSIDL_MYPICTURES	39
    CSIDL_PROFILE	40
    СSIDL_SYSTEMX86	41
    CSIDL_PROGRAM_FILESX86	42
    CSIDL_PROGRAM_FILES_COMMON	43
    СSIDL_PROGRAM_FILES_COMMONX86	44
    CSIDL_COMMON_TEMPLATES	45
    CSIDL_COMMON_DOCUMENTS	46
    CSIDL_COMMON_ADMINTOOLS	47
    CSIDL_ADMINTOOLS	48
    CSIDL_CONNECTIONS	49
    CSIDL_COMMON_MUSIC	53
    CSIDL_COMMON_PICTURES	54
    CSIDL_COMMON_VIDEO	55
    CSIDL_RESOURCES	56
    CSIDL_RESOURCES_LOCALIZED	57
    CSIDL_COMMON_OEM_LINKS	58
    CSIDL_CDBURN_AREA	59
    CSIDL_COMPUTERSNEARME	61
    CSIDL_FLAG_DONT_VERIFY	0x4000
    CSIDL_FLAG_CREATE	0x8000
    CSIDL_FLAG_MASK	0xFF00
  }

  set bCreat [expr {$create ? 1 : 0}]

  set path [string repeat \u0000 300] ;# MAX_PATH is actually 260

  set ok [dll_SHGetSpecialFolderPath 0 $path $CSIDL($what) $bCreat]

  if {$ok} {
    set ix [string first \u0000 $path]
    if {$ix > 0} {
      return [string range $path 0 [expr {$ix - 1}]]
    }
  } else {
    return {}
  }
}

puts "appdata: [SHGetSpecialFolderPath CSIDL_APPDATA false]"

Запускать следует через tclsh, например, так:

C:\> tclsh sh.tcl

wish не имеет открытого канала stdout и puts там ничего интересного не делает.

Можете так же поменять последнюю строку (с puts) на

tk_messageBox -message [SHGetSpecialFolderPath CSIDL_APPDATA false]

и запускать скрипт "просто", например, двойным щелчком мышью на его файле в Explorer.

Замечания

Вписал статью в тиклевое вики.

ANSI (8-bit) vs Unicode (UTF-16)

В любом случае, ANSI версия используется так:

ffidl::callout dll_SHGetSpecialFolderPath \
  {int pointer-utf8 int int} int \
  [ffidl::symbol shell32.dll SHGetSpecialFolderPathA]

Реализация в Ткаббере

Потребует более серьёзного подхода: