FreeImage on C# - c#

I've downloaded the latest compiled version of FreeImage, then build FreeImageNet wrapper. Put FreeImage.dll and FreeImageNet.dll on the same folder as my executable (the sample code). But everytime I run it, it says freeimage.dll is missing. I modified the code on FreeImageWrapper.cs and remove the exception handler
public static bool IsAvailable()
{
/*try
{*/
// Call a static fast executing function
Version nativeVersion = new Version(GetVersion());
Version wrapperVersion = GetWrapperVersion();
// No exception thrown, the library seems to be present
return
(nativeVersion.Major > wrapperVersion.Major) ||
((nativeVersion.Major == wrapperVersion.Major) && (nativeVersion.Minor > wrapperVersion.Minor)) ||
((nativeVersion.Major == wrapperVersion.Major) && (nativeVersion.Minor == wrapperVersion.Minor) && (nativeVersion.Build >= wrapperVersion.Build));
}
/*catch (DllNotFoundException)
{
return false;
}
catch (EntryPointNotFoundException)
{
return false;
}
catch (BadImageFormatException)
{
return false;
}*/
}
It always throws BadImageFormatException. It seems the problem is on the native dll (freeimage.dll) ?
How do I fix it ?
Thanks in advance.
I'm using Visual C# 2010 Express

This happens very often if you try to load a unmanaged 32bit dll into a 64bit process. To get around this problem open the properties of your startup project and change under Built - PlatformTarget the type from Any CPU to x86.

Related

Access violation Error in C#

I have C# windows form project on VS2013.
my graphic support by MFC C++ project through dll.
when I use 32 bit dll and 32bit C# project it's work fine.
but when use 64bit dll and 64bit C# project only work with .net framework 4 client profile and not work on .net framework 4.5 and get access violation error when use dll.
code that throw access violation error on C++ dll.
BOOL ImportElevation( CString &csFileName )
{
CString csTmpPath = GetTempFolderName(csFileName.GetBuffer());
int iResult = vtCreateDir(csTmpPath);
if (iResult == 0 && errno != EEXIST)
{
MessageBox(NULL,_T("Couldn't create temporary directory to hold contents of archive."),
_T("Error"),MB_ICONERROR);
return FALSE; // no layers created
}
CString csUnzipPath = csTmpPath + _T("/");
iResult = ExpandZip(csFileName, csUnzipPath, ProgressCallback);
if (iResult == 1)
{
// the archive contained a single file
std::string strPathName = (const char *) csUnzipPath;
for (dir_iter it(strPathName); it != dir_iter(); ++it)//at this line throw exception
{
if (it.is_directory())
continue;
csUnzipPath += it.filename().c_str();
break;
}
CElevLayer* pLayer = new CElevLayer(csFileName);
if(pLayer->ImportElevation(csUnzipPath,TRUE,ProgressCallback))
{
m_vecElevLayer.push_back(pLayer);
m_iActiveLayerIdx = m_vecElevLayer.size()-1;
pLayer->CreateMap(ProgressCallback);
return TRUE;
}
else
SAFE_DELETE(pLayer);
return FALSE;
}
// clean up after ourselves
csTmpPath = GetTempFolderName(csUnzipPath);
vtDestroyDir(csTmpPath);
return TRUE;
}
I run this dll on 3 different projects and get this error.

Best way to determine if ReportViewer is installed

