WFS Kiosk Mode 64-Bit App Not Working.

I’ve been using Kiosk Mode from the WFS with my 32-bit compiles for some time and it works great.
WFS: https://github.com/arbp/WFS/tree/master/Windows%20Functionality%20Suite/Kiosk%20Mode

I recently updated all my custom libraries for 64-bit and compiled 64-bit versions of my application. Everything functions normally when I do not enable KisokApplication but if I change to super KisokApplication no windows or controls are displayed. This is an issue because I need to be able to set the focus to a Text Field control that is contained in a window.

All I get is a black screen, no splash screen(which my app shows) and then no main window ever displays with the 64-bit compiles.

I am currently compiling with 2017 r2.1. I am not using any custom declares to change any window styles.

Can anyone offer some advice to me as to how I may resolve this issue? Things I can look for in the WFS Kiosk Mode code to alter?

This is a real problem for me right now. Thanks so much for any advice.

See here for information on WFS replacement. https://blog.xojo.com/2017/12/20/winapilib-on-github/

Thank you sir. :slight_smile:

@Bob Keeney

Can you give me any advice as to which declares in the old WFS Kiosk Mode might need to be replaced with updated code from the WinAPILib to get the windows to display properly again for 64-bit? Thanks for any advice.

WinAPILib does not have any code in it for Kiosk mode at this point.

Looking at WFS, at first review the Kiosk mode code (KioskApplicationWFS) looks 64-bit safe, but that code does rely on FolderItemExtensionsWFS.LaunchAndWait which looks like it sets up a MemoryBlock that is probably not sized properly for 64-bit.

It seems that some of the code was 32bit only, mainly pointers that will change when moving to 64bit, here’s what you will need to replace. Ideally those memory blocks should be changed to structures but I’m not about to start rewriting the WFS library :wink:

See here if you want more information on windows declares: https://blog./2017/01/22/windows-to-xojo-data-type-conversion/

[code]Public Sub LaunchAndWait(extends f as FolderItem, params as String = “”, deskName as String = “”)
// We want to launch the application and wait for
// it to finish executing before we return.
#if TargetWindows

Soft Declare Function CreateProcessW Lib "Kernel32" ( appName as WString, params as WString, _
procAttribs as Integer, threadAttribs as Integer, inheritHandles as Boolean, flags as UInt32, _
env as Integer, curDir as Integer, startupInfo as Ptr, procInfo as Ptr ) as Boolean

Soft Declare Function CreateProcessA Lib "Kernel32" ( appName as CString, params as CString, _
procAttribs as Integer, threadAttribs as Integer, inheritHandles as Boolean, flags as UInt32, _
env as Integer, curDir as Integer, startupInfo as Ptr, procInfo as Ptr ) as Boolean

dim startupInfo, procInfo as MemoryBlock

#If Target64Bit
  Const sizeOfPtr = 8
#Else
  Const sizeOfPtr = 4
#EndIf

#If Target64Bit
  startupInfo = New MemoryBlock( 104 )
#Else
  startupInfo = New MemoryBlock( 68 )
#EndIf

procInfo = new MemoryBlock( (2 * sizeOfPtr) + 4 + 4 )

dim unicodeSavvy as Boolean = System.IsFunctionAvailable( "CreateProcessW", "Kernel32" )

startupInfo.Long( 0 ) = startupInfo.Size

dim deskStr, deskPtr as MemoryBlock
if deskName <> "" then
  if unicodeSavvy then
    deskStr = ConvertEncoding( deskName + Chr( 0 ), Encodings.UTF16 )
  else
    deskStr = deskName + Chr( 0 )
  end if
  
  startupInfo.Ptr( (2 * sizeOfPtr) ) = deskStr
end if

dim ret as Boolean
if unicodeSavvy then
  ret = CreateProcessW( f.AbsolutePath, params, 0, 0, false, 0, 0, 0, startupInfo, procInfo )
else
  ret = CreateProcessA( f.AbsolutePath, params, 0, 0, false, 0, 0, 0, startupInfo, procInfo )
end if

if not ret then return

Declare Function WaitForSingleObject Lib "Kernel32" ( handle as Integer, howLong as Integer ) as Integer
Const INFINITE = -1
Const WAIT_TIMEOUT = &h00000102
Const WAIT_OBJECT_0 = &h0

// We want to loop here so that we can yield time back
// to other threads.  This means threaded applications
// will "just work", but non-threaded ones will still appear hung.
while WaitForSingleObject( procInfo.Long( 0 ), 1 ) = WAIT_TIMEOUT
  App.SleepCurrentThread( 10 )
