eFileAccessErr, ePermanentlyErased, eInvalidInput when ResolveXrefs
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report
Hi, I’m working on a project of renaming Xref for about 1000+ drawings. Most of Xrefs is in a pattern of:
A <- B <- C
A <- D <- B <- C
My plan is:
1. Rename C first
2. Open B in side DB, repath C from old to new, save B as new name, del old B
3. Then do the same for D
4. Then do the same for A
Now the code report error messages below on some file not all, and not repeat at certain file(s).
- eFileAccessErr
- ePermanentlyErased
- eInvalidInput
At
ResolveXrefs at line 16 or 42.
I figure the reason is, after C and B be renamed, when open A or D (in side DB), it still look for old C, which already be renamed. most time AutoCAD will purge old C automatically. but it will throw error some time.
I cannot approve my theory, have anybody had the similar issue and how to handle it properly?
Or could be any other reason I did not know?
Thank a lot for your time. Any help will be appreciated.
Wes
Here is my code
using Autodesk.AutoCAD.DatabaseServices;
using System;
using System.Collections.Generic;
namespace Acad1
{
class Class2
{
public bool Repath(Database db, List<RenameXref> rxXrefs)
{
bool retSaveHost = false;
try
{
db.UsingTransaction(tr =>
{
db.ResolveXrefs(true, false);
var XrGph = db.GetHostDwgXrefGraph(true);
for (int i = 1; i < XrGph.NumNodes; ++i)
{
var XrNode = XrGph.GetXrefNode(i);
var btr = XrNode.BlockTableRecordId.GetObject<BlockTableRecord>(OpenMode.ForWrite);
string oldPathName = btr.PathName;
ObjectIdCollection oids = new ObjectIdCollection();
foreach (var rxXref in rxXrefs)
{
string newPathName = GetNewPathName(oldPathName, rxXref);
if (!string.IsNullOrEmpty(newPathName))
{
btr.PathName = newPathName;
btr.Name = rxXref.NewWithoutExt;
oids.Add(btr.ObjectId);
break;
}
}
if (oids.Count > 0)
{
db.XrefEditEnabled = true;
db.ReloadXrefs(oids);
retSaveHost = true;
}
}
});
return retSaveHost;
}
catch (Exception)
{
return false;
}
}
public static string GetNewPathName(string oldPathName, RenameXref rxXref)
{
string PathName = "";
// ... rename logic goes here
PathName = $@".\{rxXref.NewName}";
return PathName;
}
}
}
here is code of open side DB
public static Database OpenSideDB(this string dwgFileName, FileOpenMode fom = FileOpenMode.OpenForReadAndAllShare)
{
if (!File.Exists(dwgFileName))
return null;
Database db = null;
try
{
db = new Database(false, true);
db.ReadDwgFile(dwgFileName, fom, true, null);
db.CloseInput(true);
}
catch (Exception)
{
// error handler
}
return db;
}
here is related code:
using System.IO;
namespace Acad1
{
public class RenameXref
{
#region
public string Old { get; private set; }
public string OldXref { get; private set; }
public string NewXref { get; private set; }
public bool FoundOld { get; private set; }
public string Lyr { get; private set; }
public string NewName
{
get
{
return Path.GetFileName(NewXref);
}
}
public string NewWithoutExt
{
get
{
return Path.GetFileNameWithoutExtension(NewXref);
}
}
#endregion
#region ctor
private RenameXref(string myOld, string myOldXref, string myNewXref, string myLyr)
{
Old = myOld;
OldXref = myOldXref;
NewXref = myNewXref;
FoundOld = File.Exists(OldXref);
Lyr = myLyr;
}
#endregion
}
}
using Autodesk.AutoCAD.DatabaseServices;
using System;
namespace Acad1
{
public static class Class4
{
public static void UsingTransaction(this Database database, Action<Transaction> action)
{
using (Transaction tr = database.TransactionManager.StartTransaction())
{
try
{
action(tr);
tr.Commit();
}
catch (Exception)
{
tr.Abort();
throw;
}
}
}
public static T GetObject<T>(this ObjectId id,
OpenMode mode = OpenMode.ForRead,
bool openErased = false,
bool openObjectOnLockedLayer = false)
where T : DBObject
{
return (T)id.GetObject(mode, openErased, openObjectOnLockedLayer);
}
}
}