FSO.GetDrive и сеть

Программирование на Visual Basic, главный форум. Обсуждение тем программирования на VB 1—6.
Даже если вы плохо разбираетесь в VB и программировании вообще — тут вам помогут. В разумных пределах, конечно.
Правила форума
Темы, в которых будет сначала написано «что нужно сделать», а затем просьба «помогите», будут закрыты.
Читайте требования к создаваемым темам.
dimix
Продвинутый пользователь
Продвинутый пользователь
Аватара пользователя
 
Сообщения: 174
Зарегистрирован: 08.02.2005 (Вт) 22:47

FSO.GetDrive и сеть

Сообщение dimix » 21.03.2005 (Пн) 19:40

Перед сохранением файла предлагаю пользователю выбрать папку. Допустим, путь содержится в переменной Path. Далее хочу проверить, реально ли записать файл в эту папку. Используя FSO проверяю тип устройства, свободно ли оно и заодно определяю свободное место:

Set DRV = FSO.GetDrive(FSO.GetDriveName(Path))
DriveType = DRV.DriveType
DriveReady = DRV.IsReady
DriveSpace = DRV.AvailableSpace

Но вот беда - если Path содержит сетевой путь, то первая строчка выдает ошибку. Можно, конечно, запретить сохранение по сети. Но если не запрещать, то как узнать, возможно ли физически писать в выбранную папку? А может это CD?

И еще попутно вопрос. Экспериментально я выяснил, что DriveType для диска A равен 1, для CD-приводов = 4, для HDD = 2. А когда он равен 3? Какие еще есть значения и для чего? И всегда ли в перечисленных случаях значения DriveType будут именно такими (1, 2, 4)?

Andrev
Продвинутый пользователь
Продвинутый пользователь
 
Сообщения: 108
Зарегистрирован: 19.01.2005 (Ср) 9:22
Откуда: Kursk

Сообщение Andrev » 22.03.2005 (Вт) 10:11

Цитата:
The DriveType property returns an integer whose value corresponds to one of the DriveType Constants listed below. Note that only an integer is returned; to use the names below they must be defined in your code.


0 = Unknown
1 = Removable
2 = Fixed
3 = Network
4 = CD-ROM
5 = RAM Disk

Думаю, переводить не стоит - сам разберешься.
В этой жизни нет ничего невозможного. Если у вас что-то не получается, значит, вы что-то делаете не так.

Alexanbar
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1727
Зарегистрирован: 13.04.2004 (Вт) 23:04
Откуда: Волгоградская обл.

Сообщение Alexanbar » 22.03.2005 (Вт) 19:06

Прежде, чем использовать сетевой ресурс в FSO, к нему надо подключиться.
'---------------------------------------------------
'Локальная сеть
'---------------------------------------------------
Public Declare Function WNetAddConnection Lib "mpr.dll" _
Alias "WNetAddConnectionA" _
(ByVal lpszNetPath As String, _
ByVal lpszPassword As String, _
ByVal lpszLocalName As String) As Long
Public Declare Function WNetCancelConnection Lib "mpr.dll" _
Alias "WNetCancelConnectionA" _
(ByVal lpszName As String, _
ByVal bForce As Long) As Long
'------------------------------------------------------
'Константы
'------------------------------------------------------
'Public Const NO_ERROR = 0 ' dderror
Public Const WN_NO_ERROR = 0 'NO_ERROR
Public Const ERROR_BAD_USERNAME = 2202&
Public Const ERROR_INVALID_PASSWORD = 86&
Public Const WN_BAD_PASSWORD = ERROR_INVALID_PASSWORD
Public Const WN_BAD_USER = ERROR_BAD_USERNAME
'-----------------------------------------------------
Public Declare Function GetUserName Lib "advapi32.dll" _
Alias "GetUserNameA" (ByVal lpBuffer As String, nSize As Long) As Long

Dex
Постоялец
Постоялец
 
Сообщения: 346
Зарегистрирован: 09.08.2004 (Пн) 16:11

Сообщение Dex » 23.03.2005 (Ср) 14:00

