1

我有一個工作safari擴展,我可以通過在Safari瀏覽器上拖動它進行手動安裝。我想知道如何以編程方式安裝它。 我已經爲firefox,chrome和IE做了這個。 在Firefox中,只需將Windows XP中的.xpi文件複製到此文件夾(「C:\ Users \ admin \ AppData \ Roaming \ Mozilla \ Firefox \ Profiles \ xxx.default \ extensions」),即可安裝擴展程序。如何使用安裝項目安裝safari擴展?

和鉻你有當我我.safariextz文件複製到該文件夾​​「C寫這些註冊表項

Windows Registry Editor Version 5.00 
[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Google\Chrome\Extensions\dlilbimladfdhkfbbcbjjnbleakbogef] 
"version"="3.6" 
"path"="C:\\extension.crx" 

,但在Safari中:\用戶\ ADMIN \應用程序數據\本地\蘋果電腦\ Safari瀏覽器\擴展「比擴展沒有得到安裝。 任何人都可以指導我如何做到這一點。

回答

1

在文件夾:

〜\ USERS \\應用程序數據\本地\蘋果電腦\ Safari瀏覽器\擴展

有一個名爲文件Extensions.plist你還需要在此文件中爲您的擴展添加一個條目。

1

「〜\ Users \ AppData \ Local \ Apple Computer \ Safari \ Extensions」文件夾中的Extension.plist是一個二進制文件。閱讀並添加一個條目,我們可以使用這個類。

using System; 
using System.Collections; 
using System.Collections.Generic; 
using System.IO; 
using System.Text; 

namespace PlistCS 
{ 
public static class Plist 
{ 
    private static List<int> offsetTable = new List<int>(); 
    private static List<byte> objectTable = new List<byte>(); 
    private static int refCount; 
    private static int objRefSize; 
    private static int offsetByteSize; 
    private static long offsetTableOffset; 

    #region Public Functions 

    public static object readPlist(string path) 
    { 
     using (FileStream f = new FileStream(path, FileMode.Open, FileAccess.Read)) 
     { 
      return readPlist(f); 
     } 
    } 

    public static object readPlistSource(string source) 
    { 
     return readPlist(System.Text.Encoding.UTF8.GetBytes(source)); 
    } 

    public static object readPlist(byte[] data) 
    { 
     return readPlist(new MemoryStream(data)); 
    } 

    public static plistType getPlistType(Stream stream) 
    { 
     byte[] magicHeader = new byte[8]; 
     stream.Read(magicHeader, 0, 8); 

     if (BitConverter.ToInt64(magicHeader, 0) == 3472403351741427810) 
     { 
      return plistType.Binary; 
     } 
     else 
     { 
      return plistType.Xml; 
     } 
    } 

    public static object readPlist(Stream stream, plistType type = plistType.Auto) 
    { 
     if (type == plistType.Auto) 
     { 
      type = getPlistType(stream); 
      stream.Seek(0, SeekOrigin.Begin); 
     } 

     if (type == plistType.Binary) 
     { 
      using (BinaryReader reader = new BinaryReader(stream)) 
      { 
       byte[] data = reader.ReadBytes((int)reader.BaseStream.Length); 
       return readBinary(data); 
      } 
     } 
     else 
     { 
      using (BinaryReader reader = new BinaryReader(stream)) 
      { 
       byte[] data = reader.ReadBytes((int)reader.BaseStream.Length); 
       return readBinary(data); 
      } 
     } 
    } 

    public static void writeBinary(object value, string path) 
    { 
     using (BinaryWriter writer = new BinaryWriter(new FileStream(path, FileMode.Create))) 
     { 
      writer.Write(writeBinary(value)); 
     } 
    } 

    public static void writeBinary(object value, Stream stream) 
    { 
     using (BinaryWriter writer = new BinaryWriter(stream)) 
     { 
      writer.Write(writeBinary(value)); 
     } 
    } 

