0

我正在构建一个 mac 应用程序,它在某个时间需要将当前登录的用户切换到不同的预设用户。本质上是一个修改后的登录窗口。

有没有办法用可可做到这一点?

——阿里

编辑:有没有办法不要求用户输入密码?

4

2 回答 2

2

在我说出我的解决方案之前,我想说@jrodatus 的答案非常好,它只是针对稍微不同的用例。

我想出了这个小applescript:

set theUser to "user"
set theUser to do shell script "/usr/bin/id -u " & theUser
set password to "pswd"
do shell script "/System/Library/CoreServices/Menu\\ Extras/User.menu/Contents/Resources/CGSession -switchToUserID " & theUser
repeat
    try
        tell application "System Events"
            repeat until visible of process "SecurityAgent" is false
                set visible of process "SecurityAgent" to false
            end repeat
            keystroke password
            keystroke return
        end tell
        exit repeat
    on error
        tell application "System Events"
        end tell
    end try
end repeat

这只是触发登录屏幕,-switchToUserID设置为用户名的用户 ID。然后当(登录界面)的至少一个窗口SecurityAgent可见时,模拟密码的击键,然后输入结果是运行时打开登录窗口,输入密码。此外,这没有延迟。

于 2013-11-29T15:04:45.560 回答
1

正如在回答类似问题here中所解释的那样,系统文件夹中隐藏了一个名为“CGSession”的命令行工具,它应该可以满足您的需求。要在 Cocoa 应用程序中运行命令行工具,请查看 NSTask。

直接切换用户,通过运行“id -u theUserName”找出你预设用户的unix用户ID,然后使用输出作为参数执行:

/System/Library/CoreServices/Menu\ Extras/User.menu/Contents/Resources/CGSession -switchToUserID theUserIDNumber

或者只是进入登录窗口(不注销),运行:

/System/Library/CoreServices/Menu\ Extras/User.menu/Contents/Resources/CGSession -suspend

这是 NSWorkspace 的快速 Obj-C 类别。

NSWorkspace-SwitchUser.h:

#import <Cocoa/Cocoa.h>

@interface NSWorkspace (SwitchUser)
-(BOOL)switchToUser:(NSString *)userName;
@end

NSWorkspace-SwitchUser.m:

#import "NSWorkspace-SwitchUser.h"
#import <sys/types.h>
#import <pwd.h>
#import <stdlib.h>
#import <unistd.h>
#import <stdio.h>

@implementation NSWorkspace (SwitchUser)

-(BOOL)switchToUser:(NSString *)userName {
    struct passwd *pwd = malloc(sizeof(struct passwd));
    if (!pwd) {
        NSLog(@"Couldn't allocate struct passwd for getpwnam_r.");
        return FALSE;
    }

    size_t buf_len = sysconf(_SC_GETPW_R_SIZE_MAX) * sizeof(char);
    char *buffer = malloc(buf_len);
    if (!buffer) {
        NSLog(@"Couldn't allocate buffer for getpwnam_r.");
        return FALSE;
    }

    getpwnam_r([userName UTF8String], pwd, buffer, buf_len, &pwd);
    if (!pwd) {
        NSLog(@"getpwnam_r failed to find the requested user.");
        return FALSE;
    }

    uid_t userID = pwd->pw_uid;

    free(pwd);
    free(buffer);

    // Run CGSession with the -switchToUserID argument
    NSTask *cgsTask = [NSTask launchedTaskWithLaunchPath:@"/System/Library/CoreServices/Menu Extras/User.menu/Contents/Resources/CGSession" 
                                               arguments:[NSArray arrayWithObjects:@"-switchToUserID",[NSString stringWithFormat:@"%u",userID],nil]];

    // Wait till the task completes.
    // Should be able to use -[NSTask waitUntilExit] instead, but it wasn't working for me :-P
    while ([cgsTask isRunning]) {
        usleep(100000);
    }

    return ([cgsTask terminationStatus] == 0);
}

@end

编辑:如果您需要在不要求用户输入密码的情况下切换用户,那么没有 AppleScript 似乎没有任何方法可以做到这一点,IMO 在任何意义上都是不安全的。但是你可能会在这里这里收集你需要的东西。

于 2013-11-28T05:38:20.453 回答