Process.Start("telnet.exe") throws exception - c#

I have two applications running on W2k8 R2 x64, one is compiled as 64bit and the other one as 32bit as it has COM dependencies.
In both I'm trying to call:
Process p = Process.Start("telnet.exe", string.Format("{0} {1}", address, port));
In the x64 it works perfectly fine, however in the 32bit one I get a System.ComponentModel.Win32Exception ("The system cannot find the file specified")?
Any idea what's going on here? Even if I call
Process.Start(#"C:\Windows\System32\telnet.exe")
I get the same exception?
Thanks,
Tom

To launch a system32 located 64bit app from a 32bit app (at least on Vista,2k8,7, doesn't work on x64 XP or 2k3) run it from the sysnative directory, i.e. "C:\windows\sysnative\telnet.exe" (alternatively disable Wow64 but that is generally a bad idea).

This drove me crazy... had one project that would find "telnet.exe" without the full path and one that refused to find it (even with the path, or never figured it out). My dev machine is 64-bit.
The problem was the target platform in build.
If it's set to x86 it will not find telnet.
set it to Any CPU it will find telnet.
sometimes you need to set it to x86, this allows your applications to see 32-bit drivers (such as odbc drivers) on 64-bit platforms

Windows Server 2008 does not have a 32 bit telnet.exe client. It only installs a 64bit version in the windows\system32 folder.

\live.sysinternals.com\tools\procmon.exe and/or procexp always has the answer.
Have you looked at the path environment variable in the context of your process? Can you prefix it with the System\SysWow64 path to make it work?

copy telnet.exe to SysWow64 folder

Related

How can I conditionally run my program in 64 bit or 32 bit mode based on external resources?

There are a few questions (and unwanted answers) all over the forums about Microsoft.ACE.OLEDB.12.0 provider not being registered on the local machine, like this one. The gist of the problem, how I understand it, is that the application will look for the provider on the same platform as what the application is running on. So if your computer is 64 bit and the provider 32 bit, then there will be a mismatch if you don't compile the application to run in 32 bit mode.
Most answers effectively deal with this by installing the appropriate data components for the current platform. Other suggestions are to compile for whichever platform the data components are available.
I am developing an app using PCs running Windows 7, 8 and 10, all 64 bit, depending on where I am, but some have older versions of Office and others newer versions. This causes me to have to change the platform for which I compile depending on the PC I currently work on. While this is no problem for me, personally, I foresee this causing headaches for the end users not being able to run the program.
Trying to avoid asking users to install other components on their computers; is there a way I can tell the program to check the platform availability of the database provider and then run in that mode? Might it be possible to create 32 bit and 64 bit extensions of the database module and load the appropriate one regardless of the mode the main program is running in?
EDIT:
I just tried to compile my database extensions on different platforms Whichever one that is not the same platform as the application causes an exception when being loaded saying that I am attempting to load an assembly from a different platform. So I guess I'm out of luck with my option 2...
You can use CorFlags utility to modify your executable on target machine, after you will detect which mode it needs to run.
First ensure that your main exe is compiled under any cpu with Prefer 32 bit flag not set. Now when application is started you need to check if we are in 64-bit process or not, and also check your dependencies (this I won't cover - I don't work with OLEDB). If you found mismatch (say you are running in 64-bit process but your dependencies are 32-bit) - you need to run external process to modify your main executable and then restart it. Easiest way to do it is via simple cmd script, like this (in this example my main exe is called ConsoleApplication3.exe):
:start
start /wait "" "C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.6.1 Tools\CorFlags.exe" ConsoleApplication3.exe /32BIT+
if errorlevel 1 (
goto start
)
start "" ConsoleApplication3.exe
Note that this is just example and if something goes wrong it will fall into endless loop, adjust to your requirements. What this script does is just updates your exe using CorFlags tool to run in 32-bit mode, then starts your main exe.
Right after starting your application, you might do the following check:
static void Main() {
if (Environment.Is64BitProcess) {
// here you also check if you have dependency mismatch, and then:
Console.WriteLine("Running in 64-bit mode. Press any key to fix");
Console.ReadKey();
// run script (here we assume script is in the same directory as main executable, and is called fix-mode.cmd
var process = new Process() {
StartInfo = new ProcessStartInfo("cmd.exe", "/c call fix-mode.cmd")
};
process.Start();
// here you should exit your application immediatly, so that CorFlags can update it (since it cannot do that while it is running)
}
else {
// after restart by our script - we will get here
Console.WriteLine("Running in 32bit mode");
}
}
Note that this tool (CorFlags) is available only with Visual Studio so you may want to pack it together with your application (might be not available on remote machine).

Could not load file or assembly 'Oracle.DataAccess' (x64)

I am trying to create a WCF service to host in IIS.
My production and development servers are 64 bit.
The WCF service needs to be able to connect to a several different Oracle databases based on the client request.
I am using Entity Framework 5 with ODAC, and with the DbContext Initialiser, I have the option of providing a database connection to use.
private void ExampleSelect(string dataSource, string user, string password)
{
var connection =
string.Format("DATA SOURCE={0};PASSWORD={1};USER ID={2}",
dataSource, password, user);
using (var context = new OracleDbContext(new OracleConnection(connection)))
{
// do stuff here
}
}
The problem I have lies with new OracleConnection(connection). To use this line, I need to reference the x64 version of Oracle.DataAccess.dll
When I come to publish, I get the warning:
and the error:
The platform target for my project is currently 'Any CPU'. If I change this to target x64, I get the same error, but this time it refers to my project and not Oracle.DataAccess
Any of the above builds successfully on my development machine, I only get the errors when I come to publish.
What am I doing wrong here?
These solutions appear to be related, but they all refer to 32 bit Oracle Dlls:
Could not load file or assembly Oracle.DataAccess
Could not load file or assembly 'Oracle.DataAccess' 64 bit ODP.NET
Could not load file or assembly 'Oracle.DataAccess error
To rule it out, I have also tried installing both the 64bit and 32bit Oracle Clients on the development server, but I still don't get as far as even publishing so I'm not sure that the server is the cause of the problem.
The Enable 32 bit Application property on the Application pool in IIS does not make any difference, but I tried it anyway.
To eliminate your problem you must meet the following conditions. Since you want everything run in x64:
1.Make sure that you have installed 64-bit Oracle client software
2.Make sure that you using 64-bit Oracle.DataAccess.dll (use corflags to verify)
3.Make sure you build your application with x64 configuration
4.Disable Enable 32 bit Application on IIS pool
This is a common mistake by many people. They install 32-bit client and try to run x64 Oracle.DataAccess

c# OPC Automation gives 80040154

I am a .Net developer. New to OPC. When I tried some samples of OPC Client all of them give this error. It seems the DLL is not registered it seems. But I don't know how and where to register this.
error: retrieving the COM class factory for component with CLSID failed due to the following error: 80040154
Even I tried this
regsvr32 Interop.OPCAutomation.dll",
but it also throws error like
The module "Interop.OPCAutomation.dll" was loaded but the entry-point DllRegisterServeer was not found.
Make sure that "Interop.OPCAutomation.dll" is a valid DLL or OCX file and then try again.
I have gone through so many existing forums. So many of them said to change the Platform Target to x86 and still I am having the same issue. FYI, I can see only see 'Active (Any CPU)' in the Platform option from the top of the Build tab of Project Properties.
Here are my environment details:
.Net 2005
OPCAutomation Weapper
Windows 7 64-bit OS
Dell Inspiron 1525 (I hope this is not a 64bit machine, but my engineer installed 64bit OS somehow).
Please help me.
Thanks in advance!
Just in case somebody is dealing with this problem (as I've recently been...) I get through it! After some time, I found out that it's something about the .NET framework running on 64-bit machines. As long as the.NET application works only with 32-bit CLR, we must set .NET framework to load CLR in WOW mode. To do so, type:
C:\WINDOWS\Microsoft.NET\Framework64\v2.0.50727\Ldr64.exe SetWow
After this you should be able to run the applications.
You can go back and revert .NET Framework as it was before by typing:
C:\WINDOWS\Microsoft.NET\Framework64\v2.0.50727\Ldr64.exe Set64
If the OPC Client Toolkit SDK (C++) is used, a problem with the remote registry service may cause this error as well.
On Windows 7, by default the Remote Registry service is set to manual and not started. Ensure that the Remote Registry service is started on all of the machines you want to deploy to. This can be done manually or using Group Policy.
The function GetCLSIDFromRemoteRegistry() uses the RemoteRegistryService in order to get the CLSID of an OPC Server. If this service is not started on the client machine, the OPC program may return the error 80040154.
The error you're getting is more than likely due to the OPC server not being properly registered. Make sure it is registered (usually by running it at the command line with a "/regserver" or "/service" parameter). There may also be security issues in which case you'd have to run 'dcomcnfg' (DCOM Config) to make sure the client has access to the server.
This question is a bit dated so I hope you figured it out by now, but I had the same exact issue and wanted to share my solution. In my case, I am using a Kepware server. If you compile and try to run a client application for this server using Interop.OPCAutomation on a machine that does not have the server installed, you will get a dll not registered error and "entry point not found" if you try to register the dll manually.
Solution: Make sure you've got the server installed and running.
Although this is an old post, I would like to share my solution.
My problem was that when I tried to install an application with the OPCAutomation.dll, it gave me 80040154 error because the class was not registered.
This is my solution, always with Administrator privileges:
Copy OPCDAAuto.dll into the "C:\Windows\System32" folder
On the cmd prompt type "C:\Windows\System32\regsvr32 opcdaauto.dll"
You should watch a message like this one:
image
Hope this helps!
The OPC dll only works in 32 Bits, my solution was to change the "Enable 32-Bit Applications" to True in the advanced settings of the relative app pool in IIS.

c# ListView populated with Current Processes Informations: PID/Process Name/Path error when not compiled for x64

I'm running a Windows 7 x64 machine when I do not compile for x64 I get an exception and my ListView just get populated with the first two non x64 processes.
That is I cannot access MainModule Property of a 64 bit process to get it's full path.
foreach(Process p in listaProcessi)
{
tempItem = new ListViewItem(p.Id.ToString());
tempItem.SubItems.Add(p.ProcessName);
tempItem.SubItems.Add(p.MainModule.FileName);
processiListView.Items.Add(tempItem);
}
I still can make it work compiling for x64 but suppose I want to compile just for x86, how do I avoid getting the excpetion ?
1) Is there any other way to discover those processes path ?
2) I could write a line like "You cannot get x64 Process path from x86 App", but still I don't have to run into the exception. How do I prevent this ? Can I check the process for a particular info so I can replace the text and avoid accessing MainModule ?
Thanks.
A 32 bit processes cannot access modules of a 64 bit process.
So it must be compiled for AnyCpu to be fully working in both x86 and x64 environments.

C# - How to get Program Files (x86) on Windows 64 bit

I'm using:
FileInfo(
System.Environment.GetFolderPath(
System.Environment.SpecialFolder.ProgramFiles)
+ #"\MyInstalledApp"
In order to determine if a program is detected on a users machine (it's not ideal, but the program I'm looking for is a right old kludge of a MS-DOS application, and I couldn't think of another method).
On Windows XP and 32-bit versions of Windows Vista this works fine. However, on x64 Windows Vista the code returns the x64 Program Files folder, whereas the application is installed in Program Files x86. Is there a way to programatically return the path to Program Files x86 without hard wiring "C:\Program Files (x86)"?
The function below will return the x86 Program Files directory in all of these three Windows configurations:
32 bit Windows
32 bit program running on 64 bit Windows
64 bit program running on 64 bit windows
static string ProgramFilesx86()
{
if( 8 == IntPtr.Size
|| (!String.IsNullOrEmpty(Environment.GetEnvironmentVariable("PROCESSOR_ARCHITEW6432"))))
{
return Environment.GetEnvironmentVariable("ProgramFiles(x86)");
}
return Environment.GetEnvironmentVariable("ProgramFiles");
}
If you're using .NET 4, there is a special folder enumeration ProgramFilesX86:
Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86)
Environment.GetEnvironmentVariable("PROGRAMFILES(X86)") ?? Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles)
Note, however, that the ProgramFiles(x86) environment variable is only available if your application is running 64-bit.
If your application is running 32-bit, you can just use the ProgramFiles environment variable whose value will actually be "Program Files (x86)".
One way would be to look for the "ProgramFiles(x86)" environment variable:
String x86folder = Environment.GetEnvironmentVariable("ProgramFiles(x86)");
I am writing an application which can run on both x86 and x64 platform for Windows 7 and querying the below variable just pulls the right program files folder path on any platform.
Environment.GetEnvironmentVariable("PROGRAMFILES")
One-liner using the new method in .NET. Will always return x86 Program Files folder.
Environment.Is64BitOperatingSystem ? Environment.GetEnvironmentVariable("ProgramFiles(x86)") : Environment.GetEnvironmentVariable("ProgramFiles"))
C# Code:
Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86)
Output:
C:\Program Files (x86)
Note:
We need to tell the compiler to not prefer a particular build platform.
Go to Visual Studio > Project Properties > Build > Uncheck "Prefer 32 bit"
Reason:
By default for most .NET Projects is "Any CPU 32-bit preferred"
When you uncheck 32 bit assembly will:
JIT to 32-bit code on 32 bit process
JIT to 32-bit code on 64 bit process

Categories