Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Общие вопросы > Конвертировать FileName в переменные среды


Автор: Чучмек 5.7.2012, 13:45
Есть ли функция, которая преобразует строки типа C:\Program Files\My\My.file в %ProgramFiles%\My\My.file ?
И наоборот?
Неохота городить огород. 

Автор: Ne1tr1n0 5.7.2012, 22:04
Надо что-то обратное http://msdn.microsoft.com/en-us/library/windows/desktop/ms724265%28v=vs.85%29.aspx?
Если да, то это наверное подойдет: http://msdn.microsoft.com/en-us/library/windows/desktop/bb773760%28v=vs.85%29.aspx

Автор: Чучмек 5.7.2012, 22:33
За первую функцию спасибо.
Вторая, к сожалению, работает не так, как хотелось.
Вместо %temp%\3.tmp возвращает %USERPROFILE%\Local Settings\Temp\3.tmp

Автор: Ne1tr1n0 5.7.2012, 23:18
к сожалению да, она только некоторые переменные среды парсит и заменяет значение в строке на имя переменной (всего 7 значений, перечислены в статье по ссылке).
Почему только эти, и не берет остальные непонятно.
Видимо придется все-таки городить велосипед.
По идее можно с помощью http://msdn.microsoft.com/en-us/library/windows/desktop/ms683187%28v=vs.85%29.aspx получить все переменные среды для процесса и самому распарсить результат, проверить его на предмет наличия в исходной строке. В результат вывести строку, в которой наибольший путь (по длине или же по кол-ву оставшихся слешей) заменен переменной.

Автор: Чучмек 5.7.2012, 23:30
Да я примерно так и делаю, через GetEnvironmentStrings.
Выбираю те, которые X:\... , сортирую по длине, и ищу вхождение. 

Автор: Ne1tr1n0 5.7.2012, 23:54
Вот набросал тут примерный вариант функции. Вроде работает. Возможно конечно придется внести какие-то дополнительные проверки, на регистр может быть или ещё на что-нить, да и мог накосячить (время-то позднее):
Код

function PathUnExpandEnvStrings(Path: string): string;
var i: integer;
    EnvStrings: PChar;
    EnvList: TStringList;
    VarParser: TStringList;
    MinLength: integer;
    EnvStringsMaxSize: Integer;
    s: string;
begin
  EnvList:=TStringList.Create;
  EnvStringsMaxSize:= 10000;
  EnvStrings:= GetEnvironmentStrings;
  try
    i:=0;
    s:='';
    while i < EnvStringsMaxSize do
    begin
      if EnvStrings[i]<>#0 then
      s:=s + EnvStrings[i]
      else
      begin
        if s='' then
        Break;
        EnvList.Add(s);
        s:='';
      end;
    Inc(i);
    end;
  finally
    FreeEnvironmentStrings(EnvStrings);
  end;

  MinLength:=Length(Path);
  for i := 0 to EnvList.Count - 1 do
  begin
    VarParser:=TStringList.Create;
    VarParser.Delimiter:='=';
    VarParser.DelimitedText:=StringReplace(EnvList[i], ' ', '#', [rfReplaceAll]);
    VarParser[1]:=StringReplace(VarParser[1], '#', ' ', [rfReplaceAll]);
    if Pos(VarParser[1], Path) <> 0 then
    begin
      if Length(Path) - Length(VarParser[1]) < MinLength then
      begin
        MinLength:=Length(Path) - Length(VarParser[1]);
        result:=StringReplace(Path, VarParser[1], '%' + VarParser[0] + '%', []);
      end;
    end;
    VarParser.Free;
  end;
  EnvList.Free;
end;

Автор: northener 6.7.2012, 01:06
Цитата(Чучмек @  5.7.2012,  22:33 Найти цитируемый пост)
Вторая, к сожалению, работает не так, как хотелось.
Вместо %temp%\3.tmp возвращает %USERPROFILE%\Local Settings\Temp\3.tmp

А чем не устраивает? 
Какая задача? Может огород городишь не на том участке поля? smile

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)