Attempting to access a 32 bit sdk through com on 64 bit - c#

Within the context of an application I'm developing data exporting functionality. This functionality takes data from the application and attempts to transfer it into another application.
This other application allows data-exchange trough a 32-bit com interface. Now my application get builds both in 32 bit and in 64 bit. In case of 32 bit there are no problems, when I build it in 64-bit however...
I've done some research on the subject and I found a solution.
I tried this and it appeared to work.. up until a point...
connnection = new ClSdk.Venice();
bsCreatedForVenVer = "11.50_";
_bsAppName = "MyApplication";
eLanguage = eLanguage.lngNld;
bWithUserInterface = true;
bsInitials = "XXX";
bsName = "Yzzzzzzzzzzzz";
bsPassword = "Yzzzzzzzzzzzz";
_bsFunction = "Uvvvvvvv Wxxxxxxx";
_bsCabinet = "Abbbb";
bsDossier = "Some Client";
accessMode = connnection.GetAccessMode();
if (accessMode == eAccessMode.amSecure)
{
connnection.LogonSecure(bsCreatedForVenVer, _bsAppName, eLanguage,
bWithUserInterface, bsName, bsPassword);
}
else
{
connnection.Logon(bsCreatedForVenVer, _bsAppName, eLanguage, bWithUserInterface, bsInitials, bsName, _bsFunction);
}
When I started I would get an exception the second I tried creating new instance of the ClSdk.Venice class. After following the steps I found on the post the creation of the instance worked flawlessly, but when coming to to the connection part (connnection.LogonSecure) a new exception was thrown: 'errNoInterfaceAsService:
No interface allowed if running as a service.'
visual studio screenshot
I've been trying to find some more information on this exception, but so far my searches didn't turn up anything useful.
Does anyone here has an idea how to resolve this?

Related

corrupted resources in wince application using Compact Framework 3.5

