2

您好,我正在为 Windows 和 Mac 开发一个注册到 uri 方案的应用程序

    static void RegisterURI()
    {
        if (Environment.OSVersion.Platform.ToString() == "Unix") //I'll never use it on any linux machine so it should be OK
        {
            //What should I put HERE ??
        }
        else
        {
            //on récupère le chemin de l'assembly
            string MyPos = System.Reflection.Assembly.GetAssembly(typeof(Program)).Location;

            var protocol = Registry.ClassesRoot
                .CreateSubKey("serialcodereader");
            protocol.SetValue("", "URL:Lancer l'écouteur de liseuse de code barre COM");
            protocol.SetValue("URL Protocol", "");
            var icon = protocol.CreateSubKey("DefaultIcon");
            icon.SetValue("", MyPos + ",1");
            var command = protocol.CreateSubKey("shell").CreateSubKey("open").CreateSubKey("command");
            command.SetValue("", '"' + MyPos + '"');
        }
    }

这是我用于 Windows 的代码,但我该如何为 OSX 做呢?

ps:很高兴知道:我一生中从未使用过任何 Mac 甚至 Iphone,所以对那些奇怪的动物保持简单 :-)

4

1 回答 1

0

我正在从事类似的工作。我确实建议浪费一些时间来检查这个:NSBundle.MainBundle.InfoDictionary.ToString()

并检查此源代码:https ://github.com/mono/monodevelop/blob/master/main/src/addins/MacPlatform/MacPlatform.cs ,因为他们使用 NSBundle 结构在运行时更改它。

尽快找到解决方案,我将与您分享。


我已经找到了一个实用的解决方案。

  1. 我从这个博客中挑选了一些信息:https ://mhut.ch/journal/2010/01/24/creating_mac_app_bundle_for_gtk_app并在那里修改了脚本
  2. 我使用 Mono 编写了一个 C#/Gtk 应用程序,以便在 Windows/Linux 环境中可重用
  3. 在那个应用程序中,我使用了一些您使用的方法来关联 Windows 环境中的 URL 模式。
  4. 我写了一个 .ini 文件来描述我的应用程序
  5. 我编写了一个 bash 脚本,它获取已编译的应用程序、.ini 文件、图标并创建一个 Apple Bundle 文件
  6. 我使用从 html 页面调用的单个 URL 进行了测试

我的项目.ini

[project]
CFBundleExecutable=ExecutableName
CFBundleName="Human Readable Executable Name"
CFBundleVersion="1.0"
REV_DOMAIN="com.sample"
URLScheme="myapp"
# src is where Mono left your executable
src='/Users/myself/Projects/MyApp/MyApp/bin/Release/'
CFBundleURLIconFile='appicons.icns'

使用示例:

$ build-mac-app.sh myProject

这将生成一个带有“.app”扩展名的文件夹以及运行它所需的所有内容。首先,请记住运行它,以便 MacOS 进行关联,其次,注意方案的使用,因为如果您在其他开发中使用了 url 方案,它将失败或打开其他应用程序。

HTML 测试文件

<a href=" myapp ://coisa-a-ser-assinada">clique para testar o assinador</a>

构建器脚本

我最初是在 pt-br 中编写的,因为它最初是今天为内部使用而开发的

#!/bin/bash

