<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>topic Re: Make XRef path relative in .NET Forum</title>
    <link>https://forums.autodesk.com/t5/net-forum/make-xref-path-relative/m-p/12163295#M7794</link>
    <description>&lt;BLOCKQUOTE&gt;&lt;HR /&gt;&lt;a href="https://forums.autodesk.com/t5/user/viewprofilepage/user-id/2976437"&gt;@WPerciful&lt;/a&gt;&amp;nbsp;wrote:&lt;BR /&gt;
&lt;P&gt;Still working on figuring out what you shared.&amp;nbsp; Haven't gotten anywhere with it as yet.&amp;nbsp; Can you add some comments to your code?&lt;/P&gt;
&lt;HR /&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;Here's a cleaned up version. This one acts on the current document.&lt;/P&gt;
&lt;LI-CODE lang="general"&gt;public static void MakeXrefPathsRelative()
{
	var doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
	var db = doc.Db;

	var thisDwgPath = db.OriginalFileName;

	using (DocumentLock docLock = doc.LockDocument())
	{
		using (Transaction tr = db.TransactionManager.StartTransaction())
		{
			BlockTable bt = tr.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable;

			// iterate all bt objects
			foreach (ObjectId btrId in bt)
			{
				BlockTableRecord btr = tr.GetObject(btrId, OpenMode.ForRead) as BlockTableRecord;

				// check if object is xref
				if (btr.IsFromExternalReference)
				{
					// open for write
					btr.UpgradeOpen();

					// orig path
					String oldXrefPath = btr.PathName;
					
					// make new relative path
					Uri path1 = new Uri(thisDwgPath);
					Uri path2 = new Uri(oldXrefPath);
					Uri diff = path1.MakeRelativeUri(path2);
					string relPath = diff.OriginalString;
					string newXrefPath = relPath.Replace(@"%20", " ");

					// assign new path
					btr.PathName = newXrefPath;
					Debug.AppendLine("Old Path : {oldXrefPath} New Path : {newXrefPath}");
				}
			}

			tr.Commit();
		}// end transaction
	}// end docLock
}
&lt;/LI-CODE&gt;</description>
    <pubDate>Thu, 10 Aug 2023 20:33:47 GMT</pubDate>
    <dc:creator>jabowabo</dc:creator>
    <dc:date>2023-08-10T20:33:47Z</dc:date>
    <item>
      <title>Make XRef path relative</title>
      <link>https://forums.autodesk.com/t5/net-forum/make-xref-path-relative/m-p/12159838#M7787</link>
      <description>&lt;P&gt;I can't seem to figure out how to make the xref file path relative.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;LI-CODE lang="general"&gt;    Public Sub ProjectCloseOut(Directory_DrawingName As String, ByVal FileType As String)
        Dim ed As Editor = Application.DocumentManager.MdiActiveDocument.Editor
        Dim db As Database = New Database(False, True)
        Dim XrGraph As XrefGraph = db.GetHostDwgXrefGraph(False)
        XrGraph = db.GetHostDwgXrefGraph(True)
        Dim root As GraphNode = XrGraph.RootNode
        Dim r As New List(Of String)
        Using db
            Try 'FileOpenMode.OpenForReadAndAllShare
                db.ReadDwgFile(Directory_DrawingName, FileOpenMode.OpenForReadAndAllShare, False, Nothing)
            Catch __unusedException1__ As System.Exception
                ed.WriteMessage(vbLf &amp;amp; "Unable To read drawing file.")
            End Try
            Using tran = db.TransactionManager.StartTransaction
                For o As Integer = 0 To root.NumOut - 1
                    Dim child As XrefGraphNode = TryCast(root.Out(o), XrefGraphNode)
                    Select Case child.XrefStatus
                        Case XrefStatus.Resolved
                            '   Make all of the xrefs relitive paths
                            Dim XrefFullFileName = child.Database.Filename
                            Dim XrefFilePath = IO.Path.GetDirectoryName(AecFullFileName)
                            Dim XrefFileName = IO.Path.GetFileNameWithoutExtension(AecFullFileName)
                            dtProjectCloseOutFiles.Rows.Add(XrefFullFileName, XrefFilePath, XrefFileName, FileType)
                        Case XrefStatus.FileNotFound Or XrefStatus.Unloaded Or XrefStatus.Unreferenced
                            '   xrefs for all model files in 3D Model folder and detach them
                            Dim XrefFullFileName = child.Database.Filename
                            Dim XrefFilePath = IO.Path.GetDirectoryName(AecFullFileName)
                            Dim XrefFileName = IO.Path.GetFileNameWithoutExtension(AecFullFileName)
                            Dim acXrefId As ObjectId = db.AttachXref(XrefFullFileName, XrefFileName)
                            db.DetachXref(acXrefId)
                    End Select
                Next
            End Using
        End Using
    End Sub&lt;/LI-CODE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Same code in C#&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;LI-CODE lang="general"&gt;public void ProjectCloseOut(string Directory_DrawingName, string FileType)
{
    Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
    Database db = new Database(false, true);
    XrefGraph XrGraph = db.GetHostDwgXrefGraph(false);
    XrGraph = db.GetHostDwgXrefGraph(true);
    GraphNode root = XrGraph.RootNode;
    List&amp;lt;string&amp;gt; r = new List&amp;lt;string&amp;gt;();
    using (db)
    {
        try // FileOpenMode.OpenForReadAndAllShare
        {
            db.ReadDwgFile(Directory_DrawingName, FileOpenMode.OpenForReadAndAllShare, false, null/* TODO Change to default(_) if this is not a reference type */);
        }
        catch (Exception __unusedException1__)
        {
            ed.WriteMessage(Constants.vbLf + "Unable To read drawing file.");
        }
        using (var tran = db.TransactionManager.StartTransaction)
        {
            for (int o = 0; o &amp;lt;= root.NumOut - 1; o++)
            {
                XrefGraphNode child = root.Out(o) as XrefGraphNode;
                switch (child.XrefStatus)
                {
                    case object _ when XrefStatus.Resolved:
                        {
                            // Make all of the xrefs relitive paths
                            var XrefFullFileName = child.Database.Filename;
                            var XrefFilePath = System.IO.Path.GetDirectoryName(AecFullFileName);
                            var XrefFileName = System.IO.Path.GetFileNameWithoutExtension(AecFullFileName);
                            dtProjectCloseOutFiles.Rows.Add(XrefFullFileName, XrefFilePath, XrefFileName, FileType);
                            break;
                        }

                    case object _ when XrefStatus.FileNotFound | XrefStatus.Unloaded | XrefStatus.Unreferenced:
                        {
                            // xrefs for all model files in 3D Model folder and detach them
                            var XrefFullFileName = child.Database.Filename;
                            var XrefFilePath = System.IO.Path.GetDirectoryName(AecFullFileName);
                            var XrefFileName = System.IO.Path.GetFileNameWithoutExtension(AecFullFileName);
                            ObjectId acXrefId = db.AttachXref(XrefFullFileName, XrefFileName);
                            db.DetachXref(acXrefId);
                            break;
                        }
                }
            }
        }
    }
}&lt;/LI-CODE&gt;</description>
      <pubDate>Wed, 09 Aug 2023 17:56:24 GMT</pubDate>
      <guid>https://forums.autodesk.com/t5/net-forum/make-xref-path-relative/m-p/12159838#M7787</guid>
      <dc:creator>WPerciful</dc:creator>
      <dc:date>2023-08-09T17:56:24Z</dc:date>
    </item>
    <item>
      <title>Re: Make XRef path relative</title>
      <link>https://forums.autodesk.com/t5/net-forum/make-xref-path-relative/m-p/12160564#M7788</link>
      <description>&lt;P&gt;You can remove the paths using the Xref Manager that ships with AutoCAD. Just load the dwgs to be changed and change the path to ".\"&lt;/P&gt;</description>
      <pubDate>Wed, 09 Aug 2023 18:42:06 GMT</pubDate>
      <guid>https://forums.autodesk.com/t5/net-forum/make-xref-path-relative/m-p/12160564#M7788</guid>
      <dc:creator>Ed__Jobe</dc:creator>
      <dc:date>2023-08-09T18:42:06Z</dc:date>
    </item>
    <item>
      <title>Re: Make XRef path relative</title>
      <link>https://forums.autodesk.com/t5/net-forum/make-xref-path-relative/m-p/12160586#M7789</link>
      <description>&lt;P&gt;I've got over 1,000 files at a time that I need to perform this on.&amp;nbsp; Which is why I'm attempting to automate the task.&lt;/P&gt;</description>
      <pubDate>Wed, 09 Aug 2023 18:48:16 GMT</pubDate>
      <guid>https://forums.autodesk.com/t5/net-forum/make-xref-path-relative/m-p/12160586#M7789</guid>
      <dc:creator>WPerciful</dc:creator>
      <dc:date>2023-08-09T18:48:16Z</dc:date>
    </item>
    <item>
      <title>Re: Make XRef path relative</title>
      <link>https://forums.autodesk.com/t5/net-forum/make-xref-path-relative/m-p/12160723#M7790</link>
      <description>&lt;P&gt;I think&amp;nbsp;&lt;a href="https://forums.autodesk.com/t5/user/viewprofilepage/user-id/14801"&gt;@Ed__Jobe&lt;/a&gt;&amp;nbsp;is referring to AdRefMan.exe which will batch rename xrefs:&lt;/P&gt;
