BlackBox Posted March 18, 2013 Posted March 18, 2013 My post came after your edit... I'm sorry to hear about your week. If your users are adept at loading this sort of customization, that simply emailing them the assembly is sufficient (I believe Outlook blocks .dll OOTB, so perhaps a link to copy updated assembly instead?), then cheers to you... That is sadly not an option here. Just be sure that your users know they need to close their session(s) before they can perform the update. There is no such 'NetUnload' function. Again, with 2011 (.NET 3.5) one can make a simple edit to Acad.Exe.Config as noted above, and then your Acad.lsp netload call can successfully load assemblies from a network location. You'll still need to work out the update procedure, as noted here regarding the lack of a 'NetUnload' function. The other option for you to load your assembly automatically, is to run a Registry Loader, which I also do depending on the purpose of the assembly. For example, if your assembly needs to Initialize() prior to Acad* files being loaded in the startup sequence, you'll want to load from the Registry since you're using 2011 (2012+ using Autoloader also loads one's assembly prior to Acad* files). If load sequence is not of any consequence, then I find Acad.lsp a great place to 'manage' one's deployment(s) from, including the Profile. I no longer deploy a full-blown .ARG file anymore, I simply bootstrap my deployments. Instead I manage the SFSP, for example, from Acad.lsp and any changes I need to make can be reloaded for all users mid-session. Lemon squeezy. Quote
BlackBox Posted March 18, 2013 Posted March 18, 2013 For example, using 2011 (.NET 3.5) as our enterprise standard currently, a small change to Acad.Exe.Config is required in order to enable the LoadFromRemoteSources Element (as Kean demonstrates here) which lets me netload assemblies from our network folder rather than replicating them (and keeping them up to date) on local disk. Here's a copy of my Acad.Exe.Config for Civil 3D 2011 that has been in use for 1+ year: [color="#2e8b57"]<!--<configuration> <configSections> <section name="microsoft.web.services2" type="Microsoft.Web.Services2.Configuration.WebServicesConfiguration, Microsoft.Web.Services2, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/> </configSections> <startup> --><!--We always use the latest version of the framework installed on the computer. If you are having problems then explicitly specify .NET 2.0 by uncommenting the following line. <supportedRuntime version="v2.0.50727"/> --><!-- </startup> <microsoft.web.services2> <messaging> <maxRequestLength>51200</maxRequestLength> </messaging> </microsoft.web.services2> <runtime> <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> <probing privatePath="Fdo\bin;Plugins\Workflow\Activities"/> </assemblyBinding> </runtime> </configuration>-->[/color] [color="blue"]<configuration> <startup [color="red"]useLegacyV2RuntimeActivationPolicy[/color]=[color="purple"]"true"[/color]> <supportedRuntime [color="red"]version[/color]=[color="purple"]"v4.0"[/color]/> </startup> <runtime> <loadFromRemoteSources [color="red"]enabled[/color]=[color="purple"]"true"[/color]/> </runtime> <system.diagnostics> <sources> <source [color="red"]name[/color]=[color="purple"]"System.Windows.Data"[/color] [color="red"]switchName[/color]=[color="purple"]"SourceSwitch"[/color]> <listeners> <remove [color="red"]name[/color]=[color="purple"]"Default"[/color] /> </listeners> </source> </sources> </system.diagnostics> </configuration>[/color] ** Note - Despite my simply commenting out the original contents of this file as shown above, I still manually make a copy of Acad.Exe.Config aptly named Acad.Exe.Config.void Quote
dbroada Posted March 18, 2013 Author Posted March 18, 2013 My week isn't too bad, its just Monday. Why do Mondays take up far more time than the weekend? And you have just answered something that was confusing me earlier. I had forgotten that there isn't a net unload. I was trying to reload my dll locally but was still getting the same error as I had from the network load. Obviously (now) I wasn't reloading. With only a few users it isn't too much of a problem keeping them all up to date but I would like to do it without their knowledge. I think for now I will stick with the "by hand" method. My first routine is one that still works very well from VBA so there is no obvious advantage but when I add a few more useful routines I may investigate automatic loading further. Quote
BlackBox Posted March 18, 2013 Posted March 18, 2013 My week isn't too bad, its just Monday. Why do Mondays take up far more time than the weekend? ... Not enough 'flare' does it everytime And you have just answered something that was confusing me earlier. I had forgotten that there isn't a net unload. I was trying to reload my dll locally but was still getting the same error as I had from the network load. Obviously (now) I wasn't reloading. With only a few users it isn't too much of a problem keeping them all up to date but I would like to do it without their knowledge. I think for now I will stick with the "by hand" method. My first routine is one that still works very well from VBA so there is no obvious advantage but when I add a few more useful routines I may investigate automatic loading further. Do whatever works best for you. To notify users of an update, I built an 'update' loader into my AcadDoc.lsp that runs the notify code (when necessary, such as .NET code, otherwise done programmatically) that gives the user the option of updating now, or on their next application start (in case they're in the middle of preparing a submittal, etc.). On occasion, if I need to query some information from the user's end (without interrupting them) in order to prepare an update, I'll simply have their Outlook email me on their behalf (programmatically). Quote
dbroada Posted March 18, 2013 Author Posted March 18, 2013 the last time I tried to get outlook to email me something I erased a complete user group on the server. We now have the "luxury" of using Lotus Notes which we can't even get to email within the office "today". emails can take up to 8 hours to reach their intended and many just never arrive. Its nice to work for a big corporation that knows what is best for us. You have given me food for thought. At least I know where to look when the installation next gets near the surface. Quote
dbroada Posted March 19, 2013 Author Posted March 19, 2013 I've decided on the simple approach. The acaddoc.lsp checks if a local version exists and if not copies it from a central location. I can comment out the check line whenever I update the dll so that it gets copied locally. I have a "spy" function to check who has logged on which I can annotate when I do these updates. There is one thing I forgot though. If I have acaddoc netloading my dll, I can't debug! Took me quite a while to find that last night after the boss made some suggestions. (setq myName (getvar "loginname")) ;check who has logged on (SETQ A (OPEN "P:\\Design_Office\\SupportFiles\\Dave.spy" "A")) (WRITE-LINE myName A) (CLOSE A) ;test with me only (if (= myName "dbroad") (PROGN (PRINC MYNAME) (if (not (findfile "D:\\RA_DesignOffice.dll" )) (vl-file-copy "P:\\Design_Office\\SupportFiles\\RA_DesignOffice.dll" "D:\\RA_DesignOffice.dll" ) ( )) ;comment out next line when debugging ;(COMMAND "NETLOAD" "D:\\RA_DesignOffice.dll")) ) ;other people follow ;(if (= (getvar "loginname") "JByatt") (alert "Thank You")) (PRINC) Quote
BlackBox Posted March 19, 2013 Posted March 19, 2013 I've decided on the simple approach. The acaddoc.lsp checks if a local version exists and if not copies it from a central location. I can comment out the check line whenever I update the dll so that it gets copied locally. I have a "spy" function to check who has logged on which I can annotate when I do these updates. There is one thing I forgot though. If I have acaddoc netloading my dll, I can't debug! Took me quite a while to find that last night after the boss made some suggestions. .NET assemblies can only be loaded once per session, so having them repeatedly netload from AcadDoc.lsp is not necessary, and has no effect after the first netload... For this task, I'd stick with Acad.lsp instead. Also, when checking for your local assembly, you might consider dually checking the System Time, to see if it (the assembly) needs to be overwritten (updated) prior to being netloaded. You can debug from Visual Studio, just use a /p "Debug" Profile call (where your Acad.lsp doesn't load) in your Project Properties, Debug tab, Command Line Arguments. Quote
dbroada Posted March 19, 2013 Author Posted March 19, 2013 I really should read replies more carefully. I guess this was covered earlier on in this thread. I am happy to use acad.lsp but I expected that to already exist in each of the machines. I can now see that nobody has one so I will use that. I will look in to the command line arguments next. Quote
dbroada Posted March 19, 2013 Author Posted March 19, 2013 BB, have I done this right? I have added the /p but my acad.lsp still gets called. I am using VS2008 express with ACADE 2011. Quote
BlackBox Posted March 19, 2013 Posted March 19, 2013 I really should read replies more carefully. I guess this was covered earlier on in this thread. I am happy to use acad.lsp but I expected that to already exist in each of the machines. I can now see that nobody has one so I will use that. I will look in to the command line arguments next. As I'm sure you already know, Acad.lsp, and AcadDoc.lsp are user-defined files that do not ship with the product OOTB. If your users do wish to load their own code files, and or project code, my earlier post may be of use to you. BB, have I done this right? I have added the /p but my acad.lsp still gets called. I am using VS2008 express with ACADE 2011. Well, let's back up for a moment.... The intent here is to effectively debug your assembly's code in session, using your production environment (or a copy of), which can be done a few different ways. One common way, so as to not affect one's actual production environment accidentally, is to make a copy of your normal working Profile (for this example, we'll call it "Debug"), where your Visual Studio Project's Properties, Debug tab, Command Line Arguments target this Profile, like so using the /p Startup Switch (see image below, VS 2010 Express C# shown). ** Edit - If you include the Command Line Arguments in a debug session from Visual Studio and have not yet manually created a copy of your working Profile of the same name being targeted, the default Profile settings will be used to create a new Profile named "Debug" just as it would were you to use this Startup Switch from a separate application icon. Also worthy of note, is that I leave my working folder blank, which effectively loads Drawing1.dwg as my ..\Debug\ folder, which can be useful as discussed below. Now, this is a copy of your working Profile, so it too will point to your Acad.lsp file to netload your Release assembly (or a copy of that you've placed on the network). One option here now, use the LOGINNAME System Variable to qualify yourself for this option, then use the vl-File-Systime function to load the newer of the two assemblies found in ..\Release\, or ..\Debug\. This will work, but you still need to write the code for this, and we're still trying to Debug your .NET code. Another way to go about this, is to place a 'bootstrap' Acad.lsp file in your Debug folder, which will netload that assembly (found in ..\Debug\), as for years AutoCAD has (to my mind) improperly loaded from the Working Folder prior to the SFSP. Does that make (more?) sense to you now? Quote
dbroada Posted March 19, 2013 Author Posted March 19, 2013 OK, I think I see. I'll be back (I'm sure) when I get a few more minutes to do this. why must we book anything like this to a project - it helps everyone but no, nobody wants to pay so it never gets progressed Quote
dbroada Posted March 21, 2013 Author Posted March 21, 2013 I thought I had this covered. I have an acad.lsp that get actioned when AutoCAD starts. A slightly reduced version here. (setq myName (getvar "loginname")) ;check who has logged on (SETQ A (OPEN "P:\\Design_Office\\SupportFiles\\Dave.spy" "A")) (WRITE-LINE myName A) (CLOSE A) (princ "\n") (PRINC MYNAME) (princ "\n") (vl-file-copy "P:\\Design_Office\\SupportFiles\\RA_DesignOffice.dll" "C:\\RA_DesignOffice.dll" ) (COMMAND "NETLOAD" "C:\\RA_DesignOffice.dll") (PRINC) why doesn't this copy the latest dll from P:\ to C:\? The P:\ drive one gets copied if the C:\ one doesn't exist but it doesn't overwrite. Quote
BlackBox Posted March 21, 2013 Posted March 21, 2013 vl-File-Copy does not overwrite, only appends to an existing file (if the append parameter is specified). Instead, perhaps something like this: ((lambda (user / supportFolder dll f dllLocal) ;; set repeated variables (setq supportFolder "P:\\Design_Office\\SupportFiles\\") (setq dll "RA_DesignOffice.dll") ;; spy (if (setq f (open (strcat supportFolder "dave.spy") "a")) (progn (write-line (strcat (menucmd "M=$(edtime,$(getvar,date),YYYY-MO-DD hh:mm:ss)") ", " user ) f ) (setq f (close f)) (prompt (strcat "\nWelcome, " user "\n")) ) ) ;; update (if (findfile (setq dllLocal "C:\\RA_DesignOffice.dll")) (if (vl-file-delete dllLocal) (vl-file-copy (strcat supportFolder dll) dllLocal) (prompt "\n** Update failed, contact Dave ** ") ) (vl-file-copy (strcat supportFolder dll) dllLocal) ) ;; update (command "._netload" dllLocal) (princ) ) (getvar 'loginname) ) ** Error handling not included Quote
dbroada Posted March 21, 2013 Author Posted March 21, 2013 excellent! I knew if I did nothing somebody would help me out. Now to look through it to see what I understand..... Quote
BlackBox Posted March 21, 2013 Posted March 21, 2013 I knew if I did nothing somebody would help me out. ... Always happy to not help. Quote
dbroada Posted March 21, 2013 Author Posted March 21, 2013 yet anotehr question.... This will copy from the master on to the local drive, presumably every time AutoCAD is loaded. One thing my spy has confirmed is that one person is starting AutoCAD every few minutes. He appears oblivious (despite constant telling) of the OPEN command and closes AutoCAD followed by double clicking in explorer, which then updates his local dll. Is there a way to modify the code to only update when the master is newer than the local? Quote
BlackBox Posted March 21, 2013 Posted March 21, 2013 In reverse order.... yet anotehr question.... ... Is there a way to modify the code to only update when the master is newer than the local? Yes, just a bit more code: (vl-load-com) ((lambda (user / supportFolder dll f dllLocal dllNetwork) ;; set repeated variables (setq supportFolder "P:\\Design_Office\\SupportFiles\\") (setq dll "RA_DesignOffice.dll") ;; spy (if (setq f (open (strcat supportFolder "dave.spy") "a")) (progn (write-line (strcat (menucmd "M=$(edtime,$(getvar,date),YYYY-MO-DD hh:mm:ss)") ", " user ) f ) (setq f (close f)) (prompt (strcat "\nWelcome, " user "\n")) ) ) ;; load (if (findfile (setq dllLocal "C:\\RA_DesignOffice.dll")) (if (not (equal (vl-file-systime dllLocal) (vl-file-systime (setq dllNetwork (strcat supportFolder dll)) ) ) ) (if (vl-file-delete dllLocal) (vl-file-copy dllNetwork dllLocal) (prompt "\n** Update failed, contact Dave ** ") ) ) (vl-file-copy (strcat supportFolder dll) dllLocal) ) (command "._netload" dllLocal) (princ) ) (getvar 'loginname) ) One thing my spy has confirmed is that one person is starting AutoCAD every few minutes. He appears oblivious (despite constant telling) of the OPEN command and closes AutoCAD followed by double clicking in explorer, which then updates his local dll. If you'd like I can provide you an assembly that will 'veto' the QUIT Command, and perform another action instead? For example, say one didn't like that when in Block Editor, selecting the "X" in the upper right invoked the QUIT Command. Instead they wanted it (selecting the "X" while in the Block Editor) to CLOSE the Block Editor... I recently slapped together a quick .NET plug-in that did just that for someone (in a place that I am not allowed to discuss until March 26th). To the point, if there's a custom ALERT you'd like for this, or a small list of users to receive... Or if you'd instead like for the "X" selection to CLOSE the active Document instead of the application (only allowing QUIT when no Titled Document is open)... It's possible. Obviously, I am not one who likes the idea of a CAD-Micro-Manager, but when used thoughtfully, and responsibly, these sorts of capabilities can add significant value to one's work. Quote
dbroada Posted March 21, 2013 Author Posted March 21, 2013 the code didn't crash my machine so a to you. I'll update the dll tomorrow to jsut see what happens. Thanks for the offer of the micro manager but I will tell the DO manager what I have found. Thanks again, I'm off home for the day so bye for now. Quote
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.