Browse Source

Fixed SD2-1252: Don't steal file associations from Visual Studio

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/branches/2.1@2330 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts
Daniel Grunwald 19 years ago
parent
commit
6362f89e72
  1. 2
      src/AddIns/Misc/FiletypeRegisterer/Project/FiletypeRegisterer.addin
  2. 7
      src/AddIns/Misc/FiletypeRegisterer/Project/FiletypeRegisterer.csproj
  3. 17
      src/AddIns/Misc/FiletypeRegisterer/Project/Src/FiletypeAssociationDoozer.cs
  4. 107
      src/AddIns/Misc/FiletypeRegisterer/Project/Src/RegisterFiletypesCommand.cs
  5. 74
      src/AddIns/Misc/FiletypeRegisterer/Project/Src/RegisterFiletypesPanel.Designer.cs
  6. 130
      src/AddIns/Misc/FiletypeRegisterer/Project/Src/RegisterFiletypesPanel.cs
  7. 2
      src/Main/Base/Project/Src/Gui/Dialogs/AbstractOptionPanel.cs

2
src/AddIns/Misc/FiletypeRegisterer/Project/FiletypeRegisterer.addin

@ -73,12 +73,14 @@ @@ -73,12 +73,14 @@
text = "SharpDevelop 1.x ${res:ICSharpCode.FiletypeRegisterer.Project}"/>
</Path>
<!--
<Path name = "/Workspace/Autostart">
<Condition name = "Compare" string = "${property:SharpDevelop.FiletypesRegisterStartup??False}" equals = "True">
<Class id = "RegisterFiletypes"
class = "ICSharpCode.FiletypeRegisterer.RegisterFiletypesCommand"/>
</Condition>
</Path>
-->
<Path name = "/SharpDevelop/Dialogs/OptionsDialog/UIOptions">
<DialogPanel id = "RegisterFiletypes"

7
src/AddIns/Misc/FiletypeRegisterer/Project/FiletypeRegisterer.csproj

@ -43,9 +43,6 @@ @@ -43,9 +43,6 @@
<ItemGroup>
<Compile Include="Configuration\AssemblyInfo.cs" />
<Compile Include="Src\RegisterFiletypesCommand.cs" />
<Compile Include="Src\RegisterFiletypesPanel.cs">
<SubType>UserControl</SubType>
</Compile>
<None Include="FiletypeRegisterer.addin">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
@ -77,6 +74,10 @@ @@ -77,6 +74,10 @@
<Compile Include="..\..\..\..\Main\GlobalAssemblyInfo.cs">
<Link>Configuration\GlobalAssemblyInfo.cs</Link>
</Compile>
<Compile Include="Src\RegisterFiletypesPanel.cs" />
<Compile Include="Src\RegisterFiletypesPanel.Designer.cs">
<DependentUpon>RegisterFiletypesPanel.cs</DependentUpon>
</Compile>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\..\Main\Base\Project\ICSharpCode.SharpDevelop.csproj">

17
src/AddIns/Misc/FiletypeRegisterer/Project/Src/FiletypeAssociationDoozer.cs

@ -18,14 +18,12 @@ namespace ICSharpCode.FiletypeRegisterer @@ -18,14 +18,12 @@ namespace ICSharpCode.FiletypeRegisterer
string id;
string icon;
string text;
bool isDefault;
public FiletypeAssociation(string id, string icon, string text, bool isDefault)
public FiletypeAssociation(string id, string icon, string text)
{
this.id = id;
this.icon = icon;
this.text = text;
this.isDefault = isDefault;
}
public string Extension {
@ -45,12 +43,6 @@ namespace ICSharpCode.FiletypeRegisterer @@ -45,12 +43,6 @@ namespace ICSharpCode.FiletypeRegisterer
return text;
}
}
public bool IsDefault {
get {
return isDefault;
}
}
}
/// <summary>
@ -65,10 +57,6 @@ namespace ICSharpCode.FiletypeRegisterer @@ -65,10 +57,6 @@ namespace ICSharpCode.FiletypeRegisterer
/// <attribute name="text" use="required">
/// The description text.
/// </attribute>
/// <attribute name="autoRegister" use="optional">
/// Boolean value that specifies if the file type is registered on every startup, even if another
/// application has already registered it. Default=false
/// </attribute>
/// <returns>
/// A FiletypeAssociation describing the specified values.
/// </returns>
@ -101,8 +89,7 @@ namespace ICSharpCode.FiletypeRegisterer @@ -101,8 +89,7 @@ namespace ICSharpCode.FiletypeRegisterer
{
return new FiletypeAssociation(codon.Id,
StringParser.Parse(codon.Properties["icon"]),
StringParser.Parse(codon.Properties["text"]),
bool.TrueString.Equals(codon.Properties["autoRegister"], StringComparison.OrdinalIgnoreCase));
StringParser.Parse(codon.Properties["text"]));
}
}
}

