If OS=XP do this, If OS=98 do that

Hello all,

I'm trying to make a button do something if the operating system is Windows XP, and do something else if the operating system is Windows 98. Can it be done?

.. and please don't tell me to make two buttons, I'm trying to solve it elegantly with just one button. :slight_smile:

Here's one of Ken's commands which does different things depending on the OS:

[How can I create a path+file name list of selected directori)

I often create Opus User Commands and toolbar buttons which are MS-DOS Batch Functions. I basically use an NT Command Script as a "script wrapper" for a more advanced Opus button. The Command script provides logic branching, variables, and file output, while Opus provides all its raw commands. The technique has its pitfalls (most of which Leo or I have already submitted to GPSoftware), but overall its a pretty potent mix.

The command Nudel linked may not exactly do what you need. It depends on how many OSes you are going to create your commands for. This script template has some good examples to work from.

:: I like to put my Opus directives up-front before my script.
::
:: NOTE: Opus directives must always start in the first column, or they
:: will be interpreted as actual commands, and will error.
::
:: I make frequent use of the following three directives inside any script.
::
:: Runmode Hide
:: This tells Opus to hide the Command Console.
:: @nofilenamequoting
:: This tells Opus to not quote any passed {file} values.
:: @firstfileonly
:: This tells Opus to use only the first selected file. Without it, Opus
:: writes lines of code containing {file/file$/filepath/etc.} once for each
:: selected file, creating more lines than you coded, before executing.

Runmode Hide
@nofilenamequoting
@firstfileonly

:Start
:: This section is where I put commands to initialize the Command Console.
:: "@Echo OFF" prevents every command line in the script from being echoed
:: back to the Command Console screen, without suppressing command output.

 @Echo OFF 
 CLS
 Echo.

:: I Find it helpful during debugging to name the Command Console window
:: title indicative of the Opus toolbar button/User Command running inside
:: of it. It also looks much more professional if I use the Console to
:: display screen messages. ask the user for input and such.

 Title Directory Opus - Toolbar Button or User Command Name

:: Most of my Opus toolbar buttons and User Commands use techniques
:: supported only by Windows 2000/XP. I never code for Windows 95/98/ME.
:: The %OS% environmental variable on the Windows NT/2000/XP family of
:: operating systems always equals "Windows_NT". I often use this next line
:: to check for an NT operating system. If one is not found, the script
:: passes control to the :95-98-ME label. However, this check DOES NOT
:: actually check for a specific Windows version.

If NOT [%OS%]==[Windows_NT] Goto 95-98-ME

:CheckVer
:: This code is much more meticulous in checking for various versions.
:: The output of the Ver command is filtered using Find. If the designated
:: version string is found, ErrorLevel will equal 0. If anything goes wrong
:: ErrorLevel will be some other value.

 Ver | Find "Windows XP" >Nul
 If Not ErrorLevel 1 Goto :XP
 
 Ver | Find "Windows 2000" >Nul
 If Not ErrorLevel 1 Goto :2000
 
 Ver | Find "Windows NT" >Nul
 If Not ErrorLevel 1 Goto NT
 
 Ver | Find "Windows 98" >Nul
 If Not ErrorLevel 1 Goto 98
 
 Ver | Find "Windows 95" >Nul
 If Not ErrorLevel 1 Goto 95
 
 Ver | Find "Windows ME" >Nul
 If Not ErrorLevel 1 Goto ME
 
 Ver | Find "MS-DOS" >Nul
 If Not ErrorLevel 1 Goto DOS

:Unknown
Echo. ERROR - Unhandled OS version.
Goto END

:XP
:: Start XP Code Here
Echo. I'm Windows XP
Goto :EOF
:: Skip to End-Of-File

:2000
:: Start 2000 Code Here
Echo. I'm Windows 2000
Goto :EOF
:: Skip to End-Of-File

:NT
:: Start NT Code Here
Echo. I'm Windows NT
Goto END
:: Skips to :END Label

