Page 1 of 2

Mac style .app loader for Windows - Archive problems

Posted: Fri Jan 04, 2013 10:30 am
by ThatOneGuy
So I finally broke down and posted something on here. I could only do so much with so little information before I needed to ask.

I am currently working on a small-ish program that opens .app filetypes in Windows. These files are basically zipped files that are loaded into temporary location and they all have an "AppInfo" pointing to the location of the executable. It worked flawlessly when I tested with a "Drag & Drop" system (the .app file is dropped onto a small un-decorated stack and is launched. A stand-alone VLC Player program launched in a matter of seconds using this system), but I wanted it to handle command-line parameters so I can set an "Open with application" rule. The program does launch now when I double-click any .app file and handles it to a point, but now it just freezes when opening the archive. It can't even progress past that point in the code. My code is beginning to become a bit of a mess since I have tried just about every arrangement I could think of to get this to work and even borrowed some sample code (which has been thoroughly mangled by now). Adding waits did nothing. It just sticks is all.

If you read the code, you will see that I added an "answer "opening archive"" command. This is where the code stops working.

This was one of my bright ideas to make Windows a little simpler, but now it is just becoming a headache. I was initially hoping of making Mac-style executable folders for programs to reduce them to one file (easier to handle and all), but there's no such thing in Windows as far as I can tell, so archives are the next best thing, aside from the ugly temporary files business.

Here's the code I am testing... If it makes any sense.

EDIT: THIS CODE IS OLD NOW. NEWER CODE AND SAMPLE .REV IS IN LATER POST.

Code: Select all

local tStartApp = ""
local tLocation = ""
local tAppInfo = ""
local tFolder = ""

on startup
   put $1 into tStartApp
end startup

on openstack
   prep
end openstack

on prep
   local tZipContents
   if the environment is not "development" then
      if tStartApp is "" then
         answer "No paramaters sent. Nothing to load."
         lock messages
         quit
      end if
   end if
   set the shellcommand to "C:\Windows\System32\cmd.exe"
   clearFileList
   wait 200 milliseconds with messages
   revdeletefolder "C:\Users\[user]\Desktop\tmp"
   new folder "C:\Users\[user]\Desktop\tmp"
   put "C:\Users\[user]\Desktop\tmp" into tFolder
   answer "opening archive" ------------------------------------------------------------------------------------------
   revZipOpenArchive tStartApp,"read"
   if the result is "ziperr" then
      answer "An error occurred."
      lock messages
      quit
   end if
   put revZipEnumerateItems(tStartApp) into tZipContents
   put tZipContents into field "FileList"
   revZipCloseArchive tStartApp
   extractArchive tStartApp, "C:\Users\[user]\Desktop\tmp"
end prep

on clearFileList
  put empty into field "FileList"
end clearFileList

on ensureFolder pFolder
  if there is a folder pFolder or pFolder is empty then
    exit ensureFolder
  end if
  set the itemDel to "/"
  ensureFolder item 1 to -2 of pFolder
  create folder pFolder
end ensureFolder

