Options

File/Folder Read Permissions

eYeeYe Member Posts: 168
edited 2009-06-17 in NAV Tips & Tricks
Is there a way to determine whether or not a user has read permission to a folder without causing an error message to be displayed?
  lRecCurrentDir.SETRANGE(Path, pRecSubFolder.Path + '\' + pRecSubFolder.Name);
  IF lRecCurrentDir.FINDFIRST THEN
   BEGIN
    ...

lRecCurrentDir is a record variable, subtype File.
If the path filtered on is not accessable, the system gives a message: "Operating System cannot gain access to...".
But it proceeds with the rest of the code.
Kind Regards,
Ewald Venter

Answers

  • Options
    Fred_CITFred_CIT Member Posts: 16
    The only solution I can come up with is placing code for checking the permissions of a folder in a codeunit and call it like this:

    IF CODEUNIT.RUN(...) THEN
    BEGIN
    // Permissions OK
    ..
    END
    ELSE
    BEGIN
    // Error on permissions
    ..
    END;

    But for sending the necessary parameters to the codeunit you will be limited using just 1 record (Although there is a workaround for this using a single instance codeunit).
    If you want you can get the precise error using the GETLASTERRORTEXT function.
  • Options
    garakgarak Member Posts: 3,263
    Sorry, thats not so easy.

    The only way i know is with (C#)

    System.IO.Directory.GetAccessControl and there the error handling

    so you can also open a CMD with using WSH and WSHExec, check what, for example, "net use" return (or other net commands), and do the rest ....

    Or place your codesnippes in a Codeunit and rund the Codeunit with:

    If Not Codeunit.run then
    message('Sorry, Folder not exist or permission denied');

    Regards.
    Do you make it right, it works too!
  • Options
    eYeeYe Member Posts: 168
    System.IO.Directory.GetAccessControl is only a .NET framework2 dll, and you can't register it in NAV :(

    The Microsoft Scripting and Windows Scripting automations don't help either... ](*,)

    The problem isn't the error handling. It is getting the system (NAV) to throw an error that I will be able to handle, rather than displaying a Windows message and proceeding with the NAV code without breaking.
    Kind Regards,
    Ewald Venter
  • Options
    eYeeYe Member Posts: 168
    Okay, I kinda found a workaround to this.

    Using the 'Microsoft Shell Controls And Automation', you can do the following:
    [b]Name	                DataType	Subtype[/b]
    lAutFolder	        Automation	'Microsoft Shell Controls And Automation'.Folder2	
    lAutFolderItems	Automation	'Microsoft Shell Controls And Automation'.FolderItems3	
    lAutFolderItem	Automation	'Microsoft Shell Controls And Automation'.FolderItem	
    
    [b]GetFolderItems(VAR pAutFolderItem : Automation "'Microsoft Shell Controls And Automation'.FolderItem")[/b]
    
    IF ISCLEAR(pAutFolderItem) THEN
     lAutFolder := gAutMSShell.NameSpace(gDriveLetter)
    ELSE
     lAutFolder := gAutMSShell.NameSpace(pAutFolderItem.Path);
    
    lAutFolderItems := lAutFolder.Items;
    FOR i := 0 TO lAutFolderItems.Count - 1  DO
     BEGIN
      lAutFolderItem := lAutFolderItems.Item(i);
    
      IF lAutFolderItem.IsFolder AND
         (STRPOS(UPPERCASE(lAutFolderItem.Name), '.ZIP') = 0) AND
         (lAutFolderItem.Name = DELCHR(lAutFolderItem.Name, '=', '&:|?*')) 
      THEN
         GetFolderItems(lAutFolderItem)
      ELSE
         DoFileAction(lAutFolderItem);
     END;
    

    The automation automatically skips the folders it does not have access to.
    NOTE: The automation treats ZIP files as a folder, and has trouble with certain tipes of folders e.g. in your WINDOWS folder there is a folder called "assembly", it is of type Folder and not File Folder, the automation has trouble with those, also it does not like certain CHARs in the folder name.

    You can also use:

    lAutFolder_FolderItems.Filter(63, '*.*'); //Applies a filter to get only FolderItems that are folders
    lAutFile_FolderItems.Filter(64, '*.flf'); //Applies a filter to get only FolderItems that are files of type .flf
    Kind Regards,
    Ewald Venter
  • Options
    eYeeYe Member Posts: 168
    This is something very strange:
    In the solution I gave above (just add a window.update in the FOR loop), the code does not work when in a table, but works 100% in a codeunit:

    I have function A, that sets certain global variables (amongst which VAR Window of type Dialog) and then calls function GetFolderItems, that calls itself recursively.

    After an unknown amount of recursive loops (this appears to happen randomly), all my global variables seem to get cleared. I promise you, I don't clear it in function GetFolderItems.

    e.g. after a couple of loops it gives an error on the Window.update that the form/dialog box is not open.

    After moving this code from the table to a codunit, it seems to be working :shock: ... Why is this?
    Kind Regards,
    Ewald Venter
  • Options
    kinekine Member Posts: 12,562
    Can you post more complex part of the code?
    Kamil Sacek
    MVP - Dynamics NAV
    My BLOG
    NAVERTICA a.s.
  • Options
    eYeeYe Member Posts: 168
    There is nothing more complex to this. the "DoFile" function checks whether the FolderItem.Name contains .flf, if so, create a log entry.
    Kind Regards,
    Ewald Venter
  • Options
    kinekine Member Posts: 12,562
    Sorry, I forgot to scroll the code subwindow... :oops:
    Kamil Sacek
    MVP - Dynamics NAV
    My BLOG
    NAVERTICA a.s.
  • Options
    SogSog Member Posts: 1,023
    You can follow in the debugger how many times the function calls itself.
    I think (I don't have any grounds for it, it's actually a hunch) that it can call itself so many times as there are records in the table, even though you don't loop trough them. After that it might clear all variables. But when you put the code in a codeunit it works. (as you've stated)
    The only difference between a codeunit and a table is that the one doesn't have records while the other one has and that is what started my train of thought.
    |Pressing F1 is so much faster than opening your browser|
    |To-Increase|
  • Options
    eYeeYe Member Posts: 168
    I created a new table with the following functions, and called start from a CU. With or without records, it runs through. :-k
    Start()
    Window.OPEN('TEST #1#############');
    gTotal := 20;
    i := 1;
    RecursiveFunction(i);
    
    
    RecursiveFunction(VAR pCounter : Integer)
    IF pCounter > gTotal THEN
     EXIT;
    
    pCounter += 1;
    Window.UPDATE(1, pCounter);
    RecursiveFunction(pCounter);
    


    LOL, change the 20 to 2000....
    NAV closes without an error....?
    Kind Regards,
    Ewald Venter
  • Options
    krikikriki Member, Moderator Posts: 9,096
    eYe wrote:
    LOL, change the 20 to 2000....
    NAV closes without an error....?
    That is probably because you have a stack-overflow. But I thought NAV gave a message about that. Which version did you use?
    Regards,Alain Krikilion
    No PM,please use the forum. || May the <SOLVED>-attribute be in your title!


  • Options
    eYeeYe Member Posts: 168
    NAV 4 SP1 native.

    4SP1 does have the stack overflow message (add currform.update(false) to .OnAfterGetRecord...)

    Anyway, I suspect I found the problem with the code on the table, the "DoFileAction" function inserts a record into the same db as it is running the code from and has a commit at the end. Could the insert and/or the commit clear the variables - moving to a seperate instance of the table itself somehow? (haven't tested this though, already moved the code to a CU)
    Kind Regards,
    Ewald Venter
  • Options
    krikikriki Member, Moderator Posts: 9,096
    [Topic moved from 'NAV/Navision' forum to 'NAV Tips & Tricks' forum]
    Regards,Alain Krikilion
    No PM,please use the forum. || May the <SOLVED>-attribute be in your title!


Sign In or Register to comment.