source: trunk/Installers/GitHub/GHInstaller_main.ipf @ 1163

Last change on this file since 1163 was 1163, checked in by ilavsky, 13 months ago

New Installer, fix bioSAXS tools saving _sub data when NOT using liberal names.

  • Property svn:eol-style set to native
File size: 21.8 KB
Line 
1#pragma TextEncoding = "UTF-8"          // For details execute DisplayHelpTopic "The TextEncoding Pragma"
2#pragma rtGlobals=3             // Use modern global access method and strict wave access.
3#pragma version = 1.13
4#pragma IgorVersion = 8.03
5
6
7
8Strconstant ksNameOfPackages ="Irena, Nika, and Indra"
9Strconstant ksWebAddressForConfFile ="https://raw.githubusercontent.com/jilavsky/SAXS_IgorCode/master/"
10//archise are (2021-11-09):         https://github.com/jilavsky/SAXS_IgorCode/archive/refs/tags/October2021.zip
11StrConstant ksWebAddressForMaster="https://github.com/jilavsky/SAXS_IgorCode/archive/refs/heads/master.zip"// - not used for now, may be if needed line 1357 in Support
12Strconstant ksNameOfConfFile ="IgorInstallerConfig.xml"
13strconstant strConstRecordwwwAddress="https://usaxs.xray.aps.anl.gov/staff/jan-ilavsky/IrenaNikaRecords/installrecord.php?"
14Strconstant NameOfInstallMessageFile ="InstallMessage.ifn"
15
16//1.13 fix issue with Github renaming folders...
17//1.12 fix issue with Giithub chanign location of zip files.            string InternalDataName = "SAXS_IgorCode"
18//1.11 critical upgrade, fix for bug in code which relies on bug in Igor behavior which will be fixed in Igor 8.05 and 9
19//1.10 adds ability to delete folders on desktop
20//1.09 adds better unzip for Windows 8 and 10.
21//1.08 added better messages for failed installations.
22//1.05 fix location of new php file, increase Igor version need - rest of the code needs 7.05 or higher anyway.
23//1.05 adds Message from installer, promoted version requirement to 7.05 
24//1.04 Addes recording of installation (method, packages, success etc) for statistical purposes.
25//1.03 updated to handle better failed downloads of files from Github.
26//1.02 Fixes to some paths which were causing issues unzipping files
27//1.0 promoted to 1.0, seems to work.
28//0.6 minor fix of support packages to handle two most common errors.
29//0.5 ready for beta release.
30//0.3 looks like first functioning version on Windows 10.
31
32//Universal installer using Github as source for installtions files.
33//****************************************************************
34//****************************************************************
35//****************************************************************
36Menu "Install Packages"
37        "Open GitHub GUI", GHW_Start()
38        help={"Open GUI to install packages from GitHub"}
39end
40
41//****************************************************************
42//*********************************F*******************************
43//****************************************************************
44//****************************************************************
45Function GHW_Start()
46        if (str2num(stringByKey("IGORVERS",IgorInfo(0)))<7.00)
47                        DoAlert /T="Important message :"  0, "This installer will work ONLY with Igor 7.00 or higher. Please, update your Igor before running this installer!" 
48                        BrowseURL "http://www.wavemetrics.com/support/versions.htm"
49        else
50                DoWIndow GH_MainPanel
51                if(V_Flag)
52                        DoWIndow/K GH_MainPanel
53                endif
54                GHW_InitializeInstaller()
55                GHW_DwnldConfFileAndScanLocal(0)
56                GHW_PrepareGUIData()
57                GHW_CreateMainpanel()
58                GHW_GenerateHelp()
59                GHW_GetAndDisplayUpdateMessage()
60        endif
61
62end
63//****************************************************************
64//****************************************************************
65//****************************************************************
66Function GHW_GetAndDisplayUpdateMessage()
67                //checks for update message and if available, gets it and presents to user.
68               
69        string FileContent
70        string ConfigFileURL=ksWebAddressForConfFile+NameOfInstallMessageFile
71        URLRequest/Z/TIME=2 url=ConfigFileURL
72        if (V_Flag != 0)
73                print "Could not get Install message file from server."
74                return 0
75        endif
76        FileContent =  S_serverResponse
77        variable refNum
78        NewPath/O/C/Q TempUserUpdateMessage, SpecialDirPath("Temporary",0,0,0)
79        Open/P=TempUserUpdateMessage  refNum as NameOfInstallMessageFile
80        FBinWrite refNum, FileContent
81        Close refNum
82        OpenNotebook/k=1/N=MessageFromAuthor/P=TempUserUpdateMessage/Z NameOfInstallMessageFile
83   return 1
84end
85
86//****************************************************************
87//****************************************************************
88//****************************************************************
89
90Function GHW_CreateMainpanel()
91
92        PauseUpdate; Silent 1           // building window...
93        NewPanel /K=1/W=(131,111,733,450) as "Install/Unistall Packages"
94        DoWindow/C GH_MainPanel
95        //ShowTools/A
96        SetDrawLayer UserBack
97        SetDrawEnv fsize= 20,fstyle= 3,textrgb= (1,4,52428)
98        DrawText 101,25,"Install/Uninstall Igor packages hosted on Github"
99        DrawText 11,45,"This Igor experiment enables user to manage "+ksNameOfPackages+" packages"
100        Button CheckVersions,pos={10,50},size={200,20},proc=GHW_ButtonProc,title="Check packages versions"
101        Checkbox DisplayBetaReleases, pos={5,77}, size={100,20}, variable = root:Packages:GHInstaller:DisplayBetaReleases, proc=GHW_CheckProc
102        Checkbox DisplayBetaReleases, help={"Check to display beta releases?"}, title="  Include Beta releases in list?"
103        Checkbox UseLocalFolder, pos={250,50}, size={100,20}, variable = root:Packages:GHInstaller:UseLocalFolder, proc=GHW_CheckProc
104        Checkbox UseLocalFolder, help={"Check to use Local Folder?"}, title="  Use Local folder?"
105        PopupMenu SelectReleaseToInstall,pos={233.00,75.00},size={231.00,23.00},bodyWidth=120,proc=GHW_PopMenuProc,title="Select Release to Install:"
106        PopupMenu SelectReleaseToInstall,help={"Select release to install"}
107        PopupMenu SelectReleaseToInstall,mode=1,value= #"root:Packages:GHInstaller:PopListOfReleaseNames"
108        SetVariable ReleaseNotes variable = root:Packages:GHInstaller:ReleaseNotes
109        SetVariable ReleaseNotes pos={10,98},size={570,18},disable=2
110        ListBox InstallationSelection,pos={10.00,120.00},size={362.00,177.00}
111        ListBox InstallationSelection,listWave=root:Packages:GHInstaller:VersionsAndInstall
112        ListBox InstallationSelection,selWave=root:Packages:GHInstaller:SelVersionsAndInstall
113        ListBox InstallationSelection,mode= 8,userColumnResize= 1
114
115        Button GetHelp,pos={480,45},size={110,20},proc=GHW_ButtonProc,title="Get Help"
116        Button InstallPackages,pos={390,126},size={200,20},proc=GHW_ButtonProc,title="Install/Update Selected", fColor=(16386,65535,16385)
117        Button UninstallPackages,pos={390,155},size={200,20},proc=GHW_ButtonProc,title="Uninstall Selected", fColor=(16386,65535,16385)
118
119        Button OpenWebSIte,pos={390,200},size={200,18},proc=GHW_ButtonProc,title="Ilavsky Web site"
120        Button OpenGitHub,pos={390,230},size={200,18},proc=GHW_ButtonProc,title="Github depository"
121        Button SignupIrena,pos={390,260},size={200,18},proc=GHW_ButtonProc,title="Sign up for Irena mailing list"
122        Button SignUpNika,pos={390,290},size={200,18},proc=GHW_ButtonProc,title="Sign up for Nika mailing list"
123//
124        DrawText 5,320,"Version 1.13 of Github Installer, JIL."
125        DrawText 5,335,"Please, check the web site for latest version before using."
126end
127//****************************************************************
128//****************************************************************
129//**************************************************************** //****************************************************************
130//****************************************************************
131//****************************************************************
132
133Function GHW_CheckProc(cba) : CheckBoxControl
134        STRUCT WMCheckboxAction &cba
135       
136        NVAR DisplayBetaReleases = root:Packages:GHInstaller:DisplayBetaReleases
137
138        switch( cba.eventCode )
139                case 2: // mouse up
140                        Variable checked = cba.checked
141                        if(stringmatch(cba.ctrlName,"DisplayBetaReleases"))
142                                GHW_PrepareGUIData()
143                                //Inst_CheckForLocalCopyPresence()
144                        endif
145                        if(stringmatch(cba.ctrlName,"UseLocalFolder"))
146                                SVAR LocalFolderPath    =       root:Packages:GHInstaller:LocalFolderPath
147                                NVAR UseLocalFolder     =       root:Packages:GHInstaller:UseLocalFolder
148                                NVAR DisplayBetaReleases = root:Packages:GHInstaller:DisplayBetaReleases
149                                if(checked)
150                                        PathInfo/S userDesktop
151                                        NewPath /M="Select Location of Folder with data downloaded from GitHub"  /O/Q LocalInstallationFolder 
152                                        PathInfo LocalInstallationFolder
153                                        LocalFolderPath = S_path
154                                        DisplayBetaReleases = 0
155                                else
156                                        KillPath/Z LocalInstallationFolder
157                                endif
158                                GHW_DwnldConfFileAndScanLocal(1)
159                                GHW_PrepareGUIData()
160                                //Inst_CheckForLocalCopyPresence()
161                        endif
162                        break
163                case -1: // control being killed
164                        break
165        endswitch
166
167        return 0
168End
169
170//****************************************************************
171//****************************************************************
172//****************************************************************
173//****************************************************************
174
175Function GHW_ButtonProc(ba) : ButtonControl
176        STRUCT WMButtonAction &ba
177
178        switch( ba.eventCode )
179                case 2: // mouse up
180                        //check Igor Pro version and bail out if not higher than 7.00
181                        string IgorInfoStr=IgorInfo(0)
182                        if(IgorVersion()<7.00)
183                                Abort "This code requires Igor 7.00 or higher, please update your Igor Pro."
184                        endif
185                       
186                        if(stringMatch(ba.ctrlName,"CheckVersions"))
187                                GHW_DwnldConfFileAndScanLocal(1)
188                                GHW_PrepareGUIData()
189                        endif
190
191                        if(stringMatch(ba.ctrlName,"InstallPackages")) 
192                                if(GHW_IsThereWhatToDo())
193                                        GHW_Install()   
194                                        GHW_DwnldConfFileAndScanLocal(1)
195                                        GHW_PrepareGUIData()
196                                else
197                                        DoALert 0, "Nothing to do, select some packages to install"
198                                endif
199                        endif
200                       
201                        if(stringMatch(ba.ctrlName,"OpenWebSite"))                     
202                                BrowseURL "http://usaxs.xray.aps.anl.gov/staff/ilavsky/index.html"
203                        endif
204                        if(stringMatch(ba.ctrlName,"OpenGitHub"))                       
205                                BrowseURL "https://github.com/jilavsky/SAXS_IgorCode"
206                        endif
207                        if(stringMatch(ba.ctrlName,"SignupIrena"))                     
208                                BrowseURL "http://www.aps.anl.gov/mailman/listinfo/irena_users"
209                        endif
210                        if(stringMatch(ba.ctrlName,"SignUpNika"))                       
211                                BrowseURL "http://www.aps.anl.gov/mailman/listinfo/nika_users"
212                        endif
213
214
215                        if(stringMatch(ba.ctrlName,"UninstallPackages"))
216                                if(GHW_IsThereWhatToDo())
217                                        GHW_Uninstall()
218                                        GHW_DwnldConfFileAndScanLocal(1)
219                                        GHW_PrepareGUIData()
220                                else
221                                        DoALert 0, "Nothing to do, select some packages to uninstall"
222                                endif
223                        endif
224                                               
225                        if(stringMatch(ba.ctrlName,"GetHelp"))
226                                GHW_GenerateHelp()
227                        endif
228                       
229                        break
230        endswitch
231
232        return 0
233End
234//****************************************************************
235Function GHW_IsThereWhatToDo()
236        Wave SelVersionsAndInstall = root:Packages:GHInstaller:SelVersionsAndInstall   
237        variable NumPckgs = DimSize(SelVersionsAndInstall, 0 )
238        variable i, result
239        result = 0
240        for(i=0;i<NumPckgs;i+=1)
241                result += SelVersionsAndInstall[i][3] > 32 ? 1 : 0
242        endfor
243       
244        return result
245
246end//****************************************************************
247//****************************************************************
248Function GHW_PopMenuProc(pa) : PopupMenuControl
249        STRUCT WMPopupAction &pa
250
251        switch( pa.eventCode )
252                case 2: // mouse up
253                        Variable popNum = pa.popNum
254                        String popStr = pa.popStr
255                        if(StringMatch(pa.ctrlName, "SelectReleaseToInstall"))
256                                //fix something here...
257                                SVAR SelectedReleaseName = root:Packages:GHInstaller:SelectedReleaseName
258                                SelectedReleaseName = popStr
259                                GHW_PrepareListboxGUIData()
260                        endif
261                        break
262                case -1: // control being killed
263                        break
264        endswitch
265
266        return 0
267End
268
269//****************************************************************
270//****************************************************************
271//****************************************************************
272//****************************************************************
273//****************************************************************
274static Function GHW_ListIgorProcFiles()
275        GetFileFolderInfo/Q/Z/P=Igor "Igor Procedures" 
276        if(V_Flag==0)
277                GHW_ListProcFiles(S_Path,1 )
278        endif
279        GetFileFolderInfo/Q/Z GHW_GetIgorUserFilesPath()+"Igor Procedures:"
280        if(V_Flag==0)
281                GHW_ListProcFiles(GHW_GetIgorUserFilesPath()+"Igor Procedures:",0)
282        endif
283        KillPath/Z tempPath
284end
285 //****************************************************************
286//****************************************************************
287 //****************************************************************
288//****************************************************************
289//****************************************************************
290//****************************************************************
291//****************************************************************
292//****************************************************************
293static Function GHW_ListIgorExtensionsFiles()
294        GetFileFolderInfo/Q/Z/P=Igor "Igor Extensions" 
295        if(V_Flag==0)
296                GHW_ListProcFiles(S_Path, 1)
297        endif
298        GetFileFolderInfo/Q/Z (GHW_GetIgorUserFilesPath()+"Igor Extensions:")
299        if(V_Flag==0)
300                GHW_ListProcFiles(GHW_GetIgorUserFilesPath()+"Igor Extensions:",0)
301        endif
302        KillPath/Z tempPath
303end
304
305//****************************************************************
306//****************************************************************
307static Function /S GHW_Windows2IgorPath(pathIn)
308        String pathIn
309        String pathOut = ParseFilePath(5, pathIn, ":", 0, 0)
310        return pathOut
311End
312
313static Function/S GHW_GetIgorUserFilesPath()
314        // This should be a Macintosh path but, because of a bug prior to Igor Pro 6.20B03
315        // it may be a Windows path.
316        String path = SpecialDirPath("Igor Pro User Files", 0, 0, 0)
317        path = GHW_Windows2IgorPath(path)
318        return path
319End
320//****************************************************************
321//****************************************************************
322//****************************************************************
323//****************************************************************
324static Function GHW_ListProcFiles(PathStr, resetWaves)
325        string PathStr
326        variable resetWaves
327       
328        String abortMessage     //HR Used if we have to abort because of an unexpected error
329       
330        string OldDf=GetDataFolder(1)
331        //create location for the results waves...
332        NewDataFolder/O/S root:Packages
333        NewDataFolder/O/S root:Packages:UseProcedureFiles
334        //if this is top call to the routine we need to wipe out the waves so we remove old junk
335        string CurFncName=GetRTStackInfo(1)
336        string CallingFncName=GetRTStackInfo(2)
337        variable runningTopLevel=0
338        if(!stringmatch(CurFncName,CallingFncName))
339                runningTopLevel=1
340        endif
341        if(resetWaves)
342                        Make/O/N=0/T FileNames         
343                        Make/O/N=0/T PathToFiles
344                        Make/O/N=0 FileVersions
345        endif
346       
347       
348        //if this was first call, now the waves are gone.
349        //and now we need to create the output waves
350        Wave/Z/T FileNames
351        Wave/Z/T PathToFiles
352        Wave/Z FIleVersions
353        If(!WaveExists(FileNames) || !WaveExists(PathToFiles) || !WaveExists(FIleVersions))
354                Make/O/T/N=0 FileNames, PathToFIles
355                Make/O/N=0 FileVersions
356                Wave/T FileNames
357                Wave/T PathToFiles
358                Wave FileVersions
359                //I am not sure if we really need all of those declarations, but, well, it should not hurt...
360        endif
361        string str
362        //this is temporary path to the place we are looking into now... 
363        NewPath/Q/O tempPath, PathStr
364        if (V_flag != 0)                //HR Add error checking to prevent infinite loop
365                sprintf abortMessage, "Unexpected error creating a symbolic path pointing to \"%s\"", PathStr
366                str= abortMessage       // To make debugging easier
367                //Inst_Append2Log(str,0)
368                Abort abortMessage
369        endif
370
371        //list al items in this path
372        string ItemsInTheFolder= IndexedFile(tempPath,-1,"????")+IndexedDir(tempPath, -1, 0 )   
373        //HR If there is a shortcut in "Igor Procedures", ItemsInTheFolder will include something like "HDF5 Browser.ipf.lnk". Windows shortcuts are .lnk files.       
374        //remove all . files.
375        ItemsInTheFolder = GrepList(ItemsInTheFolder, "^\." ,1)
376        //Now we removed all junk files on Macs (starting with .)
377        //now lets check what each of these files are and add to the right lists or follow...
378        variable i, imax=ItemsInList(ItemsInTheFolder)
379        string tempFileName, tempScraptext, tempPathStr
380        variable IamOnMac, isItXOP
381        if(stringmatch(IgorInfo(2),"Windows"))
382                IamOnMac=0
383        else
384                IamOnMac=1
385        endif
386        For(i=0;i<imax;i+=1)
387                tempFileName = stringfromlist(i,ItemsInTheFolder)
388                GetFileFolderInfo/Z/Q/P=tempPath tempFileName
389                isItXOP = IamOnMac * stringmatch(tempFileName, "*xop*" )
390               
391                if(V_isAliasShortcut)
392                        //HR If tempFileName is "HDF5 Browser.ipf.lnk", or any other shortcut to a file, S_aliasPath is a path to a file, not a folder.
393                        //HR Thus the "NewPath tempPath" command will fail.
394                        //HR Thus tempPath will retain its old value, causing you to recurse the same folder as before, resulting in an infinite loop.
395                       
396                        //is alias, need to follow and look further. Use recursion...
397                        if(strlen(S_aliasPath)>3)               //in case user has stale alias, S_aliasPath has 0 length. Need to skip this pathological case.
398                                //HR Recurse only if S_aliasPath points to a folder. I don't really know what I'm doing here but this seems like it will prevent the infinite loop.
399                                GetFileFolderInfo/Z/Q/P=tempPath S_aliasPath   
400                                isItXOP = IamOnMac * stringmatch(S_aliasPath, "*xop*" )
401                                if (V_flag==0 && V_isFolder&&!isItXOP)          //this is folder, so all items in the folder are included... Except XOP is folder too...
402                                        GHW_ListProcFiles(S_aliasPath, 0)
403                                elseif(V_flag==0 && (!V_isFolder || isItXOP))   //this is link to file. Need to include the info on the file...
404                                        //*************
405                                        Redimension/N=(numpnts(FileNames)+1) FileNames, PathToFiles,FileVersions
406                                        tempFileName =stringFromList(ItemsInList(S_aliasPath,":")-1, S_aliasPath,":")
407                                        tempPathStr = RemoveFromList(tempFileName, S_aliasPath,":")
408                                        FileNames[numpnts(FileNames)-1] = tempFileName
409                                        PathToFiles[numpnts(FileNames)-1] = tempPathStr
410                                        //try to get version from #pragma version = ... This seems to be the most robust way I found...
411                                        NewPath/Q/O tempPath, tempPathStr
412                                        if(stringmatch(tempFileName, "*.ipf"))
413                                                Grep/P=tempPath/E="(?i)^#pragma[ ]*version[ ]*=[ ]*" tempFileName as "Clipboard"
414                                                sleep/s (0.02)
415                                                tempScraptext = GetScrapText()
416                                                if(strlen(tempScraptext)>10)            //found line with #pragma version"
417                                                        tempScraptext = replaceString("#pragma",tempScraptext,"")       //remove #pragma
418                                                        tempScraptext = replaceString("version",tempScraptext,"")               //remove version
419                                                        tempScraptext = replaceString("=",tempScraptext,"")                     //remove =
420                                                        tempScraptext = replaceString("\t",tempScraptext,"  ")                  //remove optional tabulators, some actually use them.
421                                                        tempScraptext = removeending(tempScraptext," \r")                       //remove optional tabulators, some actually use them.
422                                                        //forget about the comments behind the text.
423                                                       //str2num is actually quite clever in this and converts start of the string which makes sense.
424                                                        FileVersions[numpnts(FileNames)-1]=str2num(tempScraptext)
425                                                else             //no version found, set to NaN
426                                                        FileVersions[numpnts(FileNames)-1]=NaN
427                                                endif
428                                        else                    //no version for non-ipf files
429                                                FileVersions[numpnts(FileNames)-1]=NaN
430                                        endif
431                                        //************
432                                endif
433                        endif
434                        //and now when we got back, fix the path definition to previous or all will crash...
435                        NewPath/Q/O tempPath, PathStr
436                        if (V_flag != 0)                //HR Add error checking to prevent infinite loop
437                                sprintf abortMessage, "Unexpected error creating a symbolic path pointing to \"%s\"", PathStr
438                                str= abortMessage       // To make debugging easier
439                        //      Inst_Append2Log(str,0)
440                                Abort abortMessage
441                        endif
442                elseif(V_isFolder&&!isItXOP)   
443                        //is folder, need to follow into it. Use recursion.
444                        GHW_ListProcFiles(PathStr+tempFileName+":", 0)
445                        //and fix the path back or all will fail...
446                        NewPath/Q/O tempPath, PathStr
447                        if (V_flag != 0)                //HR Add error checking to prevent infinite loop
448                                sprintf abortMessage, "Unexpected error creating a symbolic path pointing to \"%s\"", PathStr
449                                str= abortMessage       // To make debugging easier
450                        //      Inst_Append2Log(str,0)
451                                Abort abortMessage
452                        endif
453                elseif(V_isFile||isItXOP)
454                        //this is real file. Store information as needed.
455                        Redimension/N=(numpnts(FileNames)+1) FileNames, PathToFiles,FileVersions
456                        FileNames[numpnts(FileNames)-1] = tempFileName
457                        PathToFiles[numpnts(FileNames)-1] = PathStr
458                        //try to get version from #pragma version = ... This seems to be the most robust way I found...
459                        if(stringmatch(tempFileName, "*.ipf"))
460                                Grep/P=tempPath/E="(?i)^#pragma[ ]*version[ ]*=[ ]*" tempFileName as "Clipboard"
461                                sleep/s(0.02)
462                                tempScraptext = GetScrapText()
463                                if(strlen(tempScraptext)>10)            //found line with #pragma version"
464                                        tempScraptext = replaceString("#pragma",tempScraptext,"")       //remove #pragma
465                                        tempScraptext = replaceString("version",tempScraptext,"")               //remove version
466                                        tempScraptext = replaceString("=",tempScraptext,"")                     //remove =
467                                        tempScraptext = replaceString("\t",tempScraptext,"  ")                  //remove optional tabulators, some actually use them.
468                                        //forget about the comments behind the text.
469                                       //str2num is actually quite clever in this and converts start of the string which makes sense.
470                                        FileVersions[numpnts(FileNames)-1]=str2num(tempScraptext)
471                                else             //no version found, set to NaN
472                                        FileVersions[numpnts(FileNames)-1]=NaN
473                                endif
474                        else                    //no version for non-ipf files
475                                FileVersions[numpnts(FileNames)-1]=NaN
476                        endif
477                endif
478        endfor
479        setDataFolder OldDf
480end
481
482
483//***********************************
484//***********************************
485//***********************************
486//***********************************
487
488//static
489Function GHW_FileFolderExists(name,[path,file,folder])  // returns 1=exists, 0=does not exist
490        String name                                     // partial or full file name or folder name
491        String path                                     // optional path name, e.g. "home"
492        Variable file,folder    // flags, if both set or both unset, it checks for either
493        path = SelectString(ParamIsDefault(path),path,"")
494        file = ParamIsDefault(file) ? 0 : file
495        file = numtype(file) ? 0 : !(!file)
496        folder = ParamIsDefault(folder) ? 0 : folder
497        folder = numtype(folder) ? 0 : !(!folder)
498
499        if (!file && !folder)   // check for either
500                file = 1
501                folder = 1
502        endif
503
504        if (strlen(path))
505                PathInfo $path
506                if (V_flag==0)
507                        return 0
508                endif
509                name = S_path+name      // add the path to name
510        endif
511
512        GetFileFolderInfo/Q/Z=1 name
513        Variable found=0
514        found = found || (file ? V_isFile : 0)
515        found = found || (folder ? V_isFolder : 0)
516        return found
517End
Note: See TracBrowser for help on using the repository browser.