wend

Declare Sub CloseHandle Lib "Kernel32" ( handle as Integer )
CloseHandle( procInfo.Long( 0 ) )
CloseHandle( procInfo.Long( 1 * sizeOfPtr ) )

#else

#pragma unused f
#pragma unused params
#pragma unused deskName

#endif
End Sub
[/code]

@Paul Lefebvre @JulianS

Thank you both for the input! Very appreciated! :slight_smile:

[quote=369173:@JulianS]It seems that some of the code was 32bit only, mainly pointers that will change when moving to 64bit, here’s what you will need to replace. Ideally those memory blocks should be changed to structures but I’m not about to start rewriting the WFS library :wink:

See here if you want more information on windows declares: https://blog./2017/01/22/windows-to-xojo-data-type-conversion/

[code]Public Sub LaunchAndWait(extends f as FolderItem, params as String = “”, deskName as String = “”)
// We want to launch the application and wait for
// it to finish executing before we return.
#if TargetWindows

Soft Declare Function CreateProcessW Lib "Kernel32" ( appName as WString, params as WString, _
procAttribs as Integer, threadAttribs as Integer, inheritHandles as Boolean, flags as UInt32, _
env as Integer, curDir as Integer, startupInfo as Ptr, procInfo as Ptr ) as Boolean

Soft Declare Function CreateProcessA Lib "Kernel32" ( appName as CString, params as CString, _
procAttribs as Integer, threadAttribs as Integer, inheritHandles as Boolean, flags as UInt32, _
env as Integer, curDir as Integer, startupInfo as Ptr, procInfo as Ptr ) as Boolean

dim startupInfo, procInfo as MemoryBlock

#If Target64Bit
  Const sizeOfPtr = 8
#Else
  Const sizeOfPtr = 4
#EndIf

#If Target64Bit
  startupInfo = New MemoryBlock( 104 )
#Else
  startupInfo = New MemoryBlock( 68 )
#EndIf

procInfo = new MemoryBlock( (2 * sizeOfPtr) + 4 + 4 )

dim unicodeSavvy as Boolean = System.IsFunctionAvailable( "CreateProcessW", "Kernel32" )

startupInfo.Long( 0 ) = startupInfo.Size

dim deskStr, deskPtr as MemoryBlock
if deskName <> "" then
  if unicodeSavvy then
    deskStr = ConvertEncoding( deskName + Chr( 0 ), Encodings.UTF16 )
  else
    deskStr = deskName + Chr( 0 )
  end if
  
  startupInfo.Ptr( (2 * sizeOfPtr) ) = deskStr
end if

dim ret as Boolean
if unicodeSavvy then
  ret = CreateProcessW( f.AbsolutePath, params, 0, 0, false, 0, 0, 0, startupInfo, procInfo )
else
  ret = CreateProcessA( f.AbsolutePath, params, 0, 0, false, 0, 0, 0, startupInfo, procInfo )
end if

if not ret then return

Declare Function WaitForSingleObject Lib "Kernel32" ( handle as Integer, howLong as Integer ) as Integer
Const INFINITE = -1
Const WAIT_TIMEOUT = &h00000102
Const WAIT_OBJECT_0 = &h0

// We want to loop here so that we can yield time back
// to other threads.  This means threaded applications
// will "just work", but non-threaded ones will still appear hung.
while WaitForSingleObject( procInfo.Long( 0 ), 1 ) = WAIT_TIMEOUT
  App.SleepCurrentThread( 10 )
wend

Declare Sub CloseHandle Lib "Kernel32" ( handle as Integer )
CloseHandle( procInfo.Long( 0 ) )
CloseHandle( procInfo.Long( 1 * sizeOfPtr ) )

#else

#pragma unused f
#pragma unused params
#pragma unused deskName

#endif
End Sub
[/code][/quote]

This did indeed fix the issue Julian!!!

I’ve worked with a lot of declares in the past but it would have honestly taken me a lot longer to find this issue and resolve it!

This should be added to the WFS github!

Thanks again!!!

No problem.

After looking into it a bit more a structure wouldn’t really help as they’re bugged (feedback://showreport?report_id=48449) in windows and it would all miss-align anyway =s

Its a bit of a bodge but I’ve put my changes up and put in a pull request to merge them.

I’ve applied Julian’s merge to WFS and also added his updated version of LaunchAndWait to WinAPILib.

Since the Kiosk stuff looks 64-bit ready, I’ll try to add that to WinAPILib this week.