1) Download JKDefrag here: http://www.kessels.com/Jkdefrag (use version for Windows 2000/2003/XP/Vista/2008)

2) Compile the following source with PBWin 9.0 and put resulting run_defrag.exe in same directory as jkdefrag.exe

'Compiled with PBWin 9.0 - by Alan Clarke (Credits go to the PB forum tech guys)
'This Powerbasic source compiles into a simple front-end for JKDefrag.
'Download JKDefrag here: http://www.kessels.com/Jkdefrag
'Put run_defrag.exe into same directory as jkdefrag.exe (or put jkdefrag.exe into path directory)
#PBFORMS CREATED V1.51
#COMPILE EXE "run_defrag.exe"
#DIM ALL

'------------------------------------------------------------------------------
' ** Includes **
'------------------------------------------------------------------------------
#PBFORMS BEGIN INCLUDES
#IF NOT %DEF(%WINAPI)
#INCLUDE "WIN32API.INC"
#ENDIF
#PBFORMS END INCLUDES
'------------------------------------------------------------------------------

'------------------------------------------------------------------------------
' ** Constants **
'------------------------------------------------------------------------------
#PBFORMS BEGIN CONSTANTS
%IDD_DEFRAG = 101
%IDC_LABEL1 = 1005
%IDC_OK = 1006
%IDC_CANCEL = 1007
%IDC_DRIVESELECTLISTBOX = 1001
#PBFORMS END CONSTANTS
'------------------------------------------------------------------------------

'------------------------------------------------------------------------------
' ** Declarations **
'------------------------------------------------------------------------------
DECLARE CALLBACK FUNCTION ShowDIALOG1Proc()
DECLARE FUNCTION DriveSelectListBox(BYVAL hDlg AS DWORD, BYVAL lID AS LONG, BYVAL _
lCount AS LONG) AS LONG
DECLARE FUNCTION ShowDIALOG1(BYVAL hParent AS DWORD) AS LONG
#PBFORMS DECLARATIONS
'------------------------------------------------------------------------------

'------------------------------------------------------------------------------
' ** Main Application Entry Point **
'------------------------------------------------------------------------------
FUNCTION PBMAIN()
ShowDIALOG1 %HWND_DESKTOP
END FUNCTION
'------------------------------------------------------------------------------

'------------------------------------------------------------------------------
' ** CallBacks **
'------------------------------------------------------------------------------
CALLBACK FUNCTION ShowDIALOG1Proc()
DIM hDlg AS DWORD
DIM txtv AS STRING
DIM cmdline AS STRING
' DIM datav AS LONG
DIM datav2 AS LONG
DIM i AS LONG
DIM itemnum AS LONG
DIM pid AS DWORD

SELECT CASE AS LONG CBMSG
CASE %WM_INITDIALOG
' Initialization handler

CASE %WM_NCACTIVATE
STATIC hWndSaveFocus AS DWORD
IF ISFALSE CBWPARAM THEN
' Save control focus
hWndSaveFocus = GetFocus()
ELSEIF hWndSaveFocus THEN
' Restore control focus
SetFocus(hWndSaveFocus)
hWndSaveFocus = 0
END IF

CASE %WM_COMMAND
' Process control notifications
SELECT CASE AS LONG CBCTL
CASE %IDC_DriveSelectListBox

CASE %IDC_OK
'LISTBOX GET COUNT CB.HNDL, %idc_driveselectlistbox TO datav
'use cb.hndl in callback --cb.hndl = hDlg in dialog
'LISTBOX GET SELCOUNT CB.HNDL ,%idc_driveselectlistbox TO datav2
LISTBOX GET COUNT CB.HNDL ,%idc_driveselectlistbox TO datav2
cmdline = ""
FOR i =1 TO datav2
LISTBOX GET STATE CB.HNDL, %idc_driveselectlistbox, i TO itemnum
IF (itemnum = -1) THEN '0=not selected, -1=selected
LISTBOX GET TEXT CB.HNDL, %idc_driveselectlistbox, i TO txtv
cmdline = cmdline + txtv + " "
END IF
NEXT
IF cmdline <> "" THEN
pid???=SHELL("jkdefrag "+cmdline$,1)
ELSE
MSGBOX "No Drives Selected"
END IF
'msgbox cmdline
'MSGBOX "Number of items in listbox "+STR$(datav)+$CRLF + "number selected" + STR$(datav2) + $CRLF + cmdline

