Hi all, could someone please help.
I have been asked to create a setup file that needs to find the directory that a product is in and set it in %AppFolder%, but I cant seem to get it sorted.![]()
Professional Software Development Tools
Hi all, could someone please help.
I have been asked to create a setup file that needs to find the directory that a product is in and set it in %AppFolder%, but I cant seem to get it sorted.![]()
This should get you started. I haven't included any logging, nor have I run it as I don't have SF7 on this machine. Let me know how it tests out.
Here's what I'm trying to do:
1. Find all the fixed drives on the system (in case the user installed to d:\ or something). I stop at fixed drives because otherwise your installer will crawl out on mapped network drives too.
2. Search each fixed drive for your program name and build a list of all locations (there could be multiples).
3. Set the %AppFolder% variable to the first instance found.
Code:-- Define the name of the file you want to search for g_YourProductName = "product.exe"; -- Setup the empty tables needed to hold your search results t_AllDrives = {}; t_FixedDrives = {}; t_FileFolders = {}; -- Search for all drives on the system t_AllDrives = Drive.Enumerate(); -- Check if the drives found are "fixed" and if so add them to a separtate table local index; local driveLetter; for index, driveLetter in t_AllDrives do if Drive.GetInformation(driveLetter) == 3 then Table.Insert(t_FixedDrives, (Table.Count(t_FixedDrives)+1), driveLetter); end end -- Searching for the file on each drive will return a table containing the paths to all locations of your file on that drive if t_FixedDrives then for index, driveLetter in t_FixedDrives do local filePath; t_FilePaths = {}; t_FilePaths = File.Find(driveLetter, g_YourProductName, true, false); if t_FilePaths then for index, filePath in t_FilePaths do Table.Insert(t_FileFolders, (Table.Count(t_FileFolders)+1), (String.SplitPath(filePath).Drive .. String.SplitPath(filePath).folder)); end end end end -- Now you have a table containing all the folders where your program was found. -- TO DO -- If more than one folder was found, you'll need to decide whether you want to default to the first folder on the list or prompt the user to make a choice... I've gone the default route here... if t_FileFolders then SessionVar.set("%AppFolder%", t_FileFolder[1]); end
Yeah right. Who's the only one here who knows the illegal ninja moves from the government?
()))))))))o)))))))==============================================
I get an error on line 40, that t_FileFolder[1] is a nil value
Sorry... line 40 should be:
Code:SessionVar.set("%AppFolder%", t_FileFolders[1]);
Yeah right. Who's the only one here who knows the illegal ninja moves from the government?
()))))))))o)))))))==============================================
I get line 40, attempt to call field `set`(a nil value)![]()
Lua Script is case sensitive...Code:SessionVar.Set("%AppFolder%", t_FileFolders[1]);
Yeah right. Who's the only one here who knows the illegal ninja moves from the government?
()))))))))o)))))))==============================================
it now get "argument 2 must be of type string![]()
I doubt this is the problem, but one thing I noticed that looks wierd is that I used local index variable twice inside the same routine... lets change those:
The "Argument 2 must be of type string" means that when we passed the t_FileFolders[1] variable to the SessionVar.Set() action, it contained something other than a string value. We can assume that it did not contain a nil value otherwise the error would have said so. This means that somewhere in our script, the t_FileFolder[1] variable was actually populated with a value of another type... likely a boolean (or maybe a number but lua is usually pretty good at converting those on the fly as needed).Code:-- Searching for the file on each drive will return a table containing the paths to all locations of your file on that drive if t_FixedDrives then for indexA, driveLetter in t_FixedDrives do local filePath; t_FilePaths = {}; t_FilePaths = File.Find(driveLetter, g_YourProductName, true, false); if t_FilePaths then for indexB, filePath in t_FilePaths do Table.Insert(t_FileFolders, (Table.Count(t_FileFolders)+1), (String.SplitPath(filePath).Drive .. String.SplitPath(filePath).folder)); end end end end
What you'll want to do next is add some checks in the code to help debug where that value is coming from. Most developers use one of the following three methods to view their debug info:
1. Add Dialog.Message() actions where ever you want the code to tell you what it is doing (Problem here is you have to go and pull them all out later).
2. Debug.Print() outputs to the debug window (don't forget to show the window first).
3. Setup Factory has some nice logging facilities integrated. You can write just about anything you want to the log file using the SetupData.WriteToLogFile() action.
As I said in my original post, I do not have regular access to a machine with SF installed so you'll have to do a little of the leg work on this one.
Yeah right. Who's the only one here who knows the illegal ninja moves from the government?
()))))))))o)))))))==============================================
Try this Stuff: exits on first file found , however you can modify to suit.
On Start Event for a Progress Screen:
Code:-- set lua variable of 'filename.exe' to search for g_YourProductName = "TryandFindthisOneifYouCan.exe"; --set some basic progress bar parameters local nmax = 1024; DlgProgressBar.SetRange(CTRL_PROGRESS_BAR_01, 0, nmax); DlgProgressBar.SetStep(CTRL_PROGRESS_BAR_01, 5); -- now call the global function FindTarget(g_YourProductName) if FindTarget(g_YourProductName) then DlgProgressBar.SetPos(CTRL_PROGRESS_BAR_01, nmax); SessionVar.Set("%AppFolder%", strAppFolderPath); Dialog.Message("Debug allocated Session Variable", SessionVar.Expand("%AppFolder%")); --remove else DlgProgressBar.SetPos(CTRL_PROGRESS_BAR_01, nmax); Dialog.Message("Debug allocated Session Variable", "Target file: "..g_YourProductName.." was Not found"); --remove --action-s how you wish to handle continuing with 'installer' end
for Global Functions:
hthCode:function Find_CB() --basic callback display for use with a 'progress' screen local npos = DlgProgressBar.GetPos(CTRL_PROGRESS_BAR_01); if (npos >= 1024) then DlgProgressBar.SetPos(CTRL_PROGRESS_BAR_01, 0); return true; --continue else DlgProgressBar.SetPos(CTRL_PROGRESS_BAR_01, npos + 1); return true; --continue end end function FindTarget(Sbintgt) -- Setup localised empty tables needed to hold your search results local t_FilePaths = {}; local t_FileFolders = {}; local t_FixedDrives = {}; if Sbintgt then -- Search for all drives on the system local t_AllDrives = Drive.Enumerate(); if t_AllDrives then -- Check if the drives found are "fixed" and if so add them to a separate table for n, driveLetter in t_AllDrives do if (Drive.GetType(driveLetter) == 3) then Table.Insert(t_FixedDrives, (Table.Count(t_FixedDrives)+1), driveLetter); end end end end -- Search for the file on each drive if (Table.Count(t_FixedDrives) >=1) then local bfoundtgt; for n, driveLetter in t_FixedDrives do if bfoundtgt then break end --break out of main loop --local t_FilePaths = File.Find(driveLetter, Sbintgt, true, false); --no callback display local t_FilePaths = File.Find(driveLetter, Sbintgt, true, false, Find_CB); --include the call back function(slows search performance) if t_FilePaths then for n, filePath in t_FilePaths do local pathsplit = String.SplitPath(filePath); if (pathsplit ~= "") then local folder_path = pathsplit.Drive..pathsplit.Folder; Table.Insert(t_FileFolders, (Table.Count(t_FileFolders)+1), folder_path); bfoundtgt = true; break; --exit on first found end end end end end if (Table.Count(t_FileFolders) >=1) then strAppFolderPath = t_FileFolders[1]; return true; else return false; end end
(searches for filenames is the least efficient and most open to wrong ID
for a target install location)
if you can be provided with a registry key which has a path to the Application
you can use this method and then verify if the mainapp.exe exists.
Last edited by Eagle; 03-07-2006 at 08:23 AM.