AutoHotkey Community

It is currently May 26th, 2012, 2:24 pm

All times are UTC [ DST ]




Post new topic Reply to topic  [ 16 posts ]  Go to page 1, 2  Next
Author Message
 Post subject: FileSetAttrib
PostPosted: June 11th, 2005, 7:12 am 
Offline

Joined: May 16th, 2005, 8:07 am
Posts: 42
Location: Dallas, TX, USA
I'll need someone to confirm this, BUT...

I think FileSetAttrib is broken.

When I copy files over from a CD, they're all Read Only. I want to make a script to be able to delete them quickly and easily, so I needed to remove the Read Only tag on all files and folders copied over, right?

Code:
FileSetAttrib, -R, C:\MyDirectory, 1, 1


Well, this ain't doin anything. :P And I can't think of what I would be doing wrong. Anyone want to confirm or correct this?

EDIT: I tried +H, and that did work. -R still doesn't, though! (I am using this on directories, not just files. I think it actually works on files.)


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: June 11th, 2005, 7:49 am 
Offline

Joined: July 22nd, 2004, 6:33 am
Posts: 193
Location: cedar city UT
i also can not get it to work :shock: :wink:

_________________
^sleepy^


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: June 11th, 2005, 10:53 am 
Offline

Joined: March 2nd, 2004, 3:36 pm
Posts: 10720
I don't think a folder itself can be read-only. So in this case, you should specify a wildcard pattern to remove read-only from all the files inside:
FileSetAttrib, -R, C:\MyDirectory\*.*, 1, 1


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: June 11th, 2005, 3:36 pm 
Offline

Joined: May 16th, 2005, 8:07 am
Posts: 42
Location: Dallas, TX, USA
I tried that as well, but the folders all remain with the Read Only square (which is kind of ambiguous but typically means that its contents are mixed -- some +R and some -R), as opposed to the checkmark or nothing at all.

See my script first -R's all the files, then clears those out. It then proceeds to -R all the directories and delete them... but that second half isn't happening, and when I check the folder properties, it's that square (ambiguous) like I said. Even though there's nothing in the folders!

_________________
Windows XP SP2


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: June 11th, 2005, 6:04 pm 
Offline

Joined: July 22nd, 2004, 6:33 am
Posts: 193
Location: cedar city UT
Chris wrote:
I don't think a folder itself can be read-only. So in this case, you should specify a wildcard pattern to remove read-only from all the files inside:
FileSetAttrib, -R, C:\MyDirectory\*.*, 1, 1


FileSetAttrib, -R, C:\MyDirectory\*.*, 1, work'd for me :wink:

_________________
^sleepy^


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: June 12th, 2005, 3:19 am 
Offline

Joined: May 16th, 2005, 8:07 am
Posts: 42
Location: Dallas, TX, USA
I tried again (FileSetAttrib, -R, C:\MyDirectory\*.*, 1, 1), but still no luck. All the directories still have a square in Read Only, but there are no actual checkmarks. Really, really bizarre -- but definitely a bug.

_________________
Windows XP SP2


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: June 12th, 2005, 12:13 pm 
Offline

Joined: March 2nd, 2004, 3:36 pm
Posts: 10720
It might just be a question of refreshing the display. Try pressing F5 or closing and reopening Explorer.

Since doing "dir /ar" at the command prompt never shows any directories, it seems fairly certain that directories themselves cannot be read-only.

Edit: The above is incorrect. However, it seems that a folder itself cannot be made read only with Explorer. You have to use attrib +R "FolderName".


Last edited by Chris on June 13th, 2005, 12:25 pm, edited 1 time in total.

Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: June 12th, 2005, 4:11 pm 
Offline

Joined: May 16th, 2005, 8:07 am
Posts: 42
Location: Dallas, TX, USA
Then that leaves me with the question, why can't I delete them?

My script copies files and directories over from a CD to the hard drive using two loops. It retains read-only status.

