I’m creating a macro in Visual Studio 2008 (Visual Basic.NET) for Solid Edge V19. I have V19 SP12 installed and I’m using v2.0 of the Framework , although I was having the same problems with 3.5 and thought switching back to 2.0 might help.I’ve created many macros before (albeit not on my new super-fast Intel i7 PC) that successfully open several draft files in batch, do some processing of some kind and then save/close the files. I’ve never encountered anything like the problem I’m having now.I’m baffled by what I am experiencing with this latest project and I hope someone can help me.All my macro has to do is open several draft files in turn (FileA, FiileB, FleC, etc) , copy the contents of another draft file (FileX) sheet to a specific sheet in FileA, FileB, FileC, after deleting the existing contents of a the sheet in FileA, FileB, FileC.I’m adding each object in FileABC.Sheet.DrawingObjects to a SelectSet, (as .AddAll seems to consistently throw an error), doing a SelectSet.Delete, creating a SelectSet of everything in the sheet in FileX, a StartCommand(Copy) and then StartCommand(Paste) into a FileABC.Sheet.Firstly, can anyone suggest a smarter way to achieve the same thing?Even so, the above should work.OK...the problem.If I run my macro with just one file, it consistently works fine. If I add a couple of files, it mostly runs fine. As I add more files to process, I start to get more problems. I also get problems even if I add a loop in the macro to run the same process ten times on the same file. It will work fine for two, three, four attempts and then fail on the fifth, or sometimes the sixth attempt. Sometimes it will work OK for all ten attempts. Sometimes not. It’s totally random and I get a totally random selection of errors from SE and almost always in a different place in the code. The errors range from ‘The server threw an exception (RPC_SERVERFAULT)’, to ‘Pure Virtual Function Call’, ‘Class Not Loaded’, ‘Unspecified error (E_Fail)’...and more.I Marshal.ReleaseComObject and set to nothing every object after use. I’ve put a SolidEdgeApp.DoIdle after every line of code where I think Edge will need time to ‘catch up’ with my PC’s blazing fast request for it to do something. I’ve tried adding a ‘Press OK to continue’ MessageBox after closing each file. I’m also getting rid of the SE application after each run and recreating it for each new run (which I’ve sometimes had to do before, since moving to .NET) in order to try and improve the chances of it successfully running the batch. I’d rather not do this and preserve the life of the SE App object from form startup to close, but I’ve had reliability issues, similar to what I’m having now, when doing this in the past.If I can’t fix this issue, my guess is that I’m going to have to either create and dispense with an SE application object before each file that I process (surely not) or try and catch the error and restart SE as and when needed (after each time it inexplicably crashes), finding a way to recover where I was with the processing of the file before the crash (I hope not).Does any of this sound at all familiar to anyone else? Does anyone have any ideas at all what is going on? Like I said, although I’ve encountered some strange behaviour after shifting from VB6 to .NET over a year ago, I’ve never seen anything like this!
Posted by: Dave Rothan
Post date: 7/3/2009 9:15:52 AM
difficult to tell what's wrong.
In general, if you cannot reproduce a problem,
it's difficult/impossible to understand
whats going on and how to fix it.
1. find steps to reproduce the problem
2. if you think it is a bug, provide source code, data and steps to Siemens Support
I cannot imagine other ways to solve this kind
Posted by: Massimo Magris
Post date: 7/3/2009 11:52:54 AM
it is also important to use Single Thread Apartment (STA) when doing COM automation with .NET.
You may enforce STA by giving the attribute STAThread to your applications start object as shown below:
Public Shared Function Main(ByVal args As String()) As Integer
Posted by: Wolfgang Kunert
Post date: 7/3/2009 11:10:04 PM
Apart from the problem you're having, I would recommend you:
1. Open and close SE Application for each file to process, it's slower but safer.
2. I wouldn't do a copy-paste with StartCommand. I would use copy-paste with:
'Activate a document. This brings the doc window on top of the rest.
'Get the selectset.(AddAll should work, if not, a loop with Add will do)
'Copy the selectset. Not startcommand
'Activate the other DFT document
'Paste in the active window. Not startcommand but Window.Paste
Posted by: Julian Guillo
Post date: 7/7/2009 7:41:33 AM
Thanks for all your help guys.
In the end I did decide to create a new SE application object before processing each file. That worked OK, but it seems a shame that this was necessary to get the reliability I needed.
I will try out your suggestion Julian. That sounds like a much tidier way of doing it.
Thanks for the comments Massimo, but the post I made did state that I wasn't able to reproduce the problem consistently. This was why finding a solution to the problem was so difficult. What I was looking for were comments from others who had encountered some reliability issues before and found ways to resolve. Maybe Wolfgang was along the right lines. Is there a good reference anywhere that expands on what you suggested and gives guidance on automating single threaded COM applications with .NET?
In fact, is there a good reference for SE 'best practice' programming with .NET? Maybe even just COM programming in general? I find the lack of good .NET SE examples frustrating. Most of my skills acquired in the VB6 days were by looking at examples, either provided with SE or in the newsgroups. In particular, the ActiveX EXE examples were of huge benefit when creating apps that required come kind of interaction with SE. I don't know where to start with accomplishing the same thing in .NET.
Posted by: Dave Rothan
Post date: 7/9/2009 6:54:22 AM
One other quick thing...
I could only get SelectSet.AddAll to work when SE was visible. SE crashed (consistently) if I tried it when the app object was hidden. Of course, this restriction is well documented in sesdk.chm
Posted by: Dave Rothan
Post date: 7/9/2009 6:59:37 AM
May be related to Marshal.ReleaseComObject. THe name is totally misleading. Calling the API DOES NOT cause the .NET framework to actually release the underlying (edge) COM object. Instead (when the returned count is zero), the RCW becomes garbage collection eligible. The RCW will only release the COM object when GC runs and even then, .NET does not gurantee all objects eligible for GC will be collected.
Try this out after releasing your last RCW for the file - it seems to be the best way to try and force collection:
I believe .NET now also has a Marshal.FinalReleaseComObject. However, knowing MS, that just means you don't have to spin down the count to zero.
Make sure you have absolutely no RCW references outstanding when spinning the count down or you will get a .NET exception when you later use such an object.
This type of psuedo non-deterministic behavior of the .NET runtime (when an object eligible for GC is actually collected) is one of the reasons .NET and COM Interop are such a pain in the app.
Posted by: R.D. Holland
Post date: 8/14/2009 10:20:19 AM