AXForum  
Вернуться   AXForum > Microsoft Dynamics AX > DAX: Программирование
All
Забыли пароль?
Зарегистрироваться Правила Справка Пользователи Сообщения за день Поиск

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 28.12.2012, 14:36   #1  
Kainix is offline
Kainix
Участник
 
47 / 96 (4) ++++
Регистрация: 22.11.2007
Какие файлы открыты по сети
Всем привет.

Проблема следующего характера, при открытии прикрепленного файла через акс одновременно 2мя пользователями один может редактировать а второй нет. Хотелось бы чтобы второй увидел какой пользователь держит файл, в сообщении выдать имя пользователя. Вот.

Значит задача решена в VS следующим кодом
X++:
sing System;
using System.DirectoryServices;
using ActiveDs;
 
namespace NetShare
{
    class Program
    {
        static void Main(string[] args)
        {
            using (DirectoryEntry container = new DirectoryEntry("WinNT://<mashine name>/LanmanServer"))
            {
               IADsFileServiceOperations fso = container.NativeObject as IADsFileServiceOperations;
               if (fso != null)
               {
                   //foreach(IADsSession sess in fso.Sessions())
                   //{
                   //  Console.WriteLine("Name : {0} \tUser: {1} \tComputer : {2}",sess.Name, sess.User, sess.Computer);
                   //}
 
                   IADsCollection resources = fso.Resources() as IADsCollection;
                   Console.WriteLine("----- Resource info -------");
                   foreach(IADsResource resource in resources)
                   {
                       Console.WriteLine("\tPath: {0}\tUser: {1}\tLockCount: {2}\tName:{3}", resource.Path, resource.User, resource.LockCount, resource.Name);
                   }
               }
            }
            Console.Read();
        }
    }
}
Пытаюсь проделать тоже самое в аксе

X++:
static void Job117(Args _args)
{
    Com             objConnection = Com::getObjectEx("WinNT://<mashine name>/LanmanServer");
    Com             colResources;
    AnyType         any;
    ;
    
    //any =
    colResources = objConnection.Resources();
    any = colResources.get__NewEnum();
    

    info("");
}
на строке any = colResources.get__NewEnum(); сыпется и говорит что нет метода
ссылка на mdsn
http://msdn.microsoft.com/ru-ru/libr...(v=vs.85).aspx
Остальные методу приведенные в по ссылке работают. Я их вызываю с пустыми аргументами, система пишет, что метод вызван с недопустимыми параметрами

Есть у кого нить идей, почему нет метода?
Версия аксы 2009 Ru6

Последний раз редактировалось Kainix; 28.12.2012 в 14:48.
Старый 03.01.2013, 22:51   #2  
someOne is offline
someOne
Участник
Аватар для someOne
 
174 / 432 (15) +++++++
Регистрация: 11.12.2008
Адрес: Москва
Нет, так, конечно, не правильно.

У вас получается все в кучу - com, Net...

Ваш исходный пример в чистом виде в аксапту перенести, наверное, невозможно из за разнородности используемых технологий в нем.


Для начала я бы на вашем месте написал в VS пример рабочего кода с использованием "чистого" NET, без всяких там IADsFileServiceOperations, NativeObject и так далее.

После этого переложить код на язык Аксапты - дело техники.

Ну и просто для справки:
Этот фрагмент из вашего примера
X++:
DirectoryEntry container = new DirectoryEntry("WinNT://<mashine name>/LanmanServer")
в Аксапте будет не так
X++:
   Com             objConnection = Com::getObjectEx("WinNT://<mashine name>/LanmanServer");
а как то так
X++:
    System.DirectoryServices.DirectoryEntry de;
    ;
    de = new System.DirectoryServices.DirectoryEntry("WinNT://<mashine name>/LanmanServer");
так как в вашем примере из VS DirectoryEntry это объект NET а не COM
За это сообщение автора поблагодарили: Pustik (5).
Старый 09.01.2013, 07:45   #3  
Kainix is offline
Kainix
Участник
 