on extractArchive pArchive, pWhere
   local tName
   local tAppLocation
   set the itemDel to "/"
   put pWhere into tLocation
   if char -1 of tLocation is not "/" then
      put "/" after tLocation
   end if
   put char 1 to -5 of item -1 of pArchive after tLocation
   set the itemDel to "."
   if there is a folder tLocation then
      local tCount
      put 1 into tCount
      put "." & tCount after tLocation
      repeat until there is no folder tLocation
         add 1 to tCount
         put tCount into item -1 of tLocation
      end repeat
   end if
   set the itemDel to comma
   revZipOpenArchive pArchive, "read"
   repeat for each line tItem in field "FileList"
      if char -1 of tItem is "/" then
      else if item 6 of revZipDescribeItem(pArchive,tItem) is "deflate" then
         set the itemDel to "/"
         ensureFolder tLocation & "/" & item 1 to -2 of tItem
         set the itemDel to ","
         revZipExtractItemToFile pArchive, tItem, tLocation & "/" & tItem
      end if
   end repeat
   revZipCloseArchive pArchive
   set itemdelimiter to "/"
   put the last item of tStartApp into tName
   set itemdelimiter to "."
   put the first item of tName into tName
   wait for 200 milliseconds with messages
   open file "C:\Users\[user]\Desktop\tmp\" & tName & "\AppInfo"
   read from file "C:\Users\[user]\Desktop\tmp\" & tName & "\AppInfo" until return
   put it into tAppInfo
   if tAppInfo is "" then answer "AppInfo file not found!"
   close file "C:\Users\[user]\Desktop\tmp\" & tName & "\AppInfo"
   put "C:\Users\[user]\Desktop\tmp\" & tName & "\" & tAppInfo into tAppLocation
   wait for 200 milliseconds with messages
   get shell (tAppLocation)
   wait 200 milliseconds with messages
   quit
end extractArchive
I would love it if anyone has any solution to my archive failing to open and the code getting trapped there. Also, I would like it if there was a simpler way of clearing the "tmp" folder other than deleting it and re-creating it every time an app is launched. Obviously, this is only able to handle one app at a time for now, but it wouldn't be too difficult to make it delete the temporary files only on exit.

Of course, if you know of any way I can make folders executable by this program as though they were files, that would be awesome to know.

On a side note, I have another program that is to run as a miniature portable Windows wrapper that looks like a separate OS. It works great (including a lovely registry hijack for some Windows system settings that are reset afterward), aside from the fact that the background stack keeps not staying on the background (i.e. it likes to cover things instead of staying behind them). I researched everywhere for a solution to this problem, including third party solutions, but there's nothing to be found.

Re: Mac style .app loader for Windows - Archive problems

Posted: Fri Jan 04, 2013 5:53 pm
by FourthWorld
It looks like you have the in-app part of that handled, so all you need to do now is set up the Registry so the OS knows to allow certain file types to be handled by your app. Details on that are available at Ken Ray's great Tips and Tricks site:
http://www.sonsothunder.com/devres/live ... ile004.htm

You can make all of the necessary registry entries from with LiveCode, but it may be helpful to set those up in your installer so your app can handle those from the moment it's installed without having to run first.

If motivated, it's not hard to make an installer in LiveCode too, by just copying all the files you need into custom properties and writing them out again at install time. You can reduce the size of the installer using LC's built-in gzip compression; see the "compress" function on that.

As for the ".app" file extension, FileXT.com shows that to be used by a program called Punch Post:
http://filext.com/file-extension/APP

Given the vast number of apps in the Windows world, and that Microsoft provides no central registration center for file name extensions, it can be difficult to find an extension that doesn't conflict with an existing app.

RunRev solved this problem by using a longer extesnsion (".livecode"), and in most modern Win versions you're no limited to three characters so you can safely use a longer string to better ensure uniqueness.

Re: Mac style .app loader for Windows - Archive problems

Posted: Fri Jan 04, 2013 8:18 pm
by ThatOneGuy
As I mentioned in my initial post, my program already handles the .app file extension. It doesn't require any registry entry editing, all I needed to do was right-click a .app file and select "open with" then select my program. From that point on, my computer has used my "AppLauncher.exe" to open .app files. It even changes the .app icons to match my program's. I can build an installer easily later if I want to to automatically assign the file extension to open with my program and to create the folder in which the "tmp" files can be safely stored. In any case, I already know how to do that.

The problem is only with revzip not opening the archive or freezing when it opens the archive. I tried putting a few answer tests throughout my code to see where it stops. In the development environment it sends answers all the way through the code until the point at which it is supposed to exit (after the app is extracted and launched and my program is no longer needed to help it run), but it doesn't extract anything for some reason. In the standalone, it stalls when first asked to read an archive and never reaches the "quit" command at the end of the function. I need to figure out why. I know that the library is included properly because it is there when saved as standalone. I just can't figure out what's wrong with my code since it worked before implementing command-line parameters.

