Тема: Как добавить пути для поиска файлов?

Как правильно в AutoCAD добавить пути для поиска файлов? Был такой вопрос в ветке ObjectARX, а как это можно сделать в NET?

Re: Как добавить пути для поиска файлов?

> Сергей
Точно также. Только для вызова acedGetEnv и acedSetEnv использовать P/Invoke.

Re: Как добавить пути для поиска файлов?

using System ;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using System.Text ;
using Autodesk.AutoCAD.Runtime ;
using Autodesk.AutoCAD.ApplicationServices ;
using Autodesk.AutoCAD.DatabaseServices ;
using Autodesk.AutoCAD.EditorInput ;
using Autodesk.AutoCAD.Windows ;
using AcRx = Autodesk.AutoCAD.Runtime ;
using AcEd = Autodesk.AutoCAD.EditorInput ;
using AcDb = Autodesk.AutoCAD.DatabaseServices ;
using AcAp = Autodesk.AutoCAD.ApplicationServices ;
using AcWin = Autodesk.AutoCAD.Windows ;
[assembly: CommandClass(typeof(Rivilis.SetEnv))]
namespace Rivilis
{
  public class SetEnv
  {
    [System.Security.SuppressUnmanagedCodeSecurity]
      // Для AutoCAD 2006:
    [DllImport("acad.exe", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi ,EntryPoint = "acedGetEnv")]
      // Для AutoCAD 2007 и выше:
      //    [DllImport("acad.exe", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode ,EntryPoint = "acedGetEnv")]
    extern static private Int32 acedGetEnv(string var, StringBuilder val);
    [System.Security.SuppressUnmanagedCodeSecurity]
      // Для AutoCAD 2006:
    [DllImport("acad.exe", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi ,EntryPoint = "acedSetEnv")]
      // Для AutoCAD 2007 и выше:
      //    [DllImport("acad.exe", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode ,EntryPoint = "acedSetEnv")]
    extern static private Int32 acedSetEnv(string var, string val);
    static public void AddPath(string path)
    {
      StringBuilder buf = new StringBuilder(16536);
      acedGetEnv("ACAD", buf);
      buf.Append(";"); buf.Append(path);
      acedSetEnv("ACAD",buf.ToString());
    }
    [CommandMethod("TESTENV")] // Пример использования функции SetEnv.AddPath()
    static public void test()
    {
      AcWin.OpenFileDialog dlg = new AcWin.OpenFileDialog("Выберите каталог:","","","",AcWin.OpenFileDialog.OpenFileDialogFlags.AllowFoldersOnly);
      DialogResult ds = dlg.ShowDialog();
      if (ds == DialogResult.OK)
      {
        AddPath(dlg.Filename);
      }
    }
  }
}

Re: Как добавить пути для поиска файлов?

Понятно, спасибо

Re: Как добавить пути для поиска файлов?

Александр, подскажите, пожалуйста, как сделать обратное действие - удалить эти пути? С P/Invoke я пока не сталкивался - сам не разберусь

Re: Как добавить пути для поиска файлов?

Александр Пекшев aka Modis пишет:

Александр, подскажите, пожалуйста, как сделать обратное действие - удалить эти пути? С P/Invoke я пока не сталкивался - сам не разберусь

Не ленись юзать поиск.

Re: Как добавить пути для поиска файлов?

Спасибо конечно, но варианта покороче не существует?

(изменено: Hwd, 22 сентября 2010г. 19:35:47)

Re: Как добавить пути для поиска файлов?

Александр Пекшев aka Modis пишет:

Спасибо конечно, но варианта покороче не существует?

Из вопроса следует, что указанный линк даже не читался. В коде указанной статьи имелся такой фрагмент (в конце страницы указан его источник):

[System.Security.SuppressUnmanagedCodeSecurity]
[DllImport("acad.exe", CharSet = CharSet.Auto, CallingConvention = CallingConvention.Cdecl)]
private static extern int acedSetEnv(string envName, StringBuilder NewValue);

Достаточно коротко.
Раз не утруждаешь себя чтением (хотя бы по диагонали, чтобы найти нужное) - более ссылок давать не буду.

Re: Как добавить пути для поиска файлов?

Я это читал!
Чем

[System.Security.SuppressUnmanagedCodeSecurity]
[DllImport("acad.exe", CharSet = CharSet.Auto, CallingConvention = CallingConvention.Cdecl)]
private static extern int acedSetEnv(string envName, StringBuilder NewValue); 

отличается от

[System.Security.SuppressUnmanagedCodeSecurity]
[DllImport("acad.exe", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode ,EntryPoint = "acedSetEnv")]
    extern static private Int32 acedSetEnv(string var, string val);

Я просто не очень хорошо понял как это использовать, чтобы удалить нужный мне путь?
P.S. А может сильно "торможу" к вечеру :)

Re: Как добавить пути для поиска файлов?

Александр Пекшев aka Modis пишет:

Чем

[System.Security.SuppressUnmanagedCodeSecurity]
[DllImport("acad.exe", CharSet = CharSet.Auto, CallingConvention = CallingConvention.Cdecl)]
private static extern int acedSetEnv(string envName, StringBuilder NewValue); 