:ME
:: Start ME Code Here
Echo. I'm Windows ME
Goto END
:: Skips to :END Label

:98
:: Start 98 Code Here
Echo. I'm Windows 98
Goto END
:: Skips to :END Label

:95
:: Start 95 Code Here
Echo. I'm Windows 95
Goto END
:: Skips to :END Label

:DOS
:: Start DOS Code Here
Echo. I'm DOS
Goto END
:: Skips to :END Label

:95-98-ME
:: Start 95/98/ME Family Code Here
Echo. I'm not Windows NT/2000/XP
Goto END
:: Skips to :END Label

:Labels
:: Windows 2003/2000/XP all support both syntaxes below, plus labels may be
:: longer than 8 characters.
::
:: Goto :Label
:: Goto Label
::
:: Windows 95/98/ME only support the second syntax, and only the first 8
:: characters are used to distinguish label names. Thus these labels:
::
:: :DuplicateFile
:: :DuplicateFolder
::
:: would both be interpreted as
::
:: :Duplicat
::

:SetVars
:: Set Environmental Variable equal to Opus Control Sequence like this.
:: The reason the Call command is used, is to "protect" the Set command,
:: so Opus will not try to execute it as the internal Opus Set command.
::
:: Call Set OpusSourcePath={sourcepath$|noterm}
:: Call Set OpusDateTimeStamp={Date|yyyy'-'MM'-'yy}-{Time|HH'.'mm'.'ss}
::
:: Set Environmental Variable equal to value of User Command Option.
:: If you created your own User Command, with the following template:
::
:: User Command: MyUserCommand
:: Template: SWITCH1/S,SWITCH2/S,SWITCH3/S
::
:: Pass your switch (boolean) values to your Command Script like this:
::
:: Call Set Switch1=&SWITCH1:Option A:Option B&
:: Call Set Switch2=&SWITCH2:Yes:No&
:: Call Set Switch3=&SWITCH3&
::
:: %Switch3% receives a value of 0 if the switch is passed and 1 if not.

:UserCmd
:: User Commands have a quirk in that all text must start in Column 0. This
:: is because Opus stores User Commands in Reg_Multi_SZ registry values,
:: which cannot contain blank lines. To add blanks lines like I have here
:: to a User Command (purely for human readability), you must have at least
:: one space character on every line.

:dopusrt
:: To have your script run Opus, just use the following syntax:
::
:: dopusrt /CMD InternalOpusCommand Options
::
:: Opus substitutes dopusrt with the full installation path to dopusrt.exe,
:: which allows internal Opus commands to be executed externally.

:END
:: No code should go here[/code]

Wow! That's tight! Thank you very much Nudel and kenalcock.

I wonder though, when will we be able to use 'if then', 'for next', 'do while' loops in Opus? Do the programmers have such plans? It would be perfect.

Moan! While, doWhile, for, if, switch, fxCall, thread, variables, oh man... I would be so all over that. I could see it now... Opus9 the email client... Opus9 the News Reader, Opus9 the RSS feed, Opus9 the system batch process.

[quote="Spr0ket"]
I could see it now... Opus9 the email client... Opus9 the News Reader, Opus9 the RSS feed, Opus9 the system batch process.[/quote]

If the developers thought like this, we wouldn't have half the features that we have now.

You can already do some of that using the DOS commands (DOS has if and loops) or by calling a VBScript from Opus, or whatever.

It's not quite the same as integrated VBScript (i.e. where buttons are function calls and always in VBScript land) but in the rare cases where you need such things it's often good enough.

One of the current issues with Opus and batch scripts is how it parses the percent character. Currently, Opus will resolve two consecutive percent characters in your script to one. That will mess up many scripting techniques. Most notably it renders the "For" command useless.

codeFor /L %%X In (start#,step#,end#) Do (
Command
Command
Command
)[/code]

In the code above, "%%X" above would become "%X" when Opus executes the script, which will cause Cmd.exe to error. NOTE: GPSoftware is aware of, and looking at, this and other issues.

If you want to loop, you must use "Goto :Label", or in Windows 2000/XP "Call :Label". Here is some code copied from my CreateNumberedFolder User Command (available for download in the Buttons & Toolbars Forum).

 If /I %Count% GTR %Highest% Goto :Renumber
 CLS
 Echo.
 Echo. Creating Folder #: %Count%
 Echo.
 MD "¬%BaseName%¬%Count%"
 Call Set /A Count+=Increment
 Goto :MakeDirs

:Renumber
:: Opus writes "%BaseName%%Count%" as "%BaseName%Count%" in a dop0x.bat.
:: To get around this, use "%BaseName%¬%Count%" and rename the folder later.

 Call Set /A Count-=Increment
 If Not Exist "¬%BaseName%¬%Count%\." Goto :Renumber
 CLS
 Echo.
 Echo. Waiting for Opus Listing to Update...
 Echo.
 Call Set /A Wait=DefaultWait+1 && Call :Sleep
 dopusrt /CMD Select PATTERN="¬%BaseName%¬*"
 Call Set /A Wait=DefaultWait && Call :Sleep
 dopusrt /CMD Rename AUTORENAME REGEXP PATTERN="¬(%BaseName%)¬[0-9]+" TO="\1[#]" NUMBER %First% BY %Increment%
 dopusrt /cmd {%dlgstring%^|The new folders are being renumbered in the file display. Wait for all names to be updated before closing this dialog. (The update usually happens a few seconds after all folders are deselected.) Don't type anything in this dialog.^|""}
 Echo.a
 Goto :EOF[/code]

There's a lot going on in this code, and if you look, there's a mix of Opus and script commands. But the loop is facilitate by Goto :Renumber, and my counter/decumulator is facilitated by Call Set /A Count-=Increment.

Since Windows 98 does not have Call :Label available to it, you must do some creative thinking to create your own means to send control to a known place in your script and return it back to a known place. Set up your script with labels, and use one variable to track where control should be throughout the execution of the entire script.

:: Protect these commands from being executed when control returns.

 If Not .%Return%.=.Funct1. (
    <Function 1 command>
    <Function 1 command>
 )

:: %Return% environmental variable tracks script control:

 Call Set Return=Funct1
 Goto FunctA

 <Function 1 command>
 <Function 1 command>

:Funct2
:: Protect these commands from being executed when control returns.

 If Not .%Return%.=.Funct2. (
    <Function 2 command>
    <Function 2 command>
 )

:: %Return% environmental variable tracks script control:

 Call Set Return=Funct2
 Goto FunctB

 <Function 2 command>
 <Function 2 command>

:Funct3
:: Protect these commands from being executed when control returns.

 If Not .%Return%.=.Funct3. (
    <Function 3 command>
    <Function 3 command>
 )

:: %Return% environmental variable tracks script control:

 Call Set Return=Funct3
 Goto FunctA

 <Function 3 command>
 <Function 3 command>

:Funct4
:: Protect these commands from being executed when control returns.

 If Not .%Return%.=.Funct4. (
    <Function 4 command>
    <Function 4 command>
 )

:: %Return% environmental variable tracks script control:

 Call Set Return=Funct4
 Goto FunctB

 <Function 4 command>
 <Function 4 command>
 Goto End

:FunctA
:: Reusable Function A

 <Function A command>
 <Function A command>
 <Function A command>
 Goto %Return%

:FunctB
:: Reusable Function B

 <Function B command>
 <Function B command>
 <Function B command>
 Goto %Return%

:End
:: No executable code goes beyond this point[/code]

Thank you kenalcock, that's gonna come in handy. I like using as few buttons as possible, and having a button do different things on different situations.

One scripting program I use is Autohotkey. It's quite advanced. In combination with dopusrt.exe, it lets you do almost anything without the limitations of DOS scripting.