can vs insert a dwg file as a vs resource?

can vs insert a dwg file as a vs resource?

swaywood
Collaborator Collaborator
3,028 Views
18 Replies
Message 1 of 19

can vs insert a dwg file as a vs resource?

swaywood
Collaborator
Collaborator

I have many dwg blocks.

in my program, I will use them, but I do not want user see the dwg blocks in the folders.

so my question is, can vs import a dwg file into the resources, just like the jpg file.

and how to use the resource dwg file in vs c# code?

 

0 Likes
Accepted solutions (1)
3,029 Views
18 Replies
Replies (18)
Message 2 of 19

Norman_Yuan
Mentor
Mentor
Accepted solution

When you embed a DWG file as resources, it usually is extracted into memory as byte array. Since AutoCAD .NET API do not have method to use byte array/memory stream directly as DWG file, you need to firstly save it to disk before using it as DWG file.

 

Here is the example code (where I embeded a block DWG file "MyBlock.dwg" as a resource item called "MyBlock"):

 

using System.IO;
using Autodesk.AutoCAD.Runtime;
using CadApp = Autodesk.AutoCAD.ApplicationServices.Application;

[assembly: CommandClass(typeof(DwgAsResources.MyCommand))]

namespace DwgAsResources
{
    public class MyCommand 
    {
        [CommandMethod("ExtractFile")]
        public static void RunDocumentCommand()
        {
            var dwg = CadApp.DocumentManager.MdiActiveDocument;
            var ed = dwg.Editor;

            try
            {
                var blkFile = ExtractFileFromResource("MyBlock");
                if (!string.IsNullOrEmpty(blkFile))
                {
                    //Use this drawing file from AutoCAD's temp file location
                    // such as insert this block file into current drawing
                    CadApp.ShowAlertDialog(
                        "Block file saved in project resources has been extracted!");

                    File.Delete(blkFile);
                }
            }
            catch (System.Exception ex)
            {
                ed.WriteMessage("\nError: {0}", ex.Message);
            }
            finally
            {
                Autodesk.AutoCAD.Internal.Utils.PostCommandPrompt();
            }
        }

        private static string ExtractFileFromResource(string resourceName)
        {
            dynamic preferences = CadApp.Preferences;
            string filePathName = 
                (string)preferences.Files.TempFilePath + "\\" + resourceName + ".dwg";

            try
            {
                var bytes = (byte[])Properties.Resources.ResourceManager.GetObject(resourceName);
                if (File.Exists(filePathName)) File.Delete(filePathName);
                using (var stream = new FileStream(filePathName, FileMode.Create, FileAccess.Write))
                {
                    stream.Write(bytes, 0, bytes.Length);
                    stream.Close();
                }

                return filePathName;
            }
            catch
            {
                return "";
            }
        }
    }
}

HTH

 

 

Norman Yuan

Drive CAD With Code

EESignature

Message 3 of 19

KinAkira
Advocate
Advocate

@Norman_Yuan wrote:

When you embed a DWG file as resources, it usually is extracted into memory as byte array. Since AutoCAD .NET API do not have method to use byte array/memory stream directly as DWG file, you need to firstly save it to disk before using it as DWG file.

 

