Notes on a USB Key – Chapter 2
I changed the code for my project “Wendy” once again. In the former version of nstart.exe, the file had to be copied to the Notes executable directory.
This is no longer necessary now; you can copy nstart.exe to i.e the “root” directory of your USB key, regardless of where your Notes Client is installed. nstart.exe locates the notes.ini and notes.exe, makes the necessary changes and starts the client.
This is NOT project “WANDA”, IBM announced at Lotusphere2006. It is my solution on how to put a Notes client “installation” on a USB key. But I’m eager to see what IBM’s solution will look like.
Does anyone have some information about project “WANDA” ?
/////////////////////////////////////////////////////////////////////////////
// nstart.cpp
/////////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "nstart.h"
#include "SADirRead.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
#define NOTES_INI "notes.ini"
#define NOTES_PRG "notes.exe"
#define BACKSLASH ":\\"
CString Drives ="CDEFGHIJKLMNOPQRSTUVWXYZcdefghijklmnopqrstuvwxyz";
CFile* fin = NULL;
CFile* fout = NULL;
CWinApp theApp;
CSADirRead FSearch;
CFileException ex;
CString THE_NOTES_INI;
CString THE_NOTES_EXE;
char AppPath[MAX_PATH];
char pbuf[99999];
int i, j, m, n;
using namespace std;
/////////////////////////////////////////////////////////////////////////////
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
int nRetCode = 0;
if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
{
cerr < < _T("Fatal Error: MFC initialization failed") << endl;
nRetCode = 1;
}
else
try
{
GetModuleFileName(AfxGetApp()->m_hInstance,AppPath,MAX_PATH);
CString BS(_T(BACKSLASH));
CString strPath(AppPath);
CString ThisDrive (strPath.Left(1) + BS);
FSearch.ClearDirs();
FSearch.GetDirs(ThisDrive, true);
FSearch.ClearFiles();
FSearch.GetFiles(NOTES_INI);
CSADirRead::SAFileVector &IniFile = FSearch.Files();
for (CSADirRead::SAFileVector::const_iterator m = IniFile.begin();
m!=IniFile.end(); m++) {
THE_NOTES_INI = ("%s\n", (*m).m_sName);
}
fin = new CFile( THE_NOTES_INI,
CFile::modeRead | CFile::shareDenyNone);
// read NOTES.INI
ULONGLONG dwLength = fin->GetLength();
ULONGLONG nBytesRead = fin->Read( pbuf,dwLength );
fin->Close();
CString buffer(pbuf);
// replace drive letters with current drive
for (i=0; i < Drives.GetLength() ; i++ ) {
CString DriveLetter (_T(Drives.GetAt(i) + BS));
j = buffer.Replace(_T(DriveLetter), _T(ThisDrive));
}
// write notes.ini
fout = new CFile( THE_NOTES_INI ,
CFile::modeWrite | CFile::shareDenyWrite);
fout->Write(_T(buffer),dwLength);
fout->Flush();
fout->Close();
// search Notes executable
FSearch.ClearDirs();
FSearch.GetDirs(ThisDrive, true);
FSearch.ClearFiles();
FSearch.GetFiles(NOTES_PRG);
CSADirRead::SAFileVector &ExeFile = FSearch.Files();
for (CSADirRead::SAFileVector::const_iterator n = ExeFile.begin();
n!=ExeFile.end(); n++) {
THE_NOTES_EXE = ("%s\n", (*n).m_sName);
}
// start the client
ShellExecute(0, "open", THE_NOTES_EXE, 0, 0, 1);
}
catch (CFileException* pEx)
{
// if an error occurs, just make a message box
pEx->ReportError();
pEx->Delete();
nRetCode = 1;
}
catch (...)
{
nRetCode = 1;
}
return nRetCode;
}