file access in C# program called by PHP - c#

This is the context: I've got to write a source for an intranet site which allows users to import a csv file into MySQL database.
This import is very massive that's why I wrote a C# program.
This program creates some thread which reads some lines of my csv file.
These thread control, change type and insert my data into MySQL database with SQL like this:
insert into table1 (fields) values (dataline 1 ), (data line 25),...,(data line n);
This request exists for 9 tables.
This program can be used by everyone because the source code is dynamic : example to insert data I write a dictionary which contain my 9 tables with all fields, types and the CSV header of the import file (which contains some accent and symbol, I've to change it because I can't put them into fieldname in my database).
This dictionary can be create only with a file called MAP.csv
Example:
table / field / type / header
table 1 / field1_table1 /string / hêàder
table 1 / field2_table1/ int / header1
table 2 / field1_table2/ date / hêàder2
table 1 / field3_table1/ string / hêàder3
My C# program works very well when I execute the program.exe
But when I call it with php with exec("programpath.exe parameter1 parameter2",return,otherreturn) function this program can't work.
In fact when I try to access to externfile like config.xml , MAP.csv, otherfile.txt/csv/.. with my c# program. The execution stop and there is a windows error which says "program.exe stop its work" ( program.exe à cessé de fonctionner in French).
So I try to write my problem simply: when I try to access into a file with my c# program called by php, there is a window problem which stop the traitment.
EDIT :
I found the solution, I just have to do a cd c:/path_program/
In fact when I start my website the current folder is not c:/ but the folder in which Symfony starts...
Was just a beginner error.

Could be a permission problem.
The Webserver is running under a certain security context (user). Depending on the used Webserver (IIS, apache, ...) and its configuration.
As you execute an application out of your PHP it will run under the same "User" as your WebServer.
You said that it seems as your application crashes as soon as an external file gets accessed --> very possible the user which executes the website has access to run the exe but no access for the configuration file.
you use relative paths to access the file:
to map the relative to the application path to an absolute path you can use this snippet:
string appPath = System.Windows.Application.ResourceAssembly.Location;
string relativeResourcePath = "RESSOURCES/file.csv";
string absolutePath = System.IO.Path.Combine(appPath, relativeResourcePath);

Check Edit post for the solution

Related

The process cannot access the file 'filename' because it is being used by another process

I am new in C# and I have a problem connecting to a Firebird database. I want my program to access a Firebird Database [FDB format file]. I have problem, see the code below:
File.Copy(pathway, new_pathway, true);
FbConnection addDetailsConnection = new FbConnection("User=sysdba;Password=masterkey;Dialect=3;Database= " + new_pathway +
";DataSource=localhost;" );
string SQLCOMMAND = " SELECT UOM FROM ST_ITEM_UOM WHERE CODE = 'ANT'";
addDetailsConnection.Open();
FbCommand readCommand = new FbCommand(SQLCOMMAND, addDetailsConnection);
FbDataReader myreader = readCommand.ExecuteReader();
while (myreader.Read())
{
MessageBox.Show(myreader[0].ToString());
}
myreader.Close();
readCommand.Dispose();
addDetailsConnection.Close();
addDetailsConnection.Dispose();
This code lets me read my FDB file and extract the data. When the code executes for the first time, there is no error or problem, However when when I execute it again, this error is shown:
The process cannot access the file 'C:\Users\ACC-0001.FDB' because it is being used by another process.
You can use Handle to check which program is locking the file. It might be caused by your code or by another process running on your machine.
The tool identifies the process, for example:
C:>handle.exe c:\test.xlsx
Handle v3.46 Copyright (C) 1997-2011 Mark Russinovich Sysinternals -
www.sysinternals.com
EXCEL.EXE pid: 3596 type: File 414: C:\test.xlsx
As found here.
If the problem lies within your code, make sure you dispose and close all connections, preferably by using them within using sections:
using (FbConnection addDetailsConnection = new FbConnection("..."))
{
// do work
}
More details on using using can be found here.
You might have bumped into this Firebird issue: FB server reports that DB file is used by another application on secondary attachment attempt through a symlink
It only happens on Windows and only when two non-embedded connections use different path names of which one or both have a symlink in their path so they effectively point to the same location.
Both handle.exe and Process Explorer will only show the canonical (final) filename that fbserver.exe actually opens.
The only way to find out is to:
compare connection strings.
verify with handle.exe or Process Explorer that the files are indeed opened by fbserver.exe (and not by your process itself using an embedded connection)

C# Equivalent of command line assoc *.__ = ___

