Ogoun Er: Я именно так и делаю, т.е использую WindowsImpersonationContext. Используя логин и пароль пользователя в рамках этого контекста я могу выполнять какие-то действия с правами этого пользователя. Но проблема в том, что если этим пользователем, например, является тот пользователь который был создан первым при установке Windows (он входит в группу "Администраторы") попытаться поднять или опустить сетевой интерфейс, то этого сделать не получиться, прав для этого у него не достаточно. Для этого нужен пользователь Администратор, который отключён по умолчанию. Тут прослеживается аналогия с тем, что даже если зайти в систему под учётной записью того первого пользователя, то всё равно, при действиях, которые требуют административных прав всё равно будет появляться запрос UAC. Т.о получается, что в рамках этого контекста права поднять можно, но их всё равно оказывается недостаточно для выполнения административных действий.
Михаил: Можно и так конечно. Можно и процесс запустить изначально с правами уч. записи Администратор. Но не хотелось бы создавать отдельных компонентов (процессов или служб), если без них можно обойтись и сделать всё из своего кода. Если это возможно, конечно.
Скажите, пожалуйста, а будет ли правильно если я буду подключать к View коллекцию которая будет содержать экземпляры Model, а не ViewModel? Под моделью я подразумеваю класс, который как раз содержит информацию о свойствах файла. Я думаю, что отдельная ViewModel ему не нужна, поэтому можно ли подключить коллекцию с моделями напрямую к представлению, минуя приедставление-модель?
Скорее всего именно так и сделаю. Мне просто хотелось чтобы в MainViewModel не было ничего больше относящегося к подчинённым ViewModel-м, чтобы вся логика была спрятана в RemoteClientViewModel, но по-видимому так сделать в данном случае не получилось бы.
Я называю это коллекцией, потому что исхожу из следующей логики. RemoteClientViewModel "знает" о конкретном экземпляре класса клиента, к которому подключена программа и может совершать с ним некоторые действия: отправлять или скачивать файлы, получать информацию о наличии доступного/занятого места на диске, подключаться и отключаться от него. И кроме того, именно эта VievModel содержит список файлов подключенного клиента. А поскольку это и есть коллекция, а в WPF принято использовать ObservableCollection в силу её свойств, то я и говорю "коллекция".
Спасибо, но пока не понятно. Как я вижу себе структуру:
MainWindow(View)-????(ViewModel)-ProgramReadState(Model);
MainWindow(View)-????(ViewModel)-DBConnectState(Model).
Класс отвечающий за чтение настроек загрузит настройки, произведёт изменения в модели ProgramReadState. Тоже самое и для подключения к базе данных. Но что должен делать ViewModel?
Nipheris: В релизе не пробовал. На других машинах запускается нормально: ПК с Windows 7 и виртуальная машина с Windows 8.1, а также виртуальная машина с Windows XP. Забыл написать. Под "запуском" я подразумеваю запуск отладки по F5, т.е вне отладчика это исключение не появляется. Также хочу добавить, что исключение стало появляться после установки NET Reflector и первый раз возникло в консольном приложении.
Текст исключения:
System.AccessViolationException не обработано
Message: Необработанное исключение типа "System.AccessViolationException" в System.Windows.Forms.dll
Дополнительные сведения: Попытка чтения или записи в защищенную память. Это часто свидетельствует о том, что другая память повреждена.
lam0x86: Спасибо, но мой случай как раз вот этот: "Либо по одному объекту на каждое поле класса, чтобы можно было менять (или читать) разные поля одновременно из нескольких потоков". Каждое поле в этом классе изменяется в своей задаче (кроме readAtLeastOneFile, она меняется там же где и filesRead), поэтому одну переменную для блокирования использовать нельзя, но, как я теперь понимаю, нельзя использовать и отдельные переменные для get и set. Тогда получается, что ещё одна переменная для синхронизации в методе CheckReadyUpload() не нужна.
Итак, одна переменная для синхронизации на каждое поле класса, а в методе CheckReadyUpload переменную lockObj я уберу, но к полям класса я буду обращаться в методе, как и везде, через свойства.
Таким образом, класс будет выглядеть вот так:
public static class ReadyUpload
{
static readonly object lockFilesRead = new object();
static bool filesRead;
//Остальные поля убраны для краткости.
public static bool FilesRead
{
get
{
bool tmp;
lock (lockFilesRead)
{
tmp = filesRead;
}
return tmp;
}
set
{
lock (lockFilesRead)
{
filesRead = value;
}
}
}
public static bool CheckReadyUpload()
{
if (FilesRead)
{
}
//...
}
}
Поправьте меня, пожалуйста, если я не прав.
Спасибо. Мне хотелось бы инкапсулировать работу с блокировками в самом классе (поместить блокирование в свойства). Я буду использовать Monitor. Вопрос: для каждого поля класса надо будет создать свою переменную для которой получается блокировка? Я так понимаю, что нельзя использовать одну переменную для блокирования всех полей?
public static class ReadyUpload
{
static bool filesRead, readAtLeastOneFile, listsReceived, excelIsRunning;
public static bool FilesRead
{
get
{
bool tmp;
object lockObj = new object();
Monitor.Enter(lockObj);
tmp = filesRead;
Monitor.Exit(lockObj);
return tmp;
}
set
{
object lockObj = new object();
Monitor.Enter(lockObj);
filesRead = value;
Monitor.Exit(lockObj);
}
}
//...
public static bool CheckReadyUpload()
{
object lockObj = new object();
Monitor.Enter(lockObj);
//...
Monitor.Exit(lockObj);
}
}
DISaccount: Спасибо. Но почему тогда первая перегрузка метода wait, работает иначе? Т.е при её использовании поток разблокируется только тогда, когда будет получен сигнал.
Это да, но тогда получается разблокировка зависит не от получения сигнала, а от значения которое возвращает предикат(true или false)? Как я понимаю эта проверка нужна для того, чтобы при ПОЛУЧЕНИИ сигнала исключить т.н "случайный выход".