47 / 96 (4) ++++
Регистрация: 22.11.2007
Спасибо someOne за ответ.

Вот еще вариант на VS (рабочий)
X++:
using System;
using System.Runtime.InteropServices;

namespace NetShare
{
    class Program
    {
        [DllImport("Netapi32.dll", SetLastError = true)]
        static extern int NetApiBufferFree(IntPtr Buffer);

        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto, Pack = 4)]
        struct FILE_INFO_3
        {
            public int fi3_id;
            public int fi3_permission;
            public int fi3_num_locks;
            public string fi3_pathname;
            public string fi3_username;
        }

        [DllImport("netapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
        static extern int NetFileEnum(
             string servername,
             string basepath,
             string username,
             int    level,
             ref IntPtr bufptr,
             int prefmaxlen,
             out int entriesread,
             out int totalentries,
             IntPtr resume_handle
        );

        [DllImport("netapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
        static extern int NetFileGetInfo(
          string servername,
          int fileid,
          int level,
          ref IntPtr bufptr
        );

        static void Main(string[] args)
        {
            const int MAX_PREFERRED_LENGTH = -1;

            int dwReadEntries;
            int dwTotalEntries;
            IntPtr pBuffer = System.IntPtr.Zero;
            FILE_INFO_3 pCurrent = new FILE_INFO_3();
          
            int dwStatus = NetFileEnum("<mashineName>", "<fileName>", null, 3, ref pBuffer, MAX_PREFERRED_LENGTH, out dwReadEntries, out dwTotalEntries, IntPtr.Zero);

            if (dwStatus == 0)
            {
                for (int dwIndex = 0; dwIndex < dwReadEntries; dwIndex++)
                {
                    IntPtr iPtr = new IntPtr(pBuffer.ToInt32() + (dwIndex * Marshal.SizeOf(pCurrent)));
                    pCurrent = (FILE_INFO_3)Marshal.PtrToStructure(iPtr, typeof(FILE_INFO_3));

                    Console.WriteLine("dwIndex={0}", dwIndex);
                    Console.WriteLine(" id={0}", pCurrent.fi3_id);
                    Console.WriteLine(" num_locks={0}", pCurrent.fi3_num_locks);
                    Console.WriteLine(" pathname={0}", pCurrent.fi3_pathname);
                    Console.WriteLine(" permission={0}", pCurrent.fi3_permission);
                    Console.WriteLine(" username={0}", pCurrent.fi3_username);
                }
                NetApiBufferFree(pBuffer);
            }
            Console.Read();
        }
    }
}
Пытаюсь перенести на аксу

X++:
static void Job117(Args _args)
{
    DLL                     netApi32 = New Dll("netapi32.dll");
    DLLFunction             NetFileEnum = new DllFunction(netApi32, "NetFileEnum");
    int                     dwStatus, dwReadEntries, dwTotalEntries, res ;
    Binary                  struct;
    int                     MAX_PREFERRED_LENGTH = -1;
    System.IntPtr           pBuffer = new System.IntPtr(0);
    ;

     NetFileEnum.arg(ExtTypes::String,
                    ExtTypes::String,
                    ExtTypes::String,
                    ExtTypes::DWord,
                    ExtTypes::void,
                    ExtTypes::DWord,
                    ExtTypes::DWord,
                    ExtTypes::DWord,
                    ExtTypes::Pointer);

    dwStatus = NetFileEnum.call("<mashineName>",
                                "",
                                "",
                                3,
                                pBuffer,
                                MAX_PREFERRED_LENGTH,
                                dwReadEntries,
                                dwTotalEntries,
                                pBuffer);

    if(dwStatus == 0)
    {
        info("");
    }
}
Не проходит пишет ошибку
Значение регистра ESP не было сохранено при вызове функции "NetFileEnum" в библиотеке DLL "netapi32.dll". Причиной может являться вызов функции DLL, которая объявлена с неверным числом аргументов.
Что я делаю не так?
Старый 09.01.2013, 07:53   #4  
Kainix is offline
Kainix
Участник
 
47 / 96 (4) ++++
Регистрация: 22.11.2007
В аксе используется только Com технология, никакого Net там нет, в VS, использую специальную обертку кома. Просто при вызове функции get__NewEnum() Com объекта пишет что нет таковой. Если бы мне все вернуло не было бы проблем.
objConnection = Com::getObjectEx("WinNT://<mashine name>/LanmanServer"); возвращает нам ком объект ActiveDs, и я начинаю с ним работать, в VS есть for each, а в аксе такого нет, место этого я пишу colResources.get__NewEnum(), и тут получаю, что нет такого метода у ком объекта, хотя остальные методы такие как Add(), GetObject(), Remove() есть. А нужного метода нет. Печаль.

PS. Примеры из VisualStudio работоспособные. Просто не хочется создавать сборки, а потом их прикреплять , и закидывать на клиенты.

Последний раз редактировалось Kainix; 09.01.2013 в 07:56.
Старый 09.01.2013, 12:39   #5  
belugin is offline
belugin
Участник
Аватар для belugin
Сотрудники Microsoft Dynamics
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии 2011
Лучший по профессии 2009
 
4,622 / 2925 (107) +++++++++
Регистрация: 16.01.2004
Записей в блоге: 5
Цитата:
Сообщение от Kainix Посмотреть сообщение
В аксе используется только Com технология, никакого Net там нет,.
.NET CLR Interop Overview
Старый 09.01.2013, 12:49   #6  
michel1971 is offline
michel1971
Участник
 
78 / 78 (3) ++++
Регистрация: 14.01.2011
Цитата:
Сообщение от Kainix Посмотреть сообщение
objConnection = Com::getObjectEx("WinNT://<mashine name>/LanmanServer"); возвращает нам ком объект ActiveDs, и я начинаю с ним работать, в VS есть for each, а в аксе такого нет
поробуйте вот так
X++:
    comEnum = new COMEnum2Object(objConnection);
    obj = comEnum.getFirst();

    while (obj)
    {
        .......
        obj= comEnum.getNext();
    }
За это сообщение автора поблагодарили: Kainix (1).
Старый 09.01.2013, 16:16   #7  
Kainix is offline
Kainix
Участник
 
47 / 96 (4) ++++
Регистрация: 22.11.2007
Спасибо michel1971, за дельный совет. Написал
X++:
static void Job1171(Args _args)
{
    Com             IADsFileServiceOperations = Com::getObjectEx("WinNT://adm-hp22/LanmanServer");
    Com             IADsCollection;
    Com             IADsResource;
    COMEnum2Object  IADsEnumerator;
    Int             counter;
    ;

    IADsCollection = IADsFileServiceOperations.Resources();
    IADsEnumerator = new COMEnum2Object(IADsCollection);
    counter = IADsEnumerator.usageCount();
    info(strfmt("%1", counter));
    IADsResource = IADsEnumerator.getFirst();
    while(IADsResource)
    {
        info(IADsResource.User() + ";" + IADsResource.Path());
        IADsResource = IADsEnumerator.getNext();
    }
}
Что то перебирается но результат не стабилен, вылетают ошибки. Думаю эти ошибки в самом IADsFileServiceOperations, так как енумеротор не понятно что возвращает.
Прихожу к выводу что буду писать DLL через NetFileEnum доставать только нужный файл, и работать только с ним.

И еще вопрос, что лучше писать Com объект или DLL?

Последний раз редактировалось Kainix; 09.01.2013 в 16:20.
Старый 09.01.2013, 16:21   #8  
Kainix is offline
Kainix
Участник
 
47 / 96 (4) ++++
Регистрация: 22.11.2007
Цитата:
Сообщение от belugin Посмотреть сообщение
Я говорю про данную задачу. В аксе конечно же есть .Net
Старый 10.01.2013, 09:21   #9  
Kainix is offline
Kainix
Участник
 
47 / 96 (4) ++++
Регистрация: 22.11.2007
Вот родил библиотеку для просмотра кто какие файлы использует по сети.
ClassLibrary4.rar
DLL находится в папке ClassLibrary4\ClassLibrary4\bin\Debug

пример использования
X++:
static void Job1171(Args _args)
{
    FileInfo3.GetFilesInfo       FileInfo3 = new FileInfo3.GetFilesInfo();
    ;

    FileInfo3.getFilesInfo("MashineName");
    FileInfo3.firstElement();
    while(FileInfo3.moveNext())
    {
        FileInfo3.currentElement();
        info(FileInfo3.getPathName());
        info(FileInfo3.getUserName());
    }
    
    FileInfo3.getFileInfo("MashineName", "FullFileName");
    FileInfo3.currentElement();
    info(FileInfo3.getPathName());
    info(FileInfo3.getUserName());
}
FullFileName - это полный путь к файлу например C:\1.docx

Еще замечание, что в ходе тестирования было выяснено что не все программы оставляют след что ими открыт файл, т.е. если открыть txt блокнотом, то через несколько секунд он исчезает из списка открытых файлов, openiles тоже не видит. Приложения офиса работают стабильно. Будьте внимательны при использовании.

Всем спасибо за советы

Последний раз редактировалось Kainix; 10.01.2013 в 09:25.
Старый 10.01.2013, 10:31   #10  
gl00mie is offline
gl00mie
Участник
MCBMSS
Most Valuable Professional
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
3,684 / 5798 (201) ++++++++++
Регистрация: 28.11.2005
Адрес: Москва
Записей в блоге: 3
Для доступа к списку открытых по сети файлов на той или иной машине нужны права доступа "выше среднего", и простому пользователю, у которого на клиенте отрабатывает функционал документооборота и открывает файл, хранящийся в сетевой шаре (еще одно из допущений в этой теме), не удастся вот так с наскоку подключиться к файл-серверу и посмотреть, кто и какие файлы по сети с него открыл. Т.е. чтобы это работало в реальных условиях, соотв. "инспекция" должна выполняться с AOS'а, а тот должен быть запущен под учетной записью, у которой права "выше среднего" на соотв. файл-сервере, в то время как для штатной работы документооборота такие права совершенно не нужны.
Старый 10.01.2013, 10:36   #11  
Kainix is offline
Kainix
Участник
 
47 / 96 (4) ++++
Регистрация: 22.11.2007
Цитата:
Сообщение от gl00mie Посмотреть сообщение
Для доступа к списку открытых по сети файлов на той или иной машине нужны права доступа "выше среднего", и простому пользователю, у которого на клиенте отрабатывает функционал документооборота и открывает файл, хранящийся в сетевой шаре (еще одно из допущений в этой теме), не удастся вот так с наскоку подключиться к файл-серверу и посмотреть, кто и какие файлы по сети с него открыл. Т.е. чтобы это работало в реальных условиях, соотв. "инспекция" должна выполняться с AOS'а, а тот должен быть запущен под учетной записью, у которой права "выше среднего" на соотв. файл-сервере, в то время как для штатной работы документооборота такие права совершенно не нужны.
Само сабой разумеющееся, это видно из описания функции NetFileEnum. Спасибо за поправку, а то забыл написать.
 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
Метки и Меточные файлы sguryev DAX: База знаний и проекты 1 03.09.2021 12:01
Конфигурация сети для Аксапты с Порталом Narayana DAX: Администрирование 4 19.12.2012 10:45
Какие методики резервирования товаров используются в вашей компании (или вашими клиентами)? kashperuk DAX: Функционал 51 03.04.2012 13:31
Какие должны быть файлы справки ravil DAX: Администрирование 1 19.04.2004 12:04
*.aoc файлы Андре DAX: Администрирование 15 22.04.2003 07:40

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход

Рейтинг@Mail.ru
Часовой пояс GMT +3, время: 19:30.