&lt;P&gt;C:\Program Files\Autodesk\AutoCAD &amp;lt;version&amp;gt;\AdRefMan.exe&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;If you still want to code it, this may help. There's some custom method calls but should be easy to figure out.&lt;/P&gt;
&lt;LI-CODE lang="general"&gt;public static void MakeXrefPathsRelative()
{
	ObjectIdCollection objIdColl = new ObjectIdCollection();

	string nl = Environment.NewLine;

	// set flags for openFileDialog and select dwgs
	string defaultFolder = @"S:\Drafting";
	OfdFlags ofdFlags = OfdFlags.DefaultIsFolder | OfdFlags.AllowMultiple;
	List&amp;lt;string&amp;gt; dwgFilePaths = FileTools.GetDwgFileNames(defaultFolder, ofdFlags);
	if (dwgFilePaths == null || dwgFilePaths.Count == 0)
		return;

	foreach (string dwgFilePath in dwgFilePaths)
	{
		// save old database
		Database prevDb = HostApplicationServices.WorkingDatabase;

		using (Database dwgDb = new Database(false, true))
		{
			dwgDb.ReadDwgFile(dwgFilePath, FileShare.Read, true, "");
			dwgDb.CloseInput(true);

			// set the dwg as active
			HostApplicationServices.WorkingDatabase = dwgDb;

			using (Transaction tr = dwgDb.TransactionManager.StartTransaction())
			{
				BlockTable bt = tr.GetObject(dwgDb.BlockTableId, OpenMode.ForRead) as BlockTable;
				foreach (ObjectId btrId in bt)
				{
					BlockTableRecord btr = tr.GetObject(btrId, OpenMode.ForRead) as BlockTableRecord;
					if (btr.IsFromExternalReference)
					{
						btr.UpgradeOpen();
						String oldXrefPath = btr.PathName;

						Uri path1 = new Uri(dwgFilePath);
						Uri path2 = new Uri(oldXrefPath);
						Uri diff = path1.MakeRelativeUri(path2);
						string relPath = diff.OriginalString;
						string newXrefPath = relPath.Replace(@"%20", " ");
						btr.PathName = newXrefPath;
						objIdColl.Add(btrId);
						Debug.AppendLine("Old Path : {oldXrefPath} New Path : {newXrefPath}");
					}
				}

				tr.Commit();
			}// end transaction

			// reset to prev db it back ASAP
			HostApplicationServices.WorkingDatabase = prevDb;
			dwgDb.SaveAs(dwgFilePath, dwgDb.GetThisDwgVersion());
		}// end using dwgDb
	}// end foreach sourceFile

	if (Debug.Enabled)
		Debug.Dump("ModifyXrefPathLogFile", false, true);
}&lt;/LI-CODE&gt;</description>
      <pubDate>Wed, 09 Aug 2023 19:57:36 GMT</pubDate>
      <guid>https://forums.autodesk.com/t5/net-forum/make-xref-path-relative/m-p/12160723#M7790</guid>
      <dc:creator>jabowabo</dc:creator>
      <dc:date>2023-08-09T19:57:36Z</dc:date>
    </item>
    <item>
      <title>Re: Make XRef path relative</title>
      <link>https://forums.autodesk.com/t5/net-forum/make-xref-path-relative/m-p/12160733#M7791</link>
      <description>&lt;BLOCKQUOTE&gt;&lt;HR /&gt;&lt;a href="https://forums.autodesk.com/t5/user/viewprofilepage/user-id/1636004"&gt;@jabowabo&lt;/a&gt;&amp;nbsp;wrote:&lt;BR /&gt;