Типы:
1-Съёмный диск
2-Локальный диск
3-Сетевой диск
4-Компакт-диск
5-Виртуальный диск
На счёт сетевых дисков:
Не обязательно, чтобы дисководы были физически присоединены к системе - обеспечивается работа с сетевыми дисками.
Но вот беда - если Path содержит сетевой путь, то первая строчка выдает ошибку.
Ошибка возможно возникает из-за того что нет доступа к етому самому сетевому диску. :)

dimix
Продвинутый пользователь
Продвинутый пользователь
Аватара пользователя
 
Сообщения: 174
Зарегистрирован: 08.02.2005 (Вт) 22:47

Сообщение dimix » 23.03.2005 (Ср) 14:21

Dex писал(а):Ошибка возможно возникает из-за того что нет доступа к етому самому сетевому диску.


Что ты имеешь ввиду? Расшарен ли диск целиком? У меня ситуация такая - на сетевом диске расшарена папка, например Dimix. Т.е. путь выглядит так: \\Server\Dimix. Для такого пути GetDriveName в принципе не будет работать, или будет, если доступен диск, на котором папка Dimix?

А как использовать код Alexanbar'а на практике? Мне нужно выполнить WNetAddConnection, а потом использовать FSO? А FSO узнает, что я подключился к сетевому ресурсу?

Dex
Постоялец
Постоялец
 
Сообщения: 346
Зарегистрирован: 09.08.2004 (Пн) 16:11

Сообщение Dex » 23.03.2005 (Ср) 15:12

Как ты можешь обращаться к сетевому диску если токого не имеется? :? Это равносильно тому что ты будешь пытаться зайти на сайт будучи не подключённым к нету. :) Поэтому
...если доступен диск...
то и работать всё будет. Я правда не знаю насчёт GetDriveName, но если указывать путь из переменной или ещё из чего-то то всё ок. :wink:

dimix
Продвинутый пользователь
Продвинутый пользователь
Аватара пользователя
 
Сообщения: 174
Зарегистрирован: 08.02.2005 (Вт) 22:47

Сообщение dimix » 23.03.2005 (Ср) 17:53

Про диск я все понимаю. Нет доступа - обломись. Но проблема вот в чем. Когда пользователь выбирает папку в локале, я проверяю, можно ли писать на диск, на котором находится папка. Т.е. как минимум, это должен быть не сидюк. Но когда пользователь выбирает папку в сети, как мне определить, можно ли писать в эту папку? Ведь папка точно также может быть на сидюке. А если сидюк не расшарен целиком, а расшарена только папка на нем (ну, всякое бывает), то как мне определить, что эта папка на сидюке? Может быть можно определять доступность не диска, а именно пути? Тогда как?

Alexanbar
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1727
Зарегистрирован: 13.04.2004 (Вт) 23:04
Откуда: Волгоградская обл.

Сообщение Alexanbar » 23.03.2005 (Ср) 18:51

Похоже, нужно проверять, доступна ли папка на запись. Может быть просто считать атрибуты папки через тот же FSO, а затем определить, если среди них ReadOnly?

Dex
Постоялец
Постоялец
 
Сообщения: 346
Зарегистрирован: 09.08.2004 (Пн) 16:11

Сообщение Dex » 23.03.2005 (Ср) 22:29

Но когда пользователь выбирает папку в сети, как мне определить, можно ли писать в эту папку?

Вот так
Код: Выделить всё
If fso.FolderExists("Путь к папке")=True Then
'Можно писать
Else
'Нельзя писать
End if

dimix
Продвинутый пользователь
Продвинутый пользователь
Аватара пользователя
 
Сообщения: 174
Зарегистрирован: 08.02.2005 (Вт) 22:47

Сообщение dimix » 23.03.2005 (Ср) 23:48

Alexanbar писал(а):Может быть просто считать атрибуты папки через тот же FSO, а затем определить, если среди них ReadOnly?


А если папка на СD, то у нее уже "автоматом" ReadOnly?

2 Dex. А если папка на CD, разве FolderExists будет False?

Dex
Постоялец
Постоялец
 
Сообщения: 346
Зарегистрирован: 09.08.2004 (Пн) 16:11

Сообщение Dex » 24.03.2005 (Чт) 12:41

Если CD доступин то FolderExists будет True, если не доступен то False. :)