    public static byte[] writeBinary(object value) 
    { 
     offsetTable.Clear(); 
     objectTable.Clear(); 
     refCount = 0; 
     objRefSize = 0; 
     offsetByteSize = 0; 
     offsetTableOffset = 0; 

     //Do not count the root node, subtract by 1 
     int totalRefs = countObject(value) - 1; 

     refCount = totalRefs; 

     objRefSize = RegulateNullBytes(BitConverter.GetBytes(refCount)).Length; 

     composeBinary(value); 

     writeBinaryString("bplist00", false); 

     offsetTableOffset = (long)objectTable.Count; 

     offsetTable.Add(objectTable.Count - 8); 

     offsetByteSize = RegulateNullBytes(BitConverter.GetBytes(offsetTable[offsetTable.Count - 1])).Length; 

     List<byte> offsetBytes = new List<byte>(); 

     offsetTable.Reverse(); 

     for (int i = 0; i < offsetTable.Count; i++) 
     { 
      offsetTable[i] = objectTable.Count - offsetTable[i]; 
      byte[] buffer = RegulateNullBytes(BitConverter.GetBytes(offsetTable[i]), offsetByteSize); 
      Array.Reverse(buffer); 
      offsetBytes.AddRange(buffer); 
     } 

     objectTable.AddRange(offsetBytes); 

     objectTable.AddRange(new byte[6]); 
     objectTable.Add(Convert.ToByte(offsetByteSize)); 
     objectTable.Add(Convert.ToByte(objRefSize)); 

     var a = BitConverter.GetBytes((long)totalRefs + 1); 
     Array.Reverse(a); 
     objectTable.AddRange(a); 

     objectTable.AddRange(BitConverter.GetBytes((long)0)); 
     a = BitConverter.GetBytes(offsetTableOffset); 
     Array.Reverse(a); 
     objectTable.AddRange(a); 

     return objectTable.ToArray(); 
    } 

    #endregion 

    #region Private Functions 

    private static object readBinary(byte[] data) 
    { 
     offsetTable.Clear(); 
     List<byte> offsetTableBytes = new List<byte>(); 
     objectTable.Clear(); 
     refCount = 0; 
     objRefSize = 0; 
     offsetByteSize = 0; 
     offsetTableOffset = 0; 

     List<byte> bList = new List<byte>(data); 

     List<byte> trailer = bList.GetRange(bList.Count - 32, 32); 

     parseTrailer(trailer); 

     objectTable = bList.GetRange(0, (int)offsetTableOffset); 

     offsetTableBytes = bList.GetRange((int)offsetTableOffset, bList.Count - (int)offsetTableOffset - 32); 

     parseOffsetTable(offsetTableBytes); 

     return parseBinary(0); 
    } 


    private static int countObject(object value) 
    { 
     int count = 0; 
     switch (value.GetType().ToString()) 
     { 
      case "System.Collections.Generic.Dictionary`2[System.String,System.Object]": 
       Dictionary<string, object> dict = (Dictionary<string, object>)value; 
       foreach (string key in dict.Keys) 
       { 
        count += countObject(dict[key]); 
       } 
       count += dict.Keys.Count; 
       count++; 
       break; 
      case "System.Collections.Generic.List`1[System.Object]": 
       List<object> list = (List<object>)value; 
       foreach (object obj in list) 
       { 
        count += countObject(obj); 
       } 
       count++; 
       break; 
      default: 
       count++; 
       break; 
     } 
     return count; 
    } 

