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. 99
      src/AddIns/Misc/FiletypeRegisterer/Project/Src/RegisterFiletypesCommand.cs
  5. 74
      src/AddIns/Misc/FiletypeRegisterer/Project/Src/RegisterFiletypesPanel.Designer.cs
  6. 124
      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 @@
text = "SharpDevelop 1.x ${res:ICSharpCode.FiletypeRegisterer.Project}"/> text = "SharpDevelop 1.x ${res:ICSharpCode.FiletypeRegisterer.Project}"/>
</Path> </Path>
<!--
<Path name = "/Workspace/Autostart"> <Path name = "/Workspace/Autostart">
<Condition name = "Compare" string = "${property:SharpDevelop.FiletypesRegisterStartup??False}" equals = "True"> <Condition name = "Compare" string = "${property:SharpDevelop.FiletypesRegisterStartup??False}" equals = "True">
<Class id = "RegisterFiletypes" <Class id = "RegisterFiletypes"
class = "ICSharpCode.FiletypeRegisterer.RegisterFiletypesCommand"/> class = "ICSharpCode.FiletypeRegisterer.RegisterFiletypesCommand"/>
</Condition> </Condition>
</Path> </Path>
-->
<Path name = "/SharpDevelop/Dialogs/OptionsDialog/UIOptions"> <Path name = "/SharpDevelop/Dialogs/OptionsDialog/UIOptions">
<DialogPanel id = "RegisterFiletypes" <DialogPanel id = "RegisterFiletypes"

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

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

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

@ -18,14 +18,12 @@ namespace ICSharpCode.FiletypeRegisterer
string id; string id;
string icon; string icon;
string text; 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.id = id;
this.icon = icon; this.icon = icon;
this.text = text; this.text = text;
this.isDefault = isDefault;
} }
public string Extension { public string Extension {
@ -45,12 +43,6 @@ namespace ICSharpCode.FiletypeRegisterer
return text; return text;
} }
} }
public bool IsDefault {
get {
return isDefault;
}
}
} }
/// <summary> /// <summary>
@ -65,10 +57,6 @@ namespace ICSharpCode.FiletypeRegisterer
/// <attribute name="text" use="required"> /// <attribute name="text" use="required">
/// The description text. /// The description text.
/// </attribute> /// </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> /// <returns>
/// A FiletypeAssociation describing the specified values. /// A FiletypeAssociation describing the specified values.
/// </returns> /// </returns>
@ -101,8 +89,7 @@ namespace ICSharpCode.FiletypeRegisterer
{ {
return new FiletypeAssociation(codon.Id, return new FiletypeAssociation(codon.Id,
StringParser.Parse(codon.Properties["icon"]), StringParser.Parse(codon.Properties["icon"]),
StringParser.Parse(codon.Properties["text"]), StringParser.Parse(codon.Properties["text"]));
bool.TrueString.Equals(codon.Properties["autoRegister"], StringComparison.OrdinalIgnoreCase));
} }
} }
} }

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

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

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

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

Loading…
Cancel
Save