Sign up on the Revelation Software website to have access to the most current content, and to be able to ask questions and get answers from the Revelation community

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, VerQueryValue
DECLARE FUNCTION BUILD_MSG, DCOUNT, STRUCT_TO_VAR, UTILITY

*

ORIG_CURSOR=UTILITY("CURSOR","H")
CRLF=CHAR(13):CHAR(10)
FROM_PATH=.SOURCE_DIR-]TEXT
TO_PATH=.DEST_DIR-]TEXT
DLL_TABLE=.DLL_TABLE-]INVALUE
CONTROLS=";PROPERTIES=";VALUES="
BEGIN CASE
	CASE MESSAGE=CREATE"	;GOSUB CREATE_WINDOW
	CASE MESSAGE=INSTALL"	;GOSUB INSTALL_FILES
	CASE MESSAGE=REGISTER"	;GOSUB REGISTER_DLLS
	CASE MESSAGE=CLOSE"	;GOSUB CLOSE_WINDOW
END CASE
IF 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=PARAM1
FROM_PATH=DRIVE():"\DLL"
WINSYSDIR=STR(\00\,150)
DIRLEN=GetSystemDirectory(WINSYSDIR,150)
TO_PATH=WINSYSDIR1,DIRLEN
GOSUB DISPLAY_DLLS
IF RUN_TYPE#"UPGRADE" OR NO_UPGRADES THEN
	CALL SET_WINDOW(@WINDOW,"C")
	CONTROLS:=@RM:@WINDOW		;PROPERTIES:=@RM:"@RUN_TYPE";VALUES:=@RM:RUN_TYPE
	CONTROLS:=@RM:".SOURCE_DIR"	;PROPERTIES:=@RM:"TEXT"		;VALUES:=@RM:FROM_PATH
	CONTROLS:=@RM:".DEST_DIR"	;PROPERTIES:=@RM:"TEXT"		;VALUES:=@RM:TO_PATH
END ELSE
	CALL POST_EVENT(@WINDOW,"CLOSE")
END

RETURN

CLOSE_WINDOW:

LOCATE 1 IN DLL_TABLE USING @VM SETTING POS THEN
	EM=Files in the Destination Directory are out-of-date and require upgrading.":CRLF
	EM:=This application will not function correctly until this has been done."
	CALL BUILD_MSG(@WINDOW,EM,"W")
	PARENT=@@WINDOW-]PARENT
	IF PARENT#"" THEN CALL SET_PROPERTY(PARENT,"@DLL_ERROR",1)
END

RETURN

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_FILES
	FILE_NAME=FILE_LIST
	CHK_FILE=FROM_PATH:"\":FILE_NAME:\00\; GOSUB GET_FILE_VER; FROM_VER=FileVersion
	VER_STRING=CompanyName"	; GOSUB EXTRACT_VALUE; FILE_COMPANY=VER_VALUE
	VER_STRING=FileDescription"; GOSUB EXTRACT_VALUE; FILE_DESC=VER_VALUE
	CHK_FILE=TO_PATH:"\":FILE_NAME:\00\; GOSUB GET_FILE_VER; TO_VER=FileVersion
	IF FROM_VER=TO_VER THEN INSTALL_FLAG=0 ELSE
		INSTALL_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 CASE
				CASE FROM_VALUE]TO_VALUE; INSTALL_FLAG=1
				CASE FROM_VALUE=FILE_NAME
	DLL_TABLE=FILE_COMPANY
	DLL_TABLE=FILE_DESC
	DLL_TABLE=FROM_VER
	DLL_TABLE=TO_VER
	DLL_TABLE=INSTALL_FLAG
NEXT FILE_NO
IF DLL_TABLE=" THEN DLL_TABLE="
NO_UPGRADES=COUNT(DLL_TABLE,1)
IF NO_UPGRADES THEN
	STATUS_TEXT=NO_UPGRADES:" file(s) in the Destination Directory require upgrading."
END ELSE
	STATUS_TEXT=No files in the Destination Directory require upgrading."