    private static byte[] writeBinaryDictionary(Dictionary<string, object> dictionary) 
    { 
     List<byte> buffer = new List<byte>(); 
     List<byte> header = new List<byte>(); 
     List<int> refs = new List<int>(); 
     for (int i = dictionary.Count - 1; i >= 0; i--) 
     { 
      var o = new object[dictionary.Count]; 
      dictionary.Values.CopyTo(o, 0); 
      composeBinary(o[i]); 
      offsetTable.Add(objectTable.Count); 
      refs.Add(refCount); 
      refCount--; 
     } 
     for (int i = dictionary.Count - 1; i >= 0; i--) 
     { 
      var o = new string[dictionary.Count]; 
      dictionary.Keys.CopyTo(o, 0); 
      composeBinary(o[i]);//); 
      offsetTable.Add(objectTable.Count); 
      refs.Add(refCount); 
      refCount--; 
     } 

     if (dictionary.Count < 15) 
     { 
      header.Add(Convert.ToByte(0xD0 | Convert.ToByte(dictionary.Count))); 
     } 
     else 
     { 
      header.Add(0xD0 | 0xf); 
      header.AddRange(writeBinaryInteger(dictionary.Count, false)); 
     } 


     foreach (int val in refs) 
     { 
      byte[] refBuffer = RegulateNullBytes(BitConverter.GetBytes(val), objRefSize); 
      Array.Reverse(refBuffer); 
      buffer.InsertRange(0, refBuffer); 
     } 

     buffer.InsertRange(0, header); 


     objectTable.InsertRange(0, buffer); 

     return buffer.ToArray(); 
    } 

    private static byte[] composeBinaryArray(List<object> objects) 
    { 
     List<byte> buffer = new List<byte>(); 
     List<byte> header = new List<byte>(); 
     List<int> refs = new List<int>(); 

     for (int i = objects.Count - 1; i >= 0; i--) 
     { 
      composeBinary(objects[i]); 
      offsetTable.Add(objectTable.Count); 
      refs.Add(refCount); 
      refCount--; 
     } 

     if (objects.Count < 15) 
     { 
      header.Add(Convert.ToByte(0xA0 | Convert.ToByte(objects.Count))); 
     } 
     else 
     { 
      header.Add(0xA0 | 0xf); 
      header.AddRange(writeBinaryInteger(objects.Count, false)); 
     } 

     foreach (int val in refs) 
     { 
      byte[] refBuffer = RegulateNullBytes(BitConverter.GetBytes(val), objRefSize); 
      Array.Reverse(refBuffer); 
      buffer.InsertRange(0, refBuffer); 
     } 

     buffer.InsertRange(0, header); 

     objectTable.InsertRange(0, buffer); 

     return buffer.ToArray(); 
    } 

    private static byte[] composeBinary(object obj) 
    { 
     byte[] value; 
     switch (obj.GetType().ToString()) 
     { 
      case "System.Collections.Generic.Dictionary`2[System.String,System.Object]": 
       value = writeBinaryDictionary((Dictionary<string, object>)obj); 
       return value; 

      case "System.Collections.Generic.List`1[System.Object]": 
       value = composeBinaryArray((List<object>)obj); 
       return value; 

      case "System.Byte[]": 
       value = writeBinaryByteArray((byte[])obj); 
       return value; 

      case "System.Double": 
       value = writeBinaryDouble((double)obj); 
       return value; 

      case "System.Int32": 
       value = writeBinaryInteger((int)obj, true); 
       return value; 

      case "System.String": 
       value = writeBinaryString((string)obj, true); 
       return value; 

      case "System.DateTime": 
       value = writeBinaryDate((DateTime)obj); 
       return value; 

      case "System.Boolean": 
       value = writeBinaryBool((bool)obj); 
       return value; 

      default: 
       return new byte[0]; 
     } 
    } 

    public static byte[] writeBinaryDate(DateTime obj) 
    { 
     List<byte> buffer = new List<byte>(RegulateNullBytes(BitConverter.GetBytes(PlistDateConverter.ConvertToAppleTimeStamp(obj)), 8)); 
     buffer.Reverse(); 
     buffer.Insert(0, 0x33); 
     objectTable.InsertRange(0, buffer); 
     return buffer.ToArray(); 
    } 

