Click One Report Viewer Error - c#

I set
Microsoft System CLR Types for sql server 2012 x86
Microsoft System CLR Types for sql server 2012 x64
as prerequisites upon Click Once deployment. It seems to work fine on x64 machines but it crashes on x32 bit machines with the following message below. Was wondering how do I fix this?
Component Microsoft CLR types for sql server 2012 x64 has failed to install with the following error message:
"This installation package is not supported by this processor type. Contact your product vendor."
The following components were sucessfully installed:
Microsoft System CLR Types for sql server 2012 x86
The following components were not installed:
Microsoft report viewer 2012 runtime
The following components failed o install:
Microsoft System CLR Types for sql server 2012 x64

You're using the wrong package if you just want to display reports from a C# application. The easiest way of deploying the report viewer components is to include them with your ClickOnce deployment.
Go to the deployment settings and turn to the "Application files" tab and switch the deployment status to "Include" for the assemblies starting with "Microsoft.Report*".
Please note I'm using a German Visual Studio - the labels I quoted above may actually be named differently.

That is because you are trying to install a 64bit application on a 32bit machine. check what the machine is running prior to installing, and then set the applications required up for install.
This is how you can check what type the machine is running from C#
static bool is64BitProcess = (IntPtr.Size == 8);
static bool is64BitOperatingSystem = is64BitProcess || InternalCheckIsWow64();
[DllImport("kernel32.dll", SetLastError = true, CallingConvention = CallingConvention.Winapi)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool IsWow64Process(
[In] IntPtr hProcess,
[Out] out bool wow64Process
);
public static bool InternalCheckIsWow64()
{
if ((Environment.OSVersion.Version.Major == 5 && Environment.OSVersion.Version.Minor >= 1) ||
Environment.OSVersion.Version.Major >= 6)
{
using (Process p = Process.GetCurrentProcess())
{
bool retVal;
if (!IsWow64Process(p.Handle, out retVal))
{
return false;
}
return retVal;
}
}
else
{
return false;
}
}

Related

Excel 2016 VSTO Addin With Native Code DLL

Creating an Excel addin using an SDK from a 3rd party. The SDK contains a native code DLL (in both 32 and 64 bit versions). My addin code is in C# and it appears that addins only run if compiled under "AnyCPU" option.
When I attempt to run the app I get "An attempt was made to load a program with an incorrect format. (Exception from HRESULT: 0x8007000B)" which usually means a 64/32 mismatch, and the error is from attempting to load the 3rd party native code DLL.
My question is: are my assumptions correct about AnyCPU and is there a way to run native code DLL's from an addin compiled under AnyCPU? Thanks!
before .net 4.5 the AnyCPU depends on your current compile machine.
if your machine is 32bit CPU, AnyCPU will compile your program as 32bit program. if it's 64bit CPU, i t will compile as 64bits.
after .net 4.5, the AnyCPU changed:
If the process runs on a 32-bit Windows system, it runs as a 32-bit
process. IL is compiled to x86 machine code.
If the process runs on
a 64-bit Windows system, it runs as a 32-bit process. IL is compiled
to x86 machine code.
If the process runs on an ARM Windows system,
it runs as a 32-bit process. IL is compiled to ARM machine code.
If you want your program can run both 32bit and 64bit cpu, you should link your native code DLL with 32 bit version, otherwise you need to compile them in separate CPUs
Yes it is possible, you can create some wrappers functions that redirect the call to the native dll depending on the current architecture , example :
[DllImport("bin32\\Native86Dll", EntryPoint = "MyFunc", CharSet = CharSet.Ansi, ExactSpelling = true)]
public static extern int MyFunc_32(string sCommand);
[DllImport("bin64\\Native64Dll", EntryPoint = "MyFunc", CharSet = CharSet.Ansi, ExactSpelling = true)]
public static extern int MyFunc_64(string sCommand);
public static int MyFunc(string sCommand )
{
return System.Environment.Is64BitProcess ? MyFunc_64(sCommand) : MyFunc_32(sCommand);
}

DriverPackagePreinstall to work on 64 bit (compiled to 32 bit)

Is there a way I can compile an application which calls the DriverPackagePreinstall() (using Pinvoke) in such a way that it can work on 64-bit devices (Windows 7) even though it's targeted to 32bit?
The reason being it will be run as part of an installer of a much bigger application (using Windows Installer Project), which will target 32 bit but must run on a 64 bit platform also.
Here is my code:
using System;
using System.Linq;
using System.Runtime.InteropServices;
namespace MyDriver
{
class Program
{
static void Main(string[] args)
{
if (args.Count() == 0)
{
Console.WriteLine("Please specify filename!");
return;
}
int result= DriverPackagePreinstall(args[0], 0);
if (result == 0)
{
Console.WriteLine("Success");
} else {
Console.WriteLine("Error: 0x{0}", result.ToString("X8"));
}
}
[DllImport("DIFxAPI.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern Int32 DriverPackagePreinstall(
[MarshalAs(UnmanagedType.LPTStr)] string DriverPackageInfPath,
Int32 Flags);
}
}
}
If I build this targeting x86, and try to run on a 64-bit machine, I get error E0000235 (ERROR_IN_WOW64). This error goes away if I build targeting x64.
Now I don't mind compiling it twice and letting the installer decide which to install based on the platform it's being installed to. However, if I try to build the installer while including the 64-bit version I get the error,
263 File 'MyDriver.x64.exe' targeting 'AMD64' is not compatible with the project's target platform 'x86'
Alternatively a way of getting the Installer to overlook this error at build time (and run it anyway when the project is installing) would be good.
I worked around this by adding both the 64-bit and 32-bit versions of the application to a self-extracting zip-file together with a batch file which decides which one to execute.
The self-extractor is a 32-bit exe so as long no one tells Visual Studio that it contains a 64-bit one, it works.

C++ DLL being called from WCF Service Application not working when deployed in IIS 8?

I am calling a C++ DLL using DLLImport. The code is in a class library project which is being called from a WCF Service Application.
[DllImport(dllPath, SetLastError=true)]
public static extern IntPtr CDSEngineConstructor();
[DllImport(dllPath, SetLastError=true)]
[return: MarshalAs(UnmanagedType.I1)]
public static extern bool InitialiseDSEngine(StringBuilder pSB, IntPtr pDSEngine, StringBuilder pName, [MarshalAs(UnmanagedType.LPArray)] string[] ppListToLoad, UInt32 usiNumber);
I get a IntPtr on successfully calling the dll's constructor.
IntPtr pEngine = CDSEngineConstructor();
I use the above value as a parameter to call another initialize method in the dll.
if (!InitialiseDSEngine(sb, pEngine, sbReportingName, lstTyping.ToArray(), 10))
throw new Exception("Failded to initilaise the search engine. please check the logs")
EDIT: the log files are not getting created!
The above method runs fine when I run my WCF in VS2008 development server. But after deploying the same in IIS 8, the above method returns false which means it fails to initialize and I cannot proceed further.
The DLL was built with Release mode in x86. My Class Library Project is also built with same Active configuration.
I have also tried to install C++ redistributable 2008 in the server. The IIS is setup to run 32 bit applications.
I am unable to find a solution and reason for this behavior. Querying for the same returns results where the dll itself is not loaded. But I'm able to load the dll correctly in this case.
Let me know if I have missed any information.

HTTP Status 502 error when returning string from C DLL to C# DLL on Windows Server 2012

I'm working on setting up an old C# DLL (written in Visual Studio 2003) on a server running Windows Server 2012 R2. The DLL is raising an error when it calls a C DLL (also compiled using Visual Studio 2003) which returns a string. The error message raised when the C DLL attempts to return the string is as follows:
System.Net.WebException: The request failed with HTTP status 502:
Proxy Error ( The specified network name is no longer available. ).
The code runs without any issues on XP and on Windows 7, and the C# DLL is being executed by an ASP.NET web service.
The relevant C# code is as follows:
[DllImport("ESConnect.dll", SetLastError=false, CharSet=CharSet.Ansi)]
private static extern StringBuilder EsGetText(ref StringBuilder name, ref StringBuilder strReturned, ref size);
.
.
.
StringBuilder sbReturned = new StringBuilder();
StringBuilder sbTemporary = new StringBuilder();
sbTemporary=EsGetText(ref sbName, ref sbReturned, ref size);
And the C code, for the function EsGetText, is:
FNEXPORT( PSZ __stdcall, EsGetText )( PSZ *ppszName, PSZ *ppszValue, PSHORT psSize)
{
PFILE pFile = NULL;
gdClock = USE( gdClock, fnTime() );
TbxGetText( *ppszName, *ppszValue, (SHORT)( psSize ? *psSize : 0 ) );
return( *ppszValue );
}
I can tell from logging that I added that EsGetText is successfully populating the value in ppszValue but once the return command is executed the "HTTP status 502" error is raised.
Any ideas at all as to what might be causing this issue are more than welcome.
Thanks.
Set your ASP.Net web service to use an ASP.Net 2.0 app pool. If you do not have any ASP.Net 2.0 app pools available, make sure you have .Net 3.5.2 installed. It sounds like your older web service has some configuration that is not .Net 4 compatible. This is not uncommon, and if you don't need .Net 4, there's really no need to upgrade the code/service.

COM cannot start out-of-process .Net server compiled as AnyCPU

I am trying to get COM to start my out-of-process .NET COM server. It works if the server process is compiled with x64, but if I use AnyCPU (which is what I want) then it hangs for a while and eventually fails with 0x80080005 (CO_E_SERVER_EXEC_FAILURE). How can I get this to work?
I am running on a 64-bit machine: Windows 7 with Visual Studio 2008 SP1.
I can see in Task Manager that it does start my server. So I guess the problem is in the communications between COM and the server (class registration).
My test client application is written in C#, but it doesn't matter whether it is compiled for x86 or x64. The problem also occurs with something written in 32-bit C++.
If I rebuild the server using x64 and run it, and then rebuild back as AnyCPU, then COM can start it. A reboot will take me back to the original situation. Perhaps COM doesn't know in advance what bitness is going to be used, and a previous execution helps.
I found Andy McMullen's blog post and tried passing CLSCTX_ACTIVATE_64_BIT_SERVER to CoCreateInstance(), but that triggers a failure earlier: 0x80040154 (REGDB_E_CLASSNOTREG). Am I doing something wrong in my COM registration? You can see below that it is very simple. Registration occurs when running in 64 bits, and the problem occurs when the client is 64 bits, so Wow6432Node should not be involved.
Another chap has had a similar problem, but the MSFT answer is confusing. He seems to be suggesting it can only work via DCOM (see link) or COM+. I suspect either will be an awful lot of work, and substantially worse than distributing my .exe built as x64 and x86.
You may be wondering why I am implementing IPersistFile. It is because my real problem is to get BindMoniker() working from a 32-bit C++ program to my AnyCPU .Net program. I have reduced my problem to the simpler example presented here.
Here is the client code:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
[DllImport("ole32.dll", ExactSpelling = true, PreserveSig = false)]
[return: MarshalAs(UnmanagedType.Interface)]
static extern object CoCreateInstance(
[In, MarshalAs(UnmanagedType.LPStruct)] Guid rclsid,
[MarshalAs(UnmanagedType.IUnknown)] object pUnkOuter,
CLSCTX dwClsContext,
[In, MarshalAs(UnmanagedType.LPStruct)] Guid riid);
[Flags]
enum CLSCTX : uint
{
CLSCTX_LOCAL_SERVER = 0x4,
CLSCTX_ACTIVATE_64_BIT_SERVER = 0x80000,
}
private void Form1_Load(object sender, EventArgs e)
{
IPersistFile pf = (IPersistFile)CoCreateInstance(
new Guid("1984D314-FC8D-44bc-9146-8A13500666A6"),
null,
CLSCTX.CLSCTX_LOCAL_SERVER,
new Guid("0000010b-0000-0000-C000-000000000046")); // IPersistFile
pf.Load("c:\\bozo", 0);
}
}
and here is the server:
static class Program
{
[STAThread]
static void Main()
{
if (Environment.CommandLine.Contains("/reg")) {
RegistryKey cls = Registry.LocalMachine.CreateSubKey(String.Format(
"SOFTWARE\\Classes\\CLSID\\{0}", PersistFile.ClassID.ToString("B")));
cls.SetValue("InprocHandler32", "Ole32.dll");
RegistryKey ls32 = cls.CreateSubKey("LocalServer32");
ls32.SetValue(null, '"' + Application.ExecutablePath + '"');
ls32.SetValue("ServerExecutable", Application.ExecutablePath);
}
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
RegistrationServices reg = new RegistrationServices();
reg.RegisterTypeForComClients(
typeof(PersistFile),
RegistrationClassContext.LocalServer,
RegistrationConnectionType.MultipleUse);
Application.Run(new Form1());
}
}
[ComVisible(true),
Guid("1984D314-FC8D-44bc-9146-8A13500666A6"),
ClassInterface(ClassInterfaceType.None)]
public class PersistFile : IPersistFile
{
public static Guid ClassID
{
get
{
GuidAttribute a = (GuidAttribute)typeof(PersistFile).GetCustomAttributes(typeof(GuidAttribute), false)[0];
return new Guid(a.Value);
}
}
#region IPersistFile
public void GetClassID(out Guid pClassID)
{
MessageBox.Show("GetClassID");
pClassID = ClassID;
}
public int IsDirty()
{
MessageBox.Show("IsDirty");
return 1;
}
public void Load(string pszFileName, int dwMode)
{
MessageBox.Show(String.Format("Load {0}", pszFileName));
}
public void Save(string pszFileName, bool fRemember)
{
MessageBox.Show("Save");
throw new NotImplementedException();
}
public void SaveCompleted(string pszFileName)
{
MessageBox.Show("SaveCompleted");
throw new NotImplementedException();
}
public void GetCurFile(out string ppszFileName)
{
MessageBox.Show("GetCurFile");
throw new NotImplementedException();
}
#endregion
}
I guess the problem is at run-time. I have created a COM Server which registers using a C++ library (registration is performed flawlessly). I have run into problems when switching to AnyCPU from .NET (CS).
The architecture:
C++ library interfacing COM (built on both x64 and x86 platforms)
.NET library wrapper (CS) (correctly instantiates the required x64/x86 C++ library)
.NET application (CS) - COM client or COM server
Ugly things happen when registering the .NET application built as "AnyCPU". Once the COM Client invokes the COM Server through DCOM, the server application starts but the client receives error that the COM Server could not be started.
I went some steps further, analyzed registration data with procmon and other tools and I reached the same conclusion:
x86 registers the classes in CLASSES\Wow6432Node
x64 and AnyCPU register the classes in CLASSES (on a x64 windows machine, exactly the same keys; I bet that x86 and AnyCPU would register the same on an x86 machine)
Now, I did some more experiments: the x86/x64/AnyCPU COM Client can connect with no problems to any x86/x64 COM Server but it cannot connect anyhow to an AnyCPU COM Server...
I then performed the following test cases:
Have the x86 COM Server register, replace the executable with the AnyCPU COM Server: COM Client was starting the x86 COM Server, but no communication... it was starting the server over and over again..
Have the x64 COM Server register, replace the executable with the AnyCPU COM Server: COM Client was starting the x64 COM Server, but no communication... it was starting the server over and over again..
Have the AnyCPU COM Server register, replace the executable with the x86 COM Server: COM Client was able to successfully start the and connect to the x86 COM Server.
Have the AnyCPU COM Server register, replace the executable with the x64 COM Server: COM Client was able to successfully start the and connect to the x64 COM Server.
Have the x86 COM Server register, replace the executable with the x64 COM Server: COM Client was able to successfully start the and connect to the x64 COM Server.
Have the x64 COM Server register, replace the executable with the x86 COM Server: COM Client was able to successfully start the and connect to the x86 COM Server.
Where the hell is the communication problem? This is very odd... None of the presented solutions (CLSCTX_ACTIVATE_64_BIT_SERVER, PreferredServerBitness or corflags) helped.
Anyone else did some progress on this matter? Should we contact Microsoft?
Try to use the RegistrationServices class to register your com assembly. It will also choose the correct registry pathes and do some other things.
Example:
Assembly currentAssembly = Assembly.GetExecutingAssembly();
System.Runtime.InteropServices.RegistrationServices regAsm = new System.Runtime.InteropServices.RegistrationServices();
bool isRegistered = regAsm.RegisterAssembly(currentAssembly, System.Runtime.InteropServices.AssemblyRegistrationFlags.SetCodeBase);
Also I think, that .NET client assemblies have some trouble according to .NET com servers, but I can't find any resource for it...
Hope, it will help...

Categories

Resources