To reproduce:
- Create new WinForms application (NET 4.0).
- Drop XtraGrid on Form1.
- Drop SimpleButton on Form1 and in "…Click" handler write:
private void simpleButton1_Click(object sender, EventArgs e)
{
if (gridControl1.IsPrintingAvailable)
{
gridControl1.ShowPrintPreview();
}
else
{
MessageBox.Show("ERROR");
}
} - Copy all needed redistributable assemblies into the target directory on target machine and click button.
- Everything works as expected.
--- - NOW, start the application from *NETWORK SHARE* and "ERROR" message box shows.
--- - If you change event handler to this:
new XtraReport().ShowPreview(); // <-- here!
gridControl1.ShowPrintPreview();
…everything works as expected.
It looks like XtraPrinting doesn't get properly initialized/loaded when called from GridControl from network share.
Same goes for v2011 v1.6 - I believe it work properly before that…
TIA,
Dusan Pupis
Hi Dusan,
This is not a bug. When you are calling the
gridControl1.ShowPrintPreview()
method, GridControl tries to load the printing assembly using Reflection. More likely, the use of the Reflection code when running an app from the network share is forbidden and thus the IsPrintingAvailable method returns false. When you create an XtraReport instance, all required assemblies are loaded in the application domain by VS and you do not see this problem.
Thanks,
Plato
It worked until v2011 1.6…
So it is either:
a) a bug, or
b) a breaking change?
Dusan
In case you consider it a breaking change…
Could you please provide me with a short, working example of
how one can use print preview functionality of the grid control when application is being run from the network share?
LP,
Dusan
Hi Dusan,
I do not see the difference in code. This part was not changed. Here is the code used to determine if the printing is available:
static PrintHelperBase() { printingAssembly = DevExpress.Data.Utils.Helpers.LoadWithPartialName(AssemblyInfo.SRAssemblyPrinting + ", Version=" + AssemblyInfo.Version); isPrintingAvailable = printingAssembly != null; } ... public static Assembly LoadWithPartialName(string partialName) { return Assembly.LoadWithPartialName(partialName); }
This code did not change. Also, I tried to run 10.2 and 11.1 from the network share and do not see this issue. You may try to execute it manually. Does it work for you?
Thanks,
Plato
Hi.
This is quite strange.
Please allow me to quickly recap.
***
1.
CODE:
gridControl1.ShowPrintPreview();
a) from local drive => works as expected
b) from network drive => throws with "Object reference not set to…" at DevExpress.XtraPrinting.ComponentPrinter.CreateLink()
***
2.
CODE:
if (gridControl1.IsPrintingAvailable) {
gridControl1.ShowPrintPreview();
} else {
MessageBox.Show("Y U NO PRINT!?");
}
a) from local drive => works as expected
b) from network drive => shows message box
***
BUT!
***
3.
CODE:
if (PrintHelperBase.IsPrintingAvailable) {
gridControl1.ShowPrintPreview();
} else {
MessageBox.Show("Y U NO PRINT!?");
}
a) from local drive => works as expected
b) from network drive => WORKS AS EXPECTED
***
4.
SOURCE:
DevExpress.Data.Utils.Helpers.LoadWithPartialName(AssemblyInfo.SRAssemblyPrinting + ", Version=" + AssemblyInfo.Version);
gridControl1.ShowPrintPreview();
Also works as expected.
***
CONCLUSION:
Apparently gridControl1.IsPrintingAvailable does something different than PrintHelperBase.IsPrintingAvailable and does not successfully load needed assembly?
How to workaround?
WBR,
Dusan
Hi Dusan,
Please accept my sincere apologies. It looks like each time I look at the source, I see a new chain on how the code is executed. Here is the correct stack trace:
class GridControl:
public bool IsPrintingAvailable { get { return ComponentPrinter.IsPrintingAvailable(false); } }
class ComponentPrinter:
public static bool IsPrintingAvailable(bool throwException) {
return SingletonContainer.GetPrintingAssembly(throwException) != null;
}
class SingletonContainer {
static SingletonContainer() {
}
static System.Reflection.Assembly printingAssembly = DevExpress.Data.Utils.AssemblyCache.LoadDXAssembly(AssemblyInfo.SRAssemblyPrinting);
public static System.Reflection.Assembly GetPrintingAssembly(bool throwException) {
if(throwException && printingAssembly == null)
throw new Exception(AssemblyInfo.SRAssemblyPrinting + " isn't found.");
return printingAssembly;
}
}
class AssemblyCache:
public static Assembly LoadDXAssembly(string name) {
try {
AssemblyName assemName = Assembly.GetExecutingAssembly().GetName();
assemName.Name = name;
return Load(assemName);
} catch {
return null;
}
}
public static Assembly Load(AssemblyName assemName) {
lock(padlock) {
Assembly value;
if(LoadedAssemblies.TryGetValue(assemName.Name, out value))
return value;
value = Assembly.Load(assemName);
LoadedAssemblies[assemName.Name] = value;
return value;
}
}
As for the workaround, use the PrintHelperBase.IsPrintingAvailable method instead. Also, could you please send us a callstack leading to this problem?
Thanks,
Plato
Like I said previously, following errors show only when running from network, not locally.
In addition to the aforementioned PrintHelperBase.IsPrintingAvailable, which works,
I played with code snippets from source you posted and came to some conclusions:
------------------------------
1.
var available = Assembly.Load(AssemblyInfo.SRAssemblyPrinting) != null;
MessageBox.Show(available.ToString());
…returns TRUE and preview consequentially works.
------------------------------
2.
var available = DevExpress.Data.Utils.AssemblyCache.LoadDXAssembly(AssemblyInfo.SRAssemblyPrinting) != null;
MessageBox.Show(available.ToString());
…return FALSE and preview DOES NOT work.
------------------------------
3.
var assemName = Assembly.GetExecutingAssembly().GetName();
assemName.Name = AssemblyInfo.SRAssemblyPrinting;
assemName.Version = new Version(AssemblyInfo.Version);
var available = DevExpress.Data.Utils.AssemblyCache.Load(assemName) != null;
MessageBox.Show(available.ToString());
THROWS with:
System.IO.FileLoadException: Could not load file or assembly 'DevExpress.XtraPrinting.v11.1, Version=11.1.7.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies.
The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)
File name: 'DevExpress.XtraPrinting.v11.1, Version=11.1.7.0, Culture=neutral, PublicKeyToken=null'
at System.Reflection.RuntimeAssembly._nLoad(AssemblyName fileName, String codeBase, Evidence assemblySecurity, RuntimeAssembly locationHint, StackCrawlMark& stackMark, Boolean throwOnFileNotFound, Boolean forIntrospection, Boolean suppressSecurityChecks)
at System.Reflection.RuntimeAssembly.nLoad(AssemblyName fileName, String codeBase, Evidence assemblySecurity, RuntimeAssembly locationHint, StackCrawlMark& stackMark, Boolean throwOnFileNotFound, Boolean forIntrospection, Boolean suppressSecurityChecks)
at System.Reflection.RuntimeAssembly.InternalLoadAssemblyName(AssemblyName assemblyRef, Evidence assemblySecurity, StackCrawlMark& stackMark, Boolean forIntrospection, Boolean suppressSecurityChecks)
at System.Reflection.Assembly.Load(AssemblyName assemblyRef)
at DevExpress.Data.Utils.AssemblyCache.Load(AssemblyName assemName)
at WindowsFormsApplication7.Form1.simpleButton3_Click(Object sender, EventArgs e) in w:\Infoteh2\WindowsFormsApplication7\WindowsFormsApplication7\Form1.cs:line 90
------------------------------
4.
var available = DevExpress.Data.Utils.AssemblyCache.LoadWithPartialName(AssemblyInfo.SRAssemblyPrinting) != null;
MessageBox.Show(available.ToString());
…returns TRUE and preview consequentially works.
------------------------------
5.
var available = DevExpress.Data.Utils.Helpers.LoadWithPartialName(AssemblyInfo.SRAssemblyPrinting + ", Version=" + AssemblyInfo.Version) != null;
MessageBox.Show(available.ToString());
…returns TRUE and preview consequentially works.
------------------------------
So I guess the trouble lies within DevExpress.Data.Utils.AssemblyCache.LoadDXAssembly (even standard Assembly.Load WORKS).
Please find demo project attached (executable in bin/debug).
This is getting kind of urgent, so I'd appreciate your prompt reply.
TIA,
Dusan
Hi Dusan,
I've reproduced the problem using your project. It was necessary to also remove assemblies from the GAC. I have passed this issue to our R&D and we will try to fix it as soon as possible.
Thanks,
Plato
Hi Dusan,
Please accept my sincere apologies for the delay in responding.
Our developers suggest that you add the loadFromRemoteSources option to the configuration file of your application to resolve this issue. Please review the <loadFromRemoteSources> Element article for additional information. Thanks for your feedback in advance.
Thanks,
Elliot