Java application for building custom Windows executable launchers

This will be a great new feature!

In the mean time I created a Java application for building custom Windows executable launchers for any Java application, or Python and anything else for that matter. The application just compiles C# scripts into an executable with an optional embedded icon. It comes with a C# template for launching a batch file and you can download a C# template for launching jars that also checks for and downloads the appropriate JRE if necessary. It’s called CStExe and can be found here http://1337atr.weebly.com/cstexe.html

I’ve made scripts that work with bundled Java too so feel free to message me if you’d like a copy. If you’re into making exe launchers you may also want to check out Guavacado on my site, I made it to create multi-resolution icons(.ico). http://1337atr.weebly.com/guavacado.html

Everything is free of course :smile:

1 Like

Hi

I can’t agree more :slight_smile:

It’s free of charge, there is nothing (yet?) to pay but there is no source code (or I missed something, I’ve only found example.cs and a very few fxml scripts). InstallAnywhere had a free of charge version several years ago which suddenly disappeared, JarSplice has had some unfixed bugs for years, both are proprietary. If I don’t see your code, why should I trust you? Thanks for sharing anyway, I don’t want to discourage you.

It is already possible to create .ico files under any operating system supporting Java SE with Ant thanks to my contribution in Apache Commons Imaging:
https://issues.apache.org/jira/browse/IMAGING-138

PackR and JNDT do something similar than your tool but both are open source and work under any operating system supporting Java SE, not only Windows, they don’t require Microsoft .NET, the former is under a permissive license. Writing a GUI above them is doable. Their installers don’t download any JRE, it’s intentional, they require the developer to provide a JRE (OpenJDK preferably or Oracle Java) but some links to ready-to-use JREs are provided in the documentation.

Good luck.

I’m not saying what I wrote is the wolds greatest solution, I wrote it mainly for my own personal use and figured others might like to use it too. If you don’t want to use it that’s fine and if you don’t trust me that’s absolutely understandable. Technically it is open source, just not immediately available. If you check the “About me” page on my site you can see that I’ve said I’d be happy to provide the source code and project assets to anyone that asks for it. If you want the project files for CStExe or Guavacado I’d be happy to send them to you. I just haven’t yet taken the time to upload the source to GitHub yet.

CStExe provides a completely customizable launcher if you know C#, really it’s just a C# compiler so you could compile any C# script, doesn’t even need to be a launcher. Technically you can do the same thing with VisualStudio, even more actually, I just figure if all you want is a launcher then why bother with the 5GB install.

As for Guavacado, it can be used for more than just icon creation and again it was created because I wanted to use it and I enjoy programming. Guavacado works under any OS running JRE8+, CStExe needs Windows because it relies on .Net 2.0, I used IKVM for the Java to .Net interface.

I write applications an such because I enjoy programming. I really don’t care if I’ve written something that another program can already do. Writing these applications is enjoyable to me and each application I write provides me the opportunity to advance my skill set.

P.S. I am not a corporation, I have no desire to compete against other people, organizations or products. If there is another application out there that does what my application does and better that’s great, I’m glad people have access to it.

P.P.S. Oh, if you’re concerned about what the Guavacado installer is doing you could just download the mac or linux version, they work on Windows too, the difference is that they don’t have an installer and have different install instructions packaged with them. The Guavacado installer requests administrator rights because it downloads the JRE if it’s not already installed and then launches the JRE installer which requires admin level access apparently.

P.P.P.S. I believe that everyone should have access to the fruits of my labor regardless of their politics, religious beliefs, race or level of wealth. My software and the source code behind it is available to everyone free of charge and without any form of restriction(license). My software and the source is free for the poor and it is free for the rich. What they choose to do with the fruits of my labor is up to them, not me.

This is a bedrock principle of mine and I have given up almost everything that I own to support it. I absolutely do not judge or discriminate against those who do not believe the same as I or uphold the same as I.
:gift_heart:

Yes, well, you need to pick a license even if it’s just to state that it’s “public domain”. By default, you own copyright on anything that you right and without explicit permission(license) we can’t do anything with it anyway.

I speak of the “royal we” as I have no personal interest in this… just trying to squelch the semi-pervasive myth that licenses are adding restrictions. Generally, they do the opposite… the lack of license is the most restrictive form of copyright.