    public static byte[] writeBinaryBool(bool obj) 
    { 
     List<byte> buffer = new List<byte>(new byte[1] { (bool)obj ? (byte)9 : (byte)8 }); 
     objectTable.InsertRange(0, buffer); 
     return buffer.ToArray(); 
    } 

    private static byte[] writeBinaryInteger(int value, bool write) 
    { 
     List<byte> buffer = new List<byte>(BitConverter.GetBytes((long)value)); 
     buffer = new List<byte>(RegulateNullBytes(buffer.ToArray())); 
     while (buffer.Count != Math.Pow(2, Math.Log(buffer.Count)/Math.Log(2))) 
      buffer.Add(0); 
     int header = 0x10 | (int)(Math.Log(buffer.Count)/Math.Log(2)); 

     buffer.Reverse(); 

     buffer.Insert(0, Convert.ToByte(header)); 

     if (write) 
      objectTable.InsertRange(0, buffer); 

     return buffer.ToArray(); 
    } 

    private static byte[] writeBinaryDouble(double value) 
    { 
     List<byte> buffer = new List<byte>(RegulateNullBytes(BitConverter.GetBytes(value), 4)); 
     while (buffer.Count != Math.Pow(2, Math.Log(buffer.Count)/Math.Log(2))) 
      buffer.Add(0); 
     int header = 0x20 | (int)(Math.Log(buffer.Count)/Math.Log(2)); 

     buffer.Reverse(); 

     buffer.Insert(0, Convert.ToByte(header)); 

     objectTable.InsertRange(0, buffer); 

     return buffer.ToArray(); 
    } 

    private static byte[] writeBinaryByteArray(byte[] value) 
    { 
     List<byte> buffer = new List<byte>(value); 
     List<byte> header = new List<byte>(); 
     if (value.Length < 15) 
     { 
      header.Add(Convert.ToByte(0x40 | Convert.ToByte(value.Length))); 
     } 
     else 
     { 
      header.Add(0x40 | 0xf); 
      header.AddRange(writeBinaryInteger(buffer.Count, false)); 
     } 

     buffer.InsertRange(0, header); 

     objectTable.InsertRange(0, buffer); 

     return buffer.ToArray(); 
    } 

    private static byte[] writeBinaryString(string value, bool head) 
    { 
     List<byte> buffer = new List<byte>(); 
     List<byte> header = new List<byte>(); 
     foreach (char chr in value.ToCharArray()) 
      buffer.Add(Convert.ToByte(chr)); 

     if (head) 
     { 
      if (value.Length < 15) 
      { 
       header.Add(Convert.ToByte(0x50 | Convert.ToByte(value.Length))); 
      } 
      else 
      { 
       header.Add(0x50 | 0xf); 
       header.AddRange(writeBinaryInteger(buffer.Count, false)); 
      } 
     } 

     buffer.InsertRange(0, header); 

     objectTable.InsertRange(0, buffer); 

     return buffer.ToArray(); 
    } 

    private static byte[] RegulateNullBytes(byte[] value) 
    { 
     return RegulateNullBytes(value, 1); 
    } 

    private static byte[] RegulateNullBytes(byte[] value, int minBytes) 
    { 
     Array.Reverse(value); 
     List<byte> bytes = new List<byte>(value); 
     for (int i = 0; i < bytes.Count; i++) 
     { 
      if (bytes[i] == 0 && bytes.Count > minBytes) 
      { 
       bytes.Remove(bytes[i]); 
       i--; 
      } 
      else 
       break; 
     } 

     if (bytes.Count < minBytes) 
     { 
      int dist = minBytes - bytes.Count; 
      for (int i = 0; i < dist; i++) 
       bytes.Insert(0, 0); 
     } 

     value = bytes.ToArray(); 
     Array.Reverse(value); 
     return value; 
    } 