BTW: I highly doubt that I will run into problems with the .app file extension conflicting with an industrial woodworking cad application since this is likely not going to become popular enough that it would matter. There's a few others mentioned as well that use this file extension. I am still not worried about conflicts. If I run into a conflict, it's an easy task to change it since there's currently nothing in my code that checks file extensions. You can pass it a .banana file (if you feel so inclined) and it will still try to work with it. It's a matter of figuring out exactly which extension to use when making the installer. Even then, the user can assign their own extension since the apps need to be built and compiled by the user before they can be used.

Re: Mac style .app loader for Windows - Archive problems

Posted: Fri Jan 04, 2013 9:13 pm
by FourthWorld
If "Open With..." is enough for you and you're not interested in also supporting the standard double-click, then you can safely ignore the Registry tips at Ken's site.

As for the external, having the file in the appropriate location may not tell you it's been loaded correctly. You may want to add an answer dialog showing the externalCommands at some point after it should have been loaded to see if indeed it has.

If that shows what you would expect but things still aren't working, you may want to track the output of those externals, possibly also "the result", to see if there may be other error info available.

Yes, the likelihood of a conflict with a given file name extension is small, but "app" is such a popular word that I'd be surprised if others who haven't logged their use at FileXT aren't also using it, and it's easy enough to bring the likelihood of potential conflict down to zero with the addition of just a couple more characters.

Re: Mac style .app loader for Windows - Archive problems

Posted: Fri Jan 04, 2013 9:27 pm
by ThatOneGuy
As I said, using "Open with" gives you the option of selecting "Use this app for all .app files", which effectively adds the standard double-click capability. That is what I have been using so far. I don't have any need to change that yet until I build an installer to skip the ten seconds it takes to set it up manually. Since it can be anything, I'll choose something that doesn't conflict at that point.

Thanks for the advice with checking "the result". I will try that and see what shows up. I only have a check for a "ziperr" result at the point that it currently crashes, but that isn't being sent since it is meant to toss up an error message and quit. There must be something else that isn't loading properly.

I know that it does read it inside the rev engine since the "filelist" field gets populated with the contents of the archive, but it doesn't do the same thing in standalone -- the field remains empty since it never reads the archive -- and neither actually extract any of the contents to the tmp folder. In that case, it may be a dll problem.

Re: Mac style .app loader for Windows - Archive problems

Posted: Sat Jan 05, 2013 12:24 am
by Simon
Check to make sure revZip.dll is in your externals folder.

Simon

Re: Mac style .app loader for Windows - Archive problems

Posted: Sat Jan 05, 2013 3:19 am
by ThatOneGuy
revZip.dll is in my externals folder, but it still isn't opening the archive.

"The result" is always empty throughout every stage of my program. It always answers blank. It's unlikely that there is some error being sent here.

Answering externalCommands gives me "externalCommands", which means that either I did it incorrectly, or it is never initialized. The same is true of externalFunctions & externalPackages. That may just be a mistake on my part since I never used those functions before.

Re: Mac style .app loader for Windows - Archive problems

Posted: Sat Jan 05, 2013 3:40 am
by Simon
I see that you have lots of "quit" commands. Do you drop an application onto your app icon and have it run?
Have you tried putting a long "wait with messages":

Code: Select all

on openstack
wait 5 seconds with messages
   put $1 into tStartApp
   prep
end openstack
This will allow the app to load the dll. Just for test.

Simon

Re: Mac style .app loader for Windows - Archive problems

Posted: Sat Jan 05, 2013 3:45 am
by ThatOneGuy
Just tried that. It still locks up when asked to open the archive.

Re: Mac style .app loader for Windows - Archive problems