dimix
Продвинутый пользователь
Продвинутый пользователь
Аватара пользователя
 
Сообщения: 174
Зарегистрирован: 08.02.2005 (Вт) 22:47

Сообщение dimix » 24.03.2005 (Чт) 14:29

Дык, зачем мне True, моя прога не умеет писать на CD. Мне нужно, чтобы при выборе папки на CD всегда было False, не зависимо от того, что там доступно - папка или весь диск.

Dex
Постоялец
Постоялец
 
Сообщения: 346
Зарегистрирован: 09.08.2004 (Пн) 16:11

Сообщение Dex » 24.03.2005 (Чт) 15:05

А ты тогда по типу действуй. Тобишь если тип компакт-диск то и не пишем. :)

dimix
Продвинутый пользователь
Продвинутый пользователь
Аватара пользователя
 
Сообщения: 174
Зарегистрирован: 08.02.2005 (Вт) 22:47

Сообщение dimix » 24.03.2005 (Чт) 16:28

Ну елы-палы, давайте начнем сначала.
Dex, прочитай первый пост :)

Dex
Постоялец
Постоялец
 
Сообщения: 346
Зарегистрирован: 09.08.2004 (Пн) 16:11

Сообщение Dex » 24.03.2005 (Чт) 16:48

Тоесть ты имеешь ввиду что CD на сетевой папке?

IvanSh
Новичок
Новичок
 
Сообщения: 25
Зарегистрирован: 20.03.2005 (Вс) 15:20
Откуда: Minsk

Сообщение IvanSh » 24.03.2005 (Чт) 20:50

народ, а может проще перехватить ошибку записи, обработать и выдать MsgBox "ошибка записи. причина такаета..." :wink:
Наши люди лёгкими путями не идут!

Dex
Постоялец
Постоялец
 
Сообщения: 346
Зарегистрирован: 09.08.2004 (Пн) 16:11

Сообщение Dex » 24.03.2005 (Чт) 21:04

IvanSh - не в тему :lol:

dimix
Продвинутый пользователь
Продвинутый пользователь
Аватара пользователя
 
Сообщения: 174
Зарегистрирован: 08.02.2005 (Вт) 22:47

Сообщение dimix » 24.03.2005 (Чт) 21:58

Dex писал(а):Тоесть ты имеешь ввиду что CD на сетевой папке?

Ну да!!! Точнее, сетевая папка - это папка на CD. Соответственно, она существует, но вот записать в нее не получится. Т.е. нужно определить, что эта папка не доступна для записи.

2 IvanSh. Это будет выглядеть так. Пользователь выбрал папку, чего-то поделал в программе, нажал "Записать", а программа выругалась на папку. Но ведь правильнее выругаться сразу, при выборе папки.

2 ALL. А можно ли после выбора папки попытаться открыть в ней файл для записи и в случае неудачи сообщить, что папка недоступна? Такая проверка была бы универсальной, ведь не важно, почему нельзя записать, важен сам факт - можно записать или нельзя. Как такой вариант?

Dex
Постоялец
Постоялец
 
Сообщения: 346
Зарегистрирован: 09.08.2004 (Пн) 16:11

Сообщение Dex » 25.03.2005 (Пт) 0:00

Во первых если
...сетевая папка - это папка на CD.
то это уже не сетевая папка. :) Что-то я тебя не понимаю давайка заново и подробно, а то ты меня уже запутал сетевая папка или CD. :shock:

Alexanbar
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1727
Зарегистрирован: 13.04.2004 (Вт) 23:04
Откуда: Волгоградская обл.

Сообщение Alexanbar » 25.03.2005 (Пт) 17:09

Для папки на CD стандартного формата, по-идее, должен устанавливаться атрибут ReadOnly. Но если CD в формате UDF, на него можно писать при наличии в памяти, например InCD.

dimix
Продвинутый пользователь
Продвинутый пользователь
Аватара пользователя
 
Сообщения: 174
Зарегистрирован: 08.02.2005 (Вт) 22:47

Сообщение dimix » 25.03.2005 (Пт) 21:35

