Results 1 to 5 of 5

Thread: Waar zijn de voorbeelden?

  1. #1

    Waar zijn de voorbeelden

    http://blogs.codegear.com/nickhodges.../17/33179.aspx
    In Windows Vista mag een programma niet meer zomaar naar je Program Files map schrijven. De voorbeelden die we dus normaal altijd in de Delphi map zelf vinden, staan nu in de map C:\Documents and Settings\All Users\Documents\RAD Studio.

  2. #2
    En ook een blog over de locatie van je desktop state files.
    Marcel

  3. #3
    unregistered user gbuisman's Avatar
    Join Date
    Mar 2005
    Location
    Groningen
    Posts
    57
    Veel app's die ik maak schrijven naar de schijf, en dan gebruik ik een folder en file structuur in de folder waar de app staat.
    De App crert deze folders en files meestal zelf.

    Zoiets als: extractdir(application.exename) als rootfolder

    Als ik het goed begrijp is dat in Vista helemaal niet meer mogelijk.
    Vraag: Begrijp ik dit goed, of kan ik zo'n App nog steeds draaien?

    (Een en ander heeft wellicht weinig met veiligheid te maken, maar meer met het creren van incompatibiliteit, als bandiet kun je nog steeds overal een exe neerzetten, die onheil kan aanrichten, of kan dit ook niet meer?, en als alle applicaties naar de allusers folder schrijven, dan kan je daar ook als crimineel een app schrijven die die folder doorzoekt en onheil aanricht. )

  4. #4
    Dat begrijp je goed. De mappen worden weliswaar gefaked naar de users map (je software zal dus wel werken, maar misschien niet zoald verwacht), maar het is inderdaad niet meer de bedoeling dat je programma gegevens in de program files folder schrijft. Je gebuiker heeft daar simpelweg geen rechten voor.
    Marcel

  5. #5
    unregistered user gbuisman's Avatar
    Join Date
    Mar 2005
    Location
    Groningen
    Posts
    57
    Onderstaande heb ik geschreven zonder verder kennis van Vista dan het bovenstande. Code werkt wel in XP.

    Ik schrijf graag allerlei data naar een subfolder van een App, maar WindowsVista geeft je APP geen toestemming om naar de program folder te schrijven.


    Toevallig heb ik me onlangs al in de systeemfolders van Microsoft verdiept.
    Voor mezelf heb ik toen een unit ApiSpecialFolders.pas geschreven, met de function getSpecialFolder(n:integer):string.

    Het best kun je dan naar de folder:
    getSpecialFolder(CSIDL_APPDATA) + '\' + appname +'\'
    schrijven.
    Er zijn ook allerlei Apps die naar de folder Mijn Documenten schrijven, wat heel onprettig is.
    Door de typische Microsoft aanpak komen files die bij elkaar horen op allerlei plekken te staan. Maar goed, je hebt er maar mee te leren leven.

    CSIDL_APPDATA (0x001a)
    Version 4.71. The file system directory that serves as a common repository for application-specific data. A typical path is C:\Documents and Settings\username\Application Data. This CSIDL is supported by the redistributable Shfolder.dll for systems that do not have the Microsoft Internet Explorer 4.0 integrated Shell installed.


    Natuurlijk bevalt me de oplossing van microsoft niet, in bepaalde gevallen veroorzaakt hij problemen:
    1. Er kunnen meerdere schijven zijn. Het programma is geinstalleerd in de folder 'E:\myapp' en de schijf 'c:\' waar ook MijnDocumenten, etc staan, is vrijwel vol.
    Stel dat myapp echt heel grote bestanden aanmaakt, bij elkaar zo'n tien GByte. Dan moet hij wel naar de eigen subfolder schrijven.
    2. Het leuke van Delphi is dat je een exe gewoon ergens neer kunt zetten en hij doet het. Ideaal met een USB stick. Het is toch een kick als je je eigen exe kunt maken, die je op je USB stick naar de bibliotheek meeneemt en die dan precies zo kunt gebruiken als je wilt.
    Met de mooiste VisualBasic programmas die ik gemaakt heb kan dit niet!!
    Maar goed, dit is dan ook weer de typische Microsoft architectuur.
    Als je een app op een duim neerzet moet hij allerlei data juist naar de eigen folder schrijven.
    Standaard kun je zeggen: Een ap schrijft data naar de eigen folder, behalve als hnij in de programsfodler staat


    Oplossing:
    (Er is natuurlijk ook een oplossing waarbij de gebruiker via opties zelf instelt wat de datafolder is, maar die behandel ik hier niet want is te ingewikkeld voor de 50 plus computer gebruiker)

    Je kunt een var datafolder:string gebruiken.
    En je hoeft die folder maar eenmaal te initialiseren.

    In pseudocode doe je dit op de volgende manier:
    IF AppFolder in ProgramsFolder
    THEN datafolder is subfolder van AppData folder
    ELSE datafolder is subfolder van AppFolder

    IF datafolder niet bestaat
    THEN forceer het maken van datafolder



    Dit leidt zonder al te veel problemen tot:

    Code:
    unit unitDataFolder;
    { * * * * * * * * * * * * * * * * * * * * * * * * * *
    
           Dutch Homelands Software; Delphi Library
    
           written in april 2007, by gbuisman
           to please microsoft = Vista
    
           datafolder is a subfolder to the app
           when app not in the Programs Folder
           app best in a folder of its own
    
    
           datafolder is in user\Application Data folder
           when app in Programs Folder
    
           var datafolder is set in initialization section 
    
    
      * * * * * * * * * * * * * * * * * * * * * * * * * * }
    
    interface
    uses dialogs;
    var datafolder:string;
    
    procedure initDataFolder(var datafolder:string);
    
    implementation
    
    uses SysUtils, Forms
          , shellapi
          ,  Windows
          , SHLOBJ;
    
    function getSpecialFolder(n:integer):string;
    //inner code is cut'N'paste from someplace
    var
      PIDL       : PItemIDList;
      Buffer     : array[0..MAX_PATH] of Char;
    
    begin
    //SHGetSpecialFolderLocation(0, CSIDL_DESKTOPDIRECTORY, PIDL); = desktop
      SHGetSpecialFolderLocation(0, n, PIDL);
      SHGetPathFromIDList       (PIDL, Buffer);
      result:= string(Buffer);
    end;
    
    
    
    
    function getAppDataFolder:string;
      var
        programsFolder,
        appfolderpath,
        appfoldername:string;
    
      begin
        //1. check if app in programsfolder
        programsFolder:=getSpecialFolder(38);//38 = CSIDL_PROGRAM_FILES
        appfolderpath:=extractfiledir(Application.ExeName);// uses SysUtils
    
        //showmessage('programsFolder = ' + programsFolder + #13#10 +
        //            'appfolderpath = ' + appfolderpath + #13#10 +
        //            'Copy(appfolderpath,1,length(programsFolder)) = ' + Copy(appfolderpath,1,length(programsFolder)));
    
       if strComp(pchar(programsFolder),pchar(Copy(appfolderpath,1,length(programsFolder))))=0
       then
         begin
           appfoldername:=Copy(appfolderpath,length(programsFolder) + 1 ,MAX_PATH);
           result:=getSpecialFolder(26) { = CSIDL_APPDATA (0x001a)}
                   +  appfoldername;
           //showmessage('appfoldername = ' + appfoldername + #13#10 +
           //            'result = ' + result);
         end
       else
         begin
           result:=appfolderpath + '\data';
           //showmessage('result = ' + result);
         end;
    end;
    
    
    
    
    procedure initDataFolder(var datafolder:string);
    begin
      datafolder:= getAppDataFolder;
    IF NOT DirectoryExists(datafolder) THEN
         begin
         IF NOT (ForceDirectories(datafolder))then
           begin
           showmessage('application cannot run cause failed to create' + #13#10
                      + datafolder + #13#10 + 'thank you');
    
           Application.Terminate;
           end;
         end;
    end;
    
    initialization
    initDataFolder(datafolder);
    showmessage('datafolder = ' + datafolder);//comment this line!
    
    end.
    Last edited by gbuisman; 06-Apr-07 at 16:53. Reason: design

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
  •