Thanks pspeed, I was rather unaware of that so it’s good to know. I’ll have to check my about page, I know on my Chet page I say that it’s free for any use and I imagine that statement could be used as a legal argument and if someone were to e-mail me and ask for my source I’m sure they could use the e-mail correspondence as a legal argument too. Technically that wouldn’t ever be necessary because I wouldn’t ever be taking anyone to court, but I suppose any would be user of my software wouldn’t necessarily know that about me.

I did upload my software @Chat to GitHub and if I recall I opted not to select a license, I thought that meant it was “public domain” by default, but apparently I was wrong.

The thing about a license granting permission to use my source for any purpose is that, as it is how you describe, the user of the source would be required to include that license with their distribution otherwise would be users of that distribution would not be able to use it. That, in and of itself, constitutes a restriction in that the user is required to redistribute the license.

Now I wouldn’t ever take someone to court over the usage of the fruits of my labor, but, hypothetically, if I did I suppose their lawyers could use this and my last post as a legal argument too.

P.S. My website doesn’t receive a whole lot of traffic so doing it via e-mail isn’t any hassle to me at this point. Over the years there’s only ever been one person who e-mailed me asking for my project files. He wanted the source and assets to my game Soul Survivor and I promptly provided it to him. I think he’s redistributing the game via Google Play or the Amazon store and if memory serves he mentioned something about wanting to make a sequel. Never followed up with him so I don’t know what ever happened to all that. I hope everything is going well in that respect, he never asked me for some type of license or permission or anything.

P.P.S. Perhaps you can see my dilemma here. I know it is small and seemingly insignificant, but believe it or not it is important to me that I impose absolutely no restriction upon someone. How can I impose no restriction upon someone if they are then required to redistribute a “public domain” license with my sources? How can I impose no restriction upon someone if “officially” stating that there are no restrictions in and of itself constitutes a restriction?

P.P.P.S. My girlfriend just said something interesting. She says people don’t take you seriously when you just give stuff away or they are afraid of you. I said, maybe it’s because they’ve just never seen it before. That fear of the unknown, if I were anyone else yeah I’d probably be trying to scam you or have some hidden motive. However, I am not anyone else, but of course you have no way of knowing that and there’s little I can do in that respect.

P.P.P.P.S. @Nehon: So sorry, didn’t mean to hijack your thread.

Someone could say download the source code to my projects, re-brand it and sell it and never say one word to me and it would not bother me. Someone could take my work, remove my name and paste their name on it and still not a bit angry would I be. Someone may choose to use my work for good and they may choose to use it for evil. That choice belongs to them and to them belong the consequences and if there be consequences it is not from me that they arise. Use it for good or use it for evil, what is good and what is evil, it is not for me to decide.

No sweat, you didn’t.You hijacked Normen’s…
Now you wish you had hijacked mine… :smiley:

1 Like

What you describe is “public domain”… and you can put that in the source code right at the top. That is a license.

Public domain means that someone else can remove it before giving it to someone else and they’ve “re-licensed” it as their own, basically. That’s what public domain is… no restrictions at all.

Some licenses like BSD also protect you from lawsuits and keep people from using your name without permission… then users are required to keep the license in the file also because otherwise it removes the protections that the BSD license gave the author.

CC0 (creative commons 0) is another option close to public domain.

@Nehon: Alas I have gone and embarrassed myself. Life is full of surprises. @Normen: So sorry, I had no intention of hijacking your thread :smile:

@pspeed: I shall ask father time if I will be including a public domain license with any of my works. For now, he remains silent on the issue.

Note: licenses aren’t for you, really… they are for everyone else who might want to use your code.

As a developer, if I see some file without a license then by default I cannot use it. This goes for any creative work. It is automatically own with exclusive copyrights by the original creator… of which I’m guaranteed not to be.

By leaving out a simple “public domain” or license header, you force the would be user to go and seek out the creator to see if they have permission to use it. Most people just won’t bother, anyway. Especially with source code, I assume if no one bother to put a few lines of text at the beginning of the file then they don’t want to share it.

2 Likes

As usual your input is greatly appreciated, thank you.

@Tryder I wrote I don’t want to discourage you. If your program is open source, pick a license and publish it somewhere if and only if you want. pspeed is right, you should read the Bern convention, no license = copyrighted by default, it applies to your artworks too. Writing that you provide the source code if someone asks it doesn’t mean it’s open source. Nothing forces me to use your tool but when you publish something, I’m allowed to express my opinion about it in certain limits, it’s the freedom of speech, I didn’t insult you and I understand that you program just for fun. In my humble opinion, providing a binary without its source code is mostly useless on the long term, it’s just my opinion. JMonkeyEngine is written in Java, I think that using open source Java based tools is easier for a Java developer than having to follow some platform dependent instructions. I haven’t found the source code of CstExe online yet. Good luck.