Dex писал(а):Во первых если
...сетевая папка - это папка на CD.
то это уже не сетевая папка. :) Что-то я тебя не понимаю давайка заново и подробно, а то ты меня уже запутал сетевая папка или CD. :shock:


Никаких ИЛИ! Есть СD-ROM драйв. Ставим в него диск. Расшариваем не весь диск, а какую-то папку на нем. Пользователь видит эту папку, причем он ни сном ни духом, на чем эта папка - на HDD или на CD. Он выбирает эту папку, чтобы в нее писать файлы. Но ему нужно популярно объяснить, что эта папка на CD, поэтому записать в нее не удастся.

dimix
Продвинутый пользователь
Продвинутый пользователь
Аватара пользователя
 
Сообщения: 174
Зарегистрирован: 08.02.2005 (Вт) 22:47

Сообщение dimix » 25.03.2005 (Пт) 22:27

Короче, я не знаю, что происходит. Ничего не менял в своей программе, но она перестала выдавать ошибку в строке

Set DRV = FSO.GetDrive(FSO.GetDriveName(Path)) если выбрана сетевая папка...

И тип устройства теперь определяется (3), и свободное место на диске, на котором находится расшаренная папка. Причем, даже подключаться никак не нужно - просто выбираешь папку в диалоге и все. Если нет доступа (прав), то в самом диалоге выводится соответствующее предупреждение. Кстати, запретить пользователю запись в сетевую папку на CD можно уже на том основании, что свободное место на диске = 0. Но лучше, наверное, через атрибуты папки. Я делаю так:

FSO.GetFolder(Path).Attributes

Но вот как работать с возвращаемым значением? Оно имеет тип FileAttribute. Вывод значения в виде строки дает мне 16 для папки на HDD и 17 - на CD. Наверное, это отличие и заключается в атрибуте ReadOnly. Но хотелось бы поконкретнее. Может кто знает?

GM
programador
programador
 
Сообщения: 1427
Зарегистрирован: 24.06.2003 (Вт) 15:56
Откуда: 194.67.52.100

Сообщение GM » 26.03.2005 (Сб) 0:01

Вывод значения в виде строки дает мне 16 для папки на HDD и 17 - на CD. Наверное, это отличие и заключается в атрибуте ReadOnly. Но хотелось бы поконкретнее. Может кто знает?

Так понятно.
Аттрибуты:
Папка - vbDirectory = 16.
Только для чтения - vbReadonly = 1
vbDirectory or vbReadonly = 17.
Чтобы узнать подробнее об атрибутах папки, файла:
Код: Выделить всё
msgbox((attribute And vbReadOnly) > 0)  'Имеет ли файл аттрибут только для чтения
msgbox((attribute And vbDirectory) > 0)  'Является ли файл папкой
'... и так далее все константы содержатся в vbFileAttribute
الفيجوال بيسك الرابح

dimix
Продвинутый пользователь
Продвинутый пользователь
Аватара пользователя
 
Сообщения: 174
Зарегистрирован: 08.02.2005 (Вт) 22:47

Сообщение dimix » 29.03.2005 (Вт) 13:06

GM, спасибо большое!

GM писал(а):vbDirectory or vbReadonly = 17.

Но почему "or", м.б. "and"?

alibek
Большой Человек
Большой Человек
 
Сообщения: 14205
Зарегистрирован: 19.04.2002 (Пт) 11:40
Откуда: Russia

Сообщение alibek » 29.03.2005 (Вт) 14:02

Это логические операторы (сложение), а не логическое сравнение.
Lasciate ogni speranza, voi ch'entrate.

dimix
Продвинутый пользователь
Продвинутый пользователь
Аватара пользователя
 
Сообщения: 174
Зарегистрирован: 08.02.2005 (Вт) 22:47

Сообщение dimix » 30.03.2005 (Ср) 21:45

Увы, через атрибуты папки (по крайней мере, через ReadOnly) не получится :(
Дело в том, что если папка на HDD имеет атрибут ReadOnly, то это вовсе не означает, что записывать файлы в нее нельзя. Остается только через тип устройства. А может еще есть какие предложения?


Вернуться в Visual Basic 1–6

Кто сейчас на конференции

Сейчас этот форум просматривают: AhrefsBot, Yandex-бот и гости: 173

    TopList