diff --git a/app_builder/lib/app_builder/windows.ex b/app_builder/lib/app_builder/windows.ex index c233a8630..6d44637fa 100644 --- a/app_builder/lib/app_builder/windows.ex +++ b/app_builder/lib/app_builder/windows.ex @@ -13,11 +13,6 @@ defmodule AppBuilder.Windows do copy_dir(release.path, "#{app_path}/rel") - launcher_eex_path = Path.expand("#{@templates_path}/windows/Launcher.vbs.eex") - launcher_bin_path = "#{app_path}/#{app_name}Launcher.vbs" - copy_template(launcher_eex_path, launcher_bin_path, release: release, app_options: options) - File.mkdir!("#{app_path}/Logs") - manifest_eex_path = Path.expand("#{@templates_path}/windows/Manifest.xml.eex") manifest_xml_path = "#{app_path}/Manifest.xml" copy_template(manifest_eex_path, manifest_xml_path, release: release) @@ -36,6 +31,33 @@ defmodule AppBuilder.Windows do create_icon(icon_path, "#{app_path}/AppIcon.ico") end + tmp_dir = "#{Mix.Project.build_path()}/tmp" + File.mkdir_p!(tmp_dir) + launcher_eex_path = Path.expand("#{@templates_path}/windows/Launcher.vb.eex") + launcher_src_path = "#{tmp_dir}/Launcher.vb" + launcher_bin_path = "#{app_path}/#{app_name}Launcher.exe" + copy_template(launcher_eex_path, launcher_src_path, release: release, app_options: options) + File.mkdir!("#{app_path}/Logs") + + args = [ + path(launcher_src_path), + "/out:" <> path(launcher_bin_path), + "/nologo", + "/target:winexe", + "/win32manifest:" <> path(manifest_xml_path) + ] + + extra_args = + if icon_path do + ["/win32icon:" <> path("#{app_path}/AppIcon.ico")] + else + [] + end + + vbc_path = ensure_vbc() + + cmd!(vbc_path, args ++ extra_args) + for type <- Keyword.fetch!(options, :document_types) do if src_path = Keyword.get(type, :icon_path, icon_path) do dest_path = "#{app_path}/#{type[:name]}Icon.ico" @@ -53,6 +75,8 @@ defmodule AppBuilder.Windows do release end + defp path(path), do: String.replace(path, "/", "\\") + def handle_event(module, input) def handle_event(module, "open_url:" <> url) do @@ -85,6 +109,16 @@ defmodule AppBuilder.Windows do raise "couldn't find magick.exe in PATH to automatically convert images to .ico" end + def ensure_vbc do + case System.shell("dir %WINDIR%\\Microsoft.NET\\Framework64\\vbc.exe /s/b") do + {path, 0} -> + String.trim(path) + + {_, 1} -> + raise "cannot find vbc.exe. You need to install Visual Studio." + end + end + defp create_icon(src_path, dest_path) do log(:green, "creating", Path.relative_to_cwd(dest_path)) src_path = normalize_icon_path(src_path) diff --git a/app_builder/lib/templates/windows/Installer.nsi.eex b/app_builder/lib/templates/windows/Installer.nsi.eex index 956dd727a..b47fda6c9 100644 --- a/app_builder/lib/templates/windows/Installer.nsi.eex +++ b/app_builder/lib/templates/windows/Installer.nsi.eex @@ -48,7 +48,7 @@ Section "Install" ExecWait '"$INSTDIR\vcredist_x64.exe" /install' File /r rel rel - File "<%= app_name %>Launcher.vbs" + File "<%= app_name %>Launcher.exe" <%= if @app_options[:icon_path] do %> File "AppIcon.ico" <% end %> @@ -61,10 +61,11 @@ Section "Install" WriteRegStr HKCR ".<%= ext %>" "" "<%= app_name %>.<%= type[:name] %>" <% end %> WriteRegStr HKCR "<%= app_name %>.<%= type[:name] %>" "" "<%= type[:name] %>" -<%= if type[:icon_path] || @app_options[:icon_path] do %> +<%= if path = type[:icon_path] || @app_options[:icon_path] do %> + File "<%= type[:name] %>Icon.ico" WriteRegStr HKCR "<%= app_name %>.<%= type[:name] %>\DefaultIcon" "" "$INSTDIR\<%= type[:name] %>Icon.ico" <% end %> - WriteRegStr HKCR "<%= app_name %>.<%= type[:name] %>\shell\open\command" "" '$WINDIR\system32\wscript.exe "$INSTDIR\<%= app_name %>Launcher.vbs" "open_file:%1"' + WriteRegStr HKCR "<%= app_name %>.<%= type[:name] %>\shell\open\command" "" '"$INSTDIR\<%= app_name %>Launcher.exe" "open_file:%1"' <% end %> <%= for url_scheme <- Keyword.fetch!(@app_options, :url_schemes) do %> @@ -74,12 +75,12 @@ Section "Install" WriteRegStr HKCR "<%= url_scheme %>" "URL Protocol" "" WriteRegStr HKCR "<%= url_scheme %>\shell" "" "" WriteRegStr HKCR "<%= url_scheme %>\shell\open" "" "" - WriteRegStr HKCR "<%= url_scheme %>\shell\open\command" "" '$WINDIR\system32\wscript.exe "$INSTDIR\<%= app_name %>Launcher.vbs" "open_url:%1"' + WriteRegStr HKCR "<%= url_scheme %>\shell\open\command" "" '"$INSTDIR\<%= app_name %>Launcher.exe" "open_url:%1"' <% end %> SectionEnd Section "Desktop Shortcut" - CreateShortCut "$DESKTOP\<%= app_name %>.lnk" "$INSTDIR\<%= app_name %>Launcher.vbs" "" <%= if @app_options[:icon_path] do %> "$INSTDIR\AppIcon.ico" <% end %> + CreateShortCut "$DESKTOP\<%= app_name %>.lnk" "$INSTDIR\<%= app_name %>Launcher.exe" "" <%= if @app_options[:icon_path] do %> "$INSTDIR\AppIcon.ico" <% end %> SectionEnd Section "Uninstall" diff --git a/app_builder/lib/templates/windows/Launcher.vb.eex b/app_builder/lib/templates/windows/Launcher.vb.eex new file mode 100644 index 000000000..b22531eba --- /dev/null +++ b/app_builder/lib/templates/windows/Launcher.vb.eex @@ -0,0 +1,38 @@ +<% + +additional_paths = + for path <- Keyword.fetch!(@app_options, :additional_paths), into: "" do + "root & \"\\" <> String.replace(path, "/", "\\") <> ";\" & " + end + +%> + +Imports System + +Module Launcher + Sub Main(args As String()) + Dim root = My.Application.Info.DirectoryPath + Dim script = root & "\rel\bin\<%= @release.name %>.bat" + + Dim input as String + If args.count > 0 Then + input = args(0) + Else + input = "open_app" + End If + +<%= if additional_paths != "" do %> + Environment.SetEnvironmentVariable("PATH", <%= additional_paths%>Environment.GetEnvironmentVariable("PATH")) +<% end %> + + Dim cmd as String + ' try release rpc, if release is down, this will fail but that's ok. + cmd = "echo " & input & " | """ & script & """ rpc ""AppBuilder.__rpc__()""" + Shell("cmd.exe /c " & cmd, 0) + + ' try release start, if release is up, this will fail but that's ok. + Environment.SetEnvironmentVariable("APP_BUILDER_INPUT", input) + cmd = """" & script & """ start" + Shell("cmd.exe /c " & cmd, 0) + End Sub +End Module diff --git a/app_builder/lib/templates/windows/Launcher.vbs.eex b/app_builder/lib/templates/windows/Launcher.vbs.eex deleted file mode 100644 index 0d61702fe..000000000 --- a/app_builder/lib/templates/windows/Launcher.vbs.eex +++ /dev/null @@ -1,33 +0,0 @@ -<% - -additional_paths = - for path <- Keyword.fetch!(@app_options, :additional_paths), into: "" do - "root & \"" <> String.replace(path, "/", "\\") <> ";\" & " - end - -%> - -root = Left(Wscript.ScriptFullName, Len(Wscript.ScriptFullName) - Len(Wscript.ScriptName)) -script = root & "rel\bin\<%= @release.name %>.bat" - -If WScript.Arguments.Count > 0 Then - input = WScript.Arguments(0) -Else - input = "open_app" -End If - -Set shell = CreateObject("WScript.Shell") -Set env = shell.Environment("Process") -<%= if additional_paths != "" do %> -env("PATH") = <%= additional_paths %>env("PATH") -<% end %> - -' try release rpc, if release is down, this will fail but that's ok. -cmd = "echo " & input & " | """ & script & """ rpc ""AppBuilder.__rpc__()""" -status = shell.Run("cmd /c " & cmd, 0, true) - -' try release start, if release is up, this will fail but that's ok. -env("APP_BUILDER_INPUT") = input -cmd = """" & script & """ start" -status = shell.Run("cmd /c " & cmd, 0) -