Jump to content


This is a ready-only archive of the InstallSite Forum. You cannot post any new content here. / Dies ist ein Archiv des InstallSite Forums. Hier können keine neuen Beiträge veröffentlicht werden.
Photo

Working out Number of files in a file group


3 replies to this topic

baker_tony

baker_tony
  • Members
  • 5 posts

Posted 01 May 2003 - 10:22

Hi, I have file groups which have dynamic links to folders. I have a component for each file group.

The problem is, I don't want the Component to be visible if its
corresponding file group contains no files.

This may happen when a more "simple" client doesn't need the advanced
files, so the folders that the file groups point to are empty.

How can I check at run time if a file group contains files or not? That way I can set the corresponding component's visible propertly to No.

Many thanks.

Taco Bell

Taco Bell

    IS6 Expert

  • Moderators
  • 1,281 posts

Posted 01 May 2003 - 20:12

Unfortunately, there are no methods to access the properties of existing file groups.
user posted image

baker_tony

baker_tony
  • Members
  • 5 posts

Posted 02 May 2003 - 12:27

What a pain. Here is C++ code to find out the number of files in a folder.
I hope the someone might find it useful!
I have a batch file that runs this exe first which parses an ini file and spits the result out to a file that I can parse in InstallShield at run time (check out comments). The batch file then builds the install.
Here is the code (I don't know why the indentation goes away). I just create a basic console application in Visual Studio and pase this over the main file. Use at your own risk:

/*
This program will look for GetFilesSettings.ini in the same location
as the exe.

GetFilesSettings.ini should look something like this:
_____________
[Folders]
C:\Installs\Client Specific Files\Coef Files
C:\Installs\Client Specific Files\Load Files
C:\Installs\Client Specific Files\Model Ini file
C:\Installs\Client Specific Files\Models
C:\Installs\Client Specific Files\Mpan Files
C:\Installs\Client Specific Files\Release Documentation
C:\Installs\Client Specific Files\Templates
C:\Installs\Client Specific Files\Wx
[Output]
C:\Installs\Full Install\Setup Files\Uncompressed Files\Language Independent\OS Independent\files.txt
_____________

[Folders] is a list of folders you want to check to see if they contain files
[Output] is where the resulting output of the program will go.

the output will be the folder name on one line and under that the number of
folders and files that are in the folder.

Can then parse the file in InstallShield script to find out how many files
are in a file group.
*/

//#include <winbase.h>
#include "stdafx.h"
#include <string>
#include <fstream>
#include <vector>
#include <iostream>
#include <atlbase.h>
#include <stdlib.h>
using namespace std;

//will return a vector containing all the lines under the [Folders] tag
vector<string> GetFolders( vector<string> &file )
{
vector<string> folders;
bool found = false;
vector<string>::iterator fileIter = file.begin(); //used to iterate through the file

//for(pos = 0; pos < file.size(); pos++) //find the [Folders] tag
while( fileIter != file.end() )
{
if(*fileIter == "[Folders]") //if the current line is what we want
{
found = true;
break;
}
fileIter++; //move to the next line
}

if(found) //found output tag
{
fileIter++; //move to the line after the tag
while( fileIter != file.end() )
{
string line = *fileIter;
if(line[0] == '[') //if we have found the next tag
break; //don't want to read any more
else
{
if( line != "" ) //if not a blank line
folders.push_back(line); //add the line to the list of folders
}
fileIter++; //move to the next line
}
}
else
{
cout << "Couldn't find the tag \"[Folders]\" in the ini file" << endl;
}

return folders; //return the list of folders after the [Folders] tag
}

//will look in .ini file and return the output file
string GetOutputFile( vector<string> &file )
{
bool found = false;
int pos = 0;
for(pos = 0; pos < file.size(); pos++) //find the [Output] tag
{
string line = file[pos];
if(file[pos] == "[Output]") //if found [Output]
{
found = true;
break;
}
}

if(found) //found output tag
{
string outputFile = file[pos+1]; //line after [Output] should be the output file name
cout << "Output file: " << outputFile << endl;
return outputFile;
}
else
{
cout << "Couldn't find the tag \"[Output]\" in the ini file" << endl;
}

return "";
}

//this will output a file specified under [Output]
void CreateOutputFile( vector<string> &file )
{
string outputFile = GetOutputFile(file);

//open output file
std::ofstream fout;
fout.open( outputFile.c_str(), std::ios::out);

if( fout.is_open() ) //if it opened ok
{
vector<string> foldersToCheck = GetFolders(file); //will hold the list of folders under the [Folders] tag

//output to screen the list of folders
cout << endl << "Folders to check if empty:" << endl;
for(int i = 0; i < foldersToCheck.size(); i++)
{
cout << foldersToCheck[i] << endl;
}

//for each folder, check to see if it is empty
for(int j = 0; j < foldersToCheck.size(); j++)
{
int numFiles = 0; //will be set to the number of files and folders in this folder

WIN32_FIND_DATA fileFindData; // pointer to returned information
//try to find any file in the folder
string wildcard = foldersToCheck[j]+"\*";
HANDLE result = FindFirstFile( wildcard.c_str(), &fileFindData );

if( result != INVALID_HANDLE_VALUE ) //if found a file or folder
{
if( fileFindData.cFileName[0] != '.' ) //don't want to include . and .. folders
numFiles++; //increment number of files.
while( FindNextFile(result, &fileFindData) ) //while we can find files
{
if( fileFindData.cFileName[0] != '.' ) //don't want to include . and .. folders
numFiles++; //increment number of files.
}
}

//convert the number of files to text representation
char buffer[4] = {'<!--POST BOX-->'};
_itoa( numFiles, buffer, 10 );
string outLine = foldersToCheck[j] + '<!--POST BOX-->';

fout.write( outLine.c_str(), outLine.size() ); //folder
fout.write( "\r\n", 2 ); //new line

fout.write( buffer, 4 ); //number of files
fout.write( "\r\n", 2 ); //new line
}

fout.close();
}
else
{
cout << "Couldn't open file '" << outputFile << "'" << endl;
}
}

int main(int argc, char* argv[])
{
string fileName = "GetFilesSettings.ini";

//Try to open file.
//should be in same location as exe
std::ifstream fin;
fin.open( fileName.c_str(), std::ios::in);

if( fin.is_open() ) //if it opened ok
{
//read in file
const int bufsize = 1024;
char delim = '\n' ;
char buf[bufsize] ;

vector<string> file; //used to hold the contents of the file
while(fin.getline(buf,bufsize,delim)) // Checking for the end of file
{
string strBuf( buf );

if( strBuf.length() != 0 ) //we don't need no stinking blank lines!!!
{
file.push_back( strBuf );
}
}

fin.close();

if( file.size() == 0 ) //if we have not found a valid tesla.ini file
{
cout << "Nothing in file: " << fileName << endl;
}
else
{
CreateOutputFile( file );
}
}
else
{
cout << "Couldn't open file: " << fileName << endl;
}

fin.close();

return 0;
}



baker_tony

baker_tony
  • Members
  • 5 posts

Posted 02 May 2003 - 14:34

And here is my InstallShield code:

///////////////////////////////////////////////////////////////////////////////
//
// Function: HideUnnessaryComponents (mine)
//
// Purpose: Will open files.txt and hide the components that don't have files in them
//
///////////////////////////////////////////////////////////////////////////////
function HideUnnessaryComponents( )
STRING szPath, szFileName, line, compare, szData;
number nvFileHandle, nvResult;
begin
szPath = SUPPORTDIR;
szFileName = "Files.txt";
OpenFileMode(FILE_MODE_NORMAL); //text read only
if( OpenFile (nvFileHandle, szPath, szFileName) == 0 ) then
//found file
//expect it to read:
/*
C:\Installs\Client Specific Files\Coef Files
0
C:\Installs\Client Specific Files\Load Files
2
C:\Installs\Client Specific Files\Model Ini file
0
C:\Installs\Client Specific Files\Models
0
C:\Installs\Client Specific Files\Mpan Files
0
C:\Installs\Client Specific Files\Release Documentation
0
C:\Installs\Client Specific Files\Templates
0
C:\Installs\Client Specific Files\Wx
0
*/
if( LineEquals( nvFileHandle, "C:\Installs\Client Specific Files\Coef Files" ) ) then
GetLine( nvFileHandle, line );
if( StrCompare(line, "0") == 0 ) then //if there are no files to display
//make the corresponding component invisible
ComponentSetData ( MEDIA, "Client Files\Coefficient", COMPONENT_FIELD_VISIBLE, FALSE, szData ); //hid
bcoefDir = FALSE;
endif;
endif;

if( LineEquals( nvFileHandle, "C:\Installs\Client Specific Files\Load Files" ) ) then
GetLine( nvFileHandle, line );
if( StrCompare(line, "0") == 0 ) then //if there are no files to display
//make the corresponding component invisible
ComponentSetData ( MEDIA, "Client Files\Load", COMPONENT_FIELD_VISIBLE, FALSE, szData ); //hid
bloadDir = FALSE;
endif;
endif;

if( LineEquals( nvFileHandle, "C:\Installs\Client Specific Files\Model Ini file" ) ) then
GetLine( nvFileHandle, line );
//don't worry about model ini folder
/*
if( StrCompare(line, "0") == 0 ) then //if there are no files to display
//make the corresponding component invisible
ComponentSetData ( MEDIA, "Client Files\Models", COMPONENT_FIELD_VISIBLE, FALSE, szData ); //hid
bmodelDir = FALSE;
endif;
*/
endif;

if( LineEquals( nvFileHandle, "C:\Installs\Client Specific Files\Models" ) ) then
GetLine( nvFileHandle, line );
if( StrCompare(line, "0") == 0 ) then //if there are no files to display
//make the corresponding component invisible
ComponentSetData ( MEDIA, "Client Files\Models", COMPONENT_FIELD_VISIBLE, FALSE, szData ); //hid
bmodelDir = FALSE;
endif;
endif;

if( LineEquals( nvFileHandle, "C:\Installs\Client Specific Files\Mpan Files" ) ) then
GetLine( nvFileHandle, line );
if( StrCompare(line, "0") == 0 ) then //if there are no files to display
//make the corresponding component invisible
ComponentSetData ( MEDIA, "Client Files\Mpans", COMPONENT_FIELD_VISIBLE, FALSE, szData ); //hid
bmpanDir = FALSE;
endif;
endif;

if( LineEquals( nvFileHandle, "C:\Installs\Client Specific Files\Release Documentation" ) ) then
GetLine( nvFileHandle, line );
//don't worry about Release Documentation
/*
if( StrCompare(line, "0") == 0 ) then //if there are no files to display
//make the corresponding component invisible
ComponentSetData ( MEDIA, "Client Files\Mpans", COMPONENT_FIELD_VISIBLE, FALSE, szData ); //hid
bmpanDir = FALSE;
endif;
*/
endif;

if( LineEquals( nvFileHandle, "C:\Installs\Client Specific Files\Templates" ) ) then
GetLine( nvFileHandle, line );
if( StrCompare(line, "0") == 0 ) then //if there are no files to display
//make the corresponding component invisible
ComponentSetData ( MEDIA, "Client Files\Templates", COMPONENT_FIELD_VISIBLE, FALSE, szData ); //hid
btemplatesDir = FALSE;
endif;
endif;

if( LineEquals( nvFileHandle, "C:\Installs\Client Specific Files\Wx" ) ) then
GetLine( nvFileHandle, line );
if( StrCompare(line, "0") == 0 ) then //if there are no files to display
//make the corresponding component invisible
ComponentSetData ( MEDIA, "Client Files\Wx", COMPONENT_FIELD_VISIBLE, FALSE, szData ); //hid
bwxDir = FALSE;
endif;
endif;
endif;

if(bmodelDir == FALSE
&& bwxDir == FALSE
&& bloadDir == FALSE
&& bcoefDir == FALSE
&& bmpanDir == FALSE
&& btemplatesDir == FALSE) then
//no client files, don't display Client Files component
ComponentSetData ( MEDIA, "Client Files", COMPONENT_FIELD_VISIBLE, FALSE, szData ); //hid
endif;
end;




///////////////////////////////////////////////////////////////////////////////
//
// Function: LineEquals (mine)
//
// Purpose: Given a file handle, will see if the current line equals checkLine
// Returns TRUE if the checkLine and line in file equal
//
///////////////////////////////////////////////////////////////////////////////
function LineEquals( nvFileHandle, checkLine )
string line, szPath, szFileName;
number nvResult;
begin
GetLine( nvFileHandle, line );
nvResult = StrCompare(line, checkLine);
if( nvResult != 0 ) then
MessageBox(szPath^szFileName+" is incorrect. Will now display all options.", INFORMATION);
return FALSE;
endif;
return TRUE; // lines equal
end;