Thursday, January 15, 2009

Document.LoadFamilySymbol method in Revit API doesn't work for all symbols

I ran into this problem recently on an External Command I was working on. My command listed all of the available families in a directory, and allowed checkboxes to choose which one they would like to open. Further to this I listed the individual symbols from each family, so you could load just one of those instead of the whole family. My initial testing showed that this worked fine, however after getting some others to use it for a few weeks some errors cropped up on certain families. The error was that if you loaded an individual symbol, it wouldn't work, however loading the whole family did. The Revit API does not throw an exception if the loading of a family symbol was unsuccessful, so the way to check if the loading was successful is to use the 'out FamilySymbol' paramater of the LoadFamilySymbol method. Using that, and comparing working text files with not working text files showed that the ones that weren't working, had spaces after the symbol name, but before the comma, whereas the ones that were working didn't. When you use the inbuild Revit load family window, it must automatically check for this and trim all the white space, however the API call function doesn't - you must do that in your code. So when you use the LoadFamilySymbol method, make sure the string that represents your symbol has been .Trim()'ed first. Either that or make sure the person managing your families doesn't add extra spaces!

Monday, October 13, 2008

Revit 64bit & The Revit API

Revit 64bit has arrived for subscription customers, and is available from Autodesk's website. There has been some confusion around this release, as when you create a deployment of Revit off the disk, it asks if you would like to make a 64bit deployment. This is apparently a typo, and isn't really a 64bit version of Revit. So now the real deal is out, and should speed things up for Vista/XP 64bit users, especially those with 4gb of RAM. However, for API developers, it brings a couple of kinks to work around. Now the framework runs in 64bit mode, so there is the chance that some of your existing external commands will break. There are a couple of things that you can do if your external command, which was working fine in 32bit revit does not work in 64bit. Change the security permissions for Framework64 If you are receiving an error message that talks about System Security exceptions, then you should see my post on the issue of security with the 64bit .net framework. As the security settings are different in the 64bit framework, these will need to be updated as required. (Only if your application needs this, and you have access to change these settings, ie a LAN environment). Compile for Any CPU. Anthony Hauck pointed out to me that the Getting Started SDK guide has been updated to include: Compatibility of API applications with 64-bit Revit Most API applications can be built with settings that allow them to be used either with 32-bit Revit or 64-bit Revit. Use the following settings to build your project in this manner: For C# project, go to project property->Build tag, select platform target as “Any CPU”. For VB.Net project, go to project property->Compile tag, select platform as “Any CPU”. For C++/CLI project, open property page and go to Configuration properties->General->Common Language Runtime support, select /clr:safe. Note that there are some Microsoft components (such as OleDB provider for Microsoft Jet) that are not supported for 64-bit. All SDK samples are set up to work with either 32-bit or 64-bit Revit, except those samples that have dependencies to unsupported Microsoft components. For more information see this Microsoft resource: http://msdn.microsoft.com/en-us/library/ms241064(VS.80).aspx

Microsoft .Net should do all the hard work in compiling your code for 64bit compatibility (See Matt Masons post explaining why). And, as long as you don't access any 32-bit 3rd party DLL's in your application, everything should run smoothly. Compile for 64bit CPU. This should not be necessary, and is not ideal, as you cannot use it at all in a 32bit version of Revit, however it is usefull to try if only purely as a debugging tool. A problem I ran into was that one of my external commands just did not start, it did not display any error mesage, just didn't run. There was an entry in my journal file stating:
 ' 1:< DBG_INFO: Could not load file or assembly
'file:///L:\Revit\bwtools\Plotting\Plotting.dll' or one of its dependencies.
An attempt was made to load a program with an incorrect format.:
line 93 of .\Source\APIManagedExecuteCommand.cpp. 
This is the generic error for when a 32bit program is called from a 64bit environment. After some experimentation, it seems that this was caused by my application Microsofts 32bit DSOFile.dll. To get my program to start at all, I had to compile for x64, this didn't fix my problem totally (I'll discuss this below) however it allowed me to start the dll and debug to pinpoint where exactly the error was occuring. To do this in visual studio head to the properties page of your project and go to the 'build' section. Then set the platform target to 'x64'. I then specified a different output directory (as we have 64bit and 32bit users on our network) and built the project. It was then a matter of updating the target users revit.ini file to point to the 64bit build instead of the 32bit build. I did this by updating my ini edting program to detect if the operating system is vista, if so check if revit is in the program files, or program files (x86) directory and copy the text accordingly. This got my macro to start, but it then crashed when calling the DLL. This however gave me the chance to pinpoint the location of the exception. Find 64bit version of 3rd party DLL's The problem I described above, was due to me accessing a 3rd party COM DLL which is compiled for 64bit. The only way I am able to rectify this is by finding a 32bit version of the required DLL and installing it on the users machine. This will be different for each situation, but one thing to keep in mind that regsvr32.exe, the tool used to reference DLL's in the registry does not have a regsvr64.exe counterpart, contrary to common logic. Unfortunately microsoft decided to keep the name the same, but simply store it in a different directory. So C:\Windows\SysWOW64\regsvr32.exe is the 64bit dll registrar. Summary The process has been made really easy by the revit team, assuming one thing - you do not use a 3rd party 32bit dll. So for 99% of external commands, the switch is simple, and chances are you won't have to do anything! Unfortunately for the other 1% the reality of 64bit development is that you are going to run into problems with external 32bit references, and will probably be cast into DLL-hell. So test those commands! If anyone has had other issues with 64bit Revit they would like to share please comment this article or join this discussion at AUGI.

