Notifications
Clear all

[Closed] [solved] Error running script as string

I am working on a script that generates macroscripts on the fly to populate menus.

fnscript = "
fn DoubleTheSlashes input =
		(
			-- replaces slashes of a path with double slashes
			input = filterstring input \"\\\"
			outputstring = \"\"
			for a=1 to input.count do
			(
				append outputstring input[a]
				if a != input.count then append outputstring \"\\\\\"
			)
			outputstring
		)
print (DoubleTheSlashes \"Ich\\habe\\keinen\\bock\\mehr\")"

execute fnscript

I have a lot cases like the example above and everything works fine. However, this exact part justz doesn’t want to work. It would be great if one of you guys could give me a hint about what’s wrong here. I know that exectue is not the best way to do stuff. this section is just part of a larger script, i simplified it to make it more obvious.

EDIT:
Forget it, as so often when posting the solution comes, i was just missing the slashes:

fnscript = "
fn DoubleTheSlashes input =
		(
			-- replaces slashes of a path with double slashes
			input = filterstring input \"\\\\\"
			outputstring = \"\"
			for a=1 to input.count do
			(
				append outputstring input[a]
				if a != input.count then append outputstring \"\\\\\\\\\"
			)
			outputstring
		)
print (DoubleTheSlashes \"Ich\\habe\\keinen\\bock\\mehr\")"

execute fnscript
2 Replies
 JHN

The way I auto generate macroscripts is to generate simply macroscripts with a fileIn statement. That way I never touch or read the actual maxscript file. You’ve got to make sure the script executes when called offcourse. And for naming of a menu I add a special header to each maxscript like

-- macro name:This is my script

I read all first lines of the files and if it parses right it create a macroscript for it with the proper name.

How do you build the macroscripts exactly?

Here is the full block:

	--- change menuname macro
	optionsmacro = "
	macroscript "+OptionsMacroscriptName+"
	category:\"LK_Scripts\"
	(
		fn DoubleTheSlashes input =
		(
			-- replaces slashes of a path with double slashes
			input = filterstring input \"\\\\\"
			outputstring = \"\"
			for a=1 to input.count do
			(
				append outputstring input[a]
				if a != input.count then (append outputstring \"\\\\\\\\\")
			)
			outputstring
		)
		
		fn removeillegalchars input =
		(
			-- removes illegal characters from filenames
			input = filterString input \" -,:/\\~!@#$%^&*()+=|'?><;[]{}\"
			outputstring = input[1]
			for i = 2 to input.count do
			(
				outputstring = outputstring + \"_\" + input[i]
			)
			outputstring
		)
		
		fn generatenewrandomscriptname =
		(
			-- target folder:
			targetfolder = (getdir #userScripts)+\"\\\\startup\\\\\"
			
			-- random script name:
			newname = (\"smartmenu_\"+((random 001 999) as string)+\".ms\")
			
			-- full path to new script:
			mynewfile = DoubleTheSlashes (targetfolder+newname)
			
			mynewfile
		)

		try (destroydialog SETMenuName) catch()

		rollout SETMenuName \"Set scriptlister menu name\"
		(
			edittext NameInput \"New menu name\" width:200
			button BTN_commitmenuname \"Commit menu name\" width:200
			button BTN_changefolder \"Change menu folder\" width:200
			button BTN_resetsettings \"reset menu settings\" width:200
			button BTN_delete \"Delete this menu\" width:200
			button BTN_createnew \"create new menu\" width:200
			button BTN_rerun \"rerun script (debug)\" width:200
			
			on SETMenuName open do NameInput.text = getINISetting \""+fullpath+"\" \"Smart Menu Settings\" \"MenuName\"
			
			on BTN_commitmenuname pressed do
			(
				if NameInput.text != \"\" then
				(
					if ((menuMan.findMenu \""+MenuName+"\") != undefined) then
					(
						menuMan.unRegisterMenu (menuMan.findMenu \""+MenuName+"\")
					)
					
					mynewname = removeillegalchars NameInput.text
					setINISetting \""+fullpath+"\" \"Smart Menu Settings\" \"MenuName\" mynewname
					
					try (destroydialog SETMenuName) catch()
					
					-- restart script here
					FileIn \""+scripttorunagain as string+"\"
				)
			)

			on BTN_changefolder pressed do
			(
				fullpath = \""+fullpath+"\"
				Scriptordner = getSavePath caption:\"Select directory holding scripts\"
				if Scriptordner != undefined then
				(
					setINISetting fullpath \"Smart Menu Settings\" \"ScriptRootFolder\" Scriptordner
					try (destroydialog SETMenuName) catch()
					FileIn \""+scripttorunagain as string+"\"
				)
			)

			on BTN_resetsettings pressed do
			(
				try (destroydialog SETMenuName) catch()

				--- unregister menu
				if ((menuMan.findMenu \""+MenuName+"\") != undefined) then
				(
					menuMan.unRegisterMenu (menuMan.findMenu \""+MenuName+"\")
				)

				--- delete ini file
				deleteFile \""+fullpath+"\"

				--- restart script
				FileIn \""+scripttorunagain as string+"\"
			)

			on BTN_delete pressed do
			(
				try (destroydialog SETMenuName) catch()

				--- unregister menu
				if ((menuMan.findMenu \""+MenuName+"\") != undefined) then
				(
					menuMan.unRegisterMenu (menuMan.findMenu \""+MenuName+"\")
				)

				--- delete ini file
				deleteFile \""+fullpath+"\"

				--- delete menu script file
				deleteFile \""+scripttorunagain+"\"

				--- update menu bar
				menuMan.updateMenuBar()
			)

			on BTN_createnew pressed do
			(
				try (destroydialog SETMenuName) catch()

				mynewfile = generatenewrandomscriptname()
				
				-- CHECK IF THE FILE ALREADY EXISTS
				while (doesFileExist mynewfile) == true do mynewfile = generatenewrandomscriptname()

				-- create a copy of the script file in (getdir #userScripts-startup
				oldfile = DoubleTheSlashes (\""+scripttorunagain as string+"\")
				copyFile oldfile mynewfile
				
				-- strip scriptname from path and get ini location:
				NEWSCRIPTNAME = filenameFromPath mynewfile
				NEWSCRIPTNAME = getFilenameFile NEWSCRIPTNAME
				NewScriptIniLocation = (\""+iniLocation+"\\\\\"+NEWSCRIPTNAME+\".ini\")
				NewScriptIniLocation = DoubleTheSlashes NewScriptIniLocation
				
				-- create ini file with new menu name
				setINISetting NewScriptIniLocation \"Smart Menu Settings\" \"MenuName\" NEWSCRIPTNAME

				-- run it
				FileIn mynewfile
				menuMan.updateMenuBar()
			)

			on BTN_rerun pressed do
			(
				try (destroydialog SETMenuName) catch()
				FileIn \""+scripttorunagain as string+"\"
			)
		)
		createdialog SETMenuName style:#(#style_toolwindow,#style_sysmenu) width:220
	)"
	execute optionsmacro
  	OpenOptions = menuMan.createActionItem OptionsMacroscriptName "LK_Scripts" --create an ActionItem from the MacroScript
 	MenuButtonToAddStuffTo.addItem OpenOptions -1 --add the ActionItem to Cat1Button

Since i use variables in the macroscript that i declare before generating them, a fileIn doesn’t do. For example in Line 3 the variable OptionsMacroscriptName.

For everybody interested, here is the full script:

--clearlistener()

-- global hardcoded settings:
iniLocation = getdir #userScripts
Fallbackname = "FALLBACK"
Verbosity = 0

-- Get ini name from script name
scriptname = (getThisScriptFilename())
scriptname = filenameFromPath scriptname
scriptname = getFilenameFile scriptname
iniName = (scriptname+".ini")

fullpath = iniLocation+"\\"+iniName

Scriptordner = getINISetting fullpath "Smart Menu Settings" "ScriptRootFolder"
if Scriptordner == "" then
(
	Scriptordner = getSavePath caption:"Select directory holding scripts"
	if Scriptordner != undefined then setINISetting fullpath "Smart Menu Settings" "ScriptRootFolder" Scriptordner
	else if Verbosity >= 1 then print "No scripts folder specified"
)

MenuName = getINISetting fullpath "Smart Menu Settings" "MenuName"
if MenuName == "" then
(
	if Verbosity >= 1 then print "no menu name found, falling back to Fallbackname"
	setINISetting fullpath "Smart Menu Settings" "MenuName" Fallbackname
	MenuName = getINISetting fullpath "Smart Menu Settings" "MenuName"
)

fn DoubleTheSlashes input =
(
	-- replaces slashes of a path with double slashes
	input = filterstring input "\\"
	outputstring = ""
	for a=1 to input.count do
	(
		append outputstring input[a]
		if a != input.count then append outputstring "\\\\"
	)
	outputstring
)

fn removeillegalchars input =
(
	-- removes illegal characters from filenames
	input = filterString input " -,:/\\~!@#$%^&*()+=|'?><;[]{}\""
	outputstring = input[1]
	for i = 2 to input.count do
	(
		outputstring = outputstring + "_" + input[i]
	)
	outputstring
)

fn executemacroscriptcode Rootfolder category scriptname =
(
	scriptdisplayname = (filterstring scriptname ".")[1]
	scriptdisplayname = removeillegalchars scriptdisplayname
	
	macrostring = ""
	macrostring += "macroscript "
	macrostring += scriptdisplayname
	macrostring += "
"
	macrostring += "category:\"LK_Scripts\""
	macrostring += "
(
	FileIn \""
	
	scriptpath = (Rootfolder+"\\"+category+"\\"+scriptname)
	scriptpath = DoubleTheSlashes (scriptpath)
	
	macrostring += scriptpath
	
	macrostring += "\""
	macrostring += "
)"
	
	execute macrostring
	
	scriptdisplayname
)

fn getFilesRecursive rootfolder pattern =
(
	dir_array = GetDirectories (rootfolder+"/*")
	
	for f=1 to dir_array.count do
	(
		thescripts = (getFiles (dir_array[f] + pattern)) --- get scripts
		for a=1 to thescripts.count do
		(
			--- remove directories from scriptnames
			splittedname = filterstring thescripts[a] "\\"
			thescripts[a] = splittedname[splittedname.count]
		)
		
		dir_array[f] = #(dir_array[f]) --- convert string to array
		append dir_array[f] thescripts --- append scripts array to directory name
	)
	dir_array
)

fn addMenuContent Scriptordner MenuName =
(
	------------------ deleting previous menu
	if ((menuMan.findMenu MenuName) != undefined) then 
	(
		menuMan.unRegisterMenu (menuMan.findMenu MenuName)
		menuMan.updateMenuBar()
	)
	
	-- Adds content to the menu
	theMainMenu = menuMan.getMainMenuBar() --get the main menu bar
	MenuButton = menuMan.createMenu MenuName --create a menu called MenuName
	MenuMainContainer = menuMan.createSubMenuItem "MainContainer" MenuButton --create a SubMenuItem (= Popout bei click, CONTAINER)
	theMainMenu.addItem MenuMainContainer -1 --add the Container to MenuButton

	Scriptsarray = ((getFilesRecursive Scriptordner "*.ms*"))

	for a=1 to Scriptsarray.count do
	(
		Root = Scriptordner
		Category = filterstring Scriptsarray[a][1] "\\"
		Category = Category[Category.count]
		
		-- create a new menu
		Cat1Button = menuMan.createMenu Category
		--create a SubMenuItem (= Popout bei click, CONTAINER)
		Cat1Container = menuMan.createSubMenuItem "MainContainer" Cat1Button
		--add the Container to our Main Container
		MenuButton.addItem Cat1Container -1
		
		for b=1 to Scriptsarray[a][2].count do
		(
			Scriptname = Scriptsarray[a][2][b]
			macroscriptname = executemacroscriptcode Root Category Scriptname
			
			theAction1 = menuMan.createActionItem macroscriptname "LK_Scripts" --create an ActionItem from the MacroScript
			Cat1Button.addItem theAction1 -1 --add the ActionItem to Cat1Button
		)	
	)
	
	MenuButton
)

-- does thescriptfolder exist?
if (doesFileExist Scriptordner) and (getfileattribute Scriptordner #directory) then
(
	MenuButtonToAddStuffTo = addMenuContent Scriptordner MenuName

	-- Seperator
	theseperator1 = menuMan.createSeparatorItem()
	MenuButtonToAddStuffTo.addItem theseperator1 -1 --add the Seperator to Cat1Button

	-- Preparing for Options, etc 
	scripttorunagain = (getThisScriptFilename())
	scripttorunagain = DoubleTheSlashes scripttorunagain
	fullpath = DoubleTheSlashes fullpath
	OptionsMacroscriptName = (MenuName+"_options")

	--- change menuname macro
	optionsmacro = "
	macroscript "+OptionsMacroscriptName+"
	category:\"LK_Scripts\"
	(
		fn DoubleTheSlashes input =
		(
			-- replaces slashes of a path with double slashes
			input = filterstring input \"\\\\\"
			outputstring = \"\"
			for a=1 to input.count do
			(
				append outputstring input[a]
				if a != input.count then (append outputstring \"\\\\\\\\\")
			)
			outputstring
		)
		
		fn removeillegalchars input =
		(
			-- removes illegal characters from filenames
			input = filterString input \" -,:/\\~!@#$%^&*()+=|'?><;[]{}\"
			outputstring = input[1]
			for i = 2 to input.count do
			(
				outputstring = outputstring + \"_\" + input[i]
			)
			outputstring
		)
		
		fn generatenewrandomscriptname =
		(
			-- target folder:
			targetfolder = (getdir #userScripts)+\"\\\\startup\\\\\"
			
			-- random script name:
			newname = (\"smartmenu_\"+((random 001 999) as string)+\".ms\")
			
			-- full path to new script:
			mynewfile = DoubleTheSlashes (targetfolder+newname)
			
			mynewfile
		)

		try (destroydialog SETMenuName) catch()

		rollout SETMenuName \"Set scriptlister menu name\"
		(
			edittext NameInput \"New menu name\" width:200
			button BTN_commitmenuname \"Commit menu name\" width:200
			button BTN_changefolder \"Change menu folder\" width:200
			button BTN_resetsettings \"reset menu settings\" width:200
			button BTN_delete \"Delete this menu\" width:200
			button BTN_createnew \"create new menu\" width:200
			button BTN_rerun \"rerun script (debug)\" width:200
			
			on SETMenuName open do NameInput.text = getINISetting \""+fullpath+"\" \"Smart Menu Settings\" \"MenuName\"
			
			on BTN_commitmenuname pressed do
			(
				if NameInput.text != \"\" then
				(
					if ((menuMan.findMenu \""+MenuName+"\") != undefined) then
					(
						menuMan.unRegisterMenu (menuMan.findMenu \""+MenuName+"\")
					)
					
					mynewname = removeillegalchars NameInput.text
					setINISetting \""+fullpath+"\" \"Smart Menu Settings\" \"MenuName\" mynewname
					
					try (destroydialog SETMenuName) catch()
					
					-- restart script here
					FileIn \""+scripttorunagain as string+"\"
				)
			)

			on BTN_changefolder pressed do
			(
				fullpath = \""+fullpath+"\"
				Scriptordner = getSavePath caption:\"Select directory holding scripts\"
				if Scriptordner != undefined then
				(
					setINISetting fullpath \"Smart Menu Settings\" \"ScriptRootFolder\" Scriptordner
					try (destroydialog SETMenuName) catch()
					FileIn \""+scripttorunagain as string+"\"
				)
			)

			on BTN_resetsettings pressed do
			(
				try (destroydialog SETMenuName) catch()

				--- unregister menu
				if ((menuMan.findMenu \""+MenuName+"\") != undefined) then
				(
					menuMan.unRegisterMenu (menuMan.findMenu \""+MenuName+"\")
				)

				--- delete ini file
				deleteFile \""+fullpath+"\"

				--- restart script
				FileIn \""+scripttorunagain as string+"\"
			)

			on BTN_delete pressed do
			(
				try (destroydialog SETMenuName) catch()

				--- unregister menu
				if ((menuMan.findMenu \""+MenuName+"\") != undefined) then
				(
					menuMan.unRegisterMenu (menuMan.findMenu \""+MenuName+"\")
				)

				--- delete ini file
				deleteFile \""+fullpath+"\"

				--- delete menu script file
				deleteFile \""+scripttorunagain+"\"

				--- update menu bar
				menuMan.updateMenuBar()
			)

			on BTN_createnew pressed do
			(
				try (destroydialog SETMenuName) catch()

				mynewfile = generatenewrandomscriptname()
				
				-- CHECK IF THE FILE ALREADY EXISTS
				while (doesFileExist mynewfile) == true do mynewfile = generatenewrandomscriptname()

				-- create a copy of the script file in (getdir #userScripts-startup
				oldfile = DoubleTheSlashes (\""+scripttorunagain as string+"\")
				copyFile oldfile mynewfile
				
				-- strip scriptname from path and get ini location:
				NEWSCRIPTNAME = filenameFromPath mynewfile
				NEWSCRIPTNAME = getFilenameFile NEWSCRIPTNAME
				NewScriptIniLocation = (\""+iniLocation+"\\\\\"+NEWSCRIPTNAME+\".ini\")
				NewScriptIniLocation = DoubleTheSlashes NewScriptIniLocation
				
				-- create ini file with new menu name
				setINISetting NewScriptIniLocation \"Smart Menu Settings\" \"MenuName\" NEWSCRIPTNAME

				-- run it
				FileIn mynewfile
				menuMan.updateMenuBar()
			)

			on BTN_rerun pressed do
			(
				try (destroydialog SETMenuName) catch()
				FileIn \""+scripttorunagain as string+"\"
			)
		)
		createdialog SETMenuName style:#(#style_toolwindow,#style_sysmenu) width:220
	)"
	execute optionsmacro
  	OpenOptions = menuMan.createActionItem OptionsMacroscriptName "LK_Scripts" --create an ActionItem from the MacroScript
 	MenuButtonToAddStuffTo.addItem OpenOptions -1 --add the ActionItem to Cat1Button

	--update the menu bar
	menuMan.updateMenuBar()
)

For usage put it in (getdir #userscripts)\startup

It will ask for a folder and then create a menu in the main menubar, listing all the scripts in that folder and its subfolders. Each of the found scripts is represented by a macroscript holding a fileIn pointing to it. The specific codeblock is used for the optionsmenu, where you can create new menu entries from the old one. Have alook if you want and let me know what you think.