Posted: Sat Jan 05, 2013 3:59 am
by Simon
If you do drag and drop a file...
Your app and the externals folder must be on your desktop. Which would kind of ruin the whole thing.
Unless you've made a shortcut?

Re: Mac style .app loader for Windows - Archive problems

Posted: Sat Jan 05, 2013 4:07 am
by ThatOneGuy
It's not just sitting on the desktop. I have an "open with application" rule set and keep saving the standalone to the same place so that the rule continues to apply to new versions. There's no dragging and dropping going on, only double-clicking. As I said before, I made a previous tester version (which I should have saved a different copy of) that used a drag and drop stack that worked flawlessly. I would send the original program, but it was specifically built to match my user profile, so it will not work on any other computer. I will use more generic tmp folder locations on later builds so that it will work on any machine.

Anyway, I decided to start from scratch again to see where I went wrong.

Re: Mac style .app loader for Windows - Archive problems

Posted: Sat Jan 05, 2013 4:36 am
by ThatOneGuy
I found my problem ... one of them anyway.

It seems as though it doesn't like to work from the opencard message. I need to find somewhere (not idle since it's backgrounded) where I can run start the process where it will actually work. I also need to figure out when it loads the dll, since I am still not sure if it has loaded by the time it is trying to open the archive. Even with starting over from the beginning, it still freezes at the same point.

Re: Mac style .app loader for Windows - Archive problems

Posted: Sat Jan 05, 2013 6:45 am
by shaosean
The Rev libraries are loaded after all the "open" handlers.. The standalone builder creates a hidden background group that loads all the different libraries.. The best thing to do is in your openCard handler is to use a send in time command to ensure everything is loaded.. The change needed to your code is minimal..

Code: Select all

on openStack
  send "prep" to me in 1 second
end openStack

Re: Mac style .app loader for Windows - Archive problems

Posted: Sat Jan 05, 2013 9:05 am
by ThatOneGuy
OK. Sending the message after 1 second worked perfectly in the IDE, but it still doesn't open the archive in standalone. Even with a 5 second gap between launching and starting any script, it still doesn't have any archive capability. Is there some code to send that forces the dll to load so that it will start working or am I just screwed here?

I also need to figure out a way of extracting all sub-folders in the archive since it seems to have stopped working in the IDE as well. Now it only extracts the files in the main directory and ignores all sub-folders even though I loop through these as well. Is there some different format for revZip than using the standard "root/sub-folder/file"format I am using now?

EDIT ->

OK. I figured it all out. Now it works amazing while in IDE, all the way through picking the app, opening it, saving it to the tmp folder, and launching the executable pointed to with the AppInfo file it contains. I got a small test that launches my iTunes using a bat-converted exe that just has a bunch of junk files alongside it. Everything is extracted, it runs the correct file, and itunes pops up almost immediately. My problem... I still cannot open anything in standalone. It reaches the point when it is supposed to list out the files and it stalls.

Here's what I have now. Much of it is taken from the revZipper example project but has been adapted to work automatically.

ANOTHER EDIT: just made it a ton faster. Now iTunes launches in less than a second from the time I launch the test. ->

Code: Select all

local sZipActiveArchive
local state = 0

on startup
   put $1 into sZipActiveArchive
end startup

on openstack
   put $1 into sZipActiveArchive
   send prep to me in 200 milliseconds
end openstack

on prep
   clearFileList
   set the shellcommand to "C:\Windows\System32\cmd.exe"
   put $1 into sZipActiveArchive
   if the environment is "development" then
      put "C:\Apps\test1.app" into sZipActiveArchive
   end if
   openarchive sZipActiveArchive
end prep

on openArchive pArchive
  listZipContents pArchive
end openArchive

on extractActiveArchiveTo pLocation
  extractArchive sZipActiveArchive, "C:\Users\Ryan\Desktop\Tmp"
end extractActiveArchiveTo


