%INSTALLPLECS PLECS Installer. % % Installs or updates PLECS on your computer. % Copyright 2006-2010, Plexim GmbH % $LastChangedDate: 2010-02-26 17:27:59 +0100 (Fr, 26 Feb 2010) $ function installplecs help(mfilename) cleanupDir = []; % cleanupFile = []; try [matlabVer, count] = sscanf(version, '%i.%i.%i'); if count < 3, error('Unable to determine MATLAB version!'); end if ispc, if matlabVer(1) < 7, error('This installer requires MATLAB version 7.0.0 or newer.'); end else if [1 1e-3 1e-6]*matlabVer(:) < 6.005, error('This installer requires MATLAB version 6.5.0 or newer.'); end end installerPath = fileparts(mfilename('fullpath')); [platformStr, minMatlabVer] = iDeterminePlatform(matlabVer); if ([1 1e-3 1e-6]*matlabVer(:) < [1 1e-3 1e-6]*minMatlabVer(:)), error('PLECS requires MATLAB version %i.%i.%i or newer.', minMatlabVer); end [oldPLECSDir, oldPLECSVer] = iCheckForOldPLECS; [packageFile, packageVer] = iCheckForLocalPackages(installerPath, platformStr); remotePackageVer = iCheckForRemotePackages(packageVer); if ~isempty(remotePackageVer), packageVer = remotePackageVer; end; if ~isempty(oldPLECSDir) && ([1 1e-3 1e-6]*packageVer(:) <= [1 1e-3 1e-6]*oldPLECSVer(:)), fprintf('Your PLECS installation is up to date. Exiting.\n'); return; end if isempty(oldPLECSDir), installDir = iChooseInstallDir(installerPath); cleanupDir = installDir; % in case of failure, remove this dir in the catch section. extractDir = iMakeExtractDir(installDir); else installDir = oldPLECSDir; extractDir = iMakeExtractDir(installDir); cleanupDir = extractDir; % in case of failure, remove this dir in the catch section. end licenseFile = []; % if we're just updating an existing installation we can skip the next % step if isempty(oldPLECSDir) || ([1 1e-3]*packageVer([1;2]) > [1 1e-3]*oldPLECSVer([1;2])), licenseFile = iCheckLicenseFile(installerPath, extractDir, packageVer, oldPLECSDir); drawnow; end if ~isempty(remotePackageVer), packageFile = iDownloadRemotePackages(extractDir, platformStr, remotePackageVer); % cleanupFile = packageFile; % after installation, remove this file end; iExtractPackage(packageFile, extractDir); iAssertLicenseFile(licenseFile); iInstallPackage(installDir, extractDir); iInstallLicenseFile(installDir, licenseFile); iCheckConfigFile(installDir); if isempty(oldPLECSDir), iSetMatlabPath(installDir); else fprintf('Rehashing toolbox cache\n'); rehash toolboxcache end fprintf('Clean up: Removing extract directory ''%s''\n', extractDir); rmdir(extractDir, 's'); catch if exist('installDir','var'), fprintf('\n\nInstallation of PLECS into ''%s'' failed!\n', installDir); else fprintf('\n\nInstallation of PLECS failed!\n'); end if exist('cleanupDir', 'var') && ~isempty(cleanupDir), fprintf('Clean up: Removing directory ''%s''\n', cleanupDir); rmdir(cleanupDir, 's'); end fprintf('Correct errors below and try again. Exiting.\n'); rethrow(lasterror); end fprintf('Done.\n'); fprintf('PLECS version %i.%i.%i installed successfully.\n\n', packageVer); fprintf('To get started, type ''plecslib''.\n'); return; function [platformStr, minMatlabVer] = iDeterminePlatform(matlabVer) switch mexext, case {'dll', 'mexw32'} if matlabVer(1) >= 7, minMatlabVer = [7, 0, 0]; platformStr = 'w32_r14.zip'; else minMatlabVer = [6, 5, 0]; platformStr = 'w32_r13.zip'; end case {'mexw64'} minMatlabVer = [7, 4, 0]; platformStr = 'w64_r2007a.zip'; case {'mexglx'} minMatlabVer = [7, 2, 0]; platformStr = 'glx_r2006a.tar.gz'; case {'mexa64'} minMatlabVer = [7, 2, 0]; platformStr = 'a64_r2006a.tar.gz'; case {'mexmaci'} minMatlabVer = [7, 4, 0]; platformStr = 'maci_r2007a.tar.gz'; case {'mexmaci64'} minMatlabVer = [7, 9, 0]; platformStr = 'maci64_r2009b.tar.gz'; otherwise error('Unsupported platform ''%s''.', computer); end fprintf('Package extension for this platform is ''%s''.\n', platformStr); function [oldPLECSDir, oldPLECSVer] = iCheckForOldPLECS oldPLECSVer = []; oldPLECSDir = fileparts(which('plecsedit')); if isempty(oldPLECSDir), return; end v = iParseContentsFile(fullfile(oldPLECSDir, 'Contents.m')); oldPLECSVer = sscanf(v, '%i.%i.%i'); fprintf('Found PLECS version %s on your MATLAB path.\n', v); answer = questdlg(... sprintf(['PLECS version %i.%i.%i is already installed at ''%s''. ' ... 'Do you want to overwrite this installation?'], ... oldPLECSVer, oldPLECSDir), ... 'Overwrite existing PLECS?', ... 'Yes', 'Cancel', 'Cancel'); if strcmp(answer, 'Cancel'), error('PLECS is already installed at ''%s''. Remove first!', oldPLECSDir); end [m, mex] = inmem; %#ok if (~isempty(strmatch('plecsedit', mex, 'exact'))), fprintf('Clearing PLECS module...\n'); plecsclear; end fprintf('Overwriting PLECS installation at ''%s''.\n', oldPLECSDir); function v = iParseContentsFile(file) fp = fopen(file,'rt'); if fp>0 s = fgetl(fp); %#ok s = fgetl(fp); fclose(fp); if ~ischar(s) s = ''; end else s = ''; end c = strread(s, '%s', 'delimiter', ' '); if numel(c)<3 || ~strcmpi(c{2}, 'version'), error('Error parsing contents file ''%s''.', filename); end v = c{3}; function installDir = iChooseInstallDir(startDir) installDirParent = uigetdir(startDir, 'Choose location to install PLECS'); % Cancelled? if installDirParent == 0, error('User cancelled.'); end installDir = fullfile(installDirParent, 'plecs'); fprintf('Creating install directory ''%s''...\n', installDir); if exist(installDir, 'dir'), answer = questdlg(... sprintf(['Directory ''%s'' already exists.\n' ... 'Are you sure you want to use this directory?'], installDir), ... 'Directory exists', ... 'Yes', 'Cancel', 'Cancel'); if strcmp(answer, 'Cancel'), error('Directory ''%s'' already exists, user cancelled.', installDir); end else [ok, message, messageid] = mkdir(installDirParent, 'plecs'); if ~ok, error(messageid, message); end end function extractDir = iMakeExtractDir(installDir) extractDirName = 'extractPLECS'; extractDir = fullfile(installDir, extractDirName); fprintf('Creating temporary extract directory ''%s''...\n', extractDir); [ok, message, messageid] = mkdir(installDir, extractDirName); if ~ok, error(messageid, message); end function [localPackageFile, localPackageVer] = iCheckForLocalPackages(installerPath, platformStr) localPackageVer = []; localPackageFile = []; filter = fullfile(installerPath, ['plecs*' platformStr]); files = dir(filter); for idx = 1:length(files), if files(idx).isdir, continue; end [fileVer, count] = sscanf(files(idx).name, 'plecs-blockset-%i-%i-%i'); if isempty(localPackageVer) ... || (count == 3 && [1 1e-3 1e-6]*localPackageVer(:) < [1 1e-3 1e-6]*fileVer(:)), localPackageVer = fileVer; localPackageFile = fullfile(installerPath, files(idx).name); end end if ~isempty(localPackageVer), fprintf('Found local package for PLECS version %i.%i.%i.\n', localPackageVer); else fprintf('No local package for PLECS found.\n'); end function remotePackageVer = iCheckForRemotePackages(localPackageVer) remotePackageVer = []; if ~isempty(localPackageVer), % if a local package was found, ask whether to check online for newer package answer = questdlg(... sprintf(['Found local package for PLECS version %i.%i.%i. Would ' ... 'you like to check online for a newer PLECS version?'], localPackageVer), ... 'Check for newer PLECS version', ... 'Yes', 'No', 'No'); if strcmp(answer, 'No'), return; end end % Determine current version fprintf('Checking the web for current PLECS version...\n'); versionURL = 'http://www.plexim.com/downloads/version.txt'; [plecsVersionDownload, ok] = urlread(versionURL); if ~ok, error(['URL ''%s'' is not accessible! Please go to www.plexim.com/downloads/ ' ... 'and manually download the appropriate package to the same folder ' ... 'as this installer script.\n' ... 'Afterwards, rerun the installer.'], versionURL); end; [remotePackageVer, count] = sscanf(plecsVersionDownload, 'plecs-%i-%i-%i'); if count < 3, error(['Unable to determine current PLECS version! Please go to www.plexim.com/downloads/ ' ... 'and manually download the appropriate package to the same folder as this installer script.\n' ... 'Afterwards, rerun the installer.']); end; fprintf('Current PLECS version is %i.%i.%i.\n', remotePackageVer); if ~isempty(localPackageVer) ... && ([1 1e-3 1e-6]*remotePackageVer(:) <= [1 1e-3 1e-6]*localPackageVer(:)), remotePackageVer = []; end function remotePackageFile = iDownloadRemotePackages(extractDir, platformStr, remotePackageVer) fileName = sprintf('plecs-blockset-%i-%i-%i_%s', remotePackageVer, platformStr); fileURL = ['http://www.plexim.com/files/' fileName]; fprintf('Downloading ''%s''...\n', fileURL); [remotePackageFile, ok] = urlwrite(fileURL, fullfile(extractDir, fileName)); if ~ok error(['Unable to download ''%s''! Please go to www.plexim.com/downloads/ ' ... 'and manually download the appropriate package to the same folder ' ... 'as this installer script.\n' ... 'Afterwards, rerun the installer.'], fileURL); end function iExtractPackage(packageFile, extractDir) fprintf('Extracting ''%s''...\n', packageFile); if ispc, unzip(packageFile, extractDir); else if exist('untar'), %#ok untar(packageFile, extractDir); else oldwd = cd(extractDir); tmpFile = 'plecs.tar'; command = sprintf('gunzip -c %s > %s', packageFile, tmpFile); [status, output] = system(command); if status, error('Error executing command ''%s'': %s', command, output); %#ok end command = sprintf('tar -xf %s', tmpFile); [status, output] = system(command); if status, error('Error executing command ''%s'': %s', command, output); %#ok end cd(oldwd); end end function licenseFile = iCheckLicenseFile(installerPath, extractDir, packageVer, oldPLECSDir) licenseFileName = 'license.dat'; tmpLicenseFile = fullfile(extractDir, licenseFileName); licenseFile = []; fprintf('Checking license file...\n'); newLicenseFile = fullfile(installerPath, licenseFileName); if ~strcmp(installerPath, oldPLECSDir) && exist(newLicenseFile, 'file'), licenseFile = newLicenseFile; return; end if ~isempty(oldPLECSDir), oldLicenseFile = fullfile(oldPLECSDir, licenseFileName); if exist(oldLicenseFile, 'file'), [feature, version] = iParseLicenseFile(oldLicenseFile); if strcmp(feature, 'plecsedit'), if ([1 1e-3]*version(:) < [1 1e-3]*packageVer([1;2])), fprintf('Old license file does not support PLECS version %i.%i.\n', ... packageVer(1:2)); iEnterLicenseData(tmpLicenseFile, packageVer, ... sprintf(['Your current license file only supports PLECS ' ... 'version %i.%i.'], version)); licenseFile = tmpLicenseFile; return; else fprintf('Preserving old license file...\n'); return; end elseif strcmp(feature, 'plecsview'), fprintf('Old license file contains a viewer license.\n'); licenseFile = fullfile(extractDir, 'plecs', 'private', 'viewerlicense.dat'); return; elseif strcmp(feature, 'plecssv'), error(['Old license file contains a student license. Student licenses are '... 'no longer supported. Please contact info@plexim.com to request a full '... 'student license.\n']); end end answer = questdlg(... sprintf(['You appear to be using a floating PLECS license. Before upgrading PLECS to ' ... 'version %i.%i.%i please make sure that this is supported by your license server.'], ... packageVer), ... 'Server license up to date?', ... 'Continue', 'Cancel', 'Cancel'); if ~strcmp(answer, 'Continue'), error('User cancelled.'); end return; end fprintf('No license file found.\n'); answer = questdlg(... ['No license file found. Would you like to enter the license data manually ' ... 'or install the PLECS Viewer?'], ... 'Enter license type', ... 'Enter license data', 'Install Viewer', 'Enter license data'); switch answer case 'Install Viewer' fprintf('Using viewer license.\n'); licenseFile = fullfile(extractDir, 'plecs', 'private', 'viewerlicense.dat'); return; end iEnterLicenseData(tmpLicenseFile, packageVer) licenseFile = tmpLicenseFile; function iEnterLicenseData(targetLicenseFile, packageVer, introTxt) prompt = sprintf(... ['Please paste the license data for version %i.%i below or click ''Cancel'' to abort the installation.' char(10) char(10) ... 'Example:' char(10) ... '# --- cut here ---' char(10) ... 'FEATURE plecsedit plexim 1.0 permanent uncounted \\' char(10) ... ' HOSTID=MATLAB=123456 SIGN="0123 4567 89AB \\' char(10) ... ' CDEF FEDC BA98 7654 3210"' char(10) ... '# --- cut here ---' char(10)], ... packageVer(1:2)); if exist('introTxt', 'var') && ~isempty(introTxt), prompt = [introTxt ' ' prompt]; end answer = inputdlg(... prompt, ... 'Enter license data', ... 6, {''}, 'on'); if isempty(answer), error('User cancelled.'); end fprintf('Creating license file...\n'); licenseTxt = answer{1}; % our license files are pure ASCII, discard any other characters licenseTxt(licenseTxt > 127) = ' '; % put each line into an individual cell, discarding trailing spaces licenseTxt = cellstr(licenseTxt); [fid, message] = fopen(targetLicenseFile, 'wt'); if fid == -1, error('Cannot create file ''%s'': %s', targetLicenseFile, message); end for idx = 1:length(licenseTxt), fprintf(fid, '%s\n', licenseTxt{idx}); end fclose(fid); function [feature, version] = iParseLicenseFile(file) [fid, message] = fopen(file, 'rt'); if fid == -1, error('Cannot read file ''%s'': %s', file, message); end while 1, tline = fgetl(fid); if ~ischar(tline), break, end [token,tline] = strtok(tline); %#ok if ~strcmp(token, 'FEATURE'), continue, end [feature,tline] = strtok(tline); %#ok [vendor,tline] = strtok(tline); %#ok if ~strcmp(vendor, 'plexim'), continue, end [version,count] = sscanf(strtok(tline), '%i.%i'); if (count < 2), continue, end fclose(fid); return; end fclose(fid); feature = []; version = []; function iAssertLicenseFile(licenseFile) if isempty(licenseFile), return; end if ~exist(licenseFile, 'file'), error('Cannot find license file ''%s''.', licenseFile); end function iInstallPackage(installDir, extractDir) fprintf('Installing package files...\n'); [ok, message, messageid] = copyfile(fullfile(extractDir, 'plecs'), installDir); if ~ok, error(messageid, message); elseif strcmp(mexext, 'mexw32'), fprintf('Renaming MEX function to plecsedit.mexw32...\n'); movefile(fullfile(installDir, 'plecsedit.dll'), ... fullfile(installDir, ['plecsedit.' mexext])); end function iInstallLicenseFile(installDir, licenseFile) if isempty(licenseFile) || strcmp(installDir, fileparts(licenseFile)), return; end fprintf('Installing license file...\n') [ok, message, messageid] = copyfile(licenseFile, fullfile(installDir, 'license.dat')); if ~ok, error(messageid, message); end function iCheckConfigFile(installDir) configFileFull = fullfile(installDir, 'plecsconfig.m'); if exist(configFileFull, 'file'), msg = ['The configuration file ''plecsconfig.m'' is obsolete. Please ' ... 'configure PLECS via the Preferences dialog of the schematic ' ... 'editor.']; if (movefile(configFileFull, [configFileFull '_old'])), msg = [msg char(10) ... 'The file has been renamed to ''plecsconfig.m_old''.']; end fprintf('\n'); warning(msg); %#ok fprintf('\n'); warndlg(msg, 'Obsolete configuration file', 'modal'); end function iSetMatlabPath(installDir) fprintf('Adding PLECS to your MATLAB path...\n'); addpath(installDir); addpath(fullfile(installDir, 'demos')); status = 1; if any(exist('savepath') == [2 3 5 6]) status = savepath; elseif any(exist('path2rc') == [2 3 5 6]), status = path2rc; end if (status), msg = 'Unable to save MATLAB path. You will need to manually save the path!'; fprintf('\n'); warning(msg); %#ok fprintf('\n'); warndlg(msg, 'Unable to save MATLAB path', 'modal'); end