I am trying to use my coding program in C# to associate files like *.geoclass or *.meowva so that they are, in explorer, called "Geoclass Code File."
Note: I do not need it to open with my application, all I need is the equivalent of this in the cmd.exe:
ASSOC .geoclass = Geoclass Code File

Constant save file directory

I have a VS2012 in C# solution with 4 projects in 4 layer structure(Presentation, BusinessLogic, DomainModel, DataAccess) and wanted to give the user the option to select the database's file's path at the Login form, which is in the Presentation layer (it is then used when a creating connection to the Database in a static method in the DataAccess layer). And the path would be saved and used the next time the application runs.
A bit more workflow example would be:
User starts the application and the login form appears;
User chooses the Database's file path with a FolderBrowserDialog or
OpenDirectoryDialog;
User works on the application then ends it;
User starts the application and the Database's file path is the one
he picked before;
User works on the application then ends it;
User starts the application and picks another file;
User works on the application then ends it;
User starts the application and the Database's file path is the one
he picked before.
Codewise I don't want to go passing along that string (path) all around my code for each method that needs to create a connection and such.
So any ideas on how to directly save it in the method that's directly using it? If not only when the user wants to change it then just forcing the user to pick the file when the starts the application.
Currently what I'm doing is forcing the user to put the file he wants in the solution's directory with a specific name before starting the application when he wants to use another Database file. For that I'm using:
public static string path;
public static OleDbConnection createConnection()
{
path = DirProject() + "\\Calibrações Equipamentos ULSM.accdb";
OleDbConnectionStringBuilder builder = new OleDbConnectionStringBuilder();
builder["Provider"] = "Microsoft.ACE.OLEDB.12.0";
builder["Data Source"] = path;
return new OleDbConnection(builder.ConnectionString);
}
private static string DirProject()
{
string DirDebug = System.IO.Directory.GetCurrentDirectory();
string DirProject = DirDebug;
for (int counter_slash = 0; counter_slash < 3; counter_slash++)
{
DirProject = DirProject.Substring(0, DirProject.LastIndexOf(#"\"));
}
return DirProject;
}
Configuration (=data) is not saved into a method (=code). It's usually saved into a configuration file. You can leverage .NET's application and user settings mechanism to achieve what you want.
Use User Settings
How To: Write User Settings at Run Time with C#
How To: Read Settings at Run Time With C#

"Global" XML settings in C#

A settings file is a nice way to access important data anywhere in a program since we can simply say
string dogType = Settings.Default.FavoriteDogType; or Settings.Default.FavoriteDogType = "Chiwawa";
I like this but the file is managed by the computer (stored in user settings). For my application, I would like to allow the user to select there own settings file (stored by them) and use this file for the settings as in
NewWayOfUsingSettings.Load("bobsFavoriteDogInfo.xml");
and then being able to call
string dogType = NewWayOfUsingSettings.FavoriteDogType;
anywhere in the program where "bobsFavoriteDogInfo.xml" would contain the settings to use. (alternatively, Jane could load "JanesBestDog.xml" etc.) Does C# support a simple way to do this?
Thanks!

Import Microsoft Access Database in Mysql database

I have a particular situation where my client require to import (periodically) an ms-access database into his mysql website database (so it's a remote database).
Because the hosting plan is a shared hosting (not a vps), the only way to do it is through PHP through an SQL query, because I don't have ODBC support on hosting.
My current idea is this one (obviusly the client has a MS-Windows O.S.):
Create a small C# application that convert MS-Access database into a big SQL query written on a file
The application will then use FTP info to send the file into a specified directory on the website
A PHP script will then run periodically (like every 30 minutes) and check if file exists, eventually importing it into the database
I know it's not the best approach so I'm proposing a question to create a different workaround for this problem. The client already said that he wants keep using his ms-access database.
The biggest problem I have is that scripts can last only 30 seconds, which is obviusly a problem to import data.
To work around the 30-second limit, call your script repeatedly, and keep track of your progress. Here's one rough idea:
if(!file_exists('upload.sql')) exit();
$max = 2000; // the maximum number you want to execute.
if(file_exists('progress.txt')) {
$progress = file_get_contents('progress.txt');
} else {
$progress = 0;
}
// load the file into an array, expecting one query per line
$file = file('upload.sql');
foreach($file as $current => $query) {
if($current < $progress) continue; // skip the ones we've done
if($current - $progress >= $max) break; // stop before we hit the max
mysql_query($query);
}
// did we finish the file?
if($current == count($file) - 1) {
unlink('progress.txt');
unlink('upload.sql');
} else {
file_put_contents('progress.txt', $current);
}

Categories

Resources