Here is the example code (where I embeded a block DWG file "MyBlock.dwg" as a resource item called "MyBlock"):

 

        private static string ExtractFileFromResource(string resourceName)
        {
            ...
                var bytes = (byte[])
Properties.Resources.ResourceManager.GetObject(resourceName); // Error ... }

HTH

 

 


Hi @Norman_Yuan ,  I pasted your code hower It didn't work because It'd a error at above command line.

Could you please help me fix this error?

0 Likes
Message 4 of 19

Norman_Yuan
Mentor
Mentor

Well, my code did have a minor bug (but it still works with it, at least with my Acad2020/2021) here:

 

string filePathName = 
                (string)preferences.Files.TempFilePath + "\\" + resourceName + ".dwg";

should have been (i.e. extra backslash):

 

string filePathName = 
                (string)preferences.Files.TempFilePath + resourceName + ".dwg";

 Other than that, the code work OK and this line

 

var bytes = (byte[])Properties.Resources.ResourceManager.GetObject(resourceName);

works as expected, as long as the resource name is correct, again with my Acad2020/2021, and I believe also with my Acad2018 when my original reply posted. So, I am not sure what help I can offer here.

 

 

Norman Yuan

Drive CAD With Code

EESignature

Message 5 of 19

KinAkira
Advocate
Advocate

Unfortunately, It's still not working with me. I attacked my project.

 

kinakira2013_1-1621960117505.png

 

 

0 Likes
Message 6 of 19

JamesMaeding
Advisor
Advisor

I went to try this, and visual studio shows the acad references as not found.

I have 2020 installed, that is not it. The project file has like this:

<Reference Include="AcCoreMgd">
<SpecificVersion>False</SpecificVersion>

While my projects typically have

<Reference Include="accoremgd">
<HintPath>C:\Program Files\Autodesk\AutoCAD 2019\accoremgd.dll</HintPath>

which is version specific of course.

Besides editing the project file, how do I tell VS where to find the acad dll's in this case?

I've always made a different project for every version, so this sounds like something I have been missing.

thx


internal protected virtual unsafe Human() : mostlyHarmless
I'm just here for the Shelties

0 Likes
Message 7 of 19

Norman_Yuan
Mentor
Mentor

You should have indicated that the error you get is compiling error, not runtime error. Here is what I imagined what happened with your code:

1. You added a drawing into the resources;

2. You copied the code prom my post and pasted it inti class "myPlugin" and tried to build it, and got error on "Properties" are not defined/declared.

3. You add a static public member "Properties" of object type to the class "myPlugin";

4. Still the code does not compile.

 

Of course it does not compile: you defined a "Properties" member, but never instantiate it, not to mention it does not have a property "Resources" magically by itself!

 

Properties is a namespace automatically added to your project's namespace by Visual Studio when you added settings/resources to the project, i.e. [your project namespace].Properties.

 

It turns out it is a simple typo/mistake that we as programmer often overlook even stared at it straightly: your "myPlugin" class has different namespace from the namespace of the project:

 

for the project (thus the Properties):

Autocad_2020_plugin_020_Read_Data_from_Resources

for "myPlugin" class:

Autocad_2020_plugin_021_Read_Data_from_Resources

So, you need to change the "_021_" to "_020_" and remove this line(!!!):

public static object Properties { get; private set; }

 

Sometimes, a simple/stupid mistake we made may cost us hours to find it out, when working too hard.

 

Norman Yuan

Drive CAD With Code

EESignature

Message 8 of 19

JamesMaeding
Advisor
Advisor

@Norman_Yuan 

Yah, when people post their whole project without indicating where it puked during debug, its not a good sign.

Any chance you know the answer to my question on the references?

I should post that as a new topic really...


internal protected virtual unsafe Human() : mostlyHarmless
I'm just here for the Shelties

0 Likes
Message 9 of 19

Norman_Yuan
Mentor
Mentor

@JamesMaeding 

I do not recall I even needed to open project file to see the references.

 

In your case (of VS showing acad reference not found), could you just manually remove and re-add the referenced assemblies of correct version? Also make sure the .NET framework is set properly (if you somehow set the project to use very old version of .NET Frameowrk?). Of course to make sure "Copy Local" is set to false. If all these done correctly, I do not see why VS would not found Acad references... unless you made the same mistake as I pointed out in the other reply to the OP: there is typo in the namespace directive in the class file, so classes are not in the same namespace, thus do not see each other unless fully qualified class name is used.

 

Norman Yuan

Drive CAD With Code

EESignature

0 Likes
Message 10 of 19

JamesMaeding
Advisor
Advisor

@Norman_Yuan 

As far as making things work, I absolutely could just get in and assign the hint path.

I do that every time a new acad version comes out.

I'm thinking I am missing something about how VS works though.

Somewhere it has to know where to look. I got the whole solution from the OP, and was thinking it would be in the project, solution, or some config file. My VS is not finding the reference though.

I did a new post on this just now, so likely better to reply there.

 

BTW, My world continues to benefit from your past posts, especially the separate thread progress bar one.


internal protected virtual unsafe Human() : mostlyHarmless
I'm just here for the Shelties

0 Likes
Message 11 of 19

KinAkira
Advocate
Advocate

@Norman_Yuan wrote:

...

So, you need to change the "_021_" to "_020_" and remove this line(!!!):

 

 

public static object Properties { get; private set; }

 

 

 

Sometimes, a simple/stupid mistake we made may cost us hours to find it out, when working too hard.

 


Hi @Norman_Yuan , I modified my code follow your advices. But now, The error occurs at "Properties..." line; when I replace "Properties" to "Autocad_2020_plugin_020_Read_Data_from_Resources" >> This line has no error; however an error appeared at "filePathName" declared.

 

kinakira2013_0-1621989045678.png  kinakira2013_1-1621989115669.png

 

 

0 Likes
Message 12 of 19

Norman_Yuan
Mentor
Mentor

I forgot to mention one thing actually:

 

How did create your DLL project? When you start a new project in Visual Studio and choose C# as the language to use,  VS should automatically add Microsoft.CSharp in the references. But your project somehow missing this reference!

 

You need to add reference to Microsofr.CSharp to the references. Or, you may want to restart a new project, to void having to blindly fix the mess of your existing project. I have no idea how the project got messed up (missing Microsoft.CSharp reference, wrong namespace of the myPlugin class...), but that is the problem you have!

 

Norman Yuan

Drive CAD With Code

EESignature

Message 13 of 19

KinAkira
Advocate
Advocate

Great with helpfull your post, It'd work after I create a new project from "Autocad Plug-in template C#" and install the Microsoft.CSharp Nuget package 4.7.0

So many thanks with your support @Norman_Yuan . I learn a lot of thing from your posts 😊

 

kinakira2013_0-1621996069677.png

 

0 Likes
Message 14 of 19

JamesMaeding
Advisor
Advisor

@Norman_Yuan 

I think the original project posted has acad dll reference errors.

I learned that VS uses either the hint path, or build output folder, or GAC to find dlls, and none of those help here.

I would guess that the build output path used to be the acad program files folder, but got switched somehow. So I'm not losing my mind, or, what's left of it these days...

 


internal protected virtual unsafe Human() : mostlyHarmless
I'm just here for the Shelties

0 Likes
Message 15 of 19

JamesMaeding
Advisor
Advisor

@KinAkira @Norman_Yuan 

I had to do these things to get it to compile:

1) rename workspaces to match, including in project properties (I used Readdwg as the name)

