More OIPI install questions (OpenInsight Specific)
At 19 SEP 2001 12:47:32PM b cameron wrote:
Am installing OIPI 4p at a site.
The site has 20+ users running on an NT Server.
I have created 2 directories under ..\oinsight \devmode and \runtime.
These contain the .dlls and .exes with the destinction of the runtime
having the runtime oengine.exe and the devmode having the development oengine.exe.
I know I need to copy the \devmode directory up 1 level then do the install and move back; then move to the \runtime but restore the oengine.exe? Correct? Comments/suggestions?
Also, the install asks for a reboot. How come? And in this scenario
does the user accept the default install to the 'system' directory on NT?
So, then we have to reboot. Then do we install the 'new' download
oipipart2 ? and then reboot again?
After this do we 'have to' go to each workstation and do the install from the oipi_1 / _2 directories and then reboot? then do the part2 install and reboot?
This is a clients site so I would like to have my ducks in a row.
Any detailed comments or suggestions are appreciated…
At 19 SEP 2001 04:23PM b cameron wrote:
I guess I'll respond.
We ended up moving to Win2000 since they wanted to move anyway and had a production server ready and waiting.
We moved the oinsight directory over, shut down the NT Service, reinstalled the service on Win2000, installed the oipi4pro, installed
the oipipart2 and rebooted. Then, ran the RUN 'DECLARE_FNCS' 's
reopened OI and did a test. This worked on the server.
Went to a workstation and did not want to do the oipi4pro install
again because we had moved the .dll's and .exe's back to the \dev and
\runtime directories so we manually copied the oipi req. dll/ocx/etc's to
the workstations \windows\system.
The did a test and it worked. Now…
Some of the dlls/ocx/etc's were older than the win2000 SP installed.
That could be a problem?!
Also, what if anything needs to be done to with the oipipart2 install
on the workstations?
At 20 SEP 2001 03:19AM Colin Rule wrote:
We have written a DLL Installer, within our application.
This enquires on Windows/System for each of the DLLs in the DLL folder within Oinsight (the DLLs that we want to install), and compares the version number, and if more recent they are installed.
This way no other applications are affected.
This can then be performed from the workstation without the need to reboot or install OIPI stuff, and relocate things manually.
This uses various windows SDK calls, such as:
GetSystemDirectory
GetFileVersionInfoSize
GetFileVersionInfo
VerInstallFile
VerQueryValue
Followed by
CALL UTILITY("RUNWIN","REGSVR16 /U ":SRCE_PATH:"\":FILE)
One thing you have to be very careful of when comparing DLL versions is that the actual version number is stored in the DLL and is not necessarily the version number that you see when accessing properties.
I can make these SDK call structures available if anyone has trouble finding out how to use them.
Colin Rule
At 20 SEP 2001 07:35AM Barry Stevens wrote:
]]SDK call structures
Sounds an interesting practice.
How are these run.
Please excuse my ignorance.
Barry
At 20 SEP 2001 08:02AM Oystein Reigem wrote:
Colin,
Interesting.
What is it you offer to share? The DLL prototype record(s) for the functions you mentioned? Or also the actual programming you've done?
- Oystein -
At 20 SEP 2001 10:40AM Colin Rule wrote:
See above, response to Oystein
Colin
At 20 SEP 2001 10:51AM Colin Rule wrote:
Both, if you want it.
Its nothing of such critical use to our company that we cant share it with those in the Rev community, and as I get as much out of this as I put in…
![]()
Add to SYSPROCS, a record (we called our DLL_CSSP_VER)
Our company is CSSP, so you can just call it DLL_VER if you want.
VER
USHORT PASCAL VerFindFile(USHORT,LPCHAR,LPCHAR,LPCHAR,LPCHAR,LPUSHORT,LPCHAR,LPUSHORT)
LONG PASCAL GetFileVersionInfoSize(LPCHAR,LPLONG)
USHORT PASCAL GetFileVersionInfo(LPCHAR,LONG,LONG,LPCHAR)
LONG PASCAL VerInstallFile(USHORT,LPCHAR,LPCHAR,LPCHAR,LPCHAR,LPCHAR,LPCHAR,LPUSHORT)
USHORT PASCAL VerQueryValue(LPCHAR,LPCHAR,LPLONG,LPLONG)
Hopefully you can cut/paste this, as the formatting in this forum is a bit messy, VER is on the first line followed by 5 others.
Create a form to install the DLL's.
We display the list and show the DLLs and the version etc in this form.
This include an Install and Register button.
The following code is all in the OMNIEVENT.
We tend to use OMNIEVENT to have all the code in one spot.
Appropriate calls from buttons etc pass MESSAGE, and process.
The DLLs we want to install are in a DLL folder within the application directory.
The indentation etc may be stuffed up, but here goes.
* STANDARD
* DLL version checker and installer
* AG - Jan 97
*
* Check file versions of files in DLL subdirectory against local workstation
* version of files (usually in Windows system directory) and upgrade if necessary.
* Uses functions contained in VER.DLL (Windows standard DLL). See DLL_CSSP_VER
* in SYSPROCS file for function definitions & Windows SDK for info on functions.
*
*
DECLARE FUNCTION GetFileVersionInfoSize, GetFileVersionInfo, GetSystemDirectory, VerInstallFile, VerQueryValueDECLARE FUNCTION BUILD_MSG, DCOUNT, STRUCT_TO_VAR, UTILITY*
ORIG_CURSOR=UTILITY("CURSOR","H")CRLF=CHAR(13):CHAR(10)FROM_PATH=.SOURCE_DIR-]TEXTTO_PATH=.DEST_DIR-]TEXTDLL_TABLE=.DLL_TABLE-]INVALUECONTROLS=";PROPERTIES=";VALUES="BEGIN CASECASE MESSAGE=CREATE" ;GOSUB CREATE_WINDOWCASE MESSAGE=INSTALL" ;GOSUB INSTALL_FILESCASE MESSAGE=REGISTER" ;GOSUB REGISTER_DLLSCASE MESSAGE=CLOSE" ;GOSUB CLOSE_WINDOWEND CASEIF CONTROLS#"" THEN CALL BULK_SET_PROPERTY(CONTROLS,PROPERTIES,VALUES)IF ORIG_CURSOR#"H" THEN CALL UTILITY("CURSOR",ORIG_CURSOR)RETURN 1
CREATE_WINDOW:
*
* Get list of files in DLL subdirectory & windows system directory path
*
RUN_TYPE=PARAM1FROM_PATH=DRIVE():"\DLL"WINSYSDIR=STR(\00\,150)DIRLEN=GetSystemDirectory(WINSYSDIR,150)TO_PATH=WINSYSDIR1,DIRLENGOSUB DISPLAY_DLLSIF RUN_TYPE#"UPGRADE" OR NO_UPGRADES THENCALL SET_WINDOW(@WINDOW,"C")CONTROLS:=@RM:@WINDOW ;PROPERTIES:=@RM:"@RUN_TYPE";VALUES:=@RM:RUN_TYPECONTROLS:=@RM:".SOURCE_DIR" ;PROPERTIES:=@RM:"TEXT" ;VALUES:=@RM:FROM_PATHCONTROLS:=@RM:".DEST_DIR" ;PROPERTIES:=@RM:"TEXT" ;VALUES:=@RM:TO_PATHEND ELSECALL POST_EVENT(@WINDOW,"CLOSE")ENDRETURN
CLOSE_WINDOW:
LOCATE 1 IN DLL_TABLE USING @VM SETTING POS THENEM=Files in the Destination Directory are out-of-date and require upgrading.":CRLFEM:=This application will not function correctly until this has been done."CALL BUILD_MSG(@WINDOW,EM,"W")PARENT=@@WINDOW-]PARENTIF PARENT#"" THEN CALL SET_PROPERTY(PARENT,"@DLL_ERROR",1)ENDRETURN
DISPLAY_DLLS:
*
* Create list of DLL and version numbers.
*
INITDIR FROM_PATH:"\*.*"FILE_LIST=DIRLIST()NO_FILES=DCOUNT(FILE_LIST,@FM)DLL_TABLE="FOR FILE_NO=1 TO NO_FILESFILE_NAME=FILE_LISTCHK_FILE=FROM_PATH:"\":FILE_NAME:\00\; GOSUB GET_FILE_VER; FROM_VER=FileVersionVER_STRING=CompanyName" ; GOSUB EXTRACT_VALUE; FILE_COMPANY=VER_VALUEVER_STRING=FileDescription"; GOSUB EXTRACT_VALUE; FILE_DESC=VER_VALUECHK_FILE=TO_PATH:"\":FILE_NAME:\00\; GOSUB GET_FILE_VER; TO_VER=FileVersionIF FROM_VER=TO_VER THEN INSTALL_FLAG=0 ELSEINSTALL_FLAG="NO_VERS=DCOUNT(FROM_VER,".")FOR VER_FLD=1 TO NO_VERS WHILE INSTALL_FLAG="FROM_VALUE=FIELD(FROM_VER,".",VER_FLD)TO_VALUE =FIELD(TO_VER,".",VER_FLD)BEGIN CASECASE FROM_VALUE]TO_VALUE; INSTALL_FLAG=1CASE FROM_VALUE=FILE_NAMEDLL_TABLE=FILE_COMPANYDLL_TABLE=FILE_DESCDLL_TABLE=FROM_VERDLL_TABLE=TO_VERDLL_TABLE=INSTALL_FLAGNEXT FILE_NOIF DLL_TABLE=" THEN DLL_TABLE="NO_UPGRADES=COUNT(DLL_TABLE,1)IF NO_UPGRADES THENSTATUS_TEXT=NO_UPGRADES:" file(s) in the Destination Directory require upgrading."END ELSESTATUS_TEXT=No files in the Destination Directory require upgrading."ENDCONTROLS:=@RM:".DLL_TABLE" ;PROPERTIES:=@RM:"AUTOSIZECOL" ;VALUES:=@RM:3CONTROLS:=@RM:".DLL_TABLE" ;PROPERTIES:=@RM:"INVALUE" ;VALUES:=@RM:DLL_TABLECONTROLS:=@RM:".STATUS" ;PROPERTIES:=@RM:"TEXT" ;VALUES:=@RM:STATUS_TEXTCONTROLS:=@RM:".BUTTON_INSTALL" ;PROPERTIES:=@RM:"ENABLED" ;VALUES:=@RM:(NO_UPGRADES]0)RETURN
GET_FILE_VER:
*
* Call GetFileVersionInfoSize which returns the size of the file info structure and a file handle.
* Then call GetFileVersionInfo passing this size and file handle which returns the file version structure.
*
VerHandle="VerLen=GetFileVersionInfoSize(CHK_FILE,VerHandle)FileVerInfo=STR(\00\,VerLen)Retval=GetFileVersionInfo(CHK_FILE,VerHandle,VerLen,FileVerInfo)*
* Get VS_FIXEDFILEINFO structure from FileVerInfo using VerQueryValue.
* Convert VS_FIXEDFILEINFO structure to dynamic array & extract four digit version number.
* Get file language/character set identifiers for future calls VerQueryValue.
*
FileVersion="; LangCharset="IF Retval THENValPnt=0;ValLen=0Retval=VerQueryValue(FileVerInfo,"\":\00\,ValPnt,ValLen)IF ValPnt THENVS_FIXEDFILEINFO=GetValue(ValPnt,CHAR,ValLen)VS_FIXEDFILEINFO=STRUCT_TO_VAR(VS_FIXEDFILEINFO,"VS_FIXEDFILEINFO")FileVersionMS=FMT(OCONV(VS_FIXEDFILEINFO,"MX"),"R(0)#8")FileVersionLS=FMT(OCONV(VS_FIXEDFILEINFO,"MX"),"R(0)#8")FileVersion1=ICONV(FileVersionMS1,4,"MX"):".":ICONV(FileVersionMS5,4,"MX")FileVersion2=ICONV(FileVersionLS1,4,"MX"):".":ICONV(FileVersionLS5,4,"MX")FileVersion=FileVersion1:".":FileVersion2ENDValPnt=0;ValLen=0Retval=VerQueryValue(FileVerInfo,"\VarFileInfo\Translation":\00\,ValPnt,ValLen)IF ValPnt THENLangCharset=GetValue(ValPnt,LONG,"")LangCharset=FMT(OCONV(LangCharset,"MX"),"R(0)#8")LangCharset=LangCharset5,4:LangCharset1,4ENDENDRETURN
EXTRACT_VALUE:
*
* Get value for VER_STRING from FileVerInfo using VerQueryValue.
* If unsucessful then try and locate string value 'manually'.
*
ValPnt=0;ValLen=0VerQueryString=\StringFileInfo\":LangCharset:"\":VER_STRING:\00\Retval=VerQueryValue(FileVerInfo,VerQueryString,ValPnt,ValLen)VER_VALUE=GetValue(ValPnt,CHAR,ValLen)VER_VALUE=FIELD(VER_VALUE,\00\,1)IF VER_VALUE=" THENPOS=INDEX(FileVerInfo,VER_STRING,1)IF POS THEN VER_VALUE=FIELD(FileVerInfoPOS+LEN(VER_STRING)+1,9999,\00\,1)ENDRETURN
INSTALL_FILES:
*
* Install files in need of upgrade
*
TO_PATH=.DEST_DIR-]TEXTRUN_TYPE=GET_PROPERTY(@WINDOW,"@RUN_TYPE")NO_FILES=DCOUNT(DLL_TABLE,@VM)ERROR_LIST="OPEN "STD_PARAMS" TO STD_PARAMS THENREAD ERROR_LIST FROM STD_PARAMS,"VERINSTALLFILE_ERRORS" ELSE NULLENDERROR=0EM=Files in the Destination directory for this Workstation will be upgraded.":CRLF:CRLFEM:=Please exit ALL other applications before continuing."RETVAL=BUILD_MSG(@WINDOW,EM,"W":@FM:"Continue,Quit")IF RETVAL=1 THENCALL UTILITY("CURSOR","H")FOR FILE_NO=1 TO NO_FILESFILE_NAME =DLL_TABLETO_VER =DLL_TABLEINSTALL_FLAG=DLL_TABLEIF INSTALL_FLAG AND FILE_NAME#"" THEN GOSUB INSTALL_FILENEXT FILE_NOGOSUB DISPLAY_DLLSIF RUN_TYPE=UPGRADE" AND ERROR=0 THEN CALL POST_EVENT(@WINDOW,"CLOSE")ENDRETURN
INSTALL_FILE:
INSTALL_FILE=FILE_NAME:\00\SOURCE_PATH=FROM_PATH:\00\; DEST_PATH=TO_PATH:\00\IF TO_VER=" THEN CURR_PATH=\00\ ELSE CURR_PATH=DEST_PATHTEMP_FILE_LEN=150TEMP_FILE_NAME=STR(\00\,TEMP_FILE_LEN)Retval=VerInstallFile(0,INSTALL_FILE,INSTALL_FILE,SOURCE_PATH,DEST_PATH,CURR_PATH,TEMP_FILE_NAME,TEMP_FILE_LEN)IF Retval THEN GOSUB INSTALL_ERRORRETURN
INSTALL_ERROR:
ERROR=1EM=Installation of ":FILE_NAME:" file to ":TO_PATH:CRLF:"directory failed with the following errors:":CRLFNO_ERRORS=DCOUNT(ERROR_LIST,@FM)FOR ERROR_POS=1 TO NO_ERRORSERROR_BITMASK=ERROR_LISTERROR_TEXT =ERROR_LISTIF BITAND(Retval,ERROR_BITMASK) THEN EM:=CRLF:ERROR_TEXTNEXT ERROR_POSCALL BUILD_MSG(@WINDOW,EM,"E")RETURN
REGISTER_DLLS:
SRCE_PATH=FROM_PATH; DEST_PATH=TO_PATHFILE=COMDLG16.OCX" ;GOSUB REGISTER_DLLFILE=OC25.DLL" ;GOSUB REGISTER_DLLFILE=VSVIEW3-.OCX" ;GOSUB REGISTER_DLLSRCE_PATH=DRIVE() ;DEST_PATH=DEST_PATHFILE=SSUTIL.OCX" ;GOSUB REGISTER_DLLRETURN
REGISTER_DLL:
CALL UTILITY("RUNWIN","REGSVR16 /U ":SRCE_PATH:"\":FILE)CALL UTILITY("RUNWIN","REGSVR16 ":DEST_PATH:"\":FILE)RETURN
At 20 SEP 2001 10:53AM Colin Rule wrote:
Oops, forgot to mention….
We have a stored procedure used in this code called BULK_SET_PROPERTY.
This can be replaced by your own set property or short form version.
Colin
At 20 SEP 2001 11:14AM Colin Rule wrote:
Sorry, did not really explain this.
You can add command structures to the SYSPROCS file
These can define the Windows API calls as defined in the Microsoft SDK.
You can then use these to call windows functions.
We have some for various things such as
- Calling Wintab drivers for digitisers
- Accessing the DLL info (as earlier)
- Finding our the System directory location
- Reading and writing to the COM1/COM2 ports
- Drawing lines on the screen, (eg a very simple CAD system)
- Accessing the Sentinel 'dongle' structures for system security functions
- Accessing the printer info, eg like OIPI, but direct without opening the OIPI printer INIT command (saves a page each time)
There are many others in the SYSPROCS file already,and probably thousands that you could use.
When you look at the SDK there is an enormous amount of stuff.
You have to do something with these files, but its been a while, but I think there is documentation about.
Once they are registered, all you do is call them like any other function call and hey presto, the worlds your oystein… I mean oyster (sorry!!)
Colin
At 20 SEP 2001 07:42PM Barry Stevens wrote:
Colin.
Thanks very much. Terrific stuff.
At 21 SEP 2001 05:25AM Oystein Reigem wrote:
Colin,
Thanks. I've got it reformatted and printed out. I'll have a look at it come first chance.
![]()
I often think I should make a proper installation for my apps. I never got around to it. The apps themselves don't need more than a straight copy from the distribution CDs. There's no need for the Client Install. But there's always been this extra "external" step of installing OIPI. Even if the OIPI Setup mostly has worked well your idea of "reigning it in" this way is appealing.
One comment about your BULK_SET_PROPERTY: It seems to handle control names without a window name. I guess it just assumes ".XXX" is @Window:".XXX".
- Oystein -
At 21 SEP 2001 05:44AM Colin Rule wrote:
You are welcome.
Let me know if you have any problems.
Yes, BULK_SET_PROPERTY does assume the current window, unless specified.
We just use this to do them all in one place.
Doing set properties in bulk is quicker than doing then one at a time.
At 21 SEP 2001 06:02AM Oystein Reigem wrote:
Colin,
Doing set properties in bulk is quicker than doing then one at a time.
I know, even if I tend to forget when I'm programming. But also Set_Property itself can do it in bulk. But only with complete control names of course.
Well, it's time for lunch. And some cake. Because it's somebody's birthday. Must hurry before all my greedy colleagues eat it all.
![]()
- Oystein -