on extractArchive pArchive, pWhere
   local tLocation
   set the itemDel to "/"
   put pWhere into tLocation
   set the itemDel to comma
   revZipOpenArchive pArchive, "read"
   repeat for each line tItem in field "FileList"
      revZipExtractItemToFile pArchive, tItem, "C:\Users\Ryan\Desktop\Tmp" & "/" & tItem
      if char -1 of tItem is "/" then
         revZipExtractItemToFile pArchive, tItem, tLocation & "/" & tItem
      else if item 6 of revZipDescribeItem(pArchive,tItem) is "deflate" then
         set the itemDel to "/"
         ensureFolder tLocation & "/" & item 1 to -2 of tItem
         set the itemDel to ","
         revZipExtractItemToFile pArchive, tItem, tLocation & "/" & tItem
      end if
   end repeat
   revZipCloseArchive pArchive   
   launchApp
end extractArchive

on ensureFolder pFolder
  if there is a folder pFolder or pFolder is empty then
    exit ensureFolder
  end if
  set the itemDel to "/"
  ensureFolder item 1 to -2 of pFolder
  create folder pFolder
end ensureFolder

on listZipContents pArchive
  revZipOpenArchive pArchive, "read"
  local tZipContents
  put revZipEnumerateItems(pArchive) into tZipContents
  put tZipContents into field "FileList"
  revZipCloseArchive pArchive
  extractActiveArchiveTo "C:\Users\Ryan\Desktop\Tmp"
end listZipContents

on clearFileList
  put empty into field "FileList"
end clearFileList

on launchApp
   local tName
   local tAppLoc
   local tAppInfo
   set itemDel to "/"
   put the last item of sZipActiveArchive into tName
   set itemDel to "."
   put the first item of tName into tName
   open file "C:\Users\Ryan\Desktop\tmp\AppInfo"
   read from file "C:\Users\Ryan\Desktop\tmp\AppInfo" until return
   put it into tAppInfo
   if tAppInfo is "" then answer "ERROR: AppInfo file not found!"
   close file "C:\Users\Ryan\Desktop\tmp\AppInfo"
   put "C:\Users\Ryan\Desktop\tmp\" & tAppInfo into tAppLoc
   get shell (tAppLoc)
   wait 200 milliseconds with messages
   --quit
end launchApp
Obviously, I will change the tmp folder location later. This just makes it really easy for me to see what is happening.

Re: Mac style .app loader for Windows - Archive problems

Posted: Sat Jan 05, 2013 10:37 am
by ThatOneGuy
HELLO EVERYONE!

Alright, so I decided to let everyone have fun with what I have been working on here and see if anyone can figure out why it is only working in IDE and not standalone. It is already set up to receive command line parameters, so you can use the "Open with..." to launch things with it while it's in standalone. It doesn't work though. If you do try a standalone, you will notice that the text field never gets populated with text the way it does in the IDE, nor will it ever reach the quit command at the end of the code if you un-comment it.

Eventually it will be hidden and will quit by itself, but now it is visible and stays open to make it easier to work with.

In this zip file is the .rev of my program and a test1.app to play with. I do need to warn you that you will have a temporary folder created in "C:\Apps\tmp". If you already have something there, which seems unlikely, DO NOT OPEN THIS PROGRAM!!! Otherwise, it is perfectly safe. Just remove the folder when you are done playing with this program.

--------------------------------------------------------
Test.zip
(29.82 KiB) Downloaded 295 times
--------------------------------------------------------

Since no parameters are sent when the program is launched manually and they cannot be sent to a .rev file, it will ask where your app is. Just drop the .app file in the text box and hit enter. It should start YOUR iTunes. If it launches, that means it is working. If it doesn't launch, then it is likely that you don't have iTunes installed.

If anyone figures out why it doesn't accept my revZip.dll (or if it does work with yours for some reason, I would like to know.

Thanks.