    private static void parseTrailer(List<byte> trailer) 
    { 
     offsetByteSize = BitConverter.ToInt32(RegulateNullBytes(trailer.GetRange(6, 1).ToArray(), 4), 0); 
     objRefSize = BitConverter.ToInt32(RegulateNullBytes(trailer.GetRange(7, 1).ToArray(), 4), 0); 
     byte[] refCountBytes = trailer.GetRange(12, 4).ToArray(); 
     Array.Reverse(refCountBytes); 
     refCount = BitConverter.ToInt32(refCountBytes, 0); 
     byte[] offsetTableOffsetBytes = trailer.GetRange(24, 8).ToArray(); 
     Array.Reverse(offsetTableOffsetBytes); 
     offsetTableOffset = BitConverter.ToInt64(offsetTableOffsetBytes, 0); 
    } 

    private static void parseOffsetTable(List<byte> offsetTableBytes) 
    { 
     for (int i = 0; i < offsetTableBytes.Count; i += offsetByteSize) 
     { 
      byte[] buffer = offsetTableBytes.GetRange(i, offsetByteSize).ToArray(); 
      Array.Reverse(buffer); 
      offsetTable.Add(BitConverter.ToInt32(RegulateNullBytes(buffer, 4), 0)); 
     } 
    } 

    private static object parseBinaryDictionary(int objRef) 
    { 
     Dictionary<string, object> buffer = new Dictionary<string, object>(); 
     List<int> refs = new List<int>(); 
     int refCount = 0; 

     byte dictByte = objectTable[offsetTable[objRef]]; 

     int refStartPosition; 
     refCount = getCount(offsetTable[objRef], out refStartPosition); 


     if (refCount < 15) 
      refStartPosition = offsetTable[objRef] + 1; 
     else 
      refStartPosition = offsetTable[objRef] + 2 + RegulateNullBytes(BitConverter.GetBytes(refCount), 1).Length; 

     for (int i = refStartPosition; i < refStartPosition + refCount * 2 * objRefSize; i += objRefSize) 
     { 
      byte[] refBuffer = objectTable.GetRange(i, objRefSize).ToArray(); 
      Array.Reverse(refBuffer); 
      refs.Add(BitConverter.ToInt32(RegulateNullBytes(refBuffer, 4), 0)); 
     } 

     for (int i = 0; i < refCount; i++) 
     { 
      buffer.Add((string)parseBinary(refs[i]), parseBinary(refs[i + refCount])); 
     } 

     return buffer; 
    } 

    private static object parseBinaryArray(int objRef) 
    { 
     List<object> buffer = new List<object>(); 
     List<int> refs = new List<int>(); 
     int refCount = 0; 

     byte arrayByte = objectTable[offsetTable[objRef]]; 

     int refStartPosition; 
     refCount = getCount(offsetTable[objRef], out refStartPosition); 


     if (refCount < 15) 
      refStartPosition = offsetTable[objRef] + 1; 
     else 
      //The following integer has a header aswell so we increase the refStartPosition by two to account for that. 
      refStartPosition = offsetTable[objRef] + 2 + RegulateNullBytes(BitConverter.GetBytes(refCount), 1).Length; 

     for (int i = refStartPosition; i < refStartPosition + refCount * objRefSize; i += objRefSize) 
     { 
      byte[] refBuffer = objectTable.GetRange(i, objRefSize).ToArray(); 
      Array.Reverse(refBuffer); 
      refs.Add(BitConverter.ToInt32(RegulateNullBytes(refBuffer, 4), 0)); 
     } 

     for (int i = 0; i < refCount; i++) 
     { 
      buffer.Add(parseBinary(refs[i])); 
     } 

     return buffer; 
    } 

    private static int getCount(int bytePosition, out int newBytePosition) 
    { 
     byte headerByte = objectTable[bytePosition]; 
     byte headerByteTrail = Convert.ToByte(headerByte & 0xf); 
     int count; 
     if (headerByteTrail < 15) 
     { 
      count = headerByteTrail; 
      newBytePosition = bytePosition + 1; 
     } 
     else 
      count = (int)parseBinaryInt(bytePosition + 1, out newBytePosition); 
     return count; 
    } 

