需要将Windows服务与非管理员用户进程同步

时间:2011-10-21 20:27:35

标签: .net windows-services ipc mutex privileges

我正在使用(.NET2.0)服务定期执行特权操作,并通过IPC将结果返回到共享内存,并使用非管理员用户(.NET2.0)进程。

我从管理员帐户开发时一直使用全局命名的互斥锁,但当我在有限的帐户上尝试应用程序时,我收到错误:

  

其他信息:拒绝访问“Global \ timersyncu33sc3c2sd42frandomlynamedmutexoijfvgf9v3f32”路径。

非特权用户是否可以通过其他方式与服务进行交互?或者我应该只分享轮询和更新时间,并希望这些值以原子方式写入/读取?

2 个答案:

答案 0 :(得分:1)

我会使用WCF与服务交谈。这消除了特权/身份问题。 但是,由于您的代码是在.NET 2.0中,因此可以使用Remoting或NamedPipes与服务进行通信。

答案 1 :(得分:0)

我找到了以下方法,在登录并启动GUI时授予我的受限用户访问权限。请注意,函数getUsername(/*somehow*/);有几个版本,我没有列出适用于XP的实现,我确信还有其他方法,但我找到的4个中有3个对我不起作用。

void grantMutexToCurUser(Mutex ^%fpMutex) {
    try {
        fpMutex = Mutex::OpenExisting( ServerGUIBridge::NAMEDMUTEXFORTIMERSYNC,
            static_cast<MutexRights>(
            MutexRights::ReadPermissions | MutexRights::ChangePermissions) );

        MutexSecurity^ mSec = fpMutex->GetAccessControl();
        String^ user;

        try {
            user = getUsername(/*somehow*/);
            Trace::WriteLine( DateTime::Now.ToLongTimeString() + " - Granting mutex access to: " 
                + user , "grantMutexToCurUser" );
        } catch (Exception ^ex) {
            Trace::WriteLine( "getUsername: " + ex->Message, "grantMutexToCurUser" );
        }

        // First, the rule that denied the current user the right to enter and
        // release the mutex must be removed.
        MutexAccessRule^ rule = gcnew MutexAccessRule( user,
            static_cast<MutexRights>(MutexRights::Synchronize
            | MutexRights::Modify), AccessControlType::Deny );
        mSec->RemoveAccessRule( rule );

        // Now grant the user the correct rights.
        rule = gcnew MutexAccessRule( user,
            static_cast<MutexRights>(MutexRights::Synchronize
            | MutexRights::Modify), AccessControlType::Allow );
        mSec->AddAccessRule( rule );

        fpMutex->SetAccessControl( mSec );

        // Open the mutex with (MutexRights.Synchronize | MutexRights.Modify), the
        // rights required to enter and release the mutex.
        fpMutex = Mutex::OpenExisting( ewfmon::ServerGUIBridge::NAMEDMUTEXFORTIMERSYNC );
        //noThrowRelease(fpMutex);
    }
    catch ( UnauthorizedAccessException^ ex ) 
    {
        Trace::WriteLine( DateTime::Now.ToLongTimeString() + " - Unable to change permissions: "
            + ex->Message, "grantMutexToCurUser" );
    }
}