I'm maintaining a windows ce form application developed on compact framework 3.5
The problem that i'm struggling with is that the application running on a windows ce 6.0 device after a few days of working crashes. It presents an exception:
SerializationException 255 at Systems.Resources.ResourceReader.ParseMessageEnd() at
System.Resources.ResourceReader.LoadBitmap(Int 32 typeIndex) etc
I've used then .Net Reflector to analyse the exe file that runs on the device and I found out that some resources are corrupted and they have a value: Invalid resource TypeCode '-1' and the type is System.BadImageFormatException, mscorlib, Veersion=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 whilst the non corrupted resources have Version=2.0.0.0
It's really strange how the files get corrupted and the version changes.
I also found in the code a 200ms timer that runs forever and in that timer there was also this code which caused a lagging in the ui:
if (Global.ParSotteraneiQuadro.typepompa == ClParSottQuadro.EnTipoPompa.PNEUM)
{
ImagesMOTORE[0] = Resources.pump_OFF;
ImagesMOTORE[1] = Resources.pump_OFF;
ImagesMOTORE[2] = Resources.pump_ON;
ImagesMOTORE[3] = Resources.pump_ON;
btPompa.ImageBack = Resources.pump_OFF;
btPompa.ImageFore = Resources.pump_ON;
MemImageMOTORE = new ClassMemImage(ImagesMOTORE);
ImagesTempWait[0] = Resources.anim12_230;
ImagesTempWait[1] = Resources.anim22_230;
ImagesTempWait[2] = Resources.anim32_230;
ImagesTempWait[3] = Resources.anim42_230;
ImagesTempWait[4] = Resources.sfondo_arancio; // arancione vuoto
ImagesTempWait[5] = Resources.sfondo_red; // rosso vuoto
ImagesTempWait[6] = Resources.warning_230;
ImagesTempWait[7] = Resources.ok_230;
ImagesTempWait[8] = Resources.eco_top;
ImagesTempWait[9] = Resources.abil_pompa_pump;
ImagesTempWait[10] = Resources.abil_24VOLT_sfumato;
ImagesTempWait[11] = Resources.ok_230_giallo;
MemImageWaitTemp = new ClassMemImage(ImagesTempWait);
}
else
{
ImagesMOTORE[0] = Resources.motor_OFF;
ImagesMOTORE[1] = Resources.motor_OFF;
ImagesMOTORE[2] = Resources.motor_ON;
ImagesMOTORE[3] = Resources.motor_ON;
btPompa.ImageBack = Resources.motor_OFF;
btPompa.ImageFore = Resources.motor_ON;
MemImageMOTORE = new ClassMemImage(ImagesMOTORE);
ImagesTempWait[0] = Resources.anim12_230;
ImagesTempWait[1] = Resources.anim22_230;
ImagesTempWait[2] = Resources.anim32_230;
ImagesTempWait[3] = Resources.anim42_230;
ImagesTempWait[4] = Resources.sfondo_arancio; // arancione vuoto
ImagesTempWait[5] = Resources.sfondo_red; // rosso vuoto
ImagesTempWait[6] = Resources.warning_230;
ImagesTempWait[7] = Resources.ok_230;
ImagesTempWait[8] = Resources.eco_top;
ImagesTempWait[9] = Resources.abil_pompa;
ImagesTempWait[10] = Resources.abil_24VOLT_sfumato;
ImagesTempWait[11] = Resources.ok_230_giallo;
MemImageWaitTemp = new ClassMemImage(ImagesTempWait);
}
Has someone faced something like this? Thank you for your help
IIRC resources are loaded in writable memory, this means that application may overwrite that data if the pointers are used in the wrong way. Usually you don't access pointer directly in .NET, but those "Mem" classes may need some more investigation.
And just a small not on performances, maybe all the assignments and allocations should be done only if Global.ParSotteraneiQuadro.typepompa has changed since the last check.
To autorun from external storage on insert:
"Auto-Run Applications on Compact Flash Cards
Starting with Windows CE 3.0 it is possible to have an application run from a Compact Flash memory card when it is inserted into a device. This allows an application to auto-install from a Compact Flash card.
To set an application to be auto-run, you must place the application in aspecific folder for the CPU targeted by your application. The folder name isbased on the CPU number returned in the dwProcessorType member of theSYSTEM_INFO structure returned from calling GetSystemInfo. Table 3.7 shows the possible values and their associated constants.
Constant
Value
PROCESSOR_MIPS_R4000
4000
PROCESSOR_HITACHI_SH3
10003
PROCESSOR_HITACHI_SH3E
10004
PROCESSOR_HITACHI_SH4
10005
PROCESSOR_MOTOROLA_821
821
PROCESSOR_SHx_SH3
103
PROCESSOR_SHx_SH4
104
PROCESSOR_STRONGARM
2577
PROCESSOR_ARM720
1824
PROCESSOR_ARM820
2080
PROCESSOR_ARM920
2336
PROCESSOR_ARM_7TDMI
70001
Table 3.7. Processor values and associated constants
Thus, if you want your application to auto-run and the application is compiled for MIPS, you should rename your application to autorun.exe and place it in a folder called \4000, for example, \4000\autorun.exe.
If your application is compiled for CEF (Common Executable Format), you should place the autorun.exe file in a folder called \0, for example, \0\autorun.exe.
The application autorun.exe is passed the command line parameter "install" when a Compact Flash card is inserted, and with the command line parameter "uninstall" when the card is removed. This allows your autorun.exe application to uninstall itself when the card is removed. ..."
[From book: Windows CE 3.0 Application Programming]

A end product user can't create an excel interop instance