    private static object parseBinary(int objRef) 
    { 
     byte header = objectTable[offsetTable[objRef]]; 
     switch (header & 0xF0) 
     { 
      case 0: 
       { 
        //If the byte is 
        //0 return null 
        //9 return true 
        //8 return false 
        return (objectTable[offsetTable[objRef]] == 0) ? (object)null : ((objectTable[offsetTable[objRef]] == 9) ? true : false); 
       } 
      case 0x10: 
       { 
        return parseBinaryInt(offsetTable[objRef]); 
       } 
      case 0x20: 
       { 
        return parseBinaryReal(offsetTable[objRef]); 
       } 
      case 0x30: 
       { 
        return parseBinaryDate(offsetTable[objRef]); 
       } 
      case 0x40: 
       { 
        return parseBinaryByteArray(offsetTable[objRef]); 
       } 
      case 0x50://String ASCII 
       { 
        return parseBinaryAsciiString(offsetTable[objRef]); 
       } 
      case 0x60://String Unicode 
       { 
        return parseBinaryUnicodeString(offsetTable[objRef]); 
       } 
      case 0xD0: 
       { 
        return parseBinaryDictionary(objRef); 
       } 
      case 0xA0: 
       { 
        return parseBinaryArray(objRef); 
       } 
     } 
     throw new Exception("This type is not supported"); 
    } 

    public static object parseBinaryDate(int headerPosition) 
    { 
     byte[] buffer = objectTable.GetRange(headerPosition + 1, 8).ToArray(); 
     Array.Reverse(buffer); 
     double appleTime = BitConverter.ToDouble(buffer, 0); 
     DateTime result = PlistDateConverter.ConvertFromAppleTimeStamp(appleTime); 
     return result; 
    } 

    private static object parseBinaryInt(int headerPosition) 
    { 
     int output; 
     return parseBinaryInt(headerPosition, out output); 
    } 

    private static object parseBinaryInt(int headerPosition, out int newHeaderPosition) 
    { 
     byte header = objectTable[headerPosition]; 
     int byteCount = (int)Math.Pow(2, header & 0xf); 
     byte[] buffer = objectTable.GetRange(headerPosition + 1, byteCount).ToArray(); 
     Array.Reverse(buffer); 
     //Add one to account for the header byte 
     newHeaderPosition = headerPosition + byteCount + 1; 
     return BitConverter.ToInt32(RegulateNullBytes(buffer, 4), 0); 
    } 

    private static object parseBinaryReal(int headerPosition) 
    { 
     byte header = objectTable[headerPosition]; 
     int byteCount = (int)Math.Pow(2, header & 0xf); 
     byte[] buffer = objectTable.GetRange(headerPosition + 1, byteCount).ToArray(); 
     Array.Reverse(buffer); 

     return BitConverter.ToDouble(RegulateNullBytes(buffer, 8), 0); 
    } 

    private static object parseBinaryAsciiString(int headerPosition) 
    { 
     int charStartPosition; 
     int charCount = getCount(headerPosition, out charStartPosition); 

     var buffer = objectTable.GetRange(charStartPosition, charCount); 
     return buffer.Count > 0 ? Encoding.ASCII.GetString(buffer.ToArray()) : string.Empty; 
    } 

    private static object parseBinaryUnicodeString(int headerPosition) 
    { 
     int charStartPosition; 
     int charCount = getCount(headerPosition, out charStartPosition); 
     charCount = charCount * 2; 

     byte[] buffer = new byte[charCount]; 
     byte one, two; 