echo ""
echo "EDortta/build-mac-app.sh"
echo "Construtor de aplicativos para MacOSx"
echo "Este script usa a saída gerada por MonoDevelop C#/Gtk"
echo "e produz um Mac App Bundle pronto para ser distribuido"
echo "------------------------------------------------------"
if [ -f "$1" ]; then
  config="$1"
  CFBundleExecutable=`cat $config | sed -n '/\[project\]/,/\[.*\]/p' | awk -F= '/CFBundleExecutable/{print $2}' | tr -d '"' | tr -d "'"`
  CFBundleName=`cat $config | sed -n '/\[project\]/,/\[.*\]/p' | awk -F= '/CFBundleName/{print $2}' | tr -d '"' | tr -d "'"`
  CFBundleVersion=`cat $config | sed -n '/\[project\]/,/\[.*\]/p' | awk -F= '/CFBundleVersion/{print $2}' | tr -d '"' | tr -d "'"`
  REV_DOMAIN=`cat $config | sed -n '/\[project\]/,/\[.*\]/p' | awk -F= '/REV_DOMAIN/{print $2}' | tr -d '"' | tr -d "'"`
  CFBundleURLIconFile=`cat $config | sed -n '/\[project\]/,/\[.*\]/p' | awk -F= '/CFBundleURLIconFile/{print $2}' | tr -d '"' | tr -d "'"`
  URLScheme=`cat $config | sed -n '/\[project\]/,/\[.*\]/p' | awk -F= '/URLScheme/{print $2}' | tr -d '"' | tr -d "'"`
  src=`cat $config | sed -n '/\[project\]/,/\[.*\]/p' | awk -F= '/src/{print $2}' | tr -d '"' | tr -d "'"`

  echo "src=$src"

  if [ ! -d "$CFBundleExecutable.app" ]; then
    mkdir "$CFBundleExecutable.app"
    rsync -rvt mac-skel/* "$CFBundleExecutable.app/"

    sed -i -e "s/%CFBundleExecutable%/$CFBundleExecutable/g" "$CFBundleExecutable.app/Contents/Info.plist"
    sed -i -e "s/%CFBundleName%/$CFBundleName/g" "$CFBundleExecutable.app/Contents/Info.plist"
    sed -i -e "s/%CFBundleVersion%/$CFBundleVersion/g" "$CFBundleExecutable.app/Contents/Info.plist"
    sed -i -e "s/%REV_DOMAIN%/$REV_DOMAIN/g" "$CFBundleExecutable.app/Contents/Info.plist"
    sed -i -e "s/%URLScheme%/$URLScheme/g" "$CFBundleExecutable.app/Contents/Info.plist"
    sed -i -e "s/%CFBundleURLIconFile%/$CFBundleURLIconFile/g" "$CFBundleExecutable.app/Contents/Info.plist"

    if [ -f "$CFBundleExecutable.app/Contents/Info.plist-e" ]; then
        rm -f "$CFBundleExecutable.app/Contents/Info.plist-e"
    fi

    if [ -f "$CFBundleURLIconFile" ]; then
        cp "$CFBundleURLIconFile" "$CFBundleExecutable.app/Contents/Resources/$CFBundleExecutable.icns"
    fi

    mv "$CFBundleExecutable.app/Contents/MacOS/appname.sh" "$CFBundleExecutable.app/Contents/MacOS/$CFBundleExecutable.sh"
    cp -r "$src/" "$CFBundleExecutable.app/Contents/MacOS/"

    sed -i -e "s/%CFBundleExecutable%/$CFBundleExecutable/g" "$CFBundleExecutable.app/Contents/MacOS/$CFBundleExecutable.sh"
    sed -i -e "s/%CFBundleName%/$CFBundleName/g" "$CFBundleExecutable.app/Contents/MacOS/$CFBundleExecutable.sh"

    if [ -f "$CFBundleExecutable.app/Contents/MacOS/$CFBundleExecutable.sh-e" ]; then
        rm -f "$CFBundleExecutable.app/Contents/MacOS/$CFBundleExecutable.sh-e"
    fi

    chmod +x "$CFBundleExecutable.app/Contents/MacOS/$CFBundleExecutable.sh"

  else
    echo "$CFBundleExecutable.app já existe"
    echo "Por favor, considere remover a pasta"
  fi
else
    echo "Indique o seu projeto C#/GTK"
    echo "Caso precise de um exemplo, use project-sample.ini"
fi

幕后结构

在“build-mac-app.sh”和应用程序图标(从项目或其他来源移动或复制)的同一杠杆上,有一个包含这些文件的 mac-skel 文件夹:

mac-skel/
└── Contents
    ├── Info.plist
    ├── MacOS
    │   └── appname.sh
    └── Resources

mac-skel/Contents/Info.plist

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>CFBundleDevelopmentRegion</key>
    <string>pt-br</string>
    <key>CFBundleExecutable</key>
    <string>MacOS/%CFBundleExecutable%.sh</string>
    <key>CFBundleIconFile</key>
    <string>../Resources/%CFBundleExecutable%.icns</string>
    <key>CFBundleIdentifier</key>
    <string>%REV_DOMAIN%.%CFBundleExecutable%</string>
    <key>CFBundleInfoDictionaryVersion</key>
    <string>6.0</string>
    <key>CFBundleName</key>
    <string>%CFBundleName%</string>
    <key>CFBundlePackageType</key>
    <string>APPL</string>
    <key>CFBundleShortVersionString</key>
    <string>%CFBundleVersion%</string>
    <key>CFBundleSignature</key>
    <string>xmmd</string>
    <key>CFBundleVersion</key>
    <string>%CFBundleVersion%</string>
    <key>NSAppleScriptEnabled</key>
    <string>NO</string>
    <key>CFBundleURLTypes</key>
    <array>
        <dict>
            <key>CFBundleURLIconFile</key>
            <string>%CFBundleURLIconFile%</string>
            <key>CFBundleURLName</key>
            <string>%REV_DOMAIN%.%CFBundleExecutable%</string>
            <key>CFBundleURLSchemes</key>
            <array>
                <string>%URLScheme%</string>
            </array>
            <key>CFBundleURLTypes</key>
            <string>Editor</string>
        </dict>
    </array>
</dict>
</plist>

mac-skel/Contents/MacOS/appname.sh 这是从之前展示的博客中摘录的

#!/bin/sh

#get the bundle's MacOS directory full path
DIR=$(cd "$(dirname "$0")"; pwd)

#change these values to match your app
EXE_PATH="$DIR\%CFBundleExecutable%.exe"
PROCESS_NAME="%CFBundleExecutable%"
BUNDLENAME="%CFBundleName%"

#set up environment
MONO_FRAMEWORK_PATH=/Library/Frameworks/Mono.framework/Versions/Current
export DYLD_FALLBACK_LIBRARY_PATH="$DIR:$MONO_FRAMEWORK_PATH/lib:/lib:/usr/lib"
export PATH="$MONO_FRAMEWORK_PATH/bin:$PATH"

#mono version check
REQUIRED_MAJOR=2
REQUIRED_MINOR=4

VERSION_TITLE="$BUNDLENAME Não pode ser aberta"
VERSION_MSG="$BUNDLENAME requer o Framework Mono versão $REQUIRED_MAJOR.$REQUIRED_MINOR ou  posterior."
DOWNLOAD_URL="http://www.go-mono.com/mono-downloads/download.html"

MONO_VERSION="$(mono --version | grep 'Mono JIT compiler version ' |  cut -f5 -d\ )"
MONO_VERSION_MAJOR="$(echo $MONO_VERSION | cut -f1 -d.)"
MONO_VERSION_MINOR="$(echo $MONO_VERSION | cut -f2 -d.)"
if [ -z "$MONO_VERSION" ] \
    || [ $MONO_VERSION_MAJOR -lt $REQUIRED_MAJOR ] \
    || [ $MONO_VERSION_MAJOR -eq $REQUIRED_MAJOR -a $MONO_VERSION_MINOR -lt $REQUIRED_MINOR ] 
then
    osascript \
    -e "set question to display dialog \"$VERSION_MSG\" with title \"$VERSION_TITLE\" buttons {\"Cancelar\", \"Baixar...\"} default button 2" \
    -e "if button returned of question is equal to \"Baixar...\" then open location \"$DOWNLOAD_URL\""
    echo "$VERSION_TITLE"
    echo "$VERSION_MSG"
    exit 1
fi

#get an exec command that will work on the current OS version
OSX_VERSION=$(uname -r | cut -f1 -d.)
if [ $OSX_VERSION -lt 9 ]; then  # If OSX version is 10.4
    MONO_EXEC="exec mono"
else
    MONO_EXEC="exec -a \"$PROCESS_NAME\" mono"
fi

#create log file directory if it doesn't exist
LOG_FILE="$HOME/Library/Logs/$BUNDLENAME/$BUNDLENAME.log"
mkdir -p "`dirname \"$LOG_FILE\"`"

#run app using mono
$MONO_EXEC $MONO_OPTIONS "$EXE_PATH" $* 2>&1 1> "$LOG_FILE"
于 2017-11-22T14:10:49.060 回答