@@ -3,29 +3,46 @@ namespace MacUtilGUI.Services
33open System
44open System.IO
55open System.Diagnostics
6+ open System.Reflection
67open Tomlyn
78open MacUtilGUI.Models
89
910module ScriptService =
1011
11- let scriptsBasePath =
12- let currentDir = Directory.GetCurrentDirectory()
13- let scriptPath = Path.Combine( currentDir, " .." , " scripts" )
14- let resolvedPath = Path.GetFullPath( scriptPath)
15- printfn " Current directory: %s " currentDir
16- printfn " Scripts path: %s " resolvedPath
17- printfn " Scripts directory exists: %b " ( Directory.Exists( resolvedPath))
18- resolvedPath
12+ let assembly = Assembly.GetExecutingAssembly()
13+
14+ let getEmbeddedResource ( resourcePath : string ) : string option =
15+ try
16+ let resourceName = sprintf " MacUtilGUI.%s " ( resourcePath.Replace( " /" , " ." ) .Replace( " \\ " , " ." ) .Replace( " -" , " _" ))
17+ use stream = assembly.GetManifestResourceStream( resourceName)
18+ if stream <> null then
19+ use reader = new StreamReader( stream)
20+ Some( reader.ReadToEnd())
21+ else
22+ printfn " Resource not found: %s " resourceName
23+ None
24+ with
25+ | ex ->
26+ printfn " Error reading embedded resource %s : %s " resourcePath ex.Message
27+ None
28+
29+ let listEmbeddedResources () =
30+ let resourceNames = assembly.GetManifestResourceNames()
31+ printfn " Available embedded resources:"
32+ for name in resourceNames do
33+ printfn " %s " name
34+
35+ let scriptsBasePath = " "
1936
2037 let loadScriptsFromDirectory ( directoryPath : string ) : ScriptCategory list =
2138 let mutable categories = []
2239
2340 try
24- let tabDataPath = Path.Combine ( scriptsBasePath , directoryPath , " tab_data.toml" )
41+ let tabDataPath = sprintf " %s / tab_data.toml" directoryPath
2542
26- if File.Exists( tabDataPath) then
43+ match getEmbeddedResource tabDataPath with
44+ | Some content ->
2745 try
28- let content = File.ReadAllText( tabDataPath)
2946 let tomlDoc = Toml.Parse( content)
3047
3148 // Parse the TOML as a dynamic table
@@ -53,7 +70,7 @@ module ScriptService =
5370 let name = entry.[ " name" ]. ToString()
5471 let description = entry.[ " description" ]. ToString()
5572 let script = entry.[ " script" ]. ToString()
56- let fullPath = Path.Combine ( scriptsBasePath , directoryPath, script)
73+ let fullPath = sprintf " %s / %s " directoryPath script
5774
5875 yield {
5976 Name = name
@@ -76,31 +93,9 @@ module ScriptService =
7693 with
7794 | ex ->
7895 printfn " Error parsing TOML file %s : %s " tabDataPath ex.Message
79- else
80- // If no tab_data.toml, scan for .sh files directly
81- let directoryFullPath = Path.Combine( scriptsBasePath, directoryPath)
82- if Directory.Exists( directoryFullPath) then
83- let shellFiles = Directory.GetFiles( directoryFullPath, " *.sh" )
84- let scripts =
85- shellFiles
86- |> Array.map ( fun filePath ->
87- let fileName = Path.GetFileNameWithoutExtension( filePath)
88- {
89- Name = fileName
90- Description = sprintf " Shell script: %s " fileName
91- Script = Path.GetFileName( filePath)
92- TaskList = " I"
93- Category = directoryPath
94- FullPath = filePath
95- })
96- |> Array.toList
97-
98- if not scripts.IsEmpty then
99- let category = {
100- Name = directoryPath
101- Scripts = scripts
102- }
103- categories <- category :: categories
96+ | None ->
97+ printfn " ERROR: Embedded resource not found: %s " tabDataPath
98+ printfn " This should not happen if resources are properly embedded!"
10499 with
105100 | ex ->
106101 printfn " Error loading scripts from %s : %s " directoryPath ex.Message
@@ -111,9 +106,11 @@ module ScriptService =
111106 let mutable allCategories = []
112107
113108 try
114- let mainTabsPath = Path.Combine( scriptsBasePath, " tabs.toml" )
115- if File.Exists( mainTabsPath) then
116- let content = File.ReadAllText( mainTabsPath)
109+ listEmbeddedResources() // Debug: list all available resources
110+
111+ let mainTabsPath = " tabs.toml"
112+ match getEmbeddedResource mainTabsPath with
113+ | Some content ->
117114 let tomlDoc = Toml.Parse( content)
118115 let table = tomlDoc.ToModel()
119116
@@ -125,12 +122,9 @@ module ScriptService =
125122 let categories = loadScriptsFromDirectory directory
126123 allCategories <- allCategories @ categories
127124 | _ -> ()
128- else
129- // Fallback: scan known directories
130- let knownDirectories = [ " applications-setup" ; " system-setup" ]
131- for directory in knownDirectories do
132- let categories = loadScriptsFromDirectory directory
133- allCategories <- allCategories @ categories
125+ | None ->
126+ printfn " ERROR: Main tabs.toml not found in embedded resources!"
127+ printfn " This should not happen if resources are properly embedded!"
134128 with
135129 | ex ->
136130 printfn " Error loading scripts: %s " ex.Message
@@ -139,33 +133,66 @@ module ScriptService =
139133
140134 let runScript ( scriptInfo : ScriptInfo ) : string =
141135 try
142- let startInfo = ProcessStartInfo()
143- startInfo.FileName <- " /bin/bash"
144- startInfo.Arguments <- sprintf " -c \" cd '%s ' && chmod +x '%s ' && ./'%s '\" "
145- ( Path.GetDirectoryName( scriptInfo.FullPath))
146- ( Path.GetFileName( scriptInfo.FullPath))
147- ( Path.GetFileName( scriptInfo.FullPath))
148- startInfo.UseShellExecute <- false
149- startInfo.CreateNoWindow <- true
150- startInfo.RedirectStandardOutput <- true
151- startInfo.RedirectStandardError <- true
152-
153- let proc = Process.Start( startInfo)
154- if proc <> null then
155- let output = proc.StandardOutput.ReadToEnd()
156- let error = proc.StandardError.ReadToEnd()
157- proc.WaitForExit()
136+ // Get the script content from embedded resources
137+ match getEmbeddedResource scriptInfo.FullPath with
138+ | Some scriptContent ->
139+ // Create a temporary file to execute the script
140+ let tempDir = Path.GetTempPath()
141+ let scriptFileName = Path.GetFileName( scriptInfo.Script) // Get just the filename, not the full path
142+ let tempFileName = sprintf " %s _%s " ( Guid.NewGuid() .ToString( " N" ) .Substring( 0 , 8 )) scriptFileName
143+ let tempFilePath = Path.Combine( tempDir, tempFileName)
158144
159- let fullOutput =
160- if String.IsNullOrEmpty( error) then
161- output
145+ try
146+ // Write script content to temporary file
147+ File.WriteAllText( tempFilePath, scriptContent)
148+
149+ // Make the temporary file executable
150+ let chmodStartInfo = ProcessStartInfo()
151+ chmodStartInfo.FileName <- " /bin/chmod"
152+ chmodStartInfo.Arguments <- sprintf " +x \" %s \" " tempFilePath
153+ chmodStartInfo.UseShellExecute <- false
154+ chmodStartInfo.CreateNoWindow <- true
155+
156+ let chmodProc = Process.Start( chmodStartInfo)
157+ if chmodProc <> null then
158+ chmodProc.WaitForExit()
159+
160+ // Execute the script
161+ let startInfo = ProcessStartInfo()
162+ startInfo.FileName <- " /bin/bash"
163+ startInfo.Arguments <- sprintf " \" %s \" " tempFilePath
164+ startInfo.UseShellExecute <- false
165+ startInfo.CreateNoWindow <- true
166+ startInfo.RedirectStandardOutput <- true
167+ startInfo.RedirectStandardError <- true
168+
169+ let proc = Process.Start( startInfo)
170+ if proc <> null then
171+ let output = proc.StandardOutput.ReadToEnd()
172+ let error = proc.StandardError.ReadToEnd()
173+ proc.WaitForExit()
174+
175+ let fullOutput =
176+ if String.IsNullOrEmpty( error) then
177+ output
178+ else
179+ sprintf " %s \n --- ERRORS ---\n %s " output error
180+
181+ printfn " Executed script: %s (Exit Code: %d )" scriptInfo.Name proc.ExitCode
182+ fullOutput
162183 else
163- sprintf " %s \n --- ERRORS ---\n %s " output error
164-
165- printfn " Executed script: %s (Exit Code: %d )" scriptInfo.Name proc.ExitCode
166- fullOutput
167- else
168- let errorMsg = sprintf " Failed to start script: %s " scriptInfo.Name
184+ let errorMsg = sprintf " Failed to start script: %s " scriptInfo.Name
185+ printfn " %s " errorMsg
186+ errorMsg
187+ finally
188+ // Clean up temporary file
189+ if File.Exists( tempFilePath) then
190+ try
191+ File.Delete( tempFilePath)
192+ with
193+ | _ -> () // Ignore cleanup errors
194+ | None ->
195+ let errorMsg = sprintf " Script content not found in embedded resources: %s " scriptInfo.FullPath
169196 printfn " %s " errorMsg
170197 errorMsg
171198 with
0 commit comments