I’ve updated the CStExe page with a link to a zip file containing the source code and other assets. I may consider uploading this to GitHub at some point, but don’t really care to do so at this time. To be honest this application is about as simple as they come so I really didn’t think publishing the source would’ve contributed anything that wasn’t already available elsewhere.

CStExe comprises two applications, a front end and a compiler. The README file in the zip package contains some basic instructions, but to build the compiler you’ll need to make use of IKVM, www.ikvm.net. The README file contains a list of the Windows DLLs that need to be included in the project, you’ll use IKVM to create jar libraries based upon those DLLs and then include those jars as external libraries in the project.

@gouessej: On a separate note the installation instructions I was referring to were not for CStExe, they were for the different distributions of Guavacado and for a Java developer they shouldn’t be necessary at all, they merely inform the user how to obtain and install the Java Runtime Environment. Developers are not the only viewers of my web-site so including instructions on how to install the JRE and, for the Windows version, using an installer that takes care of JRE installation automatically is useful for those people who are not particularly computer savvy.

I wasn’t trying to deny your right to an opinion or to express that opinion, just expressing my own opinion.

@Tryder Thank you for publishing your source code. I suggest you to comment it a bit more so that other developers can understand it and maybe contribute. For example, ImageViewSprite seems to be very simple but you should explain why you divide by 1000000000 / fps even though understand that there is a conversion between nanoseconds and seconds.

Yeah, I’m usually pretty bad about commenting my code. I’ll see about getting a new version of the source uploaded with comments at some point in the future. In the mean time I posted the ImageViewSprite class with comments over at StackOverflow a while ago.

import javafx.animation.AnimationTimer;
import javafx.geometry.Rectangle2D;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;

public class ImageViewSprite extends AnimationTimer {


    private final ImageView imageView; //Image view that will display our sprite

    private final int totalFrames; //Total number of frames in the sequence
    private final float fps; //frames per second I.E. 24

    private final int cols; //Number of columns on the sprite sheet
    private final int rows; //Number of rows on the sprite sheet

    private final int frameWidth; //Width of an individual frame
    private final int frameHeight; //Height of an individual frame

    private int currentCol = 0;
    private int currentRow = 0;

    private long lastFrame = 0;

    public ImageViewSprite(ImageView imageView, Image image, int columns, int rows, int totalFrames, int frameWidth, int frameHeight, float framesPerSecond) {
        this.imageView = imageView;
        imageView.setImage(image);
        imageView.setViewport(new Rectangle2D(0, 0, frameWidth, frameHeight));

        cols = columns;
        this.rows = rows;
        this.totalFrames = totalFrames;
        this.frameWidth = frameWidth;
        this.frameHeight = frameHeight;
        fps = framesPerSecond;

        lastFrame = System.nanoTime();
    }

    @Override
    public void handle(long now) {
        int frameJump = (int) Math.floor((now - lastFrame) / (1000000000 / fps)); //Determine how many frames we need to advance to maintain frame rate independence

        //Do a bunch of math to determine where the viewport needs to be positioned on the sprite sheet
        if (frameJump >= 1) {
            lastFrame = now;
            int addRows = (int) Math.floor((float) frameJump / (float) cols);
            int frameAdd = frameJump - (addRows * cols);

            if (currentCol + frameAdd >= cols) {
                currentRow += addRows + 1;
                currentCol = frameAdd - (cols - currentCol);
            } else {
                currentRow += addRows;
                currentCol += frameAdd;
            }
            currentRow = (currentRow >= rows) ? currentRow - ((int) Math.floor((float) currentRow / rows) * rows) : currentRow;

            //The last row may or may not contain the full number of columns
            if ((currentRow * cols) + currentCol >= totalFrames) {
                currentRow = 0;
                currentCol = Math.abs(currentCol - (totalFrames - (int) (Math.floor((float) totalFrames / cols) * cols)));
            }

            imageView.setViewport(new Rectangle2D(currentCol * frameWidth, currentRow * frameHeight, frameWidth, frameHeight));
        }
    }
}