Indigo Rose Software

Professional Software Development Tools

 
Results 1 to 9 of 9

Thread: find a file

  1. #1
    Join Date
    Sep 2005
    Location
    uk
    Posts
    12

    Oops find a file

    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.
    Life is good
    I reject your reality and substitute my own
    www.deeks.biz

  2. #2
    Join Date
    Oct 2005
    Location
    MI
    Posts
    524
    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)))))))==============================================

  3. #3
    Join Date
    Sep 2005
    Location
    uk
    Posts
    12

    sort of works

    I get an error on line 40, that t_FileFolder[1] is a nil value
    Life is good
    I reject your reality and substitute my own
    www.deeks.biz

  4. #4
    Join Date
    Oct 2005
    Location
    MI
    Posts
    524
    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)))))))==============================================

  5. #5
    Join Date
    Sep 2005
    Location
    uk
    Posts
    12

    Grin still not good

    I get line 40, attempt to call field `set`(a nil value)
    Life is good
    I reject your reality and substitute my own
    www.deeks.biz

  6. #6
    Join Date
    Oct 2005
    Location
    MI
    Posts
    524
    Code:
    SessionVar.Set("%AppFolder%", t_FileFolders[1]);
    Lua Script is case sensitive...
    Yeah right. Who's the only one here who knows the illegal ninja moves from the government?

    ()))))))))o)))))))==============================================

  7. #7
    Join Date
    Sep 2005
    Location
    uk
    Posts
    12

    Huh? still no good

    it now get "argument 2 must be of type string
    Life is good
    I reject your reality and substitute my own
    www.deeks.biz

  8. #8
    Join Date
    Oct 2005
    Location
    MI
    Posts
    524
    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:

    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
    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).

    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)))))))==============================================

  9. #9
    Join Date
    Mar 2005
    Location
    WA 'wait a while' - Australia
    Posts
    872
    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:

    Code:
    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
    hth

    (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.

Similar Threads

  1. Example File Find across multiple Drives
    By Eagle in forum Setup Factory 7.0
    Replies: 7
    Last Post: 11-11-2008, 04:49 AM
  2. Audio Tracks Project
    By Michael in forum AutoPlay Media Studio 5.0
    Replies: 7
    Last Post: 03-18-2004, 10:58 PM
  3. HOWTO: Create a Project Template
    By Support in forum AutoPlay Media Studio 4.0 Examples
    Replies: 0
    Last Post: 10-28-2002, 01:49 PM
  4. Can search allow manual browse even if file is found?
    By RichardShaw in forum Setup Factory 5.0
    Replies: 2
    Last Post: 08-28-2000, 06:08 PM
  5. Replies: 0
    Last Post: 08-17-2000, 02:29 PM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts