Получение списка расшаренных файлов локальной сети

Общие вопросы, не зависящие от языка реализации.

Модераторы: Duncon, Hawk, Romeo, Eugie

Ответить
crack
Сообщения: 8
Зарегистрирован: 29 апр 2004, 00:14
Откуда: Санкт-Петербург

26 дек 2004, 16:24

Всем привет,
встала передо мной задача получения имён всех расшаренных файлов локальной сети. Попробовал использовать WNetEnumResource(...), но выдаётся только список share ресурсов какого либо компа, но необходимо получить имена всех вложенных папок и файлов. Подскажите пожалуйста, как можно такое осуществить, в каком направлении продвигаться?
Аватара пользователя
Romeo
Сообщения: 3091
Зарегистрирован: 02 мар 2004, 17:25
Откуда: Крым, Севастополь
Контактная информация:

27 дек 2004, 15:53

С помощью функции SHGetSpecialFolderLocation получим pidl сетевого окружения. Затем, используя интерфейс IShellFolder и его метод BindToObject, "войдём" в нужную сетевую папку и воспользуемся методом EnumObjects для получения списка её содержимого. Если имя компьюютера фиксировано, то можно воспользоваться методом ParseDisplayName у desktop-объекта (указатель на IShellFolder интерфейс которого можно предварительно получить, воспользовавшись SHGetDesktopFolder шелом) и получить соответствующий ShellFolder. Далее тот же приём: вызываем EnumObjects.
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
crack
Сообщения: 8
Зарегистрирован: 29 апр 2004, 00:14
Откуда: Санкт-Петербург

27 дек 2004, 23:28

Получаю pidl на CSIDL_NETWORK(если я всё правильно понял) но мне остаётся непонятным как войти в конкретную папку на удалённом компе? Где указать её имя? Заранее извиняюсь за может быть глупые вопросы, но опыта подобного программироапния у меня совсем мало :(
Аватара пользователя
Romeo
Сообщения: 3091
Зарегистрирован: 02 мар 2004, 17:25
Откуда: Крым, Севастополь
Контактная информация:

28 дек 2004, 12:49

Ещё раз говорю, если удалённый компьютер фиксирован, то достаточно выполнить следующие манипуляции:

Код: Выделить всё

void SHGetNameByFlag( LPSHELLFOLDER lpParentFolder, LPCITEMIDLIST lpItemIDList, LPTSTR lpszFileName, DWORD uMaxLen, DWORD uFlags)
{
	ATLASSERT(lpParentFolder != NULL);
	ATLASSERT(lpItemIDList != NULL);
	
	STRRET stStrRet;
	stStrRet.uType = STRRET_CSTR;

	HRESULT hr = lpParentFolder->GetDisplayNameOf(lpItemIDList, uFlags, &stStrRet);
	ATLASSERT(SUCCEEDED(hr));

	switch(stStrRet.uType)
	{
		case STRRET_CSTR:
		{
			_tcsncpy(lpszFileName, _bstr_t(stStrRet.cStr), uMaxLen);
			break;
		}

		case STRRET_WSTR:
		{
			IMallocPtr spMalloc;
			::SHGetMalloc(&spMalloc);

			_tcsncpy(lpszFileName, _bstr_t(stStrRet.pOleStr), uMaxLen);
			spMalloc->Free(stStrRet.pOleStr);
			break;
		}

		case STRRET_OFFSET:
		{
			_tcsncpy(lpszFileName, _bstr_t((CHAR *)lpItemIDList + stStrRet.uOffset), uMaxLen);
			break;
		}
	}
}

void main()
{
      IShellFolderPtr spDesktop;
      SHGetDesktopFolder(&spDesktop);

      IMallocPtr spMalloc;
      SHGetMalloc(&spMalloc);

      LPITEMIDLIST pidl;
      spDesktop->ParseDisplayName((NULL, NULL, L"\\RemoteComputer\Install\Players\WinAmp", NULL, &pidl, NULL);

      IShellFolderPtr spRemoteFolder;
      spDesktop->BinToObject(pidl, NULL, IID_IShellFolder, (void **)&spRemoteFolder);
      spMalloc->Free(pidl);

      IEnumIDListPtr spRemoteItems;
      spRemoteFolder->EnumObjects(NULL, SHCONTF_FOLDERS | SHCONTF_NONFOLDERS,, &spRemoteItems);

      TCHAR strItemName[100];

      while (spRemoteItems->Next(1, &pidl, NULL) == S_OK)
      {
            SHGetNameByFlag(spRemoteFolder, pidl, strItemName, 100, SHGDN_INFOLDER);
            std::cout << strItemName << std::endl;
            spMalloc->Free(pidl);
      }
}
И вообще советую почитать MSDN о shell navigation. Огромные возможности, но и не менее огромные знания, которые предстоит постичь. Желаю удачи.
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
crack
Сообщения: 8
Зарегистрирован: 29 апр 2004, 00:14
Откуда: Санкт-Петербург

28 дек 2004, 12:57

огромное спасибо :)
Аватара пользователя
Romeo
Сообщения: 3091
Зарегистрирован: 02 мар 2004, 17:25
Откуда: Крым, Севастополь
Контактная информация:

29 дек 2004, 11:56

Тема перенесена из "C/C++" в "Win API, Shell". Тематика вынуждает :)
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
Ответить