Another part of the script deletes all these files and directories, using a loop for each. First it removes read-only from the files so that they can be deleted, and then it should be removing read-only from the directories so they can be deleted as well. But no matter what I do, Windows seems to think there's something read-only about the now empty directories.

_________________
Windows XP SP2


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: June 12th, 2005, 4:25 pm 
Offline
User avatar

Joined: December 29th, 2004, 1:28 pm
Posts: 2542
Only a guess but... maybe try assigning the part of your code that changes the read-only attributes to a different label and gosub to that label (or use a function).


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: June 12th, 2005, 10:41 pm 
Offline

Joined: March 2nd, 2004, 3:36 pm
Posts: 10720
Also, verify that the folders aren't locked. This can happen when some program is using one as a working directory. One fairly certain way to tell if they are locked is to reboot and then try deleting them. Also, verify that your username has permission to delete the folders.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: June 13th, 2005, 2:53 am 
Offline

Joined: May 16th, 2005, 8:07 am
Posts: 42
Location: Dallas, TX, USA
I think it has something to do with AutohotKey. It created the folders in the first place, but now it can't delete them. But if I personally create a folder, I can manipulate its read-only tag all I want using AutohotKey.

Also, yes, as Administrator I do have all privelages to make modifications... so eh?

As for a gosub, it makes no difference -- I've tried using entirely different scripts to accomplish this and they won't do it.

Here, try this. Use AutoHotkey to copy a CD over to your hard drive somewhere and make it first run a loop through to create all the directories, then shuffle all the files in. (I had to do this because I made a progress bar, and I needed a log of all the moved files). Then try to turn read-only off using your script, or even another. Now over here, using XP SP2, that doesn't fly. I don't know why.

Maybe you can save yourself a little time by taking portions of my code... who knows. I just want someone to be able to reproduce the error. Hell, I could post the entire program I'm working on if it'll help...