END
CONTROLS:=@RM:".DLL_TABLE"		;PROPERTIES:=@RM:"AUTOSIZECOL"	;VALUES:=@RM:3
CONTROLS:=@RM:".DLL_TABLE"		;PROPERTIES:=@RM:"INVALUE"		;VALUES:=@RM:DLL_TABLE
CONTROLS:=@RM:".STATUS"			;PROPERTIES:=@RM:"TEXT"			;VALUES:=@RM:STATUS_TEXT
CONTROLS:=@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 THEN
	ValPnt=0;ValLen=0
	Retval=VerQueryValue(FileVerInfo,"\":\00\,ValPnt,ValLen)
	IF ValPnt THEN
		VS_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:".":FileVersion2
	END
	ValPnt=0;ValLen=0
	Retval=VerQueryValue(FileVerInfo,"\VarFileInfo\Translation":\00\,ValPnt,ValLen)
	IF ValPnt THEN
		LangCharset=GetValue(ValPnt,LONG,"")
		LangCharset=FMT(OCONV(LangCharset,"MX"),"R(0)#8")
		LangCharset=LangCharset5,4:LangCharset1,4		
	END
END

RETURN

EXTRACT_VALUE:

*

* Get value for VER_STRING from FileVerInfo using VerQueryValue.

* If unsucessful then try and locate string value 'manually'.

*

ValPnt=0;ValLen=0
VerQueryString=\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=" THEN
	POS=INDEX(FileVerInfo,VER_STRING,1)
	IF POS THEN VER_VALUE=FIELD(FileVerInfoPOS+LEN(VER_STRING)+1,9999,\00\,1)
END

RETURN

INSTALL_FILES:

*

* Install files in need of upgrade

*

TO_PATH=.DEST_DIR-]TEXT
RUN_TYPE=GET_PROPERTY(@WINDOW,"@RUN_TYPE")
NO_FILES=DCOUNT(DLL_TABLE,@VM)
ERROR_LIST="
OPEN "STD_PARAMS" TO STD_PARAMS THEN
	READ ERROR_LIST FROM STD_PARAMS,"VERINSTALLFILE_ERRORS" ELSE NULL
END
ERROR=0
EM=Files in the Destination directory for this Workstation will be upgraded.":CRLF:CRLF
EM:=Please exit ALL other applications before continuing."
RETVAL=BUILD_MSG(@WINDOW,EM,"W":@FM:"Continue,Quit")
IF RETVAL=1 THEN
	CALL UTILITY("CURSOR","H")
	FOR FILE_NO=1 TO NO_FILES
		FILE_NAME	=DLL_TABLE
		TO_VER		=DLL_TABLE
		INSTALL_FLAG=DLL_TABLE
		IF INSTALL_FLAG AND FILE_NAME#"" THEN GOSUB INSTALL_FILE
	NEXT FILE_NO
	GOSUB DISPLAY_DLLS
	IF RUN_TYPE=UPGRADE" AND ERROR=0 THEN CALL POST_EVENT(@WINDOW,"CLOSE")
END

RETURN

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_PATH
TEMP_FILE_LEN=150
TEMP_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_ERROR

RETURN

INSTALL_ERROR:

ERROR=1
EM=Installation of ":FILE_NAME:" file to ":TO_PATH:CRLF:"directory failed with the following errors:":CRLF
NO_ERRORS=DCOUNT(ERROR_LIST,@FM)
FOR ERROR_POS=1 TO NO_ERRORS
	ERROR_BITMASK=ERROR_LIST
	ERROR_TEXT	 =ERROR_LIST
	IF BITAND(Retval,ERROR_BITMASK)	THEN EM:=CRLF:ERROR_TEXT
NEXT ERROR_POS
CALL BUILD_MSG(@WINDOW,EM,"E")

RETURN

REGISTER_DLLS:

SRCE_PATH=FROM_PATH; DEST_PATH=TO_PATH
FILE=COMDLG16.OCX"	;GOSUB REGISTER_DLL
FILE=OC25.DLL"		;GOSUB REGISTER_DLL
FILE=VSVIEW3-.OCX"	;GOSUB REGISTER_DLL
SRCE_PATH=DRIVE()	;DEST_PATH=DEST_PATH
FILE=SSUTIL.OCX"	;GOSUB REGISTER_DLL

RETURN

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.

[email protected]


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 -

View this thread on the forum...

  • third_party_content/community/commentary/forums_nonworks/31600d20f798cd0385256acc005c3e42.txt
  • Last modified: 2023/12/28 07:40
  • by 127.0.0.1