XCopy or MOVE do not work when a WCF Service runs

2020-08-26 10:54发布

I have faced a case when the same batch file works differently from command line and when it is fired from a WCF service hosted on IIS. The difference is in XCOPY command. when I am running the batch file normally than XCOPY moves all data I need

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

but when it runs from the WCF service nothing is copied. for running the batch from my service I am using the following code Executing Batch File in C# whith some little modifications. My Application pull is running under LocalSystem account. I also tryed to use my own account for the application poll - does not work. what is wrong?

Short update: What I have learned recently is that my WCF service is running under the App Pool User, but the process isn't. In purpose of experiment I have made an update in the process-start code

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

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

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

but it does not help. Seems there is a mystic in running XCOPY under described conditions.

One more update: The same problem with XCopy is also found in a process that starts under a regular windows service.

3条回答
走好不送
2楼-- · 2020-08-26 11:12

You can use ASP.NET compatibility mode to let the WCF service impersonate a certain user. This does not require your AppPool to run under that user.

There are 3 steps involved:

Enable ASP.NET compatibility mode

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

Configure your service to use the ASP.NET compatibility mode

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

and configure ASP.NET impersonation to impersonate a user

<system.web>
    <identity impersonate="true" username="user" password="pass" />
</system.web>
查看更多
\"骚年 ilove
3楼-- · 2020-08-26 11:13

Have you tried running the application pool identity under a custom domain account? As a test you may try using your own account, although I'd not advice to keep using that on the long run, as decrypting passwords used on IIS app pools is trivial, and you would need to maintain it every time you change your own password.

Microsoft says in the IIS security best practices (http://technet.microsoft.com/en-us/library/jj635855.aspx#AppPools) that using a custom domain account is acceptable:

Blockquote Using a custom identity account is acceptable, but be sure to use a different account for each application pool.

For security reasons the default ApplicationPoolIdentity is quite locked down, this KB referees to a different issue, but should give an idea of the issues you may encounter when dealing with that: http://support.microsoft.com/kb/2005172

I hope you don't take it as a unwarranted criticism, but you should probably have showed us all the meaningful snippet of code involved. The specific reason in this case is that when you call a process, is generally a very good idea to get the exit status, but I'm not sure you are doing it or not. The exit status may give us some clue on what is going on.

Last but not least, Process Monitor and Process Explorer from Microsoft Sysinternals are great tools to investigate this class of issues, if changing the application pool identity to a custom domain account doesn't pinpoint the issue, I'd recommend using those to search for more clues.

Some references about managed services accounts

查看更多
虎瘦雄心在
4楼-- · 2020-08-26 11:15

Managed to solve my poblem thanks to this post (http://social.msdn.microsoft.com/Forums/vstudio/fr-FR/ab3c0cc7-83c2-4a86-9188-40588b7d1a52/processstart-of-xcopy-only-works-under-the-debugger?forum=netfxbcl) so actually the answer is:

This is a quirk of xcopy.exe. If you redirect the output, you have to redirect the input as well.

        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();
查看更多
登录 后发表回答