2011-06-17 68 views
0

我很努力獲得動態加載與我的插件工作。我加載插件到一個AppDomain,但我得到以下異常時,我的插件試圖執行任何MySQL代碼:mySQL錯誤與插入加載到appDomain

MySql.Data.MySqlClient.MySqlException 了未處理
消息=拒絕訪問 用戶'' @ '本地主機'(使用密碼 :否)

這裏是關於Plugins.cs的代碼:

public class Plugins { 

private static List<PluginContainer> PluginList; 
public static bool PluginsAreLoaded { 
get { 
if(PluginList==null) { 
return false; 
} 
else { 
return true; 
} 
} 
} 

public static void LoadAllPlugins(Form host) { 
//add assemblies in OD folder to appDomain 
Assembly[] list = AppDomain.CurrentDomain.GetAssemblies(); 
AppDomain appDomainAnesthesia AppDomain.CreateDomain("appDomainAnesthesia"); 
for(int i=0;i<ProgramC.Listt.Count;i++) { 
string dllPathWithVersion = String.Empty; 
if(!ProgramC.Listt[i].Enabled) { 
continue; 
} 
if(ProgramC.Listt[i].PluginDllName=="") { 
continue; 
} 
string dllPath=ODFileUtils.CombinePaths(Application.StartupPath,ProgramC.Listt[i].PluginDllName); 
if(dllPath.Contains("[VersionMajMin]")) { 
Version vers=new Version(Application.ProductVersion); 
dllPathWithVersion=dllPath.Replace("[VersionMajMin]",vers.Major.ToString()+"."+vers.Minor.ToString()); 
dllPath=dllPath.Replace("[VersionMajMin]","");//now stripped clean 
if(File.Exists(dllPathWithVersion)){ 
File.Copy(dllPathWithVersion,dllPath,true); 
} 
} 
if(!File.Exists(dllPath)) { 
continue; 
} 
//add our plugin to the appDomain 
try {      
string typeName = Path.GetFileNameWithoutExtension(dllPath) + ".Plugin"; 
PluginBase plugin = (PluginBase)appDomainAnesthesia.CreateInstanceAndUnwrap(Path.GetFileNameWithoutExtension(dllPathWithVersion), typeName); 
appDomainAnesthesia.Load(Path.GetFileNameWithoutExtension(dllPathWithVersion)); 
plugin.Host=host; 
} 
catch(Exception ex) { 
MessageBox.Show(ex.Message); 
continue;//don't add it to plugin list. 
}  
PluginContainer container=new PluginContainer(); 
container.Plugin=plugin; 
container.ProgramNum=ProgramC.Listt[i].ProgramNum; 
PluginList.Add(container); 
} 

} 

下面是PluginBase:

public abstract class PluginBase : MarshalByRefObject { 
private Form host; 
///<summary>This will be a refrence to the main FormOpenDental so that it can be used by the plugin if needed. It is set once on startup, so it's a good place to put startup code.</summary> 
public virtual Form Host { 
get { 
return host; 
} 
set { 
host=value; 
} 
} 

///<summary>These types of hooks are designed to completely replace the existing functionality of specific methods. They always belong at the top of a method.</summary> 
public virtual bool HookMethod(object sender,string methodName,params object[] parameters) { 
return false;//by default, no hooks are implemented. 
} 
///<summary>These types of hooks allow adding extra code in at some point without disturbing the existing code.</summary> 
public virtual bool HookAddCode(object sender,string hookName,params object[] parameters) { 
return false; 
} 
public virtual void LaunchToolbarButton(long patNum) { 
} 

}

PluginContainer:

class PluginContainer { 
public PluginBase Plugin; 
public long ProgramNum; 

最後,插件:

public class Plugin : PluginBase { 
private Form host; 
public AnestheticData AnesthDataCur; 
public AnestheticRecord AnestheticRecordCur; 
public Patient PatCur; 
public string SourceDirectory; 
public string DestDirectory; 
public System.ComponentModel.IContainer components; 
public long patNum; 
public static Procedure procCur; 
public static List<Procedure> ProcList; 
public static ODtextBox textNotes; 
public override Form Host { 
get { 
return host; 
} 
set { 
host=value; 
ConvertAnesthDatabase.Begin();//if this crashes, it will bubble up and result in the plugin not loading.                         } 
} 

它炸彈在

plugin.Host=host; 

Plugins.cs來自ConverAnesthDatabase.Begin()方法,因爲那裏有多個mySQL語句。

我有權訪問mySQL數據庫,所以這不是問題。

如何解決此錯誤?

+0

是否'ConvertAnesthDatabase.Begin();'的工作,當你將它直接放在在您的應用程序中,而不是動態加載它? – ChrFin

+0

是的。如果我從PluginBazse中刪除:MarshalByRefObject,則沒有任何問題。 –

+0

我只是在這裏猜測,因爲我在你的例子中找不到任何'mysql'代碼,但是它可能是你在一個'AppDomain'的靜態字段中設置了用戶名和密碼,然後嘗試在另一箇中使用它們'AppDomain'? –

回答

0

儘量不要 「擴展」 您的PluginBase和使用的接口來代替:

public interface IPlugin 
{ 
    Form Host {get; set; } 
    bool HookMethod(object sender,string methodName,params object[] parameters); 
    bool HookAddCode(object sender,string hookName,params object[] parameters); 
    void LaunchToolbarButton(long patNum); 
} 

然後

public class Plugin : IPlugin 
{ 
    ... 
} 
+0

做了這個變化,但是當我嘗試構建時,我得到:錯誤'OpenDentBusiness.Iface.HookAddCode(object,string,params object [])':接口成員不能定義\t C:\ Users \ wjs \ Desktop \ ODVersions \ opendental11.0b \ opendental11.0 \ OpenDentBusiness \ Plugins \ PluginBase.cs OpenDentBusiness –

+0

界面如何?你是否在接口中實現了'HookAddCode'方法,因爲你不能用接口來實現,你需要在插件本身中實現它? – ChrFin

+0

1月 - 彼得 - 他們沒有設置爲Current.Domain中的靜態字段,但他們被傳遞到一個窗體的靜態實例。 chrfin - 感謝您的幫助 - 不幸的是,我對插件界面沒有任何控制權,因爲我的插件是針對另一個開源程序的。 –