Code:
      2ButtonCopy:                                                                     // If the user clicks Copy...
      {
         Gui, 2: Submit, NoHide                                                         // Gather all the variables and hide the window...

         If(!destination)                                                               // If the user did not enter a destination...
         {
            MsgBox, 48, No Destination, Please enter a destination directory.            // Display error message.
            ControlFocus, Edit1, Copy from Disc                                          // Change focus to the field in question.
            Return                                                                     // Wait for user input.
         }
         Else If destination Contains *,",?,/,\,|,<,>                                    // If the destination contains *, ", ?, /, \, |, <, or >...
         {
            MsgBox, 48, Invalid Destination, The destination must not contain question marks, quotation marks, colons,`nslashes, backslashes, pipes, greater-than or less-than signs, or asterisks.
            ControlFocus, Edit1, Copy from Disc                                          // Change focus to the field in question.
            Send, {END}{SHIFTDOWN}{HOME}{SHIFTUP}                                       // Highlight the contents.
            Return                                                                     // Wait for user input.
         }

         Gui, 2: Destroy                                                               // Destroy the copy settings window.

         StringMid, disc_drive, disc_drives_choose, 1, 1                                 // Grab the drive letter.

         Gui, 3: Add, Progress, x10 y30 w300 h15 vcopy_progress                        // Draw the progress bar "copy_progress".
         Gui, 3: Add, Text, x10 y48 w300 vmb_status                                    // Draw the current MB text display.
         Gui, 3: Add, Text, x10 y63 w300 vcurrent_file                                 // Draw the current file text display.
         Gui, 3: Add, Text, x10 y78 w75 Left, Project: %project%                        // Draw the project.
         Gui, 3: Add, Text, x85 y78 w225 Right, Destination: %project%\%destination%   // Draw the destination.
         Gui, 3: Add, Button, x128 y96 w63 h30 vbutton, Cancel                           // Cancel button.
         Gui, 3: Font, s13 Bold
         Gui, 3: Add, Text, x10 y5 w300 Center vpercent_display                        // Draw the current MB text display.

         Gui, 3: Show, , Copy from Disc                                                // Make the window.

         already_present = 0

         IfExist, %Dayend_Directory%\%project%\%destination%
            already_present = 1

         FileCreateDir, %Dayend_Directory%\%project%\%destination%                     // Create the directory.

         SetBatchLines, -1                                                               // Make the operation run at maximum speed.
         total_size =                                                                  // Initialize variable "total_size" for progress bar.
         current_size =                                                                  // Initialize variable "current_size" for progress bar.
         good_to_go = 1                                                                  // Initialize variable "good_to_go" and set it to 1.
         directories_copied =
         files_copied =
         done_copying =

         Loop, %disc_drive%:\*.*, 1, 1                                                   // Parse through the entire disc.
            total_size += %A_LoopFileSize%                                             // Add up all the bytes for a total size.

         SetFormat, Float, 0.2                                                         // Set format of numeric strings to two decimal places.
         total_mb := total_size / 1048576                                                // Calculate total MB to be transferred.

         Loop, %disc_drive%:\*.*, 2, 1                                                   // Parse through all directories and subdirectories (no files).
         {
            StringTrimLeft, dir_struct, A_LoopFileFullPath, 3                           // Remove the drive letter, colon, and backslash.
            directories_copied = %directories_copied%`n%A_LoopFileFullPath%
            FileCreateDir, %Dayend_Directory%\%project%\%destination%\%dir_struct%      // Create this directory and all its parents, if necessary.
            GuiControl, 3: , current_file, %A_LoopFileFullPath%                        // Update the current file text display.
            GuiControl, 3: , mb_status, Creating directory structure...                  // Update the current MB text display.
         }

         Loop, %disc_drive%:\*.*, 0, 1                                                   // Parse through all files and files in subdirectories (no folders).
         {
            SetFormat, Float, 0.2                                                      // Set format of numeric strings to two decimal places.

            If(good_to_go = 0)                                                         // If variable "good_to_go" has been changed to 0 by a cancellation...
               Break                                                                     // Break the loop.

            current_size += %A_LoopFileSize%                                             // Add this file's size to the current size.
            percent_complete := current_size / total_size * 100                        // Create a percentage complete to use in the progress bar.
            current_mb := current_size / 1048576                                       // Calculate current MB transferred.

            StringTrimLeft, dir_struct, A_LoopFileDir, 3                                 // Remove the drive letter, colon, and backslash.
            files_copied = %files_copied%`n%A_LoopFileFullPath%
            FileCopy, %A_LoopFileFullPath%, %Dayend_Directory%\%project%\%destination%\%dir_struct%\%A_LoopFileName%, 1

            GuiControl, 3: , copy_progress, %percent_complete%                           // Update the progress bar.
            GuiControl, 3: , mb_status, %current_mb% MB of %total_mb% MB Transferred   // Update the current MB text display.
            GuiControl, 3: , current_file, %A_LoopFileFullPath%                        // Update the current file text display.
            GuiControl, 3: , percent_display, %percent_complete%`%                     // Display percentage on title bar.
         }

         GuiControl, 3: , button, Done                                                   // Change the Cancel button to a Done button.
         done_copying = 1

         Return                                                                        // Wait for user input.

         3GuiEscape:                                                                     // If user presses Escape...
         3ButtonCancel:                                                                  // If user clicks Cancel...
         3GuiClose:                                                                     // If user exits some other way...
         {
            If(!done_copying)
            {
               MsgBox, 33, Stop Copy, Are you sure you want to stop the transfer?

               IfMsgBox, OK
               {
                  good_to_go = 0                                                         // Cancel the copy loop by setting "good_to_go" to 0.

                  MsgBox, 33, Delete Files, Do you want to delete the files that were copied over?

                  IfMsgBox, OK
                  {
                     Gui, 3: Show, , Delete Files                                       // Make the window.

                     GuiControl, 3: Disable, button

                     good_to_go = 0                                                      // Cancel the copy loop by setting "good_to_go" to 0.
                     total_size = %current_size%                                       // Initialize variable "total_size" for progress bar.
                     current_size =                                                      // Initialize variable "current_size" for progress bar.

                     SetFormat, Float, 0.2                                                         // Set format of numeric strings to two decimal places.
                     total_mb := total_size / 1048576                                    // Calculate total MB to be deleted.

                     StringReplace, files_copied_fixed, files_copied, %disc_drive%:\, %Dayend_Directory%\%project%\%destination%\, All
                     StringReplace, directories_copied_fixed, directories_copied, %disc_drive%:\, %Dayend_Directory%\%project%\%destination%\, All

                     Sort, directories_copied_fixed, R // WON'T NEED THIS IF HE FIXES IT
                     FileSetAttrib, -R, %Dayend_Directory%\%project%\%destination%\*.*, 1, 1

                     Loop, Parse, files_copied_fixed, `n                                 // Parse through all directories and subdirectories (no files).
                     {
                        if A_LoopField =                                                // Omit the last `n so we don't get a double entry.
                           Continue

                        FileGetSize, current_size_file, %A_LoopField%
                        current_size += %current_size_file%                              // Subtract this file's size from the current size.
                        percent_complete := current_size / total_size * 100            // Create a percentage complete to use in the progress bar.
                        current_mb := current_size / 1048576                           // Calculate current MB deleted.

                        FileSetAttrib, -R, %A_LoopField%, 1   // WON'T NEED THIS IF HE FIXES IT
                        FileDelete, %A_LoopField%

                        GuiControl, 3: , copy_progress, %percent_complete%               // Update the progress bar.
                        GuiControl, 3: , mb_status, %current_mb% MB of %total_mb% MB Deleted   // Update the current MB text display.
                        GuiControl, 3: , current_file, %A_LoopField%                     // Update the current file text display.
                        GuiControl, 3: , percent_display, %percent_complete%`%         // Display percentage on title bar.
                     }

                     Loop, Parse, directories_copied_fixed, `n                           // Parse through all directories and subdirectories (no files).
                     {
                        if A_LoopField =                                                // Omit the last `n so we don't get a double entry.
                           Continue

                        FileDelete, %A_LoopField%
                        GuiControl, 3: , current_file, %A_LoopField%                     // Update the current file text display.
                        GuiControl, 3: , mb_status, Removing directory structure...      // Update the current MB text display.
                     }

                     GuiControl, 3: , copy_progress, 100                                 // Update the progress bar.
                     GuiControl, 3: , percent_display, 100`%                           // Display percentage on title bar.

                     GuiControl, 3: Enable, button
                     GuiControl, 3: , button, Done                                       // Change the Cancel button to a Done button.

                     If(!already_present)
                     {
                        FileDelete, %Dayend_Directory%\%project%\%destination%
                        GuiControl, 3: , current_file, %Dayend_Directory%\%project%\%destination%   // Update the current file text display.
                     }

                     Return                                                            // Wait for user input.
                  }
                  Else IfMsgBox, Cancel
                  {
                     Gui, 3: Destroy                                                   // Destroy the window.
                     Return                                                            // Wait for user input.
                  }
               }
               Else IfMsgBox, Cancel
               {
                  Return                                                               // Wait for user input.
               }
            }
            Else
            {
               Gui, 3: Destroy                                                         // Destroy the window.
               Return                                                                  // Wait for user input.
            }
         }
      }

_________________
Windows XP SP2


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: June 13th, 2005, 12:52 pm 
Offline

Joined: March 2nd, 2004, 3:36 pm
Posts: 10720
Thanks for the script. You were right about folders being read-only. I see now that you can make them so, but apparently not via Explorer (you have to use the Attrib command or a script, etc.)

I think I might know the problem now: FileDelete cannot delete folders (by design). You have to use FileRemoveDir to do that. However, as you pointed out, the read-only attribute must be turned off prior to deleting the folder. This should be fixed in the next update. In the meantime, you can work around it by specifying the "1" flag as the last parameter of FileRemoveDir.

I'm might be off-target here, so please continue to post if the issue is not resolved.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: June 13th, 2005, 3:47 pm 
Offline

Joined: May 16th, 2005, 8:07 am
Posts: 42
Location: Dallas, TX, USA
Ahh. K. I just didn't want to use FileRemoveDir because it would delete everything in that folder, but I didn't want that because perhaps that folder had already been present, and the user could accidentally be deleting prior data. Most likely not, but you can't take chances!

After re-reading the definition of FileRemoveDir, now I see that it won't touch any of the prior files unless I specify 1 in the parameter. Oops. :)

OK, cool! Glad I was able to help (and wasn't just imagining things). Funny though because I was using the wrong code to try to accomplish something, yet I still found a quirk. Heh..

EDIT: Hahaha after all that, I just changed my directory deletion command from FileDelete to FileRemoveDir and it worked. All that drama and the solution was right there... eeeesh.....

_________________
Windows XP SP2


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: June 17th, 2005, 7:19 pm 
Offline

Joined: November 6th, 2004, 11:03 am
Posts: 170
Location: Salt Lake City, UT
I"m glad someone else was having similar problems. I posted about this in
http://www.autohotkey.com/forum/viewtopic.php?t=3678, because I was having problems reading the attributes of a folder, not setting them. I hope that will also be addressed?

EDIT:
I tried to use the function below, and I couldn't make it work.
Code:
ReadOnlyDir(dir)
{
   if ((StrLen(dir) > 3) AND (InStr(dir,"\",False,0)) = (StrLen(Dir)))
      StringLeft,dir,dir,(StrLen(Dir)-1)
   If ((InStr(dir,"O:\") OR (InStr(FileExist(dir),"D") AND InStr(FileExist(dir),"R"))))
      MsgBox,16,,Destination %Dir% is Read-Only. No files will be checked out.
}

On some PCs (local drive or network drive) it always returns read-only, and on others it never returns read-only.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: June 18th, 2005, 1:04 am 
Offline

Joined: March 2nd, 2004, 3:36 pm
Posts: 10720
Concerning your issue with read-only volumes, I ran the following and it seems to work okay on non-networked drives. If it fails to work on network drives, I'm at a loss of what the problem could be:
Code:
VarSetCapacity(VolumeName, 260)
if DllCall("GetVolumeNameForVolumeMountPoint", "str", "C:\", "str", VolumeName, "Uint", 260) and not ErrorLevel
   MsgBox % "Volume Name: " . VolumeName
else if ErrorLevel
{
   MsgBox Can't call function due to ErrorLevel %ErrorLevel%.
   Return
}
else
{
   MsgBox GetVolumeNameForVolumeMountPoint() could not determine the volume name.
   Return
}

; FileExist() has a bug concerning "\\?\Volume" filenames that has been fixed
; in v1.0.35.12.  For older versions, the API can be called as follows:
SetFormat, integer, hex
Attr1 := DllCall("GetFileAttributes", str, VolumeName)
if (ErrorLevel or Attr1 = 0xFFFFFFFF)
   MsgBox Call failed.
else
   if (Attr1 & 0x1)  ; 0x1 is FILE_ATTRIBUTE_READONLY
      MsgBox The directory is read-only. Attributes = %Attr1%
   else
      MsgBox The directory is NOT read-only. Attributes = %Attr1%

Related topic: http://www.autohotkey.com/forum/viewtopic.php?t=3678

Edit: The FileExist() bug mentioned in the script above has been fixed.


Report this post
Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 16 posts ]  Go to page 1, 2  Next

All times are UTC [ DST ]


Who is online

Users browsing this forum: No registered users and 1 guest


You can post new topics in this forum
You can reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Powered by phpBB® Forum Software © phpBB Group