Lost Adventurer, Aleks Kirilenko (3D)
LC #42 Pipers Alley

View Full Version : getSaveFileName and Win 7

06-08-2011, 07:05 AM
I wrote a tool that will let the user select a save file using getSaveFileName for a export process.
Once it's selected, I check if the file is readonly, and if 'True' then use a dos command to 'check out' the file from file storage application.

The issue is this process doesn't appear to work on win 7 machines because it stops you from selecting a 'readonly' file in the dialog. Essentially stopping right there. I can't get past this point in order to process and check out the file.

Any ideas?

06-08-2011, 07:19 AM
Sounds like a user account control (UAC) issue, have you tried turning it off?

06-13-2011, 07:25 PM
Sorry for the delay in response,
Yes, I've tested it with UAC turned off and the issue still exists.

06-13-2011, 07:47 PM
Have you tried different paths for the file? For example, one that it's not on the c:\users\Administrator and try it on a c:\test.tmp file?

If you can, please post a snippet of your code.

06-13-2011, 08:01 PM
Correct, the current paths are not in any of the user directories.

sFileName = getSaveFileName filename:sExportName \

I don't see any options for this command that are related to readonly or over-writing. Your basically just selecting a filename. in XP, it doesn't care if your selecting a file marked as readonly or not. This doesn't appear to be the case with Win7. It will NOT allow you to select a file marked as readonly. So you have to cancel which will return undefined.

06-13-2011, 08:32 PM
Well I was digging a .net solution but it has the same problem, but while coding I had an idea, why not use the openfiledialog and if the file exists, it checks for the read-only flag, and if it's true, remove it and overwrite the file. If the file doesnt exist, then just create it. Made any sense? :D

06-13-2011, 09:23 PM
With getSave you can select any file including one that doesn't exist.

With getOpen you can only select files that exist, the dialog will give you the same issues if you try to select a file that doesn't already exist. Dialog will hang there until you select a valid choice or cancel.

Since I Don't know what the user is going to select ( new or existing ) I can't squeak by using getOpen.

06-14-2011, 12:37 AM
It's not pretty, but a more prettier solution involved messing deeply with the savefiledialog messages and that's wayyy beyond my knowledge, either way, it was a cool challenge, I never did anything with dialogops and uiaccessor :D

Anyway, as I've said it's not pretty because when the error dialog appears we can see it by a split second being closed by the uiaccessor, but I guess it's effective anyway. Another problem would be localization issues, so any non-english 3dsmax wouldnt work with this.

Hope this helps anyway:

DialogMonitorOPS.unRegisterNotification id:#eyeInTheSky
frmSaveFileDialog = dotNetObject "System.Windows.Forms.SaveFileDialog"

fn checkfilesave ipath ifile =
fpath = ipath + ifile
result = getFileAttribute fpath #readonly

fn dmnotification =
WindowHandle = DialogMonitorOPS.GetWindowHandle()
-- Window info, for debbuging only
/* format "Dialog Window Handle: %\n" WindowHandle
format "Dialog Name: %\n" (UIAccessor.GetWindowText WindowHandle)
format "Window Class Name: %\n" (UIAccessor.GetWindowClassName WindowHandle)
format "Window Resource ID: %\n" (UIAccessor.GetWindowResourceID WindowHandle)
format "Is Window: %\n" (UIAccessor.isWindow WindowHandle)
format "Window DLL Filename: %\n" (UIAccessor.GetWindowDllFileName WindowHandle)
format "Window DLL Description: %\n" (UIAccessor.GetWindowDllDescription WindowHandle)*/

if (UIAccessor.GetWindowText WindowHandle) == "Confirm Save As" then -- file overwrite info dialog

parent = UIAccessor.GetParentWindow WindowHandle
controls = windows.getChildrenHWND parent

fpath = ""
ffile = ""
for i in controls do
case i[4] of
"ToolbarWindow32":if i[5] != "" then fpath = substitutestring i[5] "Address: " ""
"Edit":ffile += i[5]
fpath += @"\"
rrfile = checkfilesave fpath ffile
if rrfile == true then
ipath = fpath + ffile
setFileAttribute ipath #readonly false
/* File exists and is read-only - do your stuff here */
setFileAttribute ipath #readonly true
/* file exists and it's not read-only - do your stuff here */

if (UIAccessor.GetWindowText WindowHandle) == "Save As" then -- main dialog and error dialog - they have the same caption
controls = windows.getChildrenHWND WindowHandle
nbuttons = for i in controls where i[4] == "Button" collect i
if nbuttons.count == 1 then -- file save error dialog it shows even though we did set the file attribute not to be read only, so we just want to close this
UIAccessor.CloseDialog WindowHandle
parent = UIAccessor.GetParentWindow WindowHandle -- now that we're done, we can also close the main dialog
UIAccessor.CloseDialog parent
DialogMonitorOPS.UnRegisterNotification id:#eyeInTheSky
--format "=====================\n"

DialogMonitorOPS.RegisterNotification dmnotification id:#eyeInTheSky

DialogMonitorOPS.Enabled = true

frmSaveFileDialog.Filter = "SMDExporter (*.smd)|*.smd"

dlgResult = dotNetClass "System.Windows.Forms.DialogResult"
if frmSaveFileDialog.ShowDialog() == dlgResult.OK then
/* file doesn't exist - do your stuff here */
print frmSaveFileDialog.Filename


CGTalk Moderation
06-14-2011, 12:37 AM
This thread has been automatically closed as it remained inactive for 12 months. If you wish to continue the discussion, please create a new thread in the appropriate forum.