|
Hello,
I recently finished a C# course and I'm ready to create what could be a complex program, to me at least. The idea I have is to monitor a cad application that runs on the users machine and work on a design file locally but save it to the server every x number of minutes.
Users currently work on the files on a blade server that backups are mediocre at best, a network running at 100 and not gigabit.
After reading a few articles here on C# threads and processes I now have a few questions.
Can C# monitor when the application starts\ends via the task manager and get the file path and name so I can then do a time\date compare with the version on the server vs. the one on the local machine?
Anything to consider C# wise if a second instance of the application is started? They would be two different drawings and the task manager does show two applications and processes running.
Can this be set as a service to launch, or what would be the best way to implement this once a user logs on to the machine to catch the start of the application?
Should the FileSystemWatcher or EventHandler reduce the complexity?
Any input or guides to an example already existing is appreciated.
Or should I just stay with the "Hello World" example in the book?
Thanks!
I'll tell you what, then. Why don't you call me some time when you have no class? - Thornton Melon
|
|
|
|
|
You should always move beyond the "Hello World"!
<sig notetoself="think of a better signature">
<first>Jim
<last willyoudomyhomeworkforme="false">Meadors
|
|
|
|
|
You can try System.Diagnostics.Process.GetProcessesByName to get a list of Processes. But I do not know an event for a Process being started (perhaps WMI could do so), I'd poll the list every few seconds.
But more important: how much interoperation does the application to be montired allow? Can you query its current file? Is the file read-able when it is opened in that application (could be locked!)?
|
|
|
|
|
The software does save changes automatically in the drawing which would be local in this case and then I would have it save the drawing to the server every 20 minutes.
I did find a msdn topic on services http://msdn.microsoft.com/en-us/library/zt39148a(v=vs.80).aspx[^]
I think I may be on to something and I am testing it out.
The reading of articles and implementing this is a bit like herding cats at the moment.
I'll tell you what, then. Why don't you call me some time when you have no class? - Thornton Melon
|
|
|
|
|
Steps
- Learn how to create a windows service
- Learn how to use Process
- Figure out how to manage files and specifically detect time changes and how to copy.
- Figure out how the cad app 'saves' a file
Last step is more experimental. You should probably save two back ups and alternate as that gives a better chance of one not be bad due to a copy during a write.
Last step also involves figuring out where the file is saved and to which user it belongs.
mphill4744 wrote: Users currently work on the files on a blade server
This of course is all dependent on the presumption that the 'server' is in fact windows.
|
|
|
|
|
In a C# 2008 desktop application I would like to know how to change the following code so that the files I am looking for can be located.
string Format_Date = DateTime.Now.AddMonths(-1).ToString("MM-yyyy");
String filesaveLocation = null;
filesaveLocation = Path.Combine(ConfigurationSettings.AppSettings["tLocation"], Format_Date);
if (!Directory.Exists(filesaveLocation))
{
System.IO.Directory.CreateDirectory(filesaveLocation);
logging.Error("The location " + filesaveLocation + " does not exist.");
return packageId;
}
else
{
string[] RFiles = (from path in Directory.GetFiles(filesaveLocation)
let name = Path.GetFileName(path)
where name.EndsWith(".pdf") ||
name.EndsWith(".xlsx") ||
name.EndsWith(".xls")
select path).ToArray();
}
foreach (String RFile in RFiles)
{
}
The code was written for a directory path that looks like the following:
C:\Trans\01-2013 -Note the 01-2013 is for month and year.
Now I am finding out that the file directory stucture in production looks like the following:
R:\Trans\_JAN_2013\A-Sample. Under the A-Sample directory there are 4 separate subdirectories
called: SUB1, SUB2, SUB3, and SUB4.
I was expecting to see the files in one directory instead of 4 separate directories.
Thus can you show me code and/or tell me how you would change the code to accomodae the change in the file directory strucutre?
|
|
|
|
|
First to fix the Format_Date for the month as abbreviated name:
string Format_Date = DateTime.Now.AddMonths(-1).ToString("_MMM_yyyy");
Next, to get all of the file information from all subdirectories, change the code to build RFiles to be:
var RFiles = from path in Directory.EnumerateFiles(filesaveLocation, "*.*", SearchOption.AllDirectories)
let extension = Path.GetExtension(path)
where extension == ".pdf" || extension == ".xlsx" || extension == ".xls"
select path;
It probably isn't necessary to make this into an array if you are just going to iterate over the collection in a foreach . This Linq query will return an IEnumerable<string> which can be used directly in the foreach (unless you will be modifying the values in the collection during the loop).
The string comparisons in the query will be case-sensitive, just like your use of .EndsWith(...) .
Now, if all you are going to do is iterate over this collection of filepaths, why not skip building RFiles altogether:
foreach (string RFile in Directory.EnumerateFiles(filesaveLocation, "*.*", SearchOption.AllDirectories))
{
string extension = Path.GetExtension(RFile);
if (extension == ".pdf" || extension == ".xlsx" || extension == ".xls")
{
}
}
|
|
|
|
|
I like youtr idea of 'if all you are going to do is iterate over this collection of filepaths, why not skip building RFiles altogether:'.
However I need to write out error messages to a log file if 'specified' files are not located.
|
|
|
|
|
But any 'specified' files that are not located, by definition, will not be in the iteration, so (without seeing what you are doing with the file-paths) I still don't see why you would need the collection.
|
|
|
|
|
Hi,
you can set the "ConfigurationSettings.AppSettings["tLocation"]" somewhere in your code or settings to pick up the root directory. The get all the sub directories using DirectoryInfo, and for each directory in directiories check for files.
In addition the ConfigurationSettings.AppSettings property is obsolete from .Net 2.0 framework, you should not be using that property. Instead you should be using ConfigurationManager.AppSettings.
http://msdn.microsoft.com/en-us/library/system.configuration.configurationsettings.appsettings.aspx[^]
Regards
Jegan
Think! Don't write a line of code unless you absolutely need to.
|
|
|
|
|
Can you tell me when the ConfigurationSettings.AppSettings will no longer be supported in visual studio? I would like to know so that I can make the appropriate changes to use the ConfigurationManager.AppSettings settings instead?
|
|
|
|
|
It is obsolete since .Net 2.0 that is since VS2005.
Please see the link on my last message.
Jegan
Think! Don't write a line of code unless you absolutely need to.
|
|
|
|
|
Hi,
I have a DevExpress DatePicker component in my C# windows for application which will display a DateTime and I have a timestamp or datetime field in MySQL.
I want to use the date only from the datePicker and find it by date only in the MySQL regardless of the time.
Technology News @ www.JassimRahma.com
|
|
|
|
|
..delete the time-portion of the date? A date is a double, so truncating it should do the trick.
Bastard Programmer from Hell
If you can't read my code, try converting it here[^]
|
|
|
|
|
Please, ignore Eddies suggestion, and just use the Date part of the DateTime: MSDN[^]
It removes the time portion of a DateTime value, and returns just the date:
DateTime now = DateTime.Now;
DateTime today = now.Date;
Console.WriteLine("{0} : {1}", now, today);
Gives:
06/03/2013 15:45:49 : 06/03/2013 00:00:00
[edit]Spaced the output better - OriginalGriff[/edit]
If you get an email telling you that you can catch Swine Flu from tinned pork then just delete it. It's Spam.
|
|
|
|
|
Agreed 
|
|
|
|
|
Combined with OG's answer MySQL has a DATE function which selects only the date portion of a DateTime field, something like this:
SELECT tableid, field1, field2 FROM yourTable WHERE DATE(yourDateField) = @yourDateParameter;
That will let you filter the results by only the date portion;
Hope this helps
When I was a coder, we worked on algorithms. Today, we memorize APIs for countless libraries — those libraries have the algorithms - Eric Allman
|
|
|
|
|
Jassim Rahma wrote: I have a DevExpress DatePicker component in my C# windows for application
Part 1.
Jassim Rahma wrote: and I have a timestamp or datetime field in MySQL.
Part 2.
A timestamp is not the same as a date. Now if the value was carefully manipulated correctly every time it was inserted into the database then you would have a timestamp, NOT a date, which had a fixed time part.
If and only if that is the case then you can get the date part from C# per the other suggestions and then construct the time part and then do an exact match. Probably. (A range is still probably safer.)
If however the time part varies in the database then you MUST use a range check. So if the user picks 2012-12-31 then you create two timestamp values with the following values
start = 2012-12-30 00:00:00
end = 2012-12-31 00:00:00
Then you do a database comparison like the following
where {column} > start and {column} <= end
|
|
|
|
|
CREATE PROCEDURE sp_userinformation
@UserName varchar(50),
@Password varchar(50),
@FirstName varchar(50),
@LastName varchar(50),
@Email varchar(50),
@PhoneNo varchar(50),
@Location varchar(50),
@Created_By varchar(50),
@ERROR VARCHAR(100) OUT
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
---Checking Condition if User exists or not if user not exists returns different message if exists returns different message
IF NOT EXISTS(SELECT * FROM User_Information WHERE UserName=@UserName)
BEGIN
INSERT INTO User_Information
(
UserName,
[Password],
FirstName,
LastName,
Email,
PhoneNo,
Location,
Created_By
)
VALUES
(
@UserName,
@Password,
@FirstName,
@LastName,
@Email,
@PhoneNo,
@Location,
@Created_By
)
--If User Successfully Registerd I am returing this Message as Output Parameter
SET @ERROR=@UserName+' Registered Successfully'
END
ELSE
BEGIN
--If User already Exists i am returning this Message as Output Parameter
SET @ERROR=@UserName + ' Already Exists'
END
END
|
|
|
|
|
You should really ask this in the database forum. You don't need a semi-colon at the end of SET NOCOUNT ON.
|
|
|
|
|
yeah.. correct & thanks .
|
|
|
|
|
Not a problem. I'm glad you've got it working.
|
|
|
|
|
|
|
there is a exception when i create DirectoryEntry .
code:
DirectoryEntry parent = GetDirectoryEntryByDn(path);
<big><b></b> DirectoryEntry user = parent.Children.Add("CN=" + user_name, "user");</big>
try
{
string oGUID = string.Empty;
user.Properties["samAccountName"].Value = user_name;
user.Properties["telephoneNumber"].Value = "15014088110";
user.Properties["streetAddress"].Value = "HZ";
oGUID = user.Guid.ToString();
user.CommitChanges();
}
catch
{ }
user.Close();
parent.Close();
the program run the line :
DirectoryEntry user = parent.Children.Add("CN=" + user_name, "user")
,the excpetion happened:
the exception InteropServicesCOMException "The specified Directory object is not bound to a remote resource" (and Error code
property is -2147463159)
please help me !
|
|
|
|