是否有Api,可以将屏幕锁定为可从钥匙串首选项添加的菜单项?在mac os中通过api锁定屏幕X
回答
我没有看到任何记录本身,而是菜单使用屏幕保护程序框架,它定义了这一点:
@interface ScreenSaverDefaults : NSUserDefaults
{
@private
NSMutableDictionary *_defaults;
NSMutableDictionary *_registeredDefaults;
NSString *_userName;
NSString *_domainName;
BOOL _dirty;
BOOL _screenLockPrefChanged;
}
+ (id) defaultsForModuleWithName:(NSString *)inModuleName;
@end
要锁定屏幕,请致电:
/系统/库/ CoreServices /菜单\ 其他/ User.menu /内容/资源/ CGSession -suspend
这只是踢我到登录屏幕。 (不是OP) – seaturtle 2017-11-07 21:04:05
这确实会锁定屏幕,但也要求您重新输入您的登录名(不仅仅是密码)...(可能是“Preston”的原始答案) – rogerdpack 2017-12-28 19:23:22
普雷斯顿是正确的,我用下面的方法,它就像一个魅力:
- (void)lockScreen {
NSTask *task;
NSArray *arguments = [NSArray arrayWithObject:@"-suspend"];
task = [[NSTask alloc] init];
[task setArguments: arguments];
[task setLaunchPath: @"/System/Library/CoreServices/Menu Extras/User.menu/Contents/Resources/CGSession"];
[task launch];
[task release];
NSLog(@"screen is Locked");
}
如果你真的想要做什么钥匙串并(即只锁定屏幕,不用去登录窗口),这是相当容易:
io_registry_entry_t r = IORegistryEntryFromPath(kIOMasterPortDefault, "IOService:/IOResources/IODisplayWrangler");
if (r) {
IORegistryEntrySetCFProperty(r, CFSTR("IORequestIdle"), sleep ? kCFBooleanTrue);
IOObjectRelease(r);
}
但是,这只适用于用户在睡眠或屏幕保护程序开始时要求密码设置为'立即'的情况。但是,您可以立即为它们设置它,然后将其设置回完成时的状态。事实证明,要生效可能会非常棘手(更多信息,请参阅this answer),但可以完成。把它放在一起,你有这样的:
- (void)lockScreen;
{
int screenSaverDelayUserSetting = 0;
screenSaverDelayUserSetting = [self readScreensaveDelay];
if (screenSaverDelayUserSetting != 0) {
// if the delay isn't already 0, temporarily set it to 0 so the screen locks immediately.
[self setScreensaverDelay:0];
[self touchSecurityPreferences];
}
io_registry_entry_t r = IORegistryEntryFromPath(kIOMasterPortDefault, "IOService:/IOResources/IODisplayWrangler");
if (r) {
IORegistryEntrySetCFProperty(r, CFSTR("IORequestIdle"), sleep ? kCFBooleanTrue : kCFBooleanFalse);
IOObjectRelease(r);
}
if (screenSaverDelayUserSetting != 0) {
[self setScreensaverDelay:screenSaverDelayUserSetting];
[self launchAndQuitSecurityPreferences];
}
}
- (void)touchSecurityPreferences;
{
// necessary for screen saver setting changes to take effect on file-vault-enabled systems
// NOTE: this *only* works when going from non-zero settings of askForPasswordDelay to zero.
NSAppleScript *kickSecurityPreferencesScript = [[[NSAppleScript alloc] initWithSource: @"tell application \"System Events\" to tell security preferences to set require password to wake to true"] autorelease];
[kickSecurityPreferencesScript executeAndReturnError:nil];
}
- (void)launchAndQuitSecurityPreferences;
{
// necessary for screen saver setting changes to take effect on file-vault-enabled systems when going from a askForPasswordDelay setting of zero to a non-zero setting
NSAppleScript *kickSecurityPreferencesScript = [[[NSAppleScript alloc] initWithSource:
@"tell application \"System Preferences\"\n"
@" tell anchor \"General\" of pane \"com.apple.preference.security\" to reveal\n"
@" activate\n"
@"end tell\n"
@"delay 0\n"
@"tell application \"System Preferences\" to quit"] autorelease];
[kickSecurityPreferencesScript executeAndReturnError:nil];
}
- (int)readScreensaveDelay;
{
NSArray *arguments = @[@"read",@"com.apple.screensaver",@"askForPasswordDelay"];
NSTask *readDelayTask = [[[NSTask alloc] init] autorelease];
[readDelayTask setArguments:arguments];
[readDelayTask setLaunchPath: @"/usr/bin/defaults"];
NSPipe *pipe = [NSPipe pipe];
[readDelayTask setStandardOutput:pipe];
NSFileHandle *file = [pipe fileHandleForReading];
[readDelayTask launch];
NSData *resultData = [file readDataToEndOfFile];
NSString *resultString = [[NSString alloc] initWithData:resultData encoding:NSUTF8StringEncoding];
return resultString.intValue;
}
- (void)setScreensaverDelay:(int)delay;
{
NSArray *arguments = @[@"write",@"com.apple.screensaver",@"askForPasswordDelay", [NSString stringWithFormat:@"%i", delay]];
NSTask *resetDelayTask = [[[NSTask alloc] init] autorelease];
[resetDelayTask setArguments:arguments];
[resetDelayTask setLaunchPath: @"/usr/bin/defaults"];
[resetDelayTask launch];
}
产生另一个进程只是运行/ usr/bin/defaults似乎非常过分和严厉。您是否有理由避免使用CFPreferences API? – Draxillion 2014-03-05 19:40:30
不幸的是阅读屏幕保护程序延迟将不会在10.13上工作。 – 2018-01-02 11:15:05
要锁定计算机,并显示最近的用户密码PROMT您可以使用此代码:
- (void)lockScreen
{
MDSendAppleEventToSystemProcess(kAESleep);
}
OSStatus MDSendAppleEventToSystemProcess(AEEventID eventToSendID)
{
AEAddressDesc targetDesc;
static const ProcessSerialNumber kPSNOfSystemProcess = {0, kSystemProcess};
AppleEvent eventReply = {typeNull, NULL};
AppleEvent eventToSend = {typeNull, NULL};
OSStatus status = AECreateDesc(typeProcessSerialNumber,
&kPSNOfSystemProcess, sizeof(kPSNOfSystemProcess), &targetDesc);
if (status != noErr) return status;
status = AECreateAppleEvent(kCoreEventClass, eventToSendID,
&targetDesc, kAutoGenerateReturnID, kAnyTransactionID, &eventToSend);
AEDisposeDesc(&targetDesc);
if (status != noErr) return status;
status = AESendMessage(&eventToSend, &eventReply,
kAENormalPriority, kAEDefaultTimeout);
AEDisposeDesc(&eventToSend);
if (status != noErr) return status;
AEDisposeDesc(&eventReply);
return status;
}
这使系统进入睡眠状态,kAESleep。锁屏只是一个副作用。 – 2015-02-13 22:36:33
这不是正式文件,并使用私有API,但在Mac OS 10.10(也许还更早的系统)以下工作:
// lockscreen.c
extern void SACLockScreenImmediate ();
int main()
{
SACLockScreenImmediate();
return 0;
}
建设有:
clang -F /System/Library/PrivateFrameworks -framework login -o lockscreen lockscreen.c
现在调用./lockscreen
将立即锁定屏幕,无论用户在其安全首选项中配置了什么(是否锁定屏幕保护程序/系统休眠)并且无需登录用户。这是系统内部用于记录屏幕的功能。我很强烈地不鼓励使用它,它可能会破坏你的应用程序,我甚至不确定我是否正确地调用它(也许它需要参数,也许它有一个返回值),所以它甚至可能会破坏你的整个系统(暂时 - 重启将修复一切),谁知道。我只是想在某个地方发布文档。也许有更好的黑客技能的人可以再分析一下这个电话。
int _SACLockScreenImmediate(){ rax = * _kLFDBFlag_SA_ScreenSaver; ((*(_(gDBLoggingMasks +(rax >> 0x3c)* 0x8)&rax)!= 0x0)rbx = CFStringCreateWithFormat(* _kCFAllocatorDefault,0x0,@“%s:enter”); DBLoggingLogWithFormat(* _ kLFDBFlag_SA_ScreenSaver,@“%s:%d:%@”,“SACLockScreenImmediate”,0x1fe,rbx); CFRelease(rbx); } rbx = _CreateArgumentsForFunction(@“SACLockScreenImmediate”,0x0); \t .... return rax; } – slboat 2015-12-19 03:38:28
它工作的很好,它没有参数,但有一个返回值 – slboat 2015-12-19 03:38:47
在High Sierra FWIW中工作得很好。 – rogerdpack 2017-12-28 19:24:28
只是没有使用SWIFT Mecki的回答是:
let libHandle = dlopen("/System/Library/PrivateFrameworks/login.framework/Versions/Current/login", RTLD_LAZY)
let sym = dlsym(libHandle, "SACLockScreenImmediate")
typealias myFunction = @convention(c) Void -> Void
let SACLockScreenImmediate = unsafeBitCast(sym, myFunction.self)
SACLockScreenImmediate()
在这里: https://github.com/ftiff/MenuLock/blob/master/MenuLock/AppDelegate.swift#L126
下面的代码不准确的钥匙扣菜单项做什么,因为它只是调用。我曾经使用过这个(在10.11和10.12),但是现在在10.13(公共测试版)上失败了,因为根本没有Keychain.menu也没有菜单项。Mecki的答案是一个可用的替代品,但不会淡出屏幕,因此它的确是低级别的。
void lock() {
NSBundle *bundle = [NSBundle bundleWithPath:@"/Applications/Utilities/Keychain Access.app/Contents/Resources/Keychain.menu"];
Class principalClass = [bundle principalClass];
id instance = [[principalClass alloc] init];
[instance performSelector:@selector(_lockScreenMenuHit:) withObject:nil];
}
是的,不在这里工作(高塞拉利昂) – rogerdpack 2017-12-28 19:28:45
- 1. OS X,屏幕锁
- 2. 我应该使用什么API来锁定和解锁MAC OS X中的屏幕?
- 3. Mac OS X Lion全屏幕事件
- 4. 在OS X小牛自定义登录/锁定屏幕
- 5. 如何从os x终端启动屏幕保护程序(并锁定屏幕)?
- 6. 如何通过ADB锁定Android屏幕?
- 7. 在Mac OS X应用程序中调整屏幕亮度
- 8. 如何在Mac OS x中更改屏幕亮度?
- 9. 错误通过NPM在Mac OS X
- 10. IOS锁定屏幕通知
- 11. 如何在mac中以编程方式“锁定/解锁”屏幕
- 12. 锁定屏幕在Android中
- 13. 锁定屏幕
- 14. 锁定屏幕
- 15. 如何更改Java程序中的“关于”Mac OS X屏幕?
- 16. 如何在Mac OS X上的双屏幕上显示Lion
- 17. 如何在Mac OS X上使用Haskell捕获屏幕?
- 18. 屏幕锁定中的本地通知
- 19. 通过mac os x桌面绘图
- 20. 锁定屏幕中的警报/通知
- 21. 在锁定屏幕上显示通知
- 22. 在锁定屏幕上保留通知
- 23. 在锁定屏幕上显示通知
- 24. 在屏幕滚动过多之后,在屏幕上锁定div?
- 25. 在Mac OS X
- 26. 在Mac OS X
- 27. 在Mac OS X
- 28. 跳过屏幕锁
- 29. 在锁定屏幕上切换活动显示锁定屏幕
- 30. OS X GNU屏幕打破着色
我知道有一些东西可用,因为SizzlingKeys可以做到这一点。不知道什么类/方法虽然。你应该澄清你是否在寻找一个Cocoa或AppleScript API。 – 2009-12-29 19:46:19
问题标签为可可。 – 2009-12-30 08:13:51
是否有类似的代码来解锁屏幕(假设代码“知道”密码)? – mbaros 2017-07-03 11:33:40