&lt;P&gt;I think&amp;nbsp;&lt;a href="https://forums.autodesk.com/t5/user/viewprofilepage/user-id/14801"&gt;@Ed__Jobe&lt;/a&gt;&amp;nbsp;is referring to AdRefMan.exe which will batch rename xrefs:&lt;/P&gt;
&lt;P&gt;C:\Program Files\Autodesk\AutoCAD &amp;lt;version&amp;gt;\AdRefMan.exe&lt;/P&gt;
&lt;HR /&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;&lt;a href="https://forums.autodesk.com/t5/user/viewprofilepage/user-id/2976437"&gt;@WPerciful&lt;/a&gt;&amp;nbsp;Yes, you can access it from the Start Menu. I've loaded hundreds of files at a time. It's very capable of doing it in batch mode. Do Ctrl+A to select all the files and you're good to go. Even if you bread up the 1000 into a few groups of 200-300, it'll&amp;nbsp; be quicker than writing your own app. You could have been done by now. &lt;span class="lia-unicode-emoji" title=":slightly_smiling_face:"&gt;🙂&lt;/span&gt;&lt;/P&gt;</description>
      <pubDate>Wed, 09 Aug 2023 20:05:20 GMT</pubDate>
      <guid>https://forums.autodesk.com/t5/net-forum/make-xref-path-relative/m-p/12160733#M7791</guid>
      <dc:creator>Ed__Jobe</dc:creator>
      <dc:date>2023-08-09T20:05:20Z</dc:date>
    </item>
    <item>
      <title>Re: Make XRef path relative</title>
      <link>https://forums.autodesk.com/t5/net-forum/make-xref-path-relative/m-p/12160856#M7792</link>
      <description>&lt;P&gt;&lt;a href="https://forums.autodesk.com/t5/user/viewprofilepage/user-id/1636004"&gt;@jabowabo&lt;/a&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;nice solution.&lt;/P&gt;&lt;P&gt;//-----------------&lt;/P&gt;&lt;P&gt;.NET core 2.0&amp;nbsp; onwards has a&amp;nbsp;&lt;EM&gt;&lt;FONT size="4"&gt;Path.GetRelativePath(String, String) Method&lt;/FONT&gt;&lt;/EM&gt;&lt;/P&gt;&lt;P&gt;&lt;FONT size="4"&gt;&lt;A href="https://learn.microsoft.com/en-us/dotnet/api/system.io.path.getrelativepath?view=netcore-2.0" target="_blank" rel="noopener"&gt;https://learn.microsoft.com/en-us/dotnet/api/system.io.path.getrelativepath?view=netcore-2.0&lt;/A&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;P&gt;&lt;FONT size="4"&gt;. . but oficially we can't use that yet.&lt;/FONT&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;FONT size="4"&gt;Regards,&lt;/FONT&gt;&lt;/P&gt;</description>
      <pubDate>Wed, 09 Aug 2023 21:17:31 GMT</pubDate>
      <guid>https://forums.autodesk.com/t5/net-forum/make-xref-path-relative/m-p/12160856#M7792</guid>
      <dc:creator>kerry_w_brown</dc:creator>
      <dc:date>2023-08-09T21:17:31Z</dc:date>
    </item>
    <item>
      <title>Re: Make XRef path relative</title>
      <link>https://forums.autodesk.com/t5/net-forum/make-xref-path-relative/m-p/12163070#M7793</link>
      <description>&lt;P&gt;Still working on figuring out what you shared.&amp;nbsp; Haven't gotten anywhere with it as yet.&amp;nbsp; Can you add some comments to your code?&lt;/P&gt;</description>
      <pubDate>Thu, 10 Aug 2023 18:36:44 GMT</pubDate>
      <guid>https://forums.autodesk.com/t5/net-forum/make-xref-path-relative/m-p/12163070#M7793</guid>
      <dc:creator>WPerciful</dc:creator>
      <dc:date>2023-08-10T18:36:44Z</dc:date>
    </item>
    <item>
      <title>Re: Make XRef path relative</title>
      <link>https://forums.autodesk.com/t5/net-forum/make-xref-path-relative/m-p/12163295#M7794</link>
      <description>&lt;BLOCKQUOTE&gt;&lt;HR /&gt;&lt;a href="https://forums.autodesk.com/t5/user/viewprofilepage/user-id/2976437"&gt;@WPerciful&lt;/a&gt;&amp;nbsp;wrote:&lt;BR /&gt;
