Страница 1 из 2

Как в *.wcx узнать путь к Wincmd.ini?

Добавлено: Вт апр 26, 2005 17:03
vserd
1. Есть архиваторный плугин.
Как в *.wcx узнать путь к Wincmd.ini?

2. Есть несколько копий Тотала, у которых разные файлы настроек. (заданы через параметры командной строки)
Как в *.wcx узнать путь к Wincmd.ini в данной копии?

Должна же быть какая-то возможность?
Варианты решения подходят как на C++ так и на Delphi

Добавлено: Вт апр 26, 2005 17:06
Parcan
vserd

поищи в этой ветке помоему было обсуждение алгоритма и даже с примерами.

Добавлено: Вт апр 26, 2005 17:36
vserd
А в какой конкретно (или приблизительно)?
Я посомтрел на заголовки тем, ничего "завлекательного" не нашел. :(
А читать все темы подряд не очень хочется. времени на разработку плугина не очень много, так что на 90% мусора время тратить не хочется.

Добавлено: Ср апр 27, 2005 23:50
D1P

Добавлено: Чт апр 28, 2005 12:19
vserd
D1P
:(((
темы которую вы запросили не существует
видно вся проблема в русских буквах. Что там должно быть?

Добавлено: Пт апр 29, 2005 01:32
SCHMaster
vserd
Да не морочь голову. Если ини-файл указан в параметрах запуска, то спокойно его получаешь через ParamStr

Добавлено: Пт апр 29, 2005 11:42
vserd
SCHMaster
Если ини-файл указан в параметрах запуска, то спокойно его получаешь через ParamStr
хм. Я почему-то считал и считаю что ParamStr для Dll (wcx) не соответствует тому что передается в EXE

Добавлено: Сб апр 30, 2005 01:59
SCHMaster
vserd
Ага... А твоя DLL в чьем адресном пространстве находится? Ес-сно какой-нить программы :). Неверишь - проверь :)

Добавлено: Вс май 01, 2005 10:14
D1P
vserd писал(а):D1P
:(((
темы которую вы запросили не существует
видно вся проблема в русских буквах. Что там должно быть?
Поищи по форуму, там такая тема уже поднималась (на неё и ссылка была), всё обсосали до последней косточки.

Модераторам: неплохо бы сходные темы объединять во избежание замусоривания.

Добавлено: Пн май 02, 2005 07:29
TSergey
D1P писал(а):
vserd писал(а):D1P
:(((
темы которую вы запросили не существует
видно вся проблема в русских буквах. Что там должно быть?
Поищи по форуму, там такая тема уже поднималась (на неё и ссылка была), всё обсосали до последней косточки.

Модераторам: неплохо бы сходные темы объединять во избежание замусоривания.
Та тема, в которой все обсасывалось - удалена.
Правда не понятно почему.

Добавлено: Пн май 02, 2005 07:35
TSergey
Вот как сделал я. (Для поиска wcx_ftp.ini)

Код: Выделить всё

function GetFtpIniFileName: string;
var
  s, s1, s2 :string;
  a: array [0..MAX_PATH] of char;
  i, j: integer;
  EscEn, QuoteStr, UseProgDir: boolean;
  c: char;
  reg: TRegistry;
begin
  if FTPIniFileName <> '' //Проверяем кэш (FTPIniFileName - глобальная переменная)
  then begin
    Result := FTPIniFileName;
    exit;
  end;

  // Разбор командной строки
  s := StrPas(GetCommandLine);

  i := pos('f=', s);
  if i  = 0 then  i := pos('F=', s);

  s1 := '';

  if i > 0
  then begin
    i := i + 2;
    EscEn := false;
    QuoteStr := false;
    j := length(s);
    // Разворачиваем параметр с поддержкой кавычек
    while (i <= j) do
    try
      c := s[i];
      case c of
        #9, ' ':
          if QuoteStr
          then if EscEn
            then begin
              s1 := s1 + '\'+ c;
              EscEn := false;
            end
            else s1 := s1 + c
          else break;

        '"':
          if EscEn
          then s1 := s1 + '"'
          else QuoteStr := not QuoteStr;

        '\':
          if EscEn
          then begin
            s1 := s1 + '\';
            EscEn := false;
          end
          else EscEn := true;

        else if EscEn
          then begin
            s1 := s1 + '\'+ c;
            EscEn := false;
          end
          else s1 := s1 + c
      end;
    finally
      inc(i);
    end;

    if EscEn then s1 := s1 + '\';

  end;


  UseProgDir := false;

  if s1 = ''
  then begin
    // Обрабатываем каталог Тотал Командера
    s := '%COMMANDER_PATH%\wincmd.ini';
    s2 := '%COMMANDER_PATH%\wcx_ftp.ini';

    ExpandEnvironmentStrings(PChar(s), a, MAX_PATH);
    i := GetPrivateProfileInt('Configuration', 'UseIniInProgramDir', 0, a);
    UseProgDir := (i and 2) <> 0;
    if (i and 4) <> 0 then s1 := s2;
  end;

  if s1 = ''
  then begin
    // Проверяем реестр

    try
      Reg := TRegistry.Create(KEY_READ);
      try
        Reg.RootKey := HKEY_CURRENT_USER;
        if Reg.OpenKeyReadOnly('\Software\Ghisler\Total Commander')
        then begin
          s1 := Reg.ReadString('FtpIniName');
        end
        else begin
          s1 := '';
        end;
        if S1 = ''
        then begin
          Reg.RootKey := HKEY_LOCAL_MACHINE;
          if Reg.OpenKeyReadOnly('\Software\Ghisler\Total Commander')
          then begin
            s1 := Reg.ReadString('FtpIniName');
          end;
        end;
      finally
        Reg.Free;
      end;
    except
      s1 := '';
    end;

    if (s1 = '')
    then if UseProgDir
    then s1 := s2
    else s1 := 'wcx_ftp.ini';
  end;

  if (copy(s1, 1, 2) = '.\')
  then begin
    delete(s1, 1, 2);
    s1 := '%COMMANDER_PATH%\' + s1;
  end;

  ExpandEnvironmentStrings(PChar(s1), a, MAX_PATH);
  result := strpas(a);
  FTPIniFileName := Result;
end;

Добавлено: Чт май 12, 2005 17:44
Maximus
2TSergey
Че наворотил -- непонятно)) Может оттого что я паскаль уже плохо стал читать. А что имеется в виду под поддержкой кавычек? В Билдере они и так поддерживаются. По крайней мере я никогда по этому поводу ничего дополнительно с командной строкой не делал.

Но зачем там столько кода если путь к ини-файлам и к директории в которую командир проинстален валяются себе в реестре:
HKEY_LOCAL_MACHINE\Software\Ghisler\Total Commander
и здесь тоже чето:
HKEY_CURRENT_USER\Software\Ghisler\Total Commander
Это под 98ой. А как там под ХР для разных юзверей не смотрел.

А вот кто бы мне сказал как без лишних извратов узнать где валяется моя ДЛЛ т.е. откуда была запущена(хочу туды свой ини запихнуть), а то через Application->ExeName() получаю путь к командеру.

Добавлено: Чт май 12, 2005 20:09
vserd
Maximus
Но зачем там столько кода если путь к ини-файлам и к директории в которую командир проинстален валяются себе в реестре:
HKEY_LOCAL_MACHINE\Software\Ghisler\Total Commander
А затем что там правильная обработка текущего файла настроек.
К сожалению или скорее к счастью Total Commander поддерживает явное указание пути в командной строке, если там не задано, тогда нужно анализировать битовую маску UseIniInProgramDir, и в зависимости от нее считываем из реестра, а при отсутствии ключа, искать в %windir%.
Вобщем читайте доку, она вам поможет.

А вот кто бы мне сказал как без лишних извратов узнать где валяется моя ДЛЛ т.е. откуда была запущена(хочу туды свой ини запихнуть),
Если изменить вопрос на такой: Куда правильно писать инишник для плугина. Тогда возможно воспользуйтесь структурой
PackDefaultParamStruct.DefaultIniName

DefaultIniName Suggested location+name of the ini file where the plugin could store its data. This is a fully qualified path+file name, and will be in the same directory as the wincmd.ini. It's recommended to store the plugin data in this file or at least in this directory, because the plugin directory or the Windows directory may not be writable!

Либо таким кодом:
С++ из multarc
GetModuleFileName(m_hInstance,szFullPath,MAX_PATH);

GetShortPathName(szFullPath, szPath, MAX_PATH);
m_strMAPath = szPath;

_splitpath(szFullPath,szDrive,szPath,szName,szExt);
strcpy(szExt,"ini");

_makepath(szFullPath,szDrive,szPath,szName,szExt);
m_strIniFile = szFullPath;

Добавлено: Пт май 13, 2005 02:01
Volniy
vserd писал(а):Если изменить вопрос на такой: Куда правильно писать инишник для плугина.
А если все-таки не менять вопрос? Я вот хочу писать свой ини-файл в свою же папку, а не в common. Как тогда поступить?

Добавлено: Пт май 13, 2005 02:34
CaptainFlint
Maximus
А вот кто бы мне сказал как без лишних извратов узнать где валяется моя ДЛЛ
Есть один довольно извращённый способ... Уже не помню, где нашёл, не до конца понимаю, как и почему это работает, но работает.

Итак, заводишь следующую функцию (весь код проверен на VC++ 6):

Код: Выделить всё

extern "C" void * _ReturnAddress();
#pragma intrinsic(_ReturnAddress)

HINSTANCE GetCurrentInstance()
{
    MEMORY_BASIC_INFORMATION mem;
    if (VirtualQuery(_ReturnAddress(), &mem, sizeof(mem)))
    {
        _ASSERTE(mem.Type == MEM_IMAGE);
        _ASSERTE(mem.AllocationBase != NULL);
        return (HINSTANCE)mem.AllocationBase;
    }
    return NULL;
}
Она возвращает текущий HINSTANCE. А потом пихаешь возвращаемый результат в качестве первого параметра в вызов GetModuleFileName(...).