Results 1 to 10 of 10

Thread: Path met % tekens

  1. #1

    Path met % tekens

    Hallo allemaal,

    Wij gaan migreren naar OneDrive en nu loop ik tegen een paar zaken aan in mijn software.
    Gelukkig heb ik ooit eens een variable aangemaakt (LocalPath) die door mijn software gebruik als locatie voor het wegschrijven van allerlei bestanden
    (Meestal was dit H:\temp\ o.i.d.)

    Wanneer we gebruik maken van OneDrive is deze locatie minder evident.
    De verwijzing naar iets soort gelijks op onedrive zou zijn %OneDrive%\temp\

    Voor een deel werkt dit goed.
    Wanneer ik echter een stream wil opslaan (tfilestream.create(LocalPath+'Meetprog.exe' ,fmcreate) dan krijg ik een fout melding.
    Het hele pad waar de executable vanuit gestart wordt dan voor het eerste % teken gezet

    Dus mijn variable LocalPath is dus '%OneDrive\temp\'
    Maar de output van tfilestream.create verwijst naar 'C:\SW_Dev\TestProg\Bin\%OneDrive%\Temp\'
    Uiteraard is deze locatie onjuist

    Een oplossing is door eerst SetCurrentDir(LocalPath) te gebruiken en daarna tfilestream.create('Meetprog.exe' ,fmcreate)
    Maar dit zou inhouden dat ik heeeeel veel regels moet gaan controleren.

    De vraag is dus hoe voorkom ik dat het pad van waaruit de executable gestart wordt, wordt meegenomen bij het wegschrijven naar schijf van streams (maar ook van logfiles e.d.)

    Alvast bedankt

  2. #2
    Ik gok dat je ExpandFilename(LocalPath) gebruikt.
    Deze "vertaalt" je environment variabele %OneDrive% niet.
    Geen idee of het werkt, maar je kunt natuurlijk checken op '%' in je LocalPath (%OneDrive%\temp\') en dan kijken of met GetEnvironmentVariable kunt loslaten op de tekst tussen de % tekens?

    Bart

  3. #3
    Mhhh iets te vroeg gejuicht,
    De SetCurrentDir functie werkt wel bij AssignFile(logfile,'logfile.txt')
    Dat wil zeggen het bestand logfile.txt wordt keurig in de map geplaatst die je bij SetCurrentDir opgeeft.

    Echter de functie tfilestreamcreate('blabla.blob',fmcreate) schrijft de file weg in de folder waarvan de exe gestart is

  4. #4
    Helpt het als je deze functie loslaat op je LocalPath?
    Delphi Code:
    1. function ExpandEnvVarInFilename(const S: String): String;
    2. var
    3.   p1, p2: SizeInt;
    4.   Sub, EnvS: String;
    5. begin
    6.   Result := S;
    7.   p1 := Pos('%',S);
    8.   if (p1 = 0) then Exit;
    9.   p2 := PosEx('%',S,p1+1);
    10.   if (p2 = 0) then Exit;
    11.   Sub := Copy(S,p1+1,p2-p1-1);
    12.   EnvS := GetEnvironmentVariable(Sub);
    13.   Result := StringReplace(Result, '%'+Sub+'%', EnvS, []);
    14. end;

    SetCurrentDir is niet threadsafe.
    Persoonlijk zou ik altijd proberen een "fully qualified filename" door te geven aan bestandsfuncties, zeker in dit soort situaties.
    Daarmee vermijd je iedere vorm van ambiguiteit.

    PS. Ik heb geen onedrive dus ik kan niet testen of dit daarmee ook werkt (met tfilestream), met "simpele" environmentvariabelen als %public% werkt dit prima.

    Bart

  5. #5
    Thanks!!

    Hiermee krijg ik idd een pad terug waar delphi (en tfilestream) wel mee om kunnen gaan.

  6. #6
    Quote Originally Posted by cpri View Post
    Hiermee krijg ik idd een pad terug waar delphi (en tfilestream) wel mee om kunnen gaan.
    Je kunt ook ExpandEnvironmentStrings() gebruiken. Daar kun je je hele string aan geven en dan worden de environment variabele automatisch allemaal expanded (want bij de functie van Bart wordt alleen de eerste expanded).

    Voorbeeldje:

    Delphi Code:
    1. var
    2.   c: array [0 .. 1023] of Char;
    3.   N: DWORD;
    4. begin
    5.   N := ExpandEnvironmentStrings(pChar('%APPDATA%'), c, 1024);
    6.   if N > 0 then Showmessage(c);
    7. end;

  7. #7
    OK, maar moet hij toch eerst de string parsen.
    Je kunt mijn code ook eenvoudig aanpassen dat hij bijv %public%\%someothervar%\foo\bar afhandelt.
    Zet de relevante code in een while loopje en voer die uit zolang er een % in Result voortkomt.

    Bart

  8. #8
    Quote Originally Posted by Bart B View Post
    OK, maar moet hij toch eerst de string parsen.
    Waarom moet de string eerst geparsed worden?

    Dit werkt gewoon:
    Delphi Code:
    1. var
    2.   c: array [0 .. 1023] of Char;
    3.   N: DWORD;
    4. begin
    5.   N := ExpandEnvironmentStrings(pChar('%APPDATA%\%USERNAME%\Testbestand.txt'), c, 1024);
    6.   if N > 0 then Showmessage(c);
    7. end;

    Dus gewoon de complete string meegeven en ALLE environment variabele worden vervangen. Geen loopje of parsen voor nodig.

  9. #9
    Aha, dat was me uit je eerste voorbeeld in het geheel niet duidelijk.

    Bart

  10. #10
    mov rax,marcov; push rax marcov's Avatar
    Join Date
    Apr 2004
    Location
    Ehv, Nl
    Posts
    10,357
    Vziw doen shell functies environement variable expansie, en "gewone" kernel32 en user32 functies niet. Logisch want %xxx% is een shell conventie.

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •