|
Sorry, i just got around to trying both methods. For the first one,
public void ValidateText(List textboxes)
{
Successful = true;
foreach (var tb in textboxes)
{
if (string.IsNullOrEmpty(tb.Text))
{
Successful = false;
}
}
}
how do i go about outputting the actual control name that failed? all i can do is echo tb.text which ofc is empty. Any help would be great.
modified 11-Mar-21 21:01pm.
|
|
|
|
|
What would be a good way to monitor a .ini file?
What I want to do is when the file has changed, I need to read the file and find specific text and change it and save the file.
I've attempted the file system watcher with little luck. The problem is it is firing before the file is unlocked. I have also tried to put a method in there to check if the file was locked which basically opens the file and on exception returns true if locked otherwise false.
I have also tried a looping method like this:
private void WriteFile(string file, StringBuilder sb, string oldValue)
{
StreamWriter sw = null;
try
{
sw = new StreamWriter(file, false);
sw.Write(sb.ToString());
sw.Close();
EventLog.WriteEntry("QBiniMonitor", "Successfully removed LASTUSERNAME. Old Value: " + oldValue, EventLogEntryType.Information);
}
catch (IOException)
{
WriteFile(file, sb, oldValue);
}
finally
{
if (sw != null)
{
sw.Close();
sw.Dispose();
}
}
}
It still errored out after it changes the value a couple times in a row. It changes it a couple times but then ends up with a uncaught IOException somehow
|
|
|
|
|
You can use this method in a loop until the ini file closed.
protected virtual bool IsFileLocked(FileInfo file)
{
FileStream stream = null;
try
{
stream = file.Open(FileMode.Open, FileAccess.ReadWrite, FileShare.None);
}
catch (IOException)
{
return true;
}
finally
{
if (stream != null)
stream.Close();
}
return false;
}
|
|
|
|
|
The OP could try this, but there's a race condition here. What happens if he calls this method, and it returns false, and then he opens the file but an external process has taken a lock on the file?
|
|
|
|
|
JD86 wrote: It changes it a couple times but then ends up with a uncaught IOException somehow
catch (IOException)
{
WriteFile(file, sb, oldValue);
}
You should log all exceptions; I'm betting that your WriteFile is causing the new exception, which would throw something "unhandled". So, wrap that in a try-construction too, or move it somewhere else.
I'd also recommend using a using block, as opposed to a try-finally with explicit dispose - it's a bit more readable.
Bastard Programmer from Hell
if you can't read my code, try converting it here[^]
|
|
|
|
|
I would be tempted to rewrite this method like this:
private static readonly object SyncLock = new object();
private void WriteFile(string file, StringBuilder sb, string oldValue)
{
try
{
using (StreamWriter sw = new StreamWriter(file, false))
{
sw.Write(sb.ToString());
}
EventLog.WriteEntry("QBiniMonitor", "Successfully removed LASTUSERNAME. Old Value: " + oldValue, EventLogEntryType.Information);
}
catch (IOException)
{
lock (SyncLock)
{
Monitor.Wait(SyncLock, 200);
}
WriteFile(file, sb, oldValue);
}
} The using statement removes the need to explicitly close the stream, and the lock/Monitor elements help to pause the next call to WriteFile for 200 milliseconds. Without this, you have a tight loop in there with execution of WriteFile happening immediately on failure.
|
|
|
|
|
Whoa there Slick! I see a possible StackOverflow waiting to happen if the file never gets unlocked.
|
|
|
|
|
Indeed, but I'm only working with the OPs original code - yes, if it were my code, I'd add in terminating conditions. As I don't know what the OPs ultimate use case is here, I'm loathe to suggest this - I've just had to assume that the lock has a finite limit.
|
|
|
|
|
Pete O'Hanlon wrote: I've just had to assume that the lock has a finite
limit.
True. I don't know any more about his requirements than you. I just wanted to point out that it's not the ultimate solution for anyone else just scrounging for code.
Pete O'Hanlon wrote: I'm loathe to suggest this
Kinda makes you want to take a long shower, doesn't it?
|
|
|
|
|
Use the FileSystemWatcher, when it notifies you of a change put an entry on a queue with a retrieval time of 1 second (or 200ms or whatever is appropriate in the future), and have another thread which pulls things off that queue at the right time and actions them. In this case the action is 'read file, find text, replace, write file'. If it fails, re-queue it.
|
|
|
|
|
Based on the description, I believe this is what the OP has said he's done (all except for the pause bit).
|
|
|
|
|
Sorry for the delay responses! Just had a baby girl
Anyways let me explain. I'm setting up a multi-tenant quickbooks environment. The problem is as we probably all know is it wasn't really designed for multi-tenancy. Now everything works fine with what I have except the username is populated on a program level.
So in the ProgramData directory (All Users) there is a qbw.ini file that contains LASTUSERNAME=. Each time a user launches quickbooks it reads this information and prepopulated the username field for the company database login.
I don't want people seeing other peoples logins. Most just use Admin which isn't a big deal but some use their company name. So I don't want another company seeing that.
So my idea is to monitor that file for updates using a file system watcher and changing that value in the INI file to blank. So basically changing something like this: "LASTUSERNAME=Admin" to this: "LASTUSERNAME="
Quickbooks does not place a permanent lock on this file. So we don't have to worry about quickbooks locking it for a long period of time.
I'm trying suggestions as we speak. I'm adding an error count to stop the service if an exception happens so many times within a specific time period. Hopefully this will stop an overflow exception like you were talking about. I can make something to restart the service ever so often.
Not the best plan but so far thats what I got!
|
|
|
|
|
Alright so here is what I ended up with. It seems to work... catches the IO exceptions and continues running. So far it is working good enough for me
using System;
using System.Diagnostics;
using System.IO;
using System.ServiceProcess;
using System.Text;
using System.Threading;
namespace QBiniMonitor
{
public partial class QBMonitor : ServiceBase
{
FileSystemWatcher watcher2012;
FileSystemWatcher watcher2011;
string QB2012 = Environment.ExpandEnvironmentVariables("%ALLUSERSPROFILE%") + @"\Intuit\QuickBooks 2012\";
string QB2011 = Environment.ExpandEnvironmentVariables("%ALLUSERSPROFILE%") + @"\Intuit\QuickBooks 2011\";
enum Version
{
QB2011,
QB2012
}
public QBMonitor()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
StartNewWatcher(Version.QB2011);
StartNewWatcher(Version.QB2012);
}
private void StartNewWatcher(Version watcherVersion)
{
if (watcherVersion == Version.QB2011)
{
watcher2011 = new FileSystemWatcher();
watcher2011.Path = QB2011;
watcher2011.Filter = "qbw.ini";
watcher2011.NotifyFilter = NotifyFilters.LastWrite;
watcher2011.Changed += new FileSystemEventHandler(watcher_Changed);
StartStopWatcher(Version.QB2011, true);
}
else if (watcherVersion == Version.QB2012)
{
watcher2012 = new FileSystemWatcher();
watcher2012.Path = QB2012;
watcher2012.Filter = "qbw.ini";
watcher2012.NotifyFilter = NotifyFilters.LastWrite;
watcher2012.Changed += new FileSystemEventHandler(watcher_Changed);
StartStopWatcher(Version.QB2012, true);
}
}
private void watcher_Changed(object sender, FileSystemEventArgs e)
{
FileSystemWatcher watcher = sender as FileSystemWatcher;
if (watcher.Path == QB2012)
StartStopWatcher(Version.QB2012, false);
else if (watcher.Path == QB2011)
StartStopWatcher(Version.QB2011, false);
bool saveFile = false;
string oldValue = string.Empty;
StringBuilder sb = new StringBuilder();
try
{
using (FileStream fs = new FileStream(e.FullPath, FileMode.Open, FileAccess.Read))
{
using (StreamReader sr = new StreamReader(fs))
{
while (sr.Peek() >= 0)
{
string currentLine = sr.ReadLine();
if (currentLine.StartsWith("LASTUSERNAME="))
{
if (!currentLine.Equals("LASTUSERNAME=Admin"))
{
sb.AppendLine("LASTUSERNAME=Admin");
oldValue = currentLine;
saveFile = true;
}
else
sb.AppendLine(currentLine);
}
else
sb.AppendLine(currentLine);
}
}
}
}
catch (Exception ex)
{
EventLog.WriteEntry("QBiniMonitor", "watcher_Changed::: " + ex.ToString(), EventLogEntryType.Error);
}
if (saveFile)
{
if (watcher.Path == QB2012)
WriteFile(Version.QB2012, e.FullPath, sb, oldValue, 1);
else if (watcher.Path == QB2011)
WriteFile(Version.QB2011, e.FullPath, sb, oldValue, 1);
}
else
{
if (watcher.Path == QB2012)
StartStopWatcher(Version.QB2012, true);
else if (watcher.Path == QB2011)
StartStopWatcher(Version.QB2011, true);
}
}
private static readonly object SyncLock = new object();
private void WriteFile(Version watcherVersion, string file, StringBuilder sb, string oldValue, int retryCount)
{
if (retryCount < 5)
{
try
{
using (StreamWriter sw = new StreamWriter(file, false))
{
sw.Write(sb.ToString());
}
EventLog.WriteEntry("QBiniMonitor", "Version: " + watcherVersion.ToString() + ". The value for the last username was cleared. The previous value was: " + oldValue, EventLogEntryType.Information);
StartStopWatcher(watcherVersion, true);
}
catch (IOException)
{
lock (SyncLock)
{
EventLog.WriteEntry("QBiniMonitor", "Version: " + watcherVersion.ToString() + ". File was locked. Waiting 2 seconds and trying again. Retry number: " + retryCount);
Monitor.Wait(SyncLock, 2000);
}
retryCount = retryCount + 1;
WriteFile(watcherVersion, file, sb, oldValue, retryCount);
}
}
else
{
EventLog.WriteEntry("QBiniMonitor", "WriteFile::: " + "Retry limit of 5 was reached while trying to change the data in the file. (Because the file was locked)", EventLogEntryType.Warning);
StartStopWatcher(watcherVersion, true);
}
}
private void StartStopWatcher(Version watcherVersion, bool start)
{
try
{
switch (watcherVersion)
{
case Version.QB2011:
if (start)
{
watcher2011.EnableRaisingEvents = true;
}
else
{
watcher2011.EnableRaisingEvents = false;
}
break;
case Version.QB2012:
if (start)
{
watcher2012.EnableRaisingEvents = true;
}
else
{
watcher2012.EnableRaisingEvents = false;
}
break;
default:
break;
}
}
catch (IOException ex)
{
EventLog.WriteEntry("QBiniMonitor", "StartStopWatcher::: " + ex.ToString(), EventLogEntryType.Error);
Stop();
}
catch (Exception ex)
{
EventLog.WriteEntry("QBiniMonitor", "StartStopWatcher::: " + ex.ToString(), EventLogEntryType.Error);
Stop();
}
}
protected override void OnStop()
{
if (watcher2011 != null)
{
watcher2011.EnableRaisingEvents = false;
watcher2011.Dispose();
}
if (watcher2012 != null)
{
watcher2012.EnableRaisingEvents = false;
watcher2012.Dispose();
}
}
}
}
|
|
|
|
|
I have a C# 2010 console application where I need to create a setup and deployment project for it. I do not have the setup and deployment projects in the visual studio.net 2010 application I am using. I need to find the install templates.
Can you tell me where I can find the setup and deployment project install templates so I can add them to my solution ide to work with?
|
|
|
|
|
You should find them in the Other Projects ( Project Templates )
Create a new Project of type (Other Projects - > Setup and Deployment -> VS Installer) ...
Regards,
Senthil Kumar
|
|
|
|
|
I do not have a Create a new Project of type (Other Projects - > Setup and Deployment -> VS Installer). I am somehow missing the templates.
|
|
|
|
|
If you have an Express version of Visual Studio you won't have it.
|
|
|
|
|
Don't bother. The Setup and Deployment projects were killed off in VS2012 anyway so you're going after legacy technology that, lets be honest here, sucked!
You can use any number of other tools that do a better job and are eaier to use, such as Inno Setup, Advanced Installer, InstallShield LE, WiX, ...
|
|
|
|
|
Hi everyone
which one of these way is correct?why?
Matrix m=new Matrix();
Rectangle rect=new Rectangle(0,0,10,10);
PointF[] point=
{
....
};
Warp(point, rect, m, WarpMode.Perspective,0F);
or
Warp(new PointF[]{....}, new CRect(0,10,10,10), new Matrix(), WarpMode.Perspective,0F);
|
|
|
|
|
These are the overloads as defined[^] in the framework;
GraphicsPath.Warp (PointF[], RectangleF)
GraphicsPath.Warp (PointF[], RectangleF, Matrix)
GraphicsPath.Warp (PointF[], RectangleF, Matrix, WarpMode)
GraphicsPath.Warp (PointF[], RectangleF, Matrix, WarpMode, Single)
Did that answer your question?
Bastard Programmer from Hell
if you can't read my code, try converting it here[^]
|
|
|
|
|
No I didnt, I want to know can I use of this code or not?
Warp(new PointF[]{....}, new CRect(0,10,10,10), new Matrix(), WarpMode.Perspective,0F);
|
|
|
|
|
They are both syntactically correct. However, the first option is easier to debug when things start to go wrong.
One of these days I'm going to think of a really clever signature.
|
|
|
|
|
Thank you Richard.
|
|
|
|
|
I want to keep some of my classes in library files and load them during runtime. I can load the assemblies and everything works fine. However, I don't find any function that will close or unload the assembly after a method is done using the assembly.
If the function is called several times, the assembly loading will be done multiple times. Without any function to unload it, can it cause any problem in application some times?
I'm now beginning the project so I would like to know the right approach and follow it. I would like to know before I start my project as I do not want to face any problems in the middle of the project. Please help and thanks in advance.
|
|
|
|
|
Dan_K wrote: If the function is called several times, the assembly loading will be done multiple times.
Why? Just add in a boolean that's set when it's loaded the first time, and check it before you load the assembly. That way the logic is executed only once, eliminating the need to know how often the assembly is in memory.
FWIW; it's loaded into memory once, and remains there. There's no unloading, unless you put everything in a separate AppDomain.
Bastard Programmer from Hell
if you can't read my code, try converting it here[^]
|
|
|
|
|