Я добавляю публикацию WMI в службу Windows на основе .net Framework 3.5, которая работает под учетной записью «сетевой службы».
Согласно документу , с которым я столкнулся на MSDN , учетная запись «сетевой службы» по умолчанию должна иметь разрешения на публикацию WMI. (" По умолчанию следующие пользователи и группы могут публиковать данные и события: ... Сетевая служба , ... ")
Однако, когда служба вызывает Instrumentation.Publish (myStatusClassInstance), она выдает исключение DirectoryNotFoundException;
System.IO.DirectoryNotFoundException was unhandled
Message: Could not find a part of the path 'C:\Windows\system32\WBEM\Framework\root\MyWMINamespace\MyService_SN__Version_1.0.3686.26280.cs'.
.. похоже, что System.Management.Instrumentation пытается сгенерировать код на лету, а при работе в сетевой службе выбирает каталог, для которого у сетевой службы нет разрешений.
Как лучше всего это исправить? Могу ли я переопределить целевой каталог code-gen в app.config или в коде? Я не хочу возиться с разрешениями файловой системы при развертывании службы ...
Обновление : я думаю, что это «особенность», когда старый код FX вступает в противоречие с новыми настройками безопасности в Win7. Внутри себя управляемые классы WMI извлекают каталог установки WMI из реестра и используют его в качестве пути вывода для сгенерированного кода. К сожалению, многим пользователям не разрешено (или предполагается) писать что-то под% SystemRoot% ... ... Я подал ошибку подключения ( # 530392 ), чтобы посмотреть, сможет ли MSFT внести ясность и / или предоставить исправление или обходной путь.
Обновление 2: Я предполагаю, что для обычных учетных записей пользователей это не проблема, потому что виртуализация UAC включится и сохранит файлы в другом месте. Однако, очевидно, учетная запись «сетевой службы» не покрывается виртуализацией UAC. (?)
Обновление 3: Добавлена награда 550pt. Простые ограничения: служба Windows на основе .net framework 3.5, работающая как сетевая служба, должна иметь возможность публиковать данные через WMI с использованием System.Management.Instrumentation в Win7 и Win2008 [RTM & R2] с разрешениями / параметрами безопасности по умолчанию и без обращения к модификация фреймворка внутренними / приватными членами с помощью отражения. «Из коробки», но чистые решения приветствуются. Откроет второй связанный bounty-Q в качестве заполнителя для другого 550pt, если SO позволяет.
Обновление вознаграждения: Я намерен удвоить вознаграждение за этот вопрос путем повторного ручного вопроса, который будет служить заполнителем вознаграждения:
https://stackoverflow.com/questions/2208341/bounty-placeholder (<- По-видимому, это было запрещено, поэтому вопрос о заполнителях был закрыт полицией этикета SO.) </p>
Обновление 4: Это становится все лучше и лучше. Я заметил, что installutil записывал недостающие файлы в c: \ windows \ syswow64 ... и т.д ..., поэтому я понял, что для установки службы я использовал 32-разрядную версию installutil, но служба работала как 64-битный процесс. Очевидным побочным эффектом было то, что код, сгенерированный во время работы installutil, оказался в syswow64 (32-разрядный системный каталог), а служба искала его в 64-разрядном системном каталоге (system32). (<- не по теме, но мне очень нравится, как MSFT удалось переключаться между именами там ... :)). </p>
Поэтому я попытался установить службу с 64-разрядной версией installutil. Это с треском провалилось из-за ошибок разрешения в пути% sysroot% \ wbem \ framework ... etc ... Затем я перекомпилировал сервис как x86 и зарегистрировал его снова, используя 32-битную версию installutil. Это привело к совершенно новому исключению:
System.Exception: The code generated for the instrumented assembly failed to compile.
at System.Management.Instrumentation.InstrumentedAssembly..ctor(Assembly assembly, SchemaNaming naming)
at System.Management.Instrumentation.Instrumentation.Initialize(Assembly assembly)
at System.Management.Instrumentation.Instrumentation.GetInstrumentedAssembly(Assembly assembly)
at System.Management.Instrumentation.Instrumentation.GetPublishFunction(Type type)
at System.Management.Instrumentation.Instrumentation.Publish(Object instanceData)
at SomeService.InstanceClass.PublishApp(String name) in e:\work\clientname\SomeService\SomeService\WMIProvider.cs:line 44
at SomeService.SomeServiceService..ctor() in e:\work\clientname\SomeService\SomeService\SomeServiceService.cs:line 26
at SomeService.Program.Main() in e:\work\clientname\SomeService\SomeService\Program.cs:line 17
... все ближе ...