Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I code-sign the executable launcher that is created when bundling a JavaFX application?

So after much pain I'm coming to the completion of my project and now I need to know how to code sign the executable. No, not the .jar, I know how to do that. What I need is to be able to code-sign the .exe file that launches the .jar for our users, so that they don't see the "Do you want to allow the following program from an unknown publisher" warning message.

I know how to customize the process with an INNO script and I can use that to code-sign the installer, and I know how to include different icon files that will be used for the executables and shortcuts, and I know how to code-sign the jar through the ANT script, but this, this eludes me entirely.

So, does anyone know how I can go about code-signing the .exe that launches the jar when bundling a self-contained JavaFX application?

like image 635
Will Avatar asked Dec 04 '14 05:12

Will


2 Answers

Okay so I found it. This is pretty painful because there are (if I'm using this term in the correct context) "race conditions" here in that if the code signing doesn't finish before you start running the process again, it fails because it can't do anything with the .exe because it's being used by another process.

Turns out as long as your IDE is running in Admin (for Windows anyway) there's no need to elevate your script either.

Anyay, my problem was that the file was being set as Read-Only. VERY annoying but fortunately VBScript allows for you to change a files attributes so it was just a matter of doing that before trying to code-sign it :

<?xml version = "1.0" ?>
<package>
    <job id="CodeSign">
    <script language = "VBScript">
        <![CDATA[    
            'Set File as Normal. . .

            Dim objFSO, objFile
            Set objFSO = CreateObject("Scripting.FileSystemObject")
            Set objFile = objFSO.GetFile("<Relative Path>\<File.exe>")
            objFile.Attributes = 0

            Dim Shell
            Set Shell = WScript.CreateObject("WScript.Shell")
            Shell.Run "<Code Sign> ""<Relative Path>\<File.exe>""", 1, True
            Set Shell = Nothing
            Set objFSO = Nothing
            Set objFile = Nothing
        ]]>
    </script>
    </job>
</package>

So now, finally, at LONG LAST we have a complete and viable answer to this, evidently very esoteric question that no one but myself has dealt with (or is a very closely guarded secret, I'm not sure which) : How do you code-sign the executable created by a JavaFX bundle before it gets stored?

  • Create a WSF file with either JavaScript or VBScript (your preference)
  • Add the directory in which the file is being stored to the Class Path (for NetBeans you go to Tools -> Options -> Java Tab, select Add Directory next to Class Path, browse to the directory, and add it).
  • In your WSF file, in the Script section, get the file object and set its attributes to normal (0).
  • Then Shell.Run your preferred method of code signing applications. 1 is for showing the Code Sign window, True is to make the VBScript wait until it's finished to hopefully avoid a race condition.

The .exe will ALWAYS be stored one directory up from the WSF script file so the relative path is always going to be <FILENAME>\<FILENAME.exe>.

I really, REALLY hope this saves someone a LOT of grief some day...

like image 69
Will Avatar answered Sep 20 '22 05:09

Will


Add the following as first line of package/windows/MyProject.iss file:

#expr Exec("C:\Program Files (x86)\Windows Kits\8.0\bin\x64\signtool.exe", "sign /n CompanyName /tr tsa.starfieldtech.com " + AddBackslash(SourcePath) + "MyProject\MyProject.exe")

To ensure that exe file is writable add package/windows/MyProject-post-image.wsf:

<?xml version = "1.0" ?>
<package>
    <job id="CodeSign">
    <script language = "VBScript">
        <![CDATA[    
            'Set File as Normal. . .

            Dim objFSO, objFile
            Set objFSO = CreateObject("Scripting.FileSystemObject")
            Set objFile = objFSO.GetFile("MyProject\MyProject.exe")
            objFile.Attributes = 0

        ]]>
    </script>
    </job>
</package>
like image 45
Saeid Nourian Avatar answered Sep 22 '22 05:09

Saeid Nourian