从.NET服务作为其他用户启动.NET应用程序时的权限问题?

And*_*man 24 .net c# service

我正在尝试在.NET服务的不同用户下启动.NET应用程序.我们的想法是在Windows中创建一个沙盒托管应用程序.在服务中,我以编程方式在Windows中创建用户,为该用户创建文件夹,并将主机.exe从服务器下载到该文件夹​​中.然后我使用System.Diagnostics.Process运行主机.exe.这是该过程的StartInfo:

_process = new Process
{
    StartInfo =
    {
        Arguments = " -debug",
        FileName = instanceDirectory + "host.exe",
        WorkingDirectory = instanceDirectory,
        UseShellExecute = false,
        RedirectStandardError = true,
        RedirectStandardOutput = true,
        RedirectStandardInput = true,
        UserName = Helpers.GetUserNameForInstance(_hostid),
        Password = _hostpass,
        Domain = ""
    },
    EnableRaisingEvents = true
};
Run Code Online (Sandbox Code Playgroud)

当我将服务作为SERVICE运行时,进程立即崩溃,错误代码为-1073741502.但是,当我在Windows服务中指定的同一用户运行服务但在控制台中以交互方式运行时,一切正常.只有在将服务作为SERVICE运行而不是直接在控制台中运行时才会发生这种情况.

任何帮助将非常感激.这已经很长一段时间了,这是最后的手段:(

Gyu*_*uri 14

看起来像使用new Process()用户名和密码和服务模式"不计算":)

从MSDN引用:

您可以将StartInfo属性中指定的参数更改为在进程上调用Start方法的时间.启动该过程后,更改StartInfo值不会影响或重新启动关联的进程.如果使用ProcessStartInfo .. ::.UserName和ProcessStartInfo .. ::.密码属性设置调用Start(ProcessStartInfo)方法,则调用非托管CreateProcessWithLogonW函数,即使CreateNoWindow属性值,也会在新窗口中启动该进程为true或WindowStyle属性值为Hidden.

此外,查看CreateProcessWithLogonW文档:

lpStartupInfo [in]

指向STARTUPINFO结构的指针.应用程序必须将指定用户帐户的权限添加到指定的窗口站和桌面,即使对于WinSta0\Default也是如此.

如果lpDesktop成员为NULL或空字符串,则新进程将继承其父进程的桌面和窗口站.应用程序必须将指定用户帐户的权限添加到继承的窗口站和桌面.

.NET StartupInfo中没有lpDesktop,另一方面,SERVICE用户没有桌面,这可能会导致您的问题.

长话短说,尽量设置LoadUserProfiletrue从注册表中读取用户的信息,或者你需要设置工作目录,等等.

要进一步调查,您应该检查您的环境,并可能使用FileMon记录访问哪些文件.


Sea*_*ish 5

我将尝试在新创建的用户的模拟上下文中创建进程,如下所示.

[DllImport("advapi32.DLL", SetLastError = true)]
public static extern int LogonUser(string lpszUsername, string lpszDomain, string lpszPassword, int dwLogonType, int dwLogonProvider, out IntPtr phToken);

[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
public extern static bool CloseHandle(IntPtr handle);

[DllImport("advapi32.DLL")]
public static extern bool ImpersonateLoggedOnUser(IntPtr hToken);

static void Main()
{             
    IntPtr admin_token = new IntPtr();
    WindowsIdentity wid_admin = null;
    WindowsImpersonationContext wic = null;

    LogonUser("username", "domain", "password", 9, 3, out admin_token);
    wid_admin = new WindowsIdentity(admin_token);
    wic = wid_admin.Impersonate();

    _process = new Process
    {
        StartInfo =
        {
            Arguments = " -debug",
            FileName = instanceDirectory + "host.exe",
            WorkingDirectory = instanceDirectory,
            UseShellExecute = false,
            RedirectStandardError = true,
            RedirectStandardOutput = true,
            RedirectStandardInput = true,
            UserName = Helpers.GetUserNameForInstance(_hostid),
            Password = _hostpass,
            Domain = ""
        },
        EnableRaisingEvents = true
    };

    if (wic != null) wic.Undo();
    CloseHandle(admin_token);
}
Run Code Online (Sandbox Code Playgroud)


Pau*_*cer 3

服务器之间的双跳可能会导致服务凭据丢失,也许设置 Kerberos 可以解决此问题。

http://neverknewthat.wordpress.com/2009/05/14/kerberos/