SaveFileDialog.ShowDialog() thrown FileNotFound exception - c#

The following code works fine on Windows 7 (32-bit), but when ported to 64-bit, I get an exception stating "File Not Found". I have built the project in 64-bit configuration but the issue still persists.
The issue occurs if the machine does not have Office installed.
The code is as follows:
try
{
SaveFileDialog fileDialog = new SaveFileDialog();
fileDialog.InitialDirectory = path;
// set the default extension as mdb.
fileDialog.DefaultExt = ".mdb";
// allow the user to select the file type as CSV, XML or MDB.
fileDialog.Filter = "CSV (*.csv)|*.csv|XML (*.xml)|*.xml|MDB (*.mdb)|*.mdb";
fileDialog.RestoreDirectory = true;
if (DialogResult.OK == fileDialog.ShowDialog()) // exception occured
{
this.fileNameTextBox.Text = fileDialog.FileName;
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}

The question here is what's the value of "path". x86 and x64 machines may have different folder configurations, e.g. Program Files (x86) is one of them. You may start with Environment.SpecialFolders enum, those paths should be valid.

Related

Precompiled .net 4.0 app wont run on other windows installations (error: trying to load assembly from network address)

Solution: I had to click "Unblock" in the file properties dialog in Windows Explorer.
I made an app in c# because i thought it will work on all windows versions. Today i was at my fathers place and downloaded my precompiled app from github. It was running but totally not as expected! Highlighted rows in a gridview wasnt visible, scollbars on a tabcontrol wasnt working and some other more or less small bugs. I had no time to download visual studio to recompile it but is this usual behavior? My father is running on windows 7 and i saw .NET framework 4.5 was installed - i compiled my app using v4.0 so i thought there should be no compatibility issues. I also created a Windows10 virtual machine at home after that and recognized it was the same behavior. I know highlighted rows or scrollbars are not that important but i also have a plugin system to load and reflect additional libraries and thats a basic feature of my app. And the assembly loader will NOT work either - just on the machine i have compiled on.
Should i compile it on multiple versions to support any "unknown" user and its operationg system? I saw that microsoft say i can determine the users version using https://learn.microsoft.com/en-us/dotnet/framework/migration-guide/how-to-determine-which-versions-are-installed but i can do it after my app is installed so should i create some downloader to download the correct version after installation or how is this meant?
Edit i uploaded a video on youtube to show how it should work and how it accuaally works.. https://www.youtube.com/watch?v=DTQa8WlECa8
Edit I got an error message stating (translated from native german) "It was tried to load an assembly from a network address" but i dont understand this message, i never do so.. I load assemblies using
private void m_btnRegisterModule_Click(object objectSender, EventArgs eventArgs)
{
OpenFileDialog openFileDialog = new OpenFileDialog();
openFileDialog.Multiselect = true;
openFileDialog.Title = "Register Stack";
openFileDialog.Filter = "Assemblies (*.exe, *.dll)|*.exe;*.dll|All Files (*.*)|*.*";
if (openFileDialog.ShowDialog(this) == DialogResult.Cancel) return;
Assembly assembly = null;
foreach (String file in openFileDialog.FileNames)
{
try
{
assembly = System.Reflection.Assembly.LoadFile(file);
} catch (Exception) { return; }
Type[] arrayTypes = assembly.GetExportedTypes();
foreach (Type type in arrayTypes)
{
if (!typeof(ScriptStack.Runtime.Stack).IsAssignableFrom(type)) continue;
ConstructorInfo constructorInfo = null;
try
{
constructorInfo = type.GetConstructor(new Type[0]);
}
catch (Exception) { continue; }
try
{
object objectHostModule = constructorInfo.Invoke(new object[0]);
ScriptStack.Runtime.Stack hostModule = (ScriptStack.Runtime.Stack)objectHostModule;
m_scriptManager.RegisterHostStack(hostModule);
}
catch (Exception) { continue; }
}
}
UpdateModuleControl();
pluginFilter.Select();
}
I found .net local assembly load failed with CAS policy and try to load it.. otherwise. lets see how. For now i created a messagebox to see the exact exception.
Edit Solution: I had to click "Unblock" in the file properties dialog in Windows Explorer.
Clicking "Unblock" in the file properties dialog in Windows Explorer solved my issue in some way. By "in some way" i mean i cant expect everybody to know this so someone will just think its not working crap and drop the app.. i guess

Service won't write to file [duplicate]

This question already has answers here:
How do I debug Windows services in Visual Studio?
(17 answers)
Closed 6 years ago.
I have the following code to write to a log file and it works fine in my console application:
try
{
string log = "some message";
string mFileName = "some directory to the log file";
Console.WriteLine(log);
using (StreamWriter w = File.AppendText(mFileName))
{
w.WriteLine(log);
w.Dispose();
}
}
catch (Exception e)
{
Console.WriteLine("Error Log: " + e.Message);
}
But when I run the code as a service on my PC, it stops logging altogether. I've already checked and the service has same rights as me.
Please note: The service doesn't crash, it simply runs without logging.
Most likely this has something to do with user rights.
My guess is that the system user that starts the service, doesn't have the rights to write to the file location.
One solution is to start the service with the user credentials of your own account (because you have the rights.)
Another solution is to give the user (local system ,service user or IIS user for web-service) write access to the directory, or change the path of the file to a directory were the user has write access.
if you want to make sure, add a try catch block around the using, and write the exception to console, debug or messagebox. Then you will know what goes wrong.
see possible exceptions for File.AppendText on MSDN
My guess is it throws a UnauthorizedAccessException
Why not simply create the StreamWriter directly, wrap it in a try-catch, and if there is an exception, log it with System.Diagnostics.EventLog?
try
{
using (Streamwriter sw = new StreamWriter(path, true)
{
sw.WriteLine(log);
}
}
catch (Exception ex)
{
// Log exception using System.Diagnostics.EventLog
}

Excel interop MissingMethodException on some systems

In my C# program, I am using Microsoft.Office.Interop.Excel. With this i am reading & writing data to excel file. On one machine, even though it has Office 2007, there are seeing below exception, raises at GetComponentPath() method call.
Unhandled Exception: System.MissingMethodException: Method not found: 'System.Type System.Runtime.InteropServices.Marshal.GetTypeFromCLSID(System.GUID)'.
Here is my code:
public static string GetComponentPath(OfficeComponent _component)
{
string toReturn = string.Empty;
string _key = string.Empty;
try
{
Microsoft.Office.Interop.Excel.Application _excelApp = null;
_excelApp = new Microsoft.Office.Interop.Excel.Application();
if (_excelApp != null)
{
Console.WriteLine("Excel is installed");
}
else
{
Console.WriteLine("Excel not found.");
}
}
catch (Exception ex)
{
Console.WriteLine("Error \n" + ex.ToString());
}
return toReturn;
}
public enum OfficeComponent
{
Word,
Excel,
PowerPoint,
Outlook
}
Problem : you have developed your application in your local machine with heigher version of .NET Framework and running the same on remote pc having Lower Version of.NET Framework.
Note : if you target your application to run on Heigher Version of .NET Framework it wont run on lower versions.
Solution : you need to target it to .NET Framework Lower Version available on your remote PC to run on remote pc.
Step 1: right click on project - select properties
Step 2: change the Target Framework from .NET Framework x.x to .NET Framework x.y.
Note : where x.x is heigher and x.y is lower version available on remote pc or any lower version.

Can't create Access Database with ADOX

I have a really strange problem with ADOX Interop.
I have this code:
try
{
if (File.Exists(path))
File.Delete(path);
var cat = new CatalogClass();
cat.Create("Provider=Microsoft.Jet.OLEDB.4.0; Data Source = d:\\Test.mdb; Jet OLEDB:Engine Type=5");
Marshal.ReleaseComObject(cat);
cat = null;
GC.Collect();
}
catch (FileNotFoundException e)
{
throw new FileNotFoundException("El archivo no se encuentra", e);
}
catch (COMException e)
{
throw new COMException(connStr + e.Message);
}
catch (Exception e)
{
throw new Exception(connStr, e);
}
The code is failing in the cat.Create() line. What is really weird is that on my local developer machine it works fine, but in the production server doesn't... It isn't a write permissions problem, because i have tried to generate a random file before the problem line and worked perfectly.
The COMException message is only "Not specified Error" HResult: -2147467259
The Server OS is Windows 2008 32bits. I think is a server configuration issue, but can you give me some light? I don't know what else I can do...
If you deploy your application on a 64 bit machine your code couldn't use ADOX via JET.OleDB.4.0
If this is the case, then, a fast solution could be to change your target architecture to x86.
Otherwise you could try to download and install on the target machine the 64bit version of Microsoft Access Database Engine drivers, but I don't know if they support ADOX. You will also need to change your connection string
See whether you can use ADOX Catalog outside your c# code. If you have Access installed, try with Access VBA as Steve suggested. Without Office installed, try with VBScript.
This one works on my 32 bit Windows 7. On 64 bit Windows 7, it fails with an error about "Class not registered". I realize that is not your situation, since you said your server is 32 bit (in reply to an answer which has since been deleted). However my hope is the script will either succeed or give you a more informative error message than you got from the c# error condition.
'Const cPath = "C:\Users\hans\Documents\Test.mdb"
Const cPath = "d:\Test.mdb"
Dim objCat
Dim strConnect
strConnect = "Provider=Microsoft.Jet.OLEDB.4.0;" & _
"Data Source=" & cPath & ";Jet OLEDB:Engine Type=5"
WScript.Echo strConnect
Set objCat = CreateObject("ADOX.Catalog")
objCat.Create strConnect
Set objCat = Nothing
I named that file AdoxCreateDb.vbs and ran it with cscript from a command prompt window.
cscript AdoxCreateDb.vbs

How to check if you have permission to run a exe file

C# .net Framework 4.0
Is there a simple way to check if you have the rights to run a file?
Before i do this:
//e.g. Press a button
....
string exePath = "D:\something\something.exe";
Process.Start(exePath);
i would like to check if the user has the rights to run that file?
When i'm making the function call Process.Start, windows popsup with a messagebox and says that i'm not authorized to run this application and this application is "D:\something\something.dat" and NOT .exe?
How to check if you have permission to run a exe file?
EAFP: It is Easier to Ask Forgiveness than it is to get Permission.
So, you can surround your code with try/catch block:
try {
Process.Start(path);
} catch (Win32Exception ex) {
// ...
}
and you can use Win32Exception.NativeErrorCode to access the numeric representation of the error code associated with this exception.
For more information about the error codes, check out Win32 System Error Codes.
Try surrounding Proccess.Start with try catch:
//e.g. Press a button
....
string exePath = "D:\something\something.exe";
try
{
Process.Start(exePath);
} catch (Exception e) {
// No permissions or file not found?
}
that'll do the job.

Categories

Resources