2) remove the Properties property line

3) change the line with Properties to:

var bytes = (byte[])ReadDwg.Resource.ResourceManager.GetObject(resourceName);

4) add the csharp reference

5) add hint paths to acad dll references.

 

Then it compiled. Those are basics though, so @KinAkira if you can't be comfortable doing those on your own, you are in over your head. I run into this a lot, and wonder how mentorship could be done for those learning.

Forum back and forth is ok, but really someone should be working with you in real time, interactively. If I could figure out how to do that in some affordable way for others, that might be a nice career. Its not that I or others are masters (ok, get the laugh out, go ahead....), but we do know basics and where to look to solve things.

Curious if other have ideas how to provide that real time mentoring without $200 an hour consulting fee.


internal protected virtual unsafe Human() : mostlyHarmless
I'm just here for the Shelties

0 Likes
Message 16 of 19

KinAkira
Advocate
Advocate

Hi @JamesMaeding 

I'm a newbie in CAD API. I joined this forum not too long ago. So, If my question took your time, I apologize for that. I just wanted my idea to be made reality by myself, so I started with 0 and try to learn whatever I dont know.

Thank for your advices, JamesMaeding.

0 Likes
Message 17 of 19

JamesMaeding
Advisor
Advisor

@KinAkira 

Sounds goo, keep at it. You are hitting two learning curves though, the VS/C# one, and then using it with Autocad.

The better way to do your experiments is have a "starter" program that works with Autocad.  Make that starter from scratch, no wizards! If you cannot do that, you are not ready to move on.

I also have test programs for little parts of code, before adding to my big programs.

Then copy those and add little by little. You will eventually learn that part of troubleshooting C# is doing the reverse - removing bit by bit when things won't work.

The other part is setting break points and debugging, but the thing has to compile first.

Look up my posts on how to set up the "run" string for debug. If you make a script to load the dll, then add that to the run params, you can have acad start up, load the debug dll, and its all slick. No hand loading of the debug dll.

thx


internal protected virtual unsafe Human() : mostlyHarmless
I'm just here for the Shelties

Message 18 of 19

KinAkira
Advocate
Advocate

@JamesMaeding wrote:

@KinAkira 

Sounds goo, keep at it. You are hitting two learning curves though, the VS/C# one, and then using it with Autocad.

The better way to do your experiments is have a "starter" program that works with Autocad.  Make that starter from scratch, no wizards! If you cannot do that, you are not ready to move on.

I also have test programs for little parts of code, before adding to my big programs.

Then copy those and add little by little. You will eventually learn that part of troubleshooting C# is doing the reverse - removing bit by bit when things won't work.

The other part is setting break points and debugging, but the thing has to compile first.

Look up my posts on how to set up the "run" string for debug. If you make a script to load the dll, then add that to the run params, you can have acad start up, load the debug dll, and its all slick. No hand loading of the debug dll.

thx


Thank you very much, @JamesMaeding . Your post is a great advice for me. As you see, I have 20 very small example projects (Autocad_2020_plugin_020_Read_Data_from_Resources) up to now. And I'm going on. I hope I will get supports from you and other guys in the future! 😊

 

Have a nice day!

0 Likes
Message 19 of 19

swaywood
Collaborator
Collaborator
Hi,Yuan

Thank you. The code works very well.

I'm sorry I forgot to accept it.
0 Likes