我想知道如何使用我用 Objective-C 编写的 OS X 应用程序打开文件。我在 Info.plist 中注册了文件类型,并且application:openFile:
在我的代码中。我通过这篇文章做了所有事情,它被标记为已解决。
问题是,只有当我在应用程序运行时将文件拖放到应用程序上时,这才有效。但如果我只是双击我的文件,它就不起作用。它会启动我的应用程序,但不会像我拖放那样启动。因此,其中的代码application:openFile:
在双击时不会运行,但只有在我拖放文件时才会运行。
编辑:
关于我的代码的更多细节,以及我想要实现的目标。我为另一个应用程序创建了一个包装应用程序。我们将另一个应用程序称为“HelperApp.app”。这个 HelperApp 位于/Contents/
我的包装应用程序的文件夹中。使用包装应用程序,我指定了一个新的文件类型,我们在 Info.plist 文件中将其称为“.ha”。该文件包含一些参数命令。我试图实现的目标是,当用户单击“.ha”文件时,我的包装应用程序会从该文件中读取参数并将其设置为 HelperApp,然后启动 HelperApp。这个 HelperApp 根据它得到的参数打开不同的东西。您可以在下面查看我的代码。
我有一个AppDelegate.h
和一个AppDelegate.mm
默认情况下最新的 Xcode 如何创建它。我将此行添加到我的AppDelegate.h
,就在“@end”之前:
- (BOOL)processFile:(NSString *)file;
我在我的有这些功能AppDelegate.mm
:
#import "AppDelegate.h"
#import "ArgumentParser.h"
@implementation AppDelegate
- (void)dealloc
{
[super dealloc];
}
- (BOOL)application:(NSApplication *)WrapperApp openFile:(NSString *)filename
{
return [self processFile:filename];
}
- (BOOL)processFile:(NSString *)file
{
NSLog(@"The following file has been dropped or selected: %@",file);
std::string path = [file cStringUsingEncoding:[NSString defaultCStringEncoding]];
ArgumentParser parser = ArgumentParser();
parser.getArgumentfromFile(path);
parser.setArgumentinFile(); // <== This is the "corrupted" function
NSBundle *mainBundle = [NSBundle mainBundle];
NSString *helperAppPath = [[mainBundle bundlePath]
stringByAppendingString:@"/Contents/HelperApp.app"];
[[NSWorkspace sharedWorkspace] launchApplication:helperAppPath];
return YES;
}
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
// Insert code here to initialize your application
}
损坏的功能 - setArgumentinFile()
:
void ArgumentParser::setArgumentinFile() {
std::string content = ""; // The file content
std::fstream file;
file.open("HelperApp.app/Contents/Wrapper/HelperApp.app/Contents/Info.plist");
// Open the file and modify the arguments
if(file.is_open()) {
std::stringstream stream;
stream << file.rdbuf();
std::string line = "";
bool isIt = false;
while(getline(stream, line)) {
// This line is the argument list, which needs to be modifyed
if(isIt) {
int index = (int)line.find_last_of("<");
std::string start = line.substr(0, index);
std::string end = line.substr(index, std::string::npos);
std::string argument_list = start + " " + _argument + end;
content += argument_list + '\n';
isIt = false;
}
// Save the rest of the file so we can overwrite it
else {
content += line + '\n';
}
// Next line is the argument list
if(line.find("WineProgramArguments") != std::string::npos) {
isIt = true;
}
}
file.flush();
file.close();
}
else {
file.flush();
file.close();
throw std::runtime_error("File isn't opened");
}
file.open("HelperApp.app/Contents/Wrapper/HelperApp.app/Contents/Info.plist", std::ios::out);
// Open the file and overwrite it with the modifyed argument
if(file.is_open()) {
file << content;
file.flush();
file.close();
}
else {
file.flush();
file.close();
throw std::runtime_error("File isn't opened");
}
}
processFile
如果我从in 函数中注释掉上述函数AppDelegate
,那么一切都会“顺利”运行。我的意思是包装应用程序启动并使用默认参数启动 HelperApp。所以这里应该是错误...