107
src/AddIns/Misc/FiletypeRegisterer/Project/Src/RegisterFiletypesCommand.cs

@ -16,66 +16,26 @@ using Microsoft.Win32; @@ -16,66 +16,26 @@ using Microsoft.Win32;
namespace ICSharpCode.FiletypeRegisterer {
public class RegisterFiletypesCommand : AbstractCommand
public static class RegisterFiletypesCommand
{
readonly public static string uiFiletypesProperty = "SharpDevelop.Filetypes";
// used in .addin file
readonly public static string uiRegisterStartupProperty = "SharpDevelop.FiletypesRegisterStartup";
const int SHCNE_ASSOCCHANGED = 0x08000000;
const int SHCNF_IDLIST = 0x0;
public static string GetDefaultExtensions(List<FiletypeAssociation> list)
public static void RegisterToSharpDevelop(FiletypeAssociation type)
{
StringBuilder b = new StringBuilder();
foreach (FiletypeAssociation a in list) {
if (a.IsDefault) {
if (b.Length > 0)
b.Append('|');
b.Append(a.Extension);
}
}
return b.ToString();
string mainExe = Assembly.GetEntryAssembly().Location;
RegisterFiletype(type.Extension,
type.Text,
'"' + Path.GetFullPath(mainExe) + '"' + " \"%1\"",
Path.GetFullPath(type.Icon));
}
public override void Run()
public static bool IsRegisteredToSharpDevelop(string extension)
{
List<FiletypeAssociation> list = FiletypeAssociationDoozer.GetList();
// register Combine and Project by default
RegisterFiletypes(list, PropertyService.Get(uiFiletypesProperty, GetDefaultExtensions(list)));
string openCommand = GetOpenCommand(extension);
RegisterUnknownFiletypes(list);
}
public static void RegisterFiletypes(List<FiletypeAssociation> allTypes, string types)
{
string[] singleTypes = types.Split('|');
string mainExe = Assembly.GetEntryAssembly().Location;
if (string.IsNullOrEmpty(openCommand))
return false;
foreach (FiletypeAssociation type in allTypes) {
if (Array.IndexOf(singleTypes, type.Extension) >= 0) {
RegisterFiletype(type.Extension,
type.Text,
'"' + Path.GetFullPath(mainExe) + '"' + " \"%1\"",
Path.GetFullPath(type.Icon));
}
}
}
public static void RegisterUnknownFiletypes(List<FiletypeAssociation> allTypes)
{
string mainExe = Assembly.GetEntryAssembly().Location;
string resPath = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "filetypes") + Path.DirectorySeparatorChar;
foreach (FiletypeAssociation type in allTypes) {
if (!IsRegisteredFileType(type.Extension)) {
RegisterFiletype(type.Extension,
type.Text,
'"' + Path.GetFullPath(mainExe) + '"' + " \"%1\"",
Path.GetFullPath(type.Icon));
}
}
string mainExe = Assembly.GetEntryAssembly().Location;
return openCommand.StartsWith(mainExe) || openCommand.StartsWith('"' + mainExe);
}
public static bool IsRegisteredFileType(string extension)
@ -88,12 +48,28 @@ namespace ICSharpCode.FiletypeRegisterer { @@ -88,12 +48,28 @@ namespace ICSharpCode.FiletypeRegisterer {
} catch (System.Security.SecurityException) {
// registry access might be denied
}
return false;
}
static string GetOpenCommand(string extension)
{
try {
using (RegistryKey key = Registry.CurrentUser.OpenSubKey("Software\\Classes\\." + extension)) {
return key != null;
string clsKeyName;
using (RegistryKey extKey = Registry.ClassesRoot.OpenSubKey("." + extension)) {
if (extKey != null)
clsKeyName = (string)extKey.GetValue("", "");
else
return null;
}
using (RegistryKey cmdKey = Registry.ClassesRoot.OpenSubKey(clsKeyName + "\\shell\\open\\command")) {
if (cmdKey != null)
return (string)cmdKey.GetValue("", "");
else
return null;
}
} catch (System.Security.SecurityException) {
return false;
// registry access might be denied
return null;
}
}
@ -106,9 +82,7 @@ namespace ICSharpCode.FiletypeRegisterer { @@ -106,9 +82,7 @@ namespace ICSharpCode.FiletypeRegisterer {
RegisterFiletype(Registry.CurrentUser.CreateSubKey("Software\\Classes"), extension, description, command, icon);
} catch {}
}
try {
SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, IntPtr.Zero, IntPtr.Zero);
} catch {}
NotifyShellAfterChanges();
}
static void RegisterFiletype(RegistryKey rootKey, string extension, string description, string command, string icon)
@ -140,9 +114,7 @@ namespace ICSharpCode.FiletypeRegisterer { @@ -140,9 +114,7 @@ namespace ICSharpCode.FiletypeRegisterer {
try {
UnRegisterFiletype(extension, Registry.CurrentUser.CreateSubKey("Software\\Classes"));
} catch {} // catch CreateSubKey(Software\Classes)-exceptions
try {
SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, IntPtr.Zero, IntPtr.Zero);
} catch {}
NotifyShellAfterChanges();
}
static void UnRegisterFiletype(string extension, RegistryKey root)
@ -173,5 +145,16 @@ namespace ICSharpCode.FiletypeRegisterer { @@ -173,5 +145,16 @@ namespace ICSharpCode.FiletypeRegisterer {
[System.Runtime.InteropServices.DllImport("shell32.dll")]
static extern void SHChangeNotify(int wEventId, int uFlags, IntPtr dwItem1, IntPtr dwItem2);
/// <summary>
/// Notify Windows explorer that shortcut icons have changed.
/// </summary>
static void NotifyShellAfterChanges()
{
const int SHCNE_ASSOCCHANGED = 0x08000000;
const int SHCNF_IDLIST = 0x0;
SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, IntPtr.Zero, IntPtr.Zero);
}
}
}

