Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« : 14-01-2012 13:40 » |
|
забавная проблема: если вызывать функцию GetVolumeInformationW из C++, то всё ок, если из шарпа - GetLastError возвращает ошибку 123 (Синтаксическая ошибка в имени файла, имени папки или метке тома. ) вызываю так using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms;
using System.Runtime.InteropServices;//WinAPI
namespace GetDriveSerialNumber { public partial class Form1:Form {
[DllImport("Kernel32.dll",EntryPoint="GetVolumeInformationW")] public static extern int GetVolumeInformationW ( String lpRootPathName , out String lpVolumeNameBuffer , uint nVolumeNameSize , out uint lpVolumeSerialNumber , out uint lpMaximumComponentLength, out uint lpFileSystemFlags , out String lpFileSystemNameBuffer , uint nFileSystemNameSize );
[DllImport("Kernel32.dll",EntryPoint="GetLastError")] public static extern uint GetLastError ( );
public Form1() { InitializeComponent(); }
private void but_getinfo_Click(object sender,EventArgs e) { String lpRootPathName ="E:\\"; String lpVolumeNameBuffer ; uint nVolumeNameSize = 255; uint lpVolumeSerialNumber ; uint lpMaximumComponentLength; uint lpFileSystemFlags ; String lpFileSystemNameBuffer ; uint nFileSystemNameSize = 255;
if(0!=GetVolumeInformationW ( lpRootPathName , out lpVolumeNameBuffer , nVolumeNameSize , out lpVolumeSerialNumber , out lpMaximumComponentLength, out lpFileSystemFlags , out lpFileSystemNameBuffer , nFileSystemNameSize
) ) {
}
uint err=GetLastError(); } } }
что не так ? Как-то юникодную строку неправильно заполняю ? String lpRootPathName ="E:\\";
|
|
|
Записан
|
|
|
|
Dimka
Деятель
Команда клуба
Offline
Пол:
|
|
« Ответ #1 : 14-01-2012 16:02 » |
|
Алексей1153++, в параметрах атрибута DllImport кодировку укажи - по умолчанию ANSI.
|
|
|
Записан
|
Программировать - значит понимать (К. Нюгард) Невывернутое лучше, чем вправленное (М. Аврелий) Многие готовы скорее умереть, чем подумать (Б. Рассел)
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #2 : 14-01-2012 16:32 » |
|
точно, ты же мне раньше показывал, а я и забыл )) Спасиб
Добавлено через 8 минут и 5 секунд: а вот со строками сообразить опять не могу , как выделить место в 255 символов, чтобы АПИшная функция смогла туда записать данные ?
|
|
« Последнее редактирование: 14-01-2012 16:40 от Алексей1153 »
|
Записан
|
|
|
|
Dimka
Деятель
Команда клуба
Offline
Пол:
|
|
« Ответ #3 : 14-01-2012 22:05 » |
|
Алексей1153++, ты сначала попробуй просто out string. И если не заработает, тогда покажу вариант через Marshal.
|
|
|
Записан
|
Программировать - значит понимать (К. Нюгард) Невывернутое лучше, чем вправленное (М. Аврелий) Многие готовы скорее умереть, чем подумать (Б. Рассел)
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #4 : 15-01-2012 06:22 » |
|
|
err1.gif (46.37 Кб - загружено 1742 раз.)
|
|
Записан
|
|
|
|
Dimka
Деятель
Команда клуба
Offline
Пол:
|
|
« Ответ #5 : 15-01-2012 07:25 » |
|
Алексей1153++, а где у тебя ref на этом параметре, если он двунаправленный? Добавлено через 17 минут и 35 секунд:Так, я добрался до MSDN. BOOL WINAPI GetVolumeInformationByHandleW( __in HANDLE hFile, __out LPTSTR lpVolumeNameBuffer, __in DWORD nVolumeNameSize, __out LPDWORD lpVolumeSerialNumber, __out LPDWORD lpMaximumComponentLength, __out LPDWORD lpFileSystemFlags, __out LPTSTR lpFileSystemNameBuffer, __in DWORD nFileSystemNameSize );
Это переводится следующим образом. Все LPTSTR - в string, все HANDLE в IntPtr, все DWORD в uint. Все out параметры должны также помечаться out в C#. С LPDWORD нужно разбираться подробно. lpVolumeSerialNumber A pointer to a variable that receives the volume serial number.
This parameter can be NULL if the serial number is not required.
This function returns the volume serial number that the operating system assigns when a hard disk is formatted. To programmatically obtain the hard disk's serial number that the manufacturer assigns, use the Windows Management Instrumentation (WMI) Win32_PhysicalMedia property SerialNumber.
Раз это возвращаемое число, значит out uint. lpMaximumComponentLength A pointer to a variable that receives the maximum length, in TCHARs, of a file name component that a specified file system supports.
A file name component is the portion of a file name between backslashes.
The value that is stored in the variable that *lpMaximumComponentLength points to is used to indicate that a specified file system supports long names. For example, for a FAT file system that supports long names, the function stores the value 255, rather than the previous 8.3 indicator. Long names can also be supported on systems that use the NTFS file system.
Раз это указатель на массив чисел, значит и должен быть массив чисел [MarshalAs(UnmanagedType.LPArray, SizeConst=255)] out uint[]. lpFileSystemFlags A pointer to a variable that receives flags associated with the specified file system.
Раз это возвращаемое число, значит out uint. P.S. Кстати, функция помечена как WINAPI, значит в DllImport ещё флажок добавить CallingConvention = CallingConvention.Winapi.
|
|
« Последнее редактирование: 15-01-2012 07:42 от dimka »
|
Записан
|
Программировать - значит понимать (К. Нюгард) Невывернутое лучше, чем вправленное (М. Аврелий) Многие готовы скорее умереть, чем подумать (Б. Рассел)
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #6 : 15-01-2012 09:31 » |
|
ну у меня не GetVolumeInformationByHandleW, а GetVolumeInformationW вот, сделал по аналогии namespace GetDriveSerialNumber { public partial class Form1:Form { public Form1() { InitializeComponent(); }
const int MAX_PATH=260;
[DllImport("Kernel32.dll" ,EntryPoint="GetVolumeInformationW" ,CallingConvention=CallingConvention.Winapi ,CharSet=CharSet.Unicode )] public static extern int GetVolumeInformationW ( string lpRootPathName,
[MarshalAs(UnmanagedType.LPArray,SizeConst=MAX_PATH+1)] out char[] lpVolumeNameBuffer, uint nVolumeNameSize,
out uint lpVolumeSerialNumber, out uint lpMaximumComponentLength, out uint lpFileSystemFlags,
[MarshalAs(UnmanagedType.LPArray,SizeConst=MAX_PATH+1)] out char[] lpFileSystemNameBuffer, uint nFileSystemNameSize );
[DllImport("Kernel32.dll" ,EntryPoint="GetLastError" ,CallingConvention=CallingConvention.Winapi ,CharSet=CharSet.Unicode )] public static extern uint GetLastError ( );
private void but_getinfo_Click(object sender,EventArgs e) {
string lpRootPathName ="C:\\";
char[] lpVolumeNameBuffer; uint nVolumeNameSize = MAX_PATH;
uint lpVolumeSerialNumber ; uint lpMaximumComponentLength; uint lpFileSystemFlags ;
char[] lpFileSystemNameBuffer; uint nFileSystemNameSize = MAX_PATH;
if(0!=GetVolumeInformationW ( lpRootPathName , out lpVolumeNameBuffer , nVolumeNameSize , out lpVolumeSerialNumber , out lpMaximumComponentLength, out lpFileSystemFlags , out lpFileSystemNameBuffer , nFileSystemNameSize
) ) { int iii=1; }
uint err=GetLastError(); } } }
ругается теперь вот так: Добавлено через 46 минут и 38 секунд:кстати, вот нашёл класс для определения производителя и ещё некоторых параметров привода http://msdn.microsoft.com/en-us/library/windows/desktop/aa394346(v=vs.85).aspxэто, насколько я понял, библиотека WMI и для её использования нужно подключить следующие пространства using System.Management; using ROOT.CIMV2.Win32; но пространство ROOT - неизвестно
|
err1.gif (34.14 Кб - загружено 1774 раз.)
|
« Последнее редактирование: 17-01-2012 03:05 от Алексей1153++ »
|
Записан
|
|
|
|
Dimka
Деятель
Команда клуба
Offline
Пол:
|
|
« Ответ #7 : 15-01-2012 18:09 » |
|
Алексей1153++, строчки-то зачем в массивы? А MaximumComponentLength почему в массив не переделал?
Утомляешь невнимательностью.
|
|
« Последнее редактирование: 15-01-2012 18:12 от Dimka »
|
Записан
|
Программировать - значит понимать (К. Нюгард) Невывернутое лучше, чем вправленное (М. Аврелий) Многие готовы скорее умереть, чем подумать (Б. Рассел)
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #8 : 15-01-2012 19:07 » |
|
Dimka, при чём тут невнимательность! Я и не понял, что их надо массивом, это же одинокое число типа DWORD. Я со строками пытался как раз как смассивами работать. Ну ладно, ок, вернул строки, для чисел сделал массивы на 1 элемент [DllImport("Kernel32.dll" ,EntryPoint="GetVolumeInformationW" ,CallingConvention=CallingConvention.Winapi ,CharSet=CharSet.Unicode )] public static extern int GetVolumeInformationW ( string lpRootPathName,
out string lpVolumeNameBuffer, uint nVolumeNameSize,
[MarshalAs(UnmanagedType.LPArray,SizeConst=1)] out uint[] lpVolumeSerialNumber, [MarshalAs(UnmanagedType.LPArray,SizeConst=1)] out uint[] lpMaximumComponentLength, [MarshalAs(UnmanagedType.LPArray,SizeConst=1)] out uint[] lpFileSystemFlags,
out string lpFileSystemNameBuffer, uint nFileSystemNameSize );
и сообщение теперь показывается вот такое
|
err1.gif (41.78 Кб - загружено 1658 раз.)
|
|
Записан
|
|
|
|
Dimka
Деятель
Команда клуба
Offline
Пол:
|
|
« Ответ #9 : 15-01-2012 19:59 » |
|
using System; using System.Runtime.InteropServices; using System.Text;
namespace Problem {
class Program {
const int MAX_PATH = 260; const int BufferSize = MAX_PATH + 1;
[DllImport( "Kernel32.dll", EntryPoint = "GetVolumeInformationW", CallingConvention = CallingConvention.Winapi, CharSet = CharSet.Unicode )] static extern bool GetVolumeInformation( string lpRootPathName, StringBuilder lpVolumeNameBuffer, uint nVolumeNameSize, out uint lpVolumeSerialNumber, out uint lpMaximumComponentLength, out uint lpFileSystemFlags, StringBuilder lpFileSystemNameBuffer, uint nFileSystemNameSize );
static void Main(string[] arguments) { StringBuilder volumeNameBuffer = new StringBuilder(Program.BufferSize); uint volumeSerialNumber; uint maximumComponentLength; uint fileSystemFlags; StringBuilder fileSystemNameBuffer = new StringBuilder(Program.BufferSize); if ( GetVolumeInformation( "C:\\", volumeNameBuffer, Program.BufferSize, out volumeSerialNumber, out maximumComponentLength, out fileSystemFlags, fileSystemNameBuffer, Program.BufferSize ) ) { Console.WriteLine("Name:\t\t{0}", volumeNameBuffer); Console.WriteLine("\nSN:\t\t0x{0}", volumeSerialNumber.ToString("X")); Console.WriteLine("File name size:\t{0}", maximumComponentLength); Console.WriteLine("Flags:\t\t0x{0}", fileSystemFlags.ToString("X")); Console.WriteLine("File system:\t{0}", fileSystemNameBuffer); } else { Console.WriteLine("Fail."); } Console.ReadKey(); }
}
}
|
|
« Последнее редактирование: 15-01-2012 21:11 от Dimka »
|
Записан
|
Программировать - значит понимать (К. Нюгард) Невывернутое лучше, чем вправленное (М. Аврелий) Многие готовы скорее умереть, чем подумать (Б. Рассел)
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #10 : 16-01-2012 03:29 » |
|
Dimka, во, спасибо! StringBuilder - это то, чего не хватало, и никакого маршаллинга стало не надо ) Осталось ещё WMI победить как-то. Уж не буду тебя мучать, переключусь на Джона Добавлено через 5 часов, 11 минут и 26 секунд:вот имеется такой код, который вроде то, что надо using System.Management;
...
SelectQuery q = new SelectQuery("Win32_PhysicalMedia"); ManagementObjectSearcher s = new ManagementObjectSearcher(q);
StringBuilder sb = new StringBuilder();
foreach(ManagementObject drive in s.Get()) { sb.Append(drive.Properties["SerialNumber"].Value); sb.Append(drive.Properties["Manufacturer"].Value); sb.Append("\r\n"); }
но с одной проблемой - к sb добавляются лишь пустые строки , возвращаемые .Value . Что тут не так ?
|
|
« Последнее редактирование: 16-01-2012 08:40 от Алексей1153 »
|
Записан
|
|
|
|
zubr
Гость
|
|
« Ответ #11 : 16-01-2012 09:12 » |
|
Наверно так: foreach(ManagementObject drive in s.Get()) { sb.Append(drive["SerialNumber"]); sb.Append(drive["Manufacturer"]); sb.Append("\r\n"); }
|
|
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #12 : 16-01-2012 11:37 » |
|
zubr, нет, так тоже добавляются пустые строки
|
|
« Последнее редактирование: 16-01-2012 11:40 от Алексей1153++ »
|
Записан
|
|
|
|
Джон
просто
Администратор
Offline
Пол:
|
|
« Ответ #13 : 16-01-2012 11:54 » |
|
Попробуй.
|
|
|
Записан
|
Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома. "Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash "Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman "All science is either physics or stamp collecting." Ernest Rutherford "Wer will, findet Wege, wer nicht will, findet Gründe."
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #14 : 16-01-2012 20:34 » |
|
Джон, спасибо, круто работает По аналогии вытащил нужный класс - Win32_CDROMDrive
|
|
|
Записан
|
|
|
|
|