&lt;P&gt;Still working on figuring out what you shared.&amp;nbsp; Haven't gotten anywhere with it as yet.&amp;nbsp; Can you add some comments to your code?&lt;/P&gt;
&lt;HR /&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;Here's a cleaned up version. This one acts on the current document.&lt;/P&gt;
&lt;LI-CODE lang="general"&gt;public static void MakeXrefPathsRelative()
{
	var doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
	var db = doc.Db;

	var thisDwgPath = db.OriginalFileName;

	using (DocumentLock docLock = doc.LockDocument())
	{
		using (Transaction tr = db.TransactionManager.StartTransaction())
		{
			BlockTable bt = tr.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable;

			// iterate all bt objects
			foreach (ObjectId btrId in bt)
			{
				BlockTableRecord btr = tr.GetObject(btrId, OpenMode.ForRead) as BlockTableRecord;

				// check if object is xref
				if (btr.IsFromExternalReference)
				{
					// open for write
					btr.UpgradeOpen();

					// orig path
					String oldXrefPath = btr.PathName;
					
					// make new relative path
					Uri path1 = new Uri(thisDwgPath);
					Uri path2 = new Uri(oldXrefPath);
					Uri diff = path1.MakeRelativeUri(path2);
					string relPath = diff.OriginalString;
					string newXrefPath = relPath.Replace(@"%20", " ");

					// assign new path
					btr.PathName = newXrefPath;
					Debug.AppendLine("Old Path : {oldXrefPath} New Path : {newXrefPath}");
				}
			}

			tr.Commit();
		}// end transaction
	}// end docLock
}
&lt;/LI-CODE&gt;</description>
      <pubDate>Thu, 10 Aug 2023 20:33:47 GMT</pubDate>
      <guid>https://forums.autodesk.com/t5/net-forum/make-xref-path-relative/m-p/12163295#M7794</guid>
      <dc:creator>jabowabo</dc:creator>
      <dc:date>2023-08-10T20:33:47Z</dc:date>
    </item>
  </channel>
</rss>