74
src/AddIns/Misc/FiletypeRegisterer/Project/Src/RegisterFiletypesPanel.Designer.cs generated

@ -0,0 +1,74 @@ @@ -0,0 +1,74 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
// <version>$Revision$</version>
// </file>
namespace ICSharpCode.FiletypeRegisterer
{
partial class RegisterFiletypesPanel
{
/// <summary>
/// Designer variable used to keep track of non-visual components.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Disposes resources used by the control.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing) {
if (components != null) {
components.Dispose();
}
}
base.Dispose(disposing);
}
/// <summary>
/// This method is required for Windows Forms designer support.
/// Do not change the method contents inside the source code editor. The Forms designer might
/// not be able to load this method if it was changed manually.
/// </summary>
private void InitializeComponent()
{
this.captionLabel = new System.Windows.Forms.Label();
this.fileTypesListBox = new System.Windows.Forms.CheckedListBox();
this.SuspendLayout();
//
// captionLabel
//
this.captionLabel.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.captionLabel.Location = new System.Drawing.Point(3, 0);
this.captionLabel.Name = "captionLabel";
this.captionLabel.Size = new System.Drawing.Size(328, 23);
this.captionLabel.TabIndex = 0;
this.captionLabel.Text = "${res:ICSharpCode.SharpDevelop.Gui.Dialogs.OptionPanels.RegisterFiletypesPanel.Ca" +
"ptionLabel}";
//
// fileTypesListBox
//
this.fileTypesListBox.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.fileTypesListBox.IntegralHeight = false;
this.fileTypesListBox.Location = new System.Drawing.Point(3, 26);
this.fileTypesListBox.Name = "fileTypesListBox";
this.fileTypesListBox.Size = new System.Drawing.Size(328, 299);
this.fileTypesListBox.TabIndex = 1;
//
// RegisterFiletypesPanel
//
this.Controls.Add(this.fileTypesListBox);
this.Controls.Add(this.captionLabel);
this.Name = "RegisterFiletypesPanel";
this.Size = new System.Drawing.Size(334, 328);
this.ResumeLayout(false);
}
private System.Windows.Forms.CheckedListBox fileTypesListBox;
private System.Windows.Forms.Label captionLabel;
}
}

130
src/AddIns/Misc/FiletypeRegisterer/Project/Src/RegisterFiletypesPanel.cs