     for (int i = 0; i < charCount; i += 2) 
     { 
      one = objectTable.GetRange(charStartPosition + i, 1)[0]; 
      two = objectTable.GetRange(charStartPosition + i + 1, 1)[0]; 

      if (BitConverter.IsLittleEndian) 
      { 
       buffer[i] = two; 
       buffer[i + 1] = one; 
      } 
      else 
      { 
       buffer[i] = one; 
       buffer[i + 1] = two; 
      } 
     } 

     return Encoding.Unicode.GetString(buffer); 
    } 

    private static object parseBinaryByteArray(int headerPosition) 
    { 
     int byteStartPosition; 
     int byteCount = getCount(headerPosition, out byteStartPosition); 
     return objectTable.GetRange(byteStartPosition, byteCount).ToArray(); 
    } 

    #endregion 
} 

public enum plistType 
{ 
    Auto, Binary, Xml 
} 

public static class PlistDateConverter 
{ 
    public static long timeDifference = 978307200; 

    public static long GetAppleTime(long unixTime) 
    { 
     return unixTime - timeDifference; 
    } 

    public static long GetUnixTime(long appleTime) 
    { 
     return appleTime + timeDifference; 
    } 

    public static DateTime ConvertFromAppleTimeStamp(double timestamp) 
    { 
     DateTime origin = new DateTime(2001, 1, 1, 0, 0, 0, 0); 
     return origin.AddSeconds(timestamp); 
    } 

    public static double ConvertToAppleTimeStamp(DateTime date) 
    { 
     DateTime begin = new DateTime(2001, 1, 1, 0, 0, 0, 0); 
     TimeSpan diff = date - begin; 
     return Math.Floor(diff.TotalSeconds); 
    } 
} 

}

和使用此方法在提交Installer.cs類的行動,以增加延伸部的條目Extension.plist

public void InstallSafariExt() 
    { 
     string safariExtPlist = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\Apple Computer\\Safari\\Extensions\\Extensions.plist"; 
     string safariSetupPlist = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles) + "\YourComp\\YourSoft\\Extensions.plist"; 

     string ExtDir = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\Apple Computer\\Safari\\Extensions"; 
     if (!Directory.Exists(ExtDir)) 
     { 
      Directory.CreateDirectory(ExtDir); 
      if (!File.Exists(safariExtPlist)) 
      { 
       File.Copy(safariSetupPlist, safariExtPlist); 
      } 
     } 
     else 
     { 
      if (!File.Exists(safariExtPlist)) 
      { 
       File.Copy(safariSetupPlist, safariExtPlist); 
      } 
     } 

     object obj = Plist.readPlist(safariExtPlist); 
     Dictionary<string, object> dict = (Dictionary<string, object>)obj; 
     Dictionary<string, object> NewExt = new Dictionary<string, object>(); 
     NewExt.Add("Hidden Bars", new List<object>()); 
     NewExt.Add("Added Non-Default Toolbar Items", new List<object>()); 
     NewExt.Add("Enabled", true); 
     NewExt.Add("Archive File Name", "YourExtName.safariextz"); 
     NewExt.Add("Removed Default Toolbar Items", new List<object>()); 
     NewExt.Add("Bundle Directory Name", "YourExtName.safariextension"); 
     List<object> listExt = (List<object>)dict["Installed Extensions"]; 
     listExt.Add(NewExt); 
     Plist.writeBinary(obj, safariExtPlist); 

     string safariExtFile = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles) + "\YourComp\\YourSoft\\YourExtName.safariextz"; 
     string safariInstallfolder = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\Apple Computer\\Safari\\Extensions\\YourExtName.safariextz"; 

     string[] safExtFiles = Directory.GetFiles(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\Apple Computer\\Safari\\Extensions\\", "YourExtName*.safariextz"); 
     for (int i = 0; i < safExtFiles.Length; i++) 
     { 
      if (File.Exists(safExtFiles[i])) 
       File.Delete(safExtFiles[i]); 
     } 

     File.Copy(safariExtFile, safariInstallfolder); 
    }