Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

How to run ONLY one app on a workstation 2

Status
Not open for further replies.

florindaniel

Programmer
Dec 4, 2009
120
RO
Hello,

I have this problem wich concerns both my app and some Windows settings:

There is a public workstation running some app. The app must:
1. start when turning on the computer (that's easy)
2. not allow switching to other applications (ALT+F4, minimising, etc...) !!??
3. shut down the computer when terminated

Thank you,
Daniel

 
What you're asking about is called a kiosk app. Google "VFP KIOSK APP" and you'll see several suggestions.

Having attempted it several times over the last 30 years, though, I invariably give up. Giving up all of Windows' services for managing printers and managing network connections and managing other things just makes the app unsupportable.
 
I'm afraid Dan's right. It's more difficult than you might think. The technique that Vilhelm-Ion indicated will get you some way there, but you can never prevent a determined user (or one who simply wants to fool around with the workstation) from reaching other parts of Windows.

Interestingly, this was much easier under Windows 3.1. There was a specific protocol for replacing the shell with your own software. But that's not much comfort nowadays.

Mike


__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
Or maybe you can choose something more elegant: a private desktop for your app!

Check this:

LOCAL cMainPath, cMainFile

m.cMainPath = ADDBS (JUSTPATH (SYS (16,0)))
SET DEFAULT TO (m.cMainPath)
*! * // m.cMainFile = m.cMainPath + 'main.exe'
m.cMainFile = GETFILE ( 'EXE' , 'File (& F):' , 'OK' , 0, 'Please specify the program to run in the new desktop' )
IF !EMPTY(m.cMainFile)
RunInNewDesktop (m.cMainFile)
ENDIF
RETURN

FUNCTION RunInNewDesktop
LPARAMETERS tcMainFile AS String
#define GENERIC_ALL 0x10000000
#define DESKTOP_SWITCHDESKTOP 0x0100

#define NORMAL_PRIORITY_CLASS 0x00000020
#define INFINITE 0xFFFFFFFF

#define GMEM_FIXED 0x0000
#define GMEM_ZEROINIT 0x0040

DECLARE Long CreateDesktop IN WIN32API;
String lpszDesktop,; && // name of the new Desktop
Long lpszDevice,; && // Reserved; MUST be NULL.
Long pDevMode,; && // Reserved; MUST be NULL.
Long dwFlags,; && // flags to Control Interaction with other Applications
Long dwDesiredAccess,; && // specifies Access of returned handle
Long lpsa && // specifies Security Attributes of the Desktop
DECLARE Long GetThreadDesktop IN WIN32API Long dwThreadId
DECLARE Long SetThreadDesktop IN WIN32API Long hDesktop
DECLARE Long OpenInputDesktop IN WIN32API;
Long dwFlags,; && // flags to Control Interaction with other Applications
Long fInherit,; && // specifies WHETHER returned handle is inheritable
Long dwDesiredAccess && // specifies Access of returned handle
DECLARE Long SwitchDesktop IN WIN32API Long hDesktop
DECLARE Long CloseDesktop IN WIN32API Long hDesktop

DECLARE Long CreateProcess IN WIN32API;
Long lpApplicationName,; && // pointer to name of Executable module
String lpCommandLine,; && // pointer to command line String
Long lpProcessAttributes,; && // Process Security Attributes
Long lpThreadAttributes,; && // Thread Security Attributes
Long bInheritHandles,; && // handle inheritance Flag
Long dwCreationFlags,; && // Creation flags
Long lpEnvironment,; && // pointer to new Environment Block
Long lpCurrentDirectory,; && // pointer to current Directory name
String @ lpStartupInfo,; && // pointer to STARTUPINFO
String @ lpProcessInformation && // pointer to PROCESS_INFORMATION
DECLARE Long WaitForSingleObject IN WIN32API;
Long hHandle,; && // handle to Object to wait for
Long dwMilliseconds && // time-out interval in milliseconds
DECLARE Long CloseHandle IN WIN32API Long hObject

DECLARE Long GlobalAlloc IN WIN32API Long uFlags, Long dwBytes
DECLARE Long GlobalFree IN WIN32API Long hMem
DECLARE Long GetLastError IN WIN32API

LOCAL hOrgDesktop, hOrgInput, cNewdesktop, hNewDesktop, pDesktopName, cSI, cPI

* @ save the original desktop handle
m.hOrgDesktop = GetThreadDesktop (Application.ThreadId)
m.hOrgInput = OpenInputDesktop (0, 0, DESKTOP_SWITCHDESKTOP)
* @ Create and switch to a new desktop
m.cNewdesktop = 'desktop_' + SYS (2015)
m.hNewDesktop = CreateDesktop (cNewDesktop, 0, 0, 0, GENERIC_ALL, 0)
SetThreadDesktop (m.hNewDesktop)
SwitchDesktop (m.hNewDesktop)

* @ constructor CreateProcess structural parameters needed
*! * // typedef struct {// Si _STARTUPINFO
! * * // DWORD cb;
! * * // LPTSTR lpReserved;
! * * // LPTSTR lpDesktop;
! * * // LPTSTR lpTitle;
! * * // DWORD dwx;
! * * // DWORD DWY;
! * * // DWORD dwXSize;
! * * // DWORD dwYSize;
! * * // DWORD dwXCountChars;
! * * // DWORD dwYCountChars;
! * * // DWORD dwFillAttribute;
! * * // DWORD dwFlags;
! * * // WORD wShowWindow;
! * * // WORD cbReserved2;
! * * // LPBYTE lpReserved2;
! * * // HANDLE hStdInput;
! * * // HANDLE hStdOutput;
! * * // HANDLE hStdError;
*! * //} STARTUPINFO
m.pDesktopName = GlobalAlloc (GMEM_FIXED + GMEM_ZEROINIT, LEN (m.cNewdesktop) + 1)
SYS (2600, m.pDesktopName, LEN (m.cNewdesktop), m.cNewdesktop)
m.cSI = BINTOC (0, '4RS' ) + BINTOC (m.pDesktopName, '4RS' ) + REPLICATE (CHR (0), 14 * 4)
m.cSI = BINTOC (LEN (m.cSI) + 4, '4RS' ) + m.cSI

*! * // typedef struct {// PI _PROCESS_INFORMATION
! * * // HANDLE hProcess;
! * * // HANDLE hThread;
! * * // DWORD dwProcessId;
! * * // DWORD dwThreadId;
*! * //} PROCESS_INFORMATION
m.cPI = REPLICATE (CHR (0), 4 * 4)

* @ create a new process running in the new desktop, start the main thread of the new process
IF (0 == CreateProcess (;
0, m.tcMainFile + CHR (0), 0, 0, 0, NORMAL_PRIORITY_CLASS, 0, 0,;
@ M.cSi, @ m.cPi))
MESSAGEBOX ( 'failed with error code execution' + TRANSFORM (GetLastError ()), 16, 'error message' )
ELSE
m.hProcess = CTOBIN (SUBSTR (m.cPI, 1, 4), '4RS' ) && // new process handle
m.hThread = CTOBIN (SUBSTR (m.cPI, 5, 4), '4RS' ) && // main thread handle
CloseHandle (m.hThread)
WaitForSingleObject (m.hProcess, INFINITE) && // wait until the process exits
CloseHandle (m.hProcess)
ENDIF

* @ clean up the environment
GlobalFree (m.pDesktopName) && // release allocated memory block
SwitchDesktop (m.hOrgInput) && // switch back to the original desktop
SetThreadDesktop (m.hOrgDesktop)
CloseDesktop (m.hNewDesktop)
ENDFUNC
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top