@ -1,15 +1,12 @@ @@ -1,15 +1,12 @@
// <file>
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Georg Brandl" email="g.brandl@gmx.net"/>
// <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
// <version>$Revision$</version>
// </file>
// created on 16.11.2002 at 21:14
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;
@ -19,108 +16,57 @@ using ICSharpCode.SharpDevelop.Gui; @@ -19,108 +16,57 @@ using ICSharpCode.SharpDevelop.Gui;
namespace ICSharpCode.FiletypeRegisterer
{
class RegisterFiletypesPanel : AbstractOptionPanel {
ListView list = new ListView();
Label capLbl = new Label();
CheckBox regChk = new CheckBox();
Hashtable wasChecked = new Hashtable();
List<FiletypeAssociation> allTypes;
public RegisterFiletypesPanel()
public partial class RegisterFiletypesPanel : AbstractOptionPanel
{
sealed class ListEntry
{
allTypes = FiletypeAssociationDoozer.GetList();
internal readonly FiletypeAssociation Association;
internal readonly bool InitiallyChecked;
// Initialize dialog controls
InitializeComponent();
public ListEntry(FiletypeAssociation association)
{
this.Association = association;
this.InitiallyChecked = RegisterFiletypesCommand.IsRegisteredToSharpDevelop(association.Extension);
}
// Set previous values
SelectFiletypes(PropertyService.Get(RegisterFiletypesCommand.uiFiletypesProperty, RegisterFiletypesCommand.GetDefaultExtensions(allTypes)));
regChk.Checked = PropertyService.Get(RegisterFiletypesCommand.uiRegisterStartupProperty, false);
}
public override bool ReceiveDialogMessage(DialogMessage message)
{
if (message == DialogMessage.OK) {
UnRegisterFiletypes();
RegisterFiletypesCommand.RegisterFiletypes(allTypes, SelectedFiletypes);
PropertyService.Set(RegisterFiletypesCommand.uiFiletypesProperty, SelectedFiletypes);
PropertyService.Set(RegisterFiletypesCommand.uiRegisterStartupProperty, regChk.Checked);
public override string ToString()
{
return Association.Text + " (." + Association.Extension + ")";
}
return true;
}
string SelectedFiletypes
public RegisterFiletypesPanel()
{
get {
try {
string ret = "";
foreach(ListViewItem lv in list.Items) {
if(lv.Checked) ret += (string)lv.Tag + "|";
}
return ret;
} catch {
return "";
}
}
//
// The InitializeComponent() call is required for Windows Forms designer support.
//
InitializeComponent();
captionLabel.Text = StringParser.Parse(captionLabel.Text);
}
void UnRegisterFiletypes()
public override void LoadPanelContents()
{
foreach(ListViewItem lv in list.Items) {
if((!lv.Checked) && wasChecked.Contains((string)lv.Tag)) {
RegisterFiletypesCommand.UnRegisterFiletype((string)lv.Tag);
}
foreach (FiletypeAssociation assoc in FiletypeAssociationDoozer.GetList()) {
ListEntry entry = new ListEntry(assoc);
fileTypesListBox.Items.Add(entry, entry.InitiallyChecked);
}
}
void SelectFiletypes(string types) {
string[] singleTypes = types.Split('|');
foreach(string str in singleTypes) {
wasChecked[str] = true;
foreach(ListViewItem lv in list.Items) {
if(str == (string)lv.Tag) {
lv.Checked = true;
public override bool StorePanelContents()
{
for (int i = 0; i < fileTypesListBox.Items.Count; i++) {
bool newChecked = fileTypesListBox.GetItemChecked(i);
ListEntry entry = (ListEntry)fileTypesListBox.Items[i];
if (entry.InitiallyChecked != newChecked) {
if (newChecked) {
RegisterFiletypesCommand.RegisterToSharpDevelop(entry.Association);
} else {
RegisterFiletypesCommand.UnRegisterFiletype(entry.Association.Extension);
}
}
}
}
void InitializeComponent()
{
capLbl.Location = new Point(8, 8);
capLbl.Size = new Size(136, 16);
capLbl.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
capLbl.Text = StringParser.Parse("${res:ICSharpCode.SharpDevelop.Gui.Dialogs.OptionPanels.RegisterFiletypesPanel.CaptionLabel}");
list.Location = new Point(8, 30);
list.Size = new Size(136, 250);
list.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
list.View = View.List;
list.CheckBoxes = true;
FillList(list);
regChk.Location = new Point(8, 300);
regChk.Size = new Size(136, 20);
regChk.Anchor = capLbl.Anchor;
regChk.Text = StringParser.Parse("${res:ICSharpCode.SharpDevelop.Gui.Dialogs.OptionPanels.RegisterFiletypesPanel.RegisterCheckBox}");
this.Controls.AddRange(new Control[] {capLbl, list, regChk});
}
void FillList(ListView list)
{
foreach (FiletypeAssociation type in allTypes) {
ListViewItem lv;
lv = new ListViewItem(type.Text + " (." + type.Extension + ")");
lv.Tag = type.Extension;
list.Items.Add(lv);
}
return true;
}
}
}

2
src/Main/Base/Project/Src/Gui/Dialogs/AbstractOptionPanel.cs

@ -13,7 +13,7 @@ using ICSharpCode.SharpDevelop.Gui.XmlForms; @@ -13,7 +13,7 @@ using ICSharpCode.SharpDevelop.Gui.XmlForms;
namespace ICSharpCode.SharpDevelop.Gui
{
public abstract class AbstractOptionPanel : BaseSharpDevelopUserControl, IDialogPanel
public class AbstractOptionPanel : BaseSharpDevelopUserControl, IDialogPanel
{
bool wasActivated = false;
bool isFinished = true;

Loading…
Cancel
Save