What is the best way to find out if reportviewer and WindowsInstaller-KB893803-v2-x86 is installed on a PC? Is there a way to find out what public key to use to find out if a specific program is installed on a PC? (Tried this, didn't work)
Best Way To Determine If .NET 3.5 Is Installed
This is how to check if .NET 3.5 is installed, but i take it you need a another public key to know if report viewer is installed, but I don't know how to get the public key.
All I can think of is to check if the installation directory exists on the computer, would that be an acceptable way to check?
You could check in the Registry
public bool IsInstalled()
{
RegistryKey registryBase = RegistryKey.OpenRemoteBaseKey(RegistryHive.LocalMachine, string.Empty);
if (registryBase != null)
{
return registryBase.OpenSubKey("Software\\Microsoft\\ReportViewer\\v2.0.50727") != null;
}
return false;
}
In my machine (Win7 & Server 2012), the registry key is different.
bool exist = false;
RegistryKey registryBase = RegistryKey.OpenRemoteBaseKey(RegistryHive.LocalMachine, string.Empty);
if (registryBase != null)
{
exist = registryBase.OpenSubKey("Software\\Wow6432Node\\Microsoft\\.NETFramework\\v2.0.50727\\AssemblyFoldersEx\\ReportViewer v10") != null;
}
You could also query the GAC for the assemblies, as shown in this SO question.
I did a Regshot diff on a MS Report Viewer version 10 install to find the key because neither of the others posted here were working.
Here is the actual diff results on a fresh windows server VM.
Anyways, the key I found for this version was:
SOFTWARE\Wow6432Node\Microsoft\ReportViewer\v10.0
The code I used:
public bool IsInstalledReportViewer()
{
try
{
RegistryKey registryBase = RegistryKey.OpenRemoteBaseKey(RegistryHive.LocalMachine, string.Empty);
if (registryBase != null)
{
// check the two possible reportviewer v10 registry keys
return registryBase.OpenSubKey(#"Software\Microsoft\ReportViewer\v2.0.50727") != null
|| registryBase.OpenSubKey(#"Software\Wow6432Node\Microsoft\.NETFramework\v2.0.50727\AssemblyFoldersEx\ReportViewer v10") != null
|| registryBase.OpenSubKey(#"SOFTWARE\Wow6432Node\Microsoft\ReportViewer\v10.0") != null;
}
}
catch (Exception ex)
{
Debug.WriteLine(ex);
// put proper exception handling here
}
return false;
}

C# Get MAC address with Mono (for Mac platform)

I have this C# function that work fine but unfortunately mono does not support System.Net.NetworkInformation.NetworkInterface Type for Mac platforms.
System.Net.NetworkInformation.NetworkInterfaceType Type = 0;
string MacAddress = ModSupBase.EMPTY_STRING;
try
{
System.Net.NetworkInformation.NetworkInterface[] theNetworkInterfaces =
System.Net.NetworkInformation.NetworkInterface.GetAllNetworkInterfaces();
foreach (System.Net.NetworkInformation.NetworkInterface currentInterface in theNetworkInterfaces)
{
Type = currentInterface.NetworkInterfaceType;
if (Type == System.Net.NetworkInformation.NetworkInterfaceType.Ethernet
|| Type == System.Net.NetworkInformation.NetworkInterfaceType.GigabitEthernet
|| Type == System.Net.NetworkInformation.NetworkInterfaceType.FastEthernetFx)
{
MacAddress = currentInterface.GetPhysicalAddress().ToString();
break;
}
}
return MacAddress;
}
catch (System.Exception ex)
{
ModErrorHandle.Error_Handler(ex);
return ModSupBase.EMPTY_STRING;
}
I have read this information using the mono migration utility (I think this is true)
there anoher way to get the MAC addrees with mono on MAC platform?
Thank you !
I don't known if work of not. I have only downloaded the last version of the mono migration utility and in the report I see:
NetworkInterface[] NetworkInterface.GetAllNetworkInterfaces() Only works on Linux and Windows
I don't known if this true. Do you think is a false positive?
Which version of Mono you are referring to? Looking at the Mono's trunk source code I'm pretty sure it is implemented now.

How to get stack trace of a running process from within a Visual Studio add-in?

I am writing a Visual Studio add-in in C# which will run while I am debugging a process in the same Visual Studio window and I need access to that the process' stack trace from within my add-in. I tried putting this code into my add-in but it returns the add-in's stack trace, not the process I am debugging.
System.Diagnostics.StackTrace stacktrace = new System.Diagnostics.StackTrace(true);
System.Diagnostics.StackFrame stackframe = stacktrace.GetFrame(0);
Any help would be appreciated.
The easiest way would be to ask the debugger for the stack frames through the DTE automation object. The DTE object should be available to you through your add-in. The property you want is Debugger.CurrentThread.StackFrames. If you're using .NET 4, you can do:
static string GetCurrentStackTrace(DTE dte)
{
bool canGetStackTrace =
(dte != null) &&
(dte.Debugger != null) &&
(dte.Debugger.CurrentThread != null) &&
(dte.Debugger.CurrentThread.StackFrames != null);
if (!canGetStackTrace)
return string.Empty;
return string.Join(
"\n",
dte.Debugger.CurrentThread.StackFrames.Cast<StackFrame>().Select(f => f.FunctionName)
);
}
Otherwise, you can do:
static string GetCurrentStackTrace(DTE dte)
{
bool canGetStackTrace =
(dte != null) &&
(dte.Debugger != null) &&
(dte.Debugger.CurrentThread != null) &&
(dte.Debugger.CurrentThread.StackFrames != null);
if (!canGetStackTrace)
return string.Empty;
StringBuilder stackTrace = new StringBuilder();
foreach (StackFrame frame in dte.Debugger.CurrentThread.StackFrames)
{
stackTrace.AppendFormat("{0}\n", frame.FunctionName);
}
return stackTrace.ToString();
}
The painful and involved way would be to use ICorDebug and StackWalk64 to get managed and native stacks separately and then stitch them together by hand. Since you're a VS add-in, you might as well let the debugger do the heavy lifting for you!
The code is working as expected since when you call the code, your add-in (under VS) is the "current process".
I am not sure what you mean by "currently running process" (do you mean the process being run/debugged under VS?), but I don't think its possible to get a stack-trace of another process.

C# Visual Studio 2008 Reference to system32.dll ... how?

I need the reference system32/shell32.dll as I use some shell functions to read out the recycling bin. I tried "Add Reference --> COM --> Microsoft Shell Controls and Automatation" and "Add Reference --> Browse ---> [going to the system32/shell32.dll directly]. Both adds the shell32 reference to my references. But when I look at the properties, I see the path of the reference looks like this: "C:\Users\Tim\Documents\Visual Studio 2008\Projects\Wing\FileWing\obj\Debug\Interop.Shell32.dll" ...
I'll not deploy this \obj\Debug\ path to my installer. So how can I reference the end-users shell32.dll directly? Is there a way? Why does VS2008 create this strange path? Can I change this path so it doesn't sit in this strange subfolder?
Hmmm. Okay after revisiting PInvoke, I'm sure that I don't quite get it :-/
Let me illustrate the code I need to handle. I'm digging though the recycling bin and seek for a item that I want to recover. Is there any way NOT fighting though the PInvoke to get this done?
private void recoverRecyclerBinEntry(string fileName, int size)
{
try
{
Shell Shl = new Shell();
Folder Recycler = Shl.NameSpace(10);
// scans through all the recyclers entries till the one to recover has been found
for (int i = 0; i < Recycler.Items().Count; i++)
{
FolderItem FI = Recycler.Items().Item(i);
string FileName = Recycler.GetDetailsOf(FI, 0);
if (Path.GetExtension(FileName) == "")
FileName += Path.GetExtension(FI.Path);
//Necessary for systems with hidden file extensions.
string FilePath = Recycler.GetDetailsOf(FI, 1);
string combinedPath = Path.Combine(FilePath, FileName);
if (size == FI.Size && fileName == combinedPath)
{
Debug.Write("Match found. Restoring " + combinedPath + "...");
Undelete(FI);
Debug.WriteLine("done.");
}
else
{
Debug.WriteLine("No match");
}
}
}
catch (Exception ex)
{
Debug.WriteLine(ex.Message);
Debug.WriteLine(ex.StackTrace);
}
}
private bool Undelete(FolderItem Item)
{
try
{
foreach (FolderItemVerb FIVerb in Item.Verbs())
{
if (
(FIVerb.Name.ToUpper().Contains("WIEDERHERSTELLEN")) ||
(FIVerb.Name.ToUpper().Contains("ESTORE")) ||
(FIVerb.Name.ToUpper().Contains("NDELETE"))
)
{
FIVerb.DoIt();
return true;
}
}
//execute the first one:
Item.Verbs().Item(0).DoIt();
return true;
}
catch (Exception)
{
Debug.WriteLine("ERROR undeleting");
return false;
}
}
I believe you are looking for P/Invoke (Platform Invoke)
Once you get the method for including and using the DLLs down, you can visit pinvoke.net to get specific code snippets for using certain methods.
Are you just using DllImport to access functionality in shell32/kernel32? If so, you don't need to add a reference.
For example:
[DllImport("KERNEL32.DLL", EntryPoint="MoveFileW", SetLastError=true,
CharSet=CharSet.Unicode, ExactSpelling=true,
CallingConvention=CallingConvention.StdCall)]
public static extern bool MoveFile(String src, String dst);
Here's a tutorial on using platform invoke and here's an MSDN article.
After you add the dll reference using VS 2008, you can open the properties for the .dll.
Make sure Copy Local is set to True.
If that doesn't work another solution is to add the .dll as an item to you project, and make is as content, and tell it to copy to the output directory.

Categories

Resources