28.12.2012, 14:36 | #1 |
Участник
|
Какие файлы открыты по сети
Всем привет.
Проблема следующего характера, при открытии прикрепленного файла через акс одновременно 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(""); } ссылка на 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 |
Участник
|
Нет, так, конечно, не правильно.
У вас получается все в кучу - 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"); |
|
|
За это сообщение автора поблагодарили: Pustik (5). |
09.01.2013, 07:45 | #3 |
Участник
|
Спасибо 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 |
Участник
|
В аксе используется только 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 |
Участник
|
|
|
09.01.2013, 12:49 | #6 |
Участник
|
Цитата:
X++: comEnum = new COMEnum2Object(objConnection); obj = comEnum.getFirst(); while (obj) { ....... obj= comEnum.getNext(); } |
|
|
За это сообщение автора поблагодарили: Kainix (1). |
09.01.2013, 16:16 | #7 |
Участник
|
Спасибо 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(); } } Прихожу к выводу что буду писать DLL через NetFileEnum доставать только нужный файл, и работать только с ним. И еще вопрос, что лучше писать Com объект или DLL? Последний раз редактировалось Kainix; 09.01.2013 в 16:20. |
|
09.01.2013, 16:21 | #8 |
Участник
|
|
|
10.01.2013, 09:21 | #9 |
Участник
|
Вот родил библиотеку для просмотра кто какие файлы использует по сети.
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()); } Еще замечание, что в ходе тестирования было выяснено что не все программы оставляют след что ими открыт файл, т.е. если открыть txt блокнотом, то через несколько секунд он исчезает из списка открытых файлов, openiles тоже не видит. Приложения офиса работают стабильно. Будьте внимательны при использовании. Всем спасибо за советы Последний раз редактировалось Kainix; 10.01.2013 в 09:25. |
|
10.01.2013, 10:31 | #10 |
Участник
|
Для доступа к списку открытых по сети файлов на той или иной машине нужны права доступа "выше среднего", и простому пользователю, у которого на клиенте отрабатывает функционал документооборота и открывает файл, хранящийся в сетевой шаре (еще одно из допущений в этой теме), не удастся вот так с наскоку подключиться к файл-серверу и посмотреть, кто и какие файлы по сети с него открыл. Т.е. чтобы это работало в реальных условиях, соотв. "инспекция" должна выполняться с AOS'а, а тот должен быть запущен под учетной записью, у которой права "выше среднего" на соотв. файл-сервере, в то время как для штатной работы документооборота такие права совершенно не нужны.
|
|
10.01.2013, 10:36 | #11 |
Участник
|
Цитата:
Сообщение от gl00mie
Для доступа к списку открытых по сети файлов на той или иной машине нужны права доступа "выше среднего", и простому пользователю, у которого на клиенте отрабатывает функционал документооборота и открывает файл, хранящийся в сетевой шаре (еще одно из допущений в этой теме), не удастся вот так с наскоку подключиться к файл-серверу и посмотреть, кто и какие файлы по сети с него открыл. Т.е. чтобы это работало в реальных условиях, соотв. "инспекция" должна выполняться с AOS'а, а тот должен быть запущен под учетной записью, у которой права "выше среднего" на соотв. файл-сервере, в то время как для штатной работы документооборота такие права совершенно не нужны.
|
|