I'm creating a wpf application for internal deployment.
A user using the software is getting the following error when trying to create an excel interop instance.
Retrieving the COM class factory for component with CLSID (...) failed due to the following error: 80070002 The system cannot find the file specified
The section that is catching the error is the following
try
{
_excelApplication = new Microsoft.Office.Interop.Excel.Application();
GetWindowThreadProcessId(_excelApplication.Hwnd, out ExcelAppProcessId);
_excelApplication.ScreenUpdating = false;
}
catch(Exception e)
{
//TODO Move message box to parents
MessageBox.Show($"Termination Error: Could not open Excel Application: {e.Message}");
Environment.Exit(110);
}
Previously the same user had an issue while trying to open Access (can't remember what the exact error was) and I implemented the following to fix it.
try
{
//MessageBox.Show($"OS: {EnvironmentFunctions.is64BitOperatingSystem} Process: {EnvironmentFunctions.is64BitProcess}");
if (EnvironmentFunctions.is64BitOperatingSystem && !EnvironmentFunctions.is64BitProcess)
{
string PathValue = "";
string sAdd = "";
string strCommonFiles =
Environment.GetEnvironmentVariable("CommonProgramFiles(x86)");
sAdd = ";" + strCommonFiles + "\\microsoft shared\\DAO";
PathValue = Environment.GetEnvironmentVariable("Path");
PathValue += sAdd;
Environment.SetEnvironmentVariable("path", PathValue);
}
_accessApplication = new Microsoft.Office.Interop.Access.Application();
GetWindowThreadProcessId(_accessApplication.hWndAccessApp(), out AccessAppProcessId);
}
catch
{
MessageBox.Show("Termination Error: Could not open Access Application");
Environment.Exit(110);
}
Would there be a similar solution but for the Excel interop?
Notes about the user: They are one of the few left running windows 7.
Retrieving the COM class factory for component with CLSID (...) failed due to the following error: 80070002 The system cannot find the file specified
Typically this error is caused by only a few issues, which I will list below.
Recent Windows updates
Partition issue's and or problems
Bitness issue's (determined what Office is installed on the end machine and what the application is compiled against)
I asked earlier about what you were targeting because you have some code that is checking if the pc is 64bit and you have already ran into some issues. This then lead me to bitness issues with creating instances of Excel.
My recommendation and solution to your exact issue is because the end machine is 32bit, so compiling for x86/32bit should fix the issue.
On a final note, you may be able to remove that old code as it wouldn't be needed anymore.

Same machine, different app domains, same GUIDs coming up

I'm fairly certain I'm either doing something wrong, or understanding something wrong. It's hard to give a piece of code to show my problem, so I'm going to try explaining my scenario, with the outcome.
I'm starting up several instances of a DLL, in the same console application, but in it's own app domain. I then generated a Guid.NewGuid() that I assign to a class in the instance, and set the application's folder to a new folder. This works great so far. I can see everything works great, and my instances are seperated. However... when I started changing my app's folder to the same name as the unique GUID generated for that class I started picking up anomolies.
It works fine, when I instantiate the new instances slowly, but when I hammer new ones in, the application started picking up data in its folder, when it started up. After some investigation, I found that its because that folder already exist, due to that GUID already being instantiated. On further investigation, I can see that the machine takes a bit of a pause, and then continues to generated the new instances, all with the same GUID.
I understand that the GUID generating algorithm uses the MAC as part of it, but I was under the impression that even if the same machine, at the same exact moment generates two GUIDs, it would still be unique.
Am I correct in that statement? Where am I wrong?
Code :
Guid guid = Guid.NewGuid();
string myFolder = Path.Combine(baseFolder, guid.ToString());
AppDomain ad = AppDomain.CurrentDomain;
Console.WriteLine($"{ad.Id} - {guid.ToString()}");
string newHiveDll = Path.Combine(myFolder, "HiveDriveLibrary.dll");
if (!Directory.Exists(myFolder))
{
Directory.CreateDirectory(myFolder);
}
if (!File.Exists(newHiveDll))
{
File.Copy(hiveDll, newHiveDll);
}
Directory.SetCurrentDirectory(myFolder);
var client = ServiceHelper.CreateServiceClient(serviceURL);
ElementConfig config = new ElementConfig();
ElementConfig fromFile = ElementConfigManager.GetElementConfig();
if (fromFile == null)
{
config.ElementGUID = guid;
config.LocalServiceURL = serviceURL;
config.RegisterURL = registerServiceURL;
}
else
{
config = fromFile;
}
Directory.SetCurrentDirectory is a thin wrapper atop the Kernel 32 function SetCurrentDirectory.
Unfortunately, the .NET documentation writers didn't choose to copy the warning from the native function:
Multithreaded applications and shared library code should not use the SetCurrentDirectory function and should avoid using relative path names. The current directory state written by the SetCurrentDirectory function is stored as a global variable in each process, therefore multithreaded applications cannot reliably use this value without possible data corruption from other threads that may also be reading or setting this value
It's your reliance on this function that's creating the appearance that multiple threads have magically selected exactly the same GUID value.

WPF Printing (XpsDocumentWriter) working in debug but not in deployment

Hopefully some of the experienced WPF developers have come across this issue before.
BACKGROUND: This information is probably not necessary to helping fixing the problem, but in case it is relevant.
My solution consists of three projects. A front-end GUI, a business logic service, and a printer service. The three projects have IPC via named pipes. The business logic hands the printing logic a label type and a pallet id.
The Problem: The printing logic then creates the label and prints it (by adding it to the print queue of a printer) As the title suggests this all works fine when I am debugging in visual studio. However when I deploy / install the services on my developer pc it is not working.
Update: It is not throwing an exception but I am only logging "About to send doc to printer" and not the line "Sent doc to printer" So it is hanging on the dw1.Write(fixedDoc); line
More Information: I am using .Net 4.0 in the printing project / visual studio 2013
public void printLabel(string labelType, string _palletID = null)
{
try
{
ILabelTemplate Label = createLabel(labelType, _palletID);
PrintDialog pd = new PrintDialog();
FixedDocument fixedDoc = new FixedDocument();
PageContent pageContent = new PageContent();
FixedPage fixedPage = getFixedPage();
fixedDoc.DocumentPaginator.PageSize = new System.Windows.Size(fixedPage.Width, fixedPage.Height);
IXamlTemplate vm = CreateViewModel(Label);
ILabelPrintDocument template = CreateTemplate(Label);
template.dockPanel.DataContext = vm;
template.dockPanel.Height = fixedPage.Height;
template.dockPanel.Width = fixedPage.Width;
template.dockPanel.UpdateLayout();
fixedPage.Children.Add(template.dockPanel);
((System.Windows.Markup.IAddChild)pageContent).AddChild(fixedPage);
fixedDoc.Pages.Add(pageContent);
XpsDocumentWriter dw1 = PrintQueue.CreateXpsDocumentWriter(new System.Printing.PrintQueue(new System.Printing.PrintServer(), Label.PrinterName));
Library.WriteErrorLog("About to send doc to printer");
dw1.Write(fixedDoc);
Library.WriteErrorLog("Sent doc to printer");
}
catch (Exception ex)
{
Library.WriteErrorLog(ex);
}
SOLVED ... kind of
After several hours of trying different things and reading about this, I found that it was due to my application running as me when I'm debugging but as a LOCAL SYSTEM when I have it deployed. And a local system service does not have access to network resources such as printers. Despite learning this, I then started down the path of how to make a C# service print. Well after seeing many posts (too late in the game to be very helpful)
Like this and also this one I have learned that I was going down the wrong path.
The moral of the story is, if you're reading this post you're probably not at the level of "writing your own printing DLL using the Win32 API (in C/C++ for instance), then use it from your service with P/Invoke"
The solution that did work for me was instead of running this project as a service which was started via my GUI. I have instead turned it into a process which is still started and stopped via my GUI.
The code in question is
if (File.Exists(AppDomain.CurrentDomain.BaseDirectory + "\\yourAppNameGoesHere.exe"))
{
Process.Start(AppDomain.CurrentDomain.BaseDirectory + "\\yourAppNameGoesHere.exe");
}
then when the GUI is closed I run the code
if (File.Exists(AppDomain.CurrentDomain.BaseDirectory + "\\yourAppNameGoesHere.exe"))
{
Process[] myapps = Process.GetProcesses("yourAppNameGoesHere.exe");
foreach (Process _p in myapps)
{
_p.Kill();
}
}

C# program connecting to example DBus daemon always gets 'Access is denied: DBus.BusObject'

For our current project we are using DBus (1.6.n).
It is largely accessed from C++ in shared memory mode, and this works really well.
I am now trying to access the same DBus from a C# program.
In order to try things out first, I downloaded the latest version of dbus-sharp I could find, and started the daemon included in the download to see if I could connect to it from my test C# app.
Whenever I make a connection, the daemon console shows that I am communicating with it, but as soon as I try to access any methods on the connection I get the error;
'Access is denied: DBus.BusObject'
Here is the code I have tried;
DBus.Bus dBus = null;
try
{
//input address comes from the UI and ends up as "tcp:host=localhost,port=12345";
//dBus = new Bus(InputAddress.Text + inputAddressExtension.Text);
//string s = dBus.GetId();
//dBus.Close();
//DBus.Bus bus = DBus.Bus.System;
//DBus.Bus bus = Bus.Open(InputAddress.Text + inputAddressExtension.Text);
//DBus.Bus bus = DBus.Bus.Session;
//DBus.Bus bus = DBus.Bus.Starter;
var conn = Connection.Open(InputAddress.Text + inputAddressExtension.Text);
var bus = conn.GetObject<Introspectable>(#"org.freedesktop.DBus.Introspectable", new ObjectPath("/org/freedesktop/DBus/Introspectable"));
bus.Introspect();
}
finally
{
if(dBus != null)
dBus.Close();
}
The commented code produces the same error eventually too.
I have stepped through with the debugger and it always gets to the following code in the TypeImplementer.cs;
public Type GetImplementation (Type declType)
{
Type retT;
lock (getImplLock)
if (map.TryGetValue (declType, out retT))
return retT;
string proxyName = declType.FullName + "Proxy";
Type parentType;
if (declType.IsInterface)
parentType = typeof (BusObject);
else
parentType = declType;
TypeBuilder typeB = modB.DefineType (proxyName, TypeAttributes.Class | TypeAttributes.Public, parentType);
if (declType.IsInterface)
Implement (typeB, declType);
foreach (Type iface in declType.GetInterfaces ())
Implement (typeB, iface);
retT = typeB.CreateType (); <======== Fails here ==========
lock (getImplLock)
map[declType] = retT;
return retT;
}
I have not found any useful examples or documentation about accessing DBus from C#, and there seem to be few recent entries about this anywhere, so maybe no-one else is trying this.
I am running the daemon in the same folder as the test program.
As I am running on windows, the daemon is listening on the tcp setting;
string addr = "tcp:host=localhost,port=12345";
Since this is the example included with the download, I thought it would be really simple to get it going, but alas no luck yet.
Has anyone else been here and know the next piece of the puzzle?
Any ideas would be appreciated.
Having received no comment or response, I will answer the question with the information I have found since asking it.
There appears to be no useful C# interface to DBus. (By useful, I mean one that works!)
The only information or examples I could find are not up to date and no effort appears to be being expended on providing a working interface.
I have decided to interface with DBus by using a C++ implementation written as a Windows service, and my C# program will send messages to DBus via the service. This seems to work ok, so satisfies the business need.
I am disappointed not to be able to get the C# to DBus working, but there are lots of service bus implementations that work on Windows, so in future I will look at implementing those instead of DBus.
If anyone does come up with a workable, documented solution to accessing DBus from C# on Windows, I would still be interested to see it.
I had the same error when I created new test project and add dbus cs source files to it main project assembly. It was when IBusProxy type dynamically created in dynamically created assembly.
asmB = AppDomain.CurrentDomain.DefineDynamicAssembly (new AssemblyName ("NDesk.DBus.Proxies"), canSave ? AssemblyBuilderAccess.RunAndSave : AssemblyBuilderAccess.Run);
modB = asmB.DefineDynamicModule ("NDesk.DBus.Proxies");
......
retT = typeB.CreateType ();
I think it was cause current running assembly isnt friendly for created assembly. And just when I add to project compiled NDesk.DBus.dll this error disappeared.

Categories