отличается от

[System.Security.SuppressUnmanagedCodeSecurity]
[DllImport("acad.exe", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode ,EntryPoint = "acedSetEnv")]
    extern static private Int32 acedSetEnv(string var, string val);

Насколько я знаю - автор приведённого мною фрагмента кода всё тот же Александр Ривилис. Работу первого варианта не проверял, но уверен, что и он рабочий.

Александр Пекшев aka Modis пишет:

Я просто не очень хорошо понял как это использовать, чтобы удалить нужный мне путь?
P.S. А может сильно "торможу" к вечеру

Данный метод записывает в реестр твою версию строки, в которой перечислены каталоги, разделённые символом ";".

Т.е. ты сначала извлекаешь из реестра строку, содержащую в себе перечень каталогов поиска и выполняешь над ней Split(';'), получая массив строк. Удаляешь ненужные тебе и заново собираешь их в одну строку, разделяя каталоги символом ';'. Затем используешь ту функцию, которую тебе показали - она запишет собранную тобой строку обратно в реестр. Всё. Что в этом непонятного?
Всё это выполняется в коде, на который я тебе дал ссылку. Можно было и самому разобраться.

Re: Как добавить пути для поиска файлов?

Спасибо. Просто в Вашей ссылке Вы делали большой класс, большая часть которого мне не требуется. Из ваших 234 строк мне надо порядка 50. Признаю свою вину, что не разобрался полностью в Вашем коде => не выбрал нужные мне части. Приношу свои извинения

Re: Как добавить пути для поиска файлов?

Александр Пекшев aka Modis пишет:

Спасибо. Просто в Вашей ссылке Вы делали большой класс, большая часть которого мне не требуется. Из ваших 234 строк мне надо порядка 50. Признаю свою вину, что не разобрался полностью в Вашем коде => не выбрал нужные мне части. Приношу свои извинения

Да не извиняйся ты  :)
Просто постарайся быть повнимательней.

Re: Как добавить пути для поиска файлов?

Hwd пишет:

Насколько я знаю - автор приведённого мною фрагмента кода всё тот же Александр Ривилис.

Как ни странно, но это так. И коду уже больше трех лет.

Re: Как добавить пути для поиска файлов?

Сделал по аналогии с вышеприведенным кодом:

static public void RemoveSupportFiles()
        {
            try
            {
                string CurDir = new FileInfo(Assembly.GetExecutingAssembly().Location).DirectoryName;
                string str1 = CurDir + @"\Res";
                string str2 = CurDir + @"\Data";
                StringBuilder buf = new StringBuilder(16536);
                acedGetEnv("ACAD", buf);
                buf.Replace(str1, "");
                buf.Replace(str2, "");
                buf.Replace(";;", ";");
                acedSetEnv("ACAD", buf.ToString());
            }
            catch (Autodesk.AutoCAD.Runtime.Exception ex)
            { MessageBox.Show(ex.Message); }
        }

Протестировал несколько раз - все отлично работает

Re: Как добавить пути для поиска файлов?

Александр Пекшев aka Modis пишет:

CurDir + @"\Res"

никогда не пиши так, как ты показал.
Подобные вещи делают таким образом:

Path.Combine(CurDir, "Res");

Re: Как добавить пути для поиска файлов?

А если я использую такую вещь??:

CurDir + @"\Res\file.dwg"

(изменено: Hwd, 23 сентября 2010г. 21:19:55)

Re: Как добавить пути для поиска файлов?

Александр Пекшев aka Modis пишет:

CurDir + @"\Res\file.dwg"

Вообще грамотней использовать Path.Combine(...).
В версии .net 4.0 можно было бы написать так:

Path.Combine(CurDir, "Res", "file.dwg");

но в .Net 3.5 и ниже такой перегрузки метода нет. Приходится писать так:

Path.Combine(Path.Combine(CurDir, "Res"), "file.dwg");

ну или воспользоваться твоим вариантом, но вообще такой способ считается "некрасивым" что ли... Хотя в данной ситуации и

Path.Combine(Path.Combine(CurDir, "Res"), "file.dwg");

красотой не блещет...

(изменено: Hwd, 23 сентября 2010г. 21:54:25)

Re: Как добавить пути для поиска файлов?

но в .Net 3.5 и ниже такой перегрузки метода нет.

хотя можно самому реализовать недостающий функционал. Делается это так:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            string[] x = new string[] {"мама", "мыла", "раму", "папа", "смотрел", "телевизор" };
            Console.WriteLine(Combine('\\', x));
            Console.Read();
        }

        /// <summary>
        /// Объединить массив строк, разделив их нужным символом
        /// </summary>
        /// <param name="ch">Символ, который следует использовать в качестве разделителя</param>
        /// <param name="args">Коллекция строк, которую следует объединить в одну строку, используя 
        /// в качестве параметра разделителя первый параметр</param>
        /// <returns></returns>
        public static string Combine(char ch, string[] args)
        {
            StringBuilder sb = new StringBuilder();
            foreach (string item in args)
            {
                sb.Append(string.Format("{0}{1}", item, ch));
            }
            string result = sb.ToString().Remove(sb.ToString().Length - 1);
            return result;
        }
    }
}