[Closed] Test plugin written on C# without reloading 3d MAX
something in the back of my mind says that dll error might be something to do with admin rights
I run max with the admin rights so it is unlikely to be the issue.
__declspec(dllexport) ULONG CanAutoDefer()
{
return 1;
}
__declspec(dllexport) ULONG CanAutoDefer()
{
return 0;
}
tried bothof these CanAutoDefer
doesn’t affect the error dialog
for some reason if I run this code after the unloadPlugin
(
fn pad val w:10 pc:"_" =
(
if w > 0 then
(
if isKindOf pc string and pc != "" then -- pad with char
(
(dotNetObject "system.string" (val as string)).padRight w pc
)
else
(
(dotNetObject "system.string" (val as string)).padRight w
)
)
else
if w < 0 then ( (dotNetObject "system.string" (val as string)).padLeft -w )
else ( val as string )
)
dd = (dotNetClass "Autodesk.Max.GlobalInterface").Instance.dlldir.instance
for i=0 to dd.count-1 do
(
plug = dd.item i
format "%: %loaded:%defferable:%\n" (pad i w:-3) (pad plug.FileName w:34 pc:"_") (pad plug.IsLoaded w:8) (try (plug.IsDeferrable) catch ("[ error ]"))
)
)
it clearly shows that max don’t really delete the class when we call UnloadPlugin
306: materialid_modifier.dlm___________loaded:false___defferable:[ error ] 307: partgrav.dlm______________________loaded:false___defferable:true 308: proteus.dlm_______________________loaded:false___defferable:true
upd…
nope, class is actually deleted from OSM modifiers list
next thing to try is to substitute timestamp of new dll with the old one.
upd2
it didn’t worked out either
I rediscovered my work around for the Deferred DLL error… in the post build script I get the Modification Date and Time from the Destination file, copy the file then set the new file to the saved Modification Date and TIme from the previous file
As I mentioned it didn’t work for me, for unknown reason
I did these three steps manually, without any errors, but after step 3 max becomes unusable…
-- Step 1. reset, save timestamps and unload
dll_path = @"path-to-dlm"
file = (dotNetClass "system.io.file")
created = file.GetCreationTime dll_path
accessed = file.GetLastAccessTime dll_path
modified = file.GetLastWriteTime dll_path
unloadPlugin "materialid_modifier.dlm" -- returns true
-- Step 2.compile fresh dll in VS
-- Step 3. Update timestamps and reload dlm
file.SetCreationTime dll_path created
file.SetLastAccessTime dll_path accessed
file.SetLastWriteTime dll_path modified
LoadDllsFromDir (getdir #maxroot + "plugins\\") "materialid*.dlm" -- returns true, but DOESN'T load a thing
I had to remove my mod button from here. It was the reason why max become unusable on plugin reload
btw…
(dotNetClass “Autodesk.Max.GlobalInterface”).Instance.DllDir.instance.LoadADll “materialID_Modifier.dlm” true
still shows Deferred DLL error dialog
woohoo… it kinda works
LoadDllsFromDir is the one to blame
I have to load my plug manually through Customize > Plug-in Manager interface
Thanks, Klvnk. Without your help it wouldn’t be possible at all.
it’s always going to be a flakey process, but as it’s only for helping with dev so if it works 50% of the time it’s a win. Also try and keep your plugin out of the UI till it’s finished (specifically keep it off the command panel buttons) as it i’ll crash max for sure.
this my load plugin code btw
def_visible_primitive(loadPlugin, "loadPlugin");
Value* loadPlugin_cf(Value **arg_list, int count)
{
check_arg_count(loadPlugin, 1, count);
const TCHAR* name = arg_list[0]->to_string();
DllDir *dd = MAXScript_interface->GetDllDirectory();
TCHAR theDir[MAX_PATH];
for(int q = 0; q < dd->Count(); q++)
{
#if MAX_VERSION_MAJOR > 13
DllDesc *dsc = const_cast<DllDesc *>(&(*dd)[q]);
#else
DllDesc *dsc = &(*dd)[q];
#endif
#if MAX_VERSION_MAJOR > 13
if(_tcsicmp(dsc->GetFileName(), name)==0)
{
//_tcscpy(dsc->GetFileName(), name);
_tcscpy(theDir, dsc->GetDirectoryName());
}
#else
if(_tcsicmp(dsc->fname, name)==0)
{
//_tcscpy(dsc->fname, name);
_tcscpy(theDir, dsc->directory);
}
#endif
}
#ifdef _UNICODE
bool loaded = dd->LoadADll(wcscat(theDir,name),TRUE);
#else
bool loaded = dd->LoadADll(strcat(theDir,name),TRUE);
#endif
if(loaded)
DeepRefreshUI(MAXScript_interface);
return bool_result(loaded);
}
Yep, placing it into the ui was reckless for sure.
Thanks for the code.
upd.
I’ve added postbuild event to hardcode the filetime attributes to keep them from change
nircmd.exe setfiletime “$(TargetDir)$(TargetFileName)” “01-01-2000 00:00:00” “01-01-2000 00:00:00”
Now it takes a couple of seconds to reload a modifier! Fantastic!
upd2
And what is even greater than that is that I can recompile it while debugging in Hybrid mode and my breakpoints are still there and working. Well, at least if I don’t change much code