64bit System.Security.SecurityException errors

In a follow up to a previous post of mine, which talked about the intranet security levels and how to change the permissions. I have one change to make. When running your application in the 64bit framework, permissions are different, so the previously posted batch file will not do anything to solve your issues. To fix it, add '64' onto the end of the Framework part of the caspol path. for example: echo y|C:\WINDOWS\Microsoft.NET\Framework64\v2.0.50727\caspol.exe -m -ag 1.2 -url file://server/share/* FullTrust I came across this problem using the new Revit 64bit with some of my API programs that access C drive or use the network.

Friday, August 29, 2008

RIS services fails to start with Error 127: the specified procedure could not be found error

This occurs after installing Windows 2003 SP2. The reason for this is that the new Windows Deployment Services (to allow Vista images to be made) is installed, and then is put in charge of the RIS deployment, rendering the Remote Installation service obsolete. To fix this, run services.msc and make your RIS service startup type to be manual or disabled, and select Windows Deployment Services to be automatic. You can then boot into the pre execution environment as normal and your old images will be there. See HERE for more information.

Wednesday, August 20, 2008

How to get the full path of a file from a HTML File Input

This could also be modified for use in an ASP.Net FileUpload. I was making an internal intranet site where I wanted a user to choose a file, and then my ASP.Net application would use the path to generate categories etc (ie if its in the Columns folder, the file is a Column). Unfortunately ASP.Net does not allow you to retrieve the whole path (ie C:\Columns\Test.rfa) from a file upload control, it only will show you the actual file name (Test.rfa). To get around this, I made use of Javascripts OnChange event. First, on the <input type="file"> I added "onchange="CapturePath(this.value);" Then, at the top of my page I added a javascript function which does the following: function CapturePath(value) { document.getElementById("<%Response.Write(filePathHidden.UniqueID);%>").value = value; } As I was using ASP.net, I wanted to store the path for postback to the server, so I added an control, called 'filePathHidden', and then when the user changes the value of the File Input, it sends the path to this hidden. You could modify the code to use a normal HTML Hidden as well. Then, on post back, I get the value of the hidden and use it as I please.

Monday, August 18, 2008

How to detect Windows Vista in batch file or logon script

Previously, in our logon scripts, we'd used the 'ver' command to get the windows version, and selected the third word (XP or 2000 etc) but now that no longer works properly, so a better way of doing it is this:

VER | findstr /i "5.0." > nul IF %ERRORLEVEL% EQU 0 set version=2000

VER | findstr /i "5.1." > nul IF %ERRORLEVEL% EQU 0 set version=XP

VER | findstr /i "5.2." > nul IF %ERRORLEVEL% EQU 0 set version=2003

VER | findstr /i "6.0." > nul IF %ERRORLEVEL% EQU 0 set version=Vista

This searches for the build number in the ver string.

Increase vista performance

A tweak I am doing on all Vista machines in the office here, is this: Go into control panel, choose classic mode - > Performance Information and Tools -> Adjust Visual Effects -> 'Choose for Best Performance' (this turns off everything) and then in the list check: - show thumbnails instead of icons - Smooth edges of screen fonts - Use visual styles on windows and buttons (to turn these 3 back on) These 3 are personal preference, but the last one especially makes a big difference in looks when it is turned on, without this your theme stays on the 'windows classic' mode, looking like windows 98 did. So if you don't like that theme, leave that one checked. This will get rid of someof the Vista looks, though it doesn't look all that different, and will make it feel alot 'snappier', especially due to the lack of fading in and out which makes your system appear slower.