CASE %IDC_CANCEL
DIALOG END CBHNDL, 0
FUNCTION = 1

END SELECT
END SELECT
END FUNCTION
'------------------------------------------------------------------------------

'------------------------------------------------------------------------------
' ** Populate Listbox **
'------------------------------------------------------------------------------
FUNCTION DriveSelectListBox(BYVAL hDlg AS DWORD, BYVAL lID AS LONG, BYVAL lCount AS LONG) AS LONG
LOCAL i AS LONG, buffer AS STRING, zDrive AS ASCIIZ * 26
DIM sDrive(1:26) AS STRING

' Obtain a list of drives from the system
buffer = STRING$(2048, $NUL)
buffer = LEFT$(buffer, GetLogicalDriveStrings(LEN(buffer), BYVAL STRPTR(buffer)))

FOR i = 1 TO PARSECOUNT(buffer, $NUL)-1
zDrive = PARSE$(buffer, $NUL, i)
IF GetDriveType(zDrive)=%DRIVE_FIXED THEN
LISTBOX ADD hDlg, lID, LEFT$(zDrive,2)
sDrive(i)= LEFT$(zDrive,2)
END IF
NEXT i

END FUNCTION
'------------------------------------------------------------------------------

'------------------------------------------------------------------------------
' ** Dialogs **
'------------------------------------------------------------------------------
FUNCTION ShowDIALOG1(BYVAL hParent AS DWORD) AS LONG
LOCAL lRslt AS LONG

#PBFORMS BEGIN DIALOG %IDD_DEFRAG->->
LOCAL hDlg AS DWORD

DIALOG NEW hParent, "Defragment Drive", 79, 70, 112, 144, %WS_POPUP OR _
%WS_BORDER OR %WS_DLGFRAME OR %WS_SYSMENU OR %WS_MINIMIZEBOX OR _
%WS_CLIPSIBLINGS OR %WS_VISIBLE OR %DS_MODALFRAME OR %DS_3DLOOK OR _
%DS_NOFAILCREATE OR %DS_SETFONT, %WS_EX_CONTROLPARENT OR %WS_EX_LEFT _
OR %WS_EX_LTRREADING OR %WS_EX_RIGHTSCROLLBAR, TO hDlg
CONTROL ADD LISTBOX, hDlg, %IDC_DRIVESELECTLISTBOX, , 15, 25, 80, 75, _
%WS_CHILD OR %WS_VISIBLE OR %WS_TABSTOP OR %WS_VSCROLL OR _
%LBS_MULTIPLESEL OR %LBS_SORT OR %LBS_NOTIFY, %WS_EX_CLIENTEDGE OR _
%WS_EX_LEFT OR %WS_EX_LTRREADING OR %WS_EX_RIGHTSCROLLBAR
CONTROL ADD LABEL, hDlg, %IDC_LABEL1, "Select drive(s) to defrag", 15, _
10, 80, 10
CONTROL ADD BUTTON, hDlg, %IDC_OK, "OK", 5, 110, 45, 25
CONTROL ADD BUTTON, hDlg, %IDC_CANCEL, "Cancel", 60, 110, 45, 25
#PBFORMS END DIALOG

DriveSelectListBox hDlg, %IDC_DriveSelectListBox, 30

DIALOG SHOW MODAL hDlg, CALL ShowDIALOG1Proc TO lRslt

#PBFORMS BEGIN CLEANUP %IDD_DEFRAG
#PBFORMS END CLEANUP

FUNCTION = lRslt
END FUNCTION
'------------------------------------------------------------------------------