XCopy или MOVE не работают, когда служба WCF запускает пакетный файл. Зачем?

Я сталкивался со случаем, когда один и тот же пакетный файл работает не так, как в командной строке, и когда он запускается из службы WCF, размещенной в IIS. Разница в команде XCOPY. когда я запускаю командный файл в обычном режиме, XCOPY перемещает все нужные мне данные

XCOPY "C:\from" "C:\to" /K /R /E /I /S /C /H /G /X /Y

но когда он запускается из службы WCF, ничего не копируется. для запуска пакета из моего сервиса я использую следующий код Executing Batch File в C# с небольшими изменениями. Моя заявка работает под учетной записью LocalSystem. Я также пытался использовать свою учетную запись для опроса приложений - не работает. что случилось?

Краткое обновление: недавно я узнал, что моя служба WCF работает под пользователем пула приложений, но этот процесс не выполняется. В целях эксперимента я сделал обновление в коде запуска процесса

var pwdArray = "mypassword".ToArray();
var pwd = new System.Security.SecureString();

Array.ForEach(pwdArray, pwd.AppendChar);
processInfo.UserName = "myuser";

processInfo.Password = pwd;
processInfo.Domain = "LocalMachine";

но это не помогает. Кажется, есть мистик в запуске XCOPY в описанных условиях.

Еще одно обновление: та же проблема с XCopy также обнаружена в процессе, который запускается под обычной службой Windows.

3 ответа

Решение

Мне удалось решить мою проблему благодаря этому посту ( http://social.msdn.microsoft.com/Forums/vstudio/fr-FR/ab3c0cc7-83c2-4a86-9188-40588b7d1a52/processstart-of-xcopy-only-works-under-the-debugger?forum=netfxbcl), поэтому на самом деле ответ таков:

Это причуда xcopy.exe. Если вы перенаправляете вывод, вы должны также перенаправить ввод.

        var command = "XCOPY ...."
        processInfo = new ProcessStartInfo("cmd.exe", "/c " + command);
        processInfo.CreateNoWindow = true;
        processInfo.UseShellExecute = true;
        // *** Redirect the output ***
        // unfortunately you cannot do it for X Copy

        //processInfo.RedirectStandardError = true;
        //processInfo.RedirectStandardOutput = true;


        process = Process.Start(processInfo);
        process.WaitForExit();

Вы можете использовать режим совместимости ASP.NET, чтобы служба WCF выдавала себя за определенного пользователя. Это не требует, чтобы ваш AppPool работал под этим пользователем.

Есть 3 этапа:

Включить режим совместимости ASP.NET

   <system.serviceModel>
       ...
       <serviceHostingEnvironment ... aspNetCompatibilityEnabled="true"/>
   </system.serviceModel>

Настройте службу для использования режима совместимости ASP.NET

[AspNetCompatibilityRequirements(RequirementsMode=AspNetCompatibilityRequirementsMode.Required]
public class MyService : IMyService
{
    public void DoTheCopying()
    {
    ...
    }
}

и настроить олицетворение ASP.NET для олицетворения пользователя

<system.web>
    <identity impersonate="true" username="user" password="pass" />
</system.web>

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

В рекомендациях по безопасности IIS Microsoft ( http://technet.microsoft.com/en-us/library/jj635855.aspx) говорится, что использование учетной записи настраиваемого домена допустимо:

Цитата Использование пользовательской учетной записи допускается, но обязательно используйте разные учетные записи для каждого пула приложений.

По соображениям безопасности ApplicationPoolIdentity по умолчанию довольно заблокирован, этот КБ относится к другой проблеме, но должен дать представление о проблемах, с которыми вы можете столкнуться при решении этой проблемы: http://support.microsoft.com/kb/2005172

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

И последнее, но не менее важное: Process Monitor и Process Explorer от Microsoft Sysinternals являются отличными инструментами для исследования этого класса проблем, если изменение удостоверения пула приложений на учетную запись настраиваемого домена не позволяет точно определить проблему, я рекомендую использовать их для поиска больше подсказок.

Некоторые ссылки на учетные записи управляемых сервисов

Другие вопросы по тегам