|
I suspect that what you are seeing is simply the result of an operation taking time to complete, and the timer that is doing the polling is gradually slipping as a result.
|
|
|
|
|
This is how i coded.
lDueTime = 60000;
lPeriod = 300000;
TimerCallback timerDelegate = new TimerCallback(FileOperations);
ThreadTimer = new Timer(timerDelegate, null, lDueTime, lPeriod);
public void FileOperations()
{
// My code goes here
}
Long Live
|
|
|
|
|
Hi,
in my program, I want to prepare a choice for user to make the program run when windows starts. (But not when s/he installs the program) I want to make it optional. For that I wrote (when the user checks that option):
string registryaddress = @"Software\Microsoft\Windows\CurrentVersion\Run";
RegistryKey rk = Registry.CurrentUser.OpenSubKey(registryaddress).CreateSubKey("programname");
rk.SetValue("programname",Application.ExecutablePath);
and I get a runtime error as follows :
"Unauthorized access exception " , Cannot write to the registry key...
I need help in this one, and also when the user unchecks this option , I have to delete this registry right?
But the bigger problem occurs when user checks this option but uninstalls the program after that. How can I make the C# Setup Deployement project (I mean the installer) uninstall this registry file, which had not been installed during the installation rather done by the user sometime after.
Thanks..
|
|
|
|
|
Registry.CurrentUser.OpenSubKey(registryaddress)
opens the key as a readonly key. Try
Registry.CurrentUser.OpenSubKey(registryaddress, true)
to open it with write permissions. MSDN[^]
To have the installer remove it on an un-installation, you could have the installer put the key in the registry when the program is installed; then when the installer is run to remove the program it'll automatically remove the key for you. If you want the autostart disabled by default then you could put a little check in your app that removes the key the first time it's run. It may be a little kludgy but it's just an idea
|
|
|
|
|
ok, but when I open the registry part in the setup project, tree-view on the left shows registry but narrows down only to :
H_KEY_CURRENT_USER -> Software -> [Manufacturer]
while I somehow must create the key in the following path, as we talked about earlier :
H_KEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run
I'm not familiar with registry stuff so I'm stuck at this point
On the other hand, some friends said I could put a shortcut to my application's exe file into the Users Startup Folder using Setup Project.
This method seems to be working but to avoid the autostart, I shall delete this shortcut when user doesn't want so. This brings me two other problems as:
1) Startup path is
C:\Documents and Settings\[username]\Start Menu\Programs\Startup
but how can I get the username?
2) I dont even know how to make a shortcut. I only know File.Rename, File.Exists and File.Delete
I would be too glad if you help me out in either scenarios.
|
|
|
|
|
Fortunately you've got lots of options here
Option 1) In the setup project, right click on the Software registry key, select [ New -> Key ] and create a key called "Microsoft", then right click on that and add "Windows" until you get down to where you put your applications path
Option 2) Environment.SpecialFolder.Startup returns the users Startup folder. To create a windows shortcut, add a reference in your project to IWshRuntimeLibrary , then try this snippet:
IWshRuntimeLibrary.WshShell winShell = new IWshRuntimeLibrary.WshShellClass();
IWshRuntimeLibrary.IWshShortcut shortcut = (IWshRuntimeLibrary.IWshShortcut)winShell.CreateShortcut(pathToShortcut);
shortcut.TargetPath = pathToTarget;
shortcut.Save();
where pathToShortcut is something like Environment.SpecialFolder.Startup + "\\MyApp.lnk" and pathToTarget is the full path to your app; it's probably a good idea to throw a try { } catch (COMException) { } around it all since they're COM objects you'd be using. To remove a shortcut just use a File.Delete .
Option 3) Use a custom action. On installation, uninstallation, upgrade, rollback, etc you can define a custom executable for the installer to execute. You could create one that simply checks for the reg key when the program is removed and deletes it if it exists. Check here[^] for a tutorial.
|
|
|
|
|
this post looks veery useful! Thanks a lot!
One last thing that I have to ask before I let you go is:
Jimmanuel wrote: To create a windows shortcut, add a reference in your project to IWshRuntimeLibrary,
I couldnt find this reference in the COM tab.
Rather I have : (I thought they may be related)
Microsoft Script Control 1.0
Microsoft Scripting Runtime
Microsoft Script Scriptlet Library
But they too didnt help me use IWshRuntimeLibrary
Is it someting I have to download from internet?
I'm using Visual Studio .NET 2005 by the way
|
|
|
|
|
Sorry, it's the "Windows Script Host Object Model" in the COM tab but when it's been added to the project it's shown as IWshRuntimeLibrary
|
|
|
|
|
Man I solved the previous problem :
it was "Windows Script Host Object Model" to use and after that Library was defined and I could create a shortcut
But now I'm having trouble with "Enviroment.SpecialFolder.Startup"
when I do this one :
MessageBox.Show(System.IO.Directory.Exists(Environment.SpecialFolder.Startup.ToString())+"");
I get false? Is there something wrong ...
IWshRuntimeLibrary.WshShell winShell = new IWshRuntimeLibrary.WshShellClass();
IWshRuntimeLibrary.IWshShortcut shortcut = (IWshRuntimeLibrary.IWshShortcut)winShell.CreateShortcut(Environment.SpecialFolder.Startup+"\\a.lnk");
shortcut.TargetPath = "D:\\a.txt";
shortcut.Save();
This also didnt work for me It says "system couldnt find the path" for the environment part..
|
|
|
|
|
whoops I found this one too:
Environment.GetFolderPath(Environment.SpecialFolder.Startup)+"\\a.lnk"
worked..
sorry for keeping you busy, thanks a lot!!!
|
|
|
|
|
methhoo wrote: Environment.GetFolderPath
whoops, forgot that part
glad to help
|
|
|
|
|
Pls see the code that I have used for setting the registry option when the user checks that option
void startup_Click(object sender, EventArgs e)<br />
{<br />
RegistryKey key = Registry.CurrentUser.CreateSubKey(@"Software\Microsoft\Windows\CurrentVersion\Run");<br />
if (((MenuItem)sender).Checked)<br />
{<br />
key.DeleteValue("MyApp", false);<br />
((MenuItem)sender).Checked = false; <br />
}<br />
else<br />
{<br />
key.SetValue("MyApp", Application.ExecutablePath, RegistryValueKind.String);<br />
((MenuItem)sender).Checked = true;<br />
}<br />
}
methhoo wrote: How can I make the C# Setup Deployement project
I am not sure about this..
*jaans
|
|
|
|
|
So how do you handle the situation that; user uninstalls your program , but registry is still there. I mean wouldn't it cause an error every time windows starts, unless user knows how to delete this registry file.
I wish we could trigger (may be) an exe file when uninstall procedure begins, and do whatever stuff to do, after that uninstall would also delete this worker exe.file
|
|
|
|
|
Hi,
In my dataset I have numerous table adapters which I need to chose from at runtime.
I can create at runtime a text string for the adapter I need to use however I cannot use that string to construct the method. What I have done is create an array of tableadapters and then used the index of that array to contruct the method.
As the project grows, this is becoming a consuming exercise and I am surprised there isn't a better way.
Is there some way that you can select a tableadapter from the dataset at runtime using the string representation of the table adapter to select it with.
Thanks.
|
|
|
|
|
Glen Harvy,
I THINK its possible to do this with Reflection, but i've never used it, maybe a bit of googling/someone else might be able to confirm my post.
Regards,
Gareth.
|
|
|
|
|
Thanks for your response.
I've never used reflection either! <grunt> Guess I'll have to learn
I've tried googling (always do) and I'm sure it's there but what do I search on is the hard part
Glen Harvy
|
|
|
|
|
Hi All:
I've been trying to figure out how to print multiple copies of a page. This code is as close as I've been able to come, but I get odd results. The first time I try to print I specify 2 pages and I get 4 pages. Without leaving the program, the second time I try to print I specify 2 pages and I get one page printed with the second page on top of the first.
Any thoughts you have are very much appreciated!
Dale E. Moore
using System;<br />
using System.Drawing;<br />
using System.Drawing.Printing;<br />
using System.Windows.Forms;<br />
namespace MultipleCopies<br />
{<br />
public partial class Form2 : Form<br />
{<br />
private PrintDocument printDoc = new PrintDocument();<br />
private int copiesToPrint;<br />
public Form2()<br />
{<br />
InitializeComponent();<br />
}<br />
private void button1_Click(object sender, EventArgs e)<br />
{<br />
printDoc.PrintPage += new PrintPageEventHandler(printDoc_PrintPage); <br />
PrintDialog dlg = new PrintDialog();<br />
dlg.PrinterSettings = new PrinterSettings();<br />
if (dlg.ShowDialog() == DialogResult.OK) {<br />
copiesToPrint = dlg.PrinterSettings.Copies;<br />
printDoc.Print(); <br />
}<br />
}<br />
private void printDoc_PrintPage(Object sender, PrintPageEventArgs e) {<br />
String textToPrint = "Printing " + copiesToPrint;<br />
Font printFont = new Font("Courier New", 12);<br />
int leftMargin = e.MarginBounds.Left;<br />
int topMargin = e.MarginBounds.Top;<br />
e.Graphics.DrawString(textToPrint, printFont, Brushes.Black, leftMargin, topMargin);<br />
copiesToPrint--;<br />
if (copiesToPrint < 1) <br />
e.HasMorePages = false;<br />
else <br />
e.HasMorePages = true;<br />
}<br />
[STAThread]<br />
static void Main()<br />
{<br />
Application.Run(new Form2());<br />
}<br />
}<br />
}
|
|
|
|
|
Shouldn't it be:
dlg.PrinterSettings.Copies = copiesToPrint;
Since you want to set the number of copies, not get the number.
Regards,
Gareth.
|
|
|
|
|
Thank you for the dialog; I fear I have been unclear in my specification! I want to print multiple copies of a multi-page document. So
printDoc.PrinterSettings.Copies = dlg.PrinterSettings.Copies; should set the copies and the number gets stuffed, but it seems to only control the first printing. And I've changed the source code, below, to identify the numberOfPages which also only seems to work on the first printing.
using System;
using System.Drawing;
using System.Drawing.Printing;
using System.Windows.Forms;
namespace MultipleCopies
{
public partial class Form2 : Form
{
private PrintDocument printDoc = new PrintDocument();
private int numberOfPages;
public Form2()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
printDoc.PrintPage += new PrintPageEventHandler(printDoc_PrintPage);
PrintDialog dlg = new PrintDialog();
dlg.PrinterSettings = new PrinterSettings();
if (dlg.ShowDialog() == DialogResult.OK) {
printDoc.PrinterSettings.Copies = dlg.PrinterSettings.Copies;
numberOfPages = 2;
printDoc.Print();
}
}
private void printDoc_PrintPage(Object sender, PrintPageEventArgs e)
{
String textToPrint = "Printing copies " + printDoc.PrinterSettings.Copies
+ ", pages " + numberOfPages;
Font printFont = new Font("Courier New", 12);
int leftMargin = e.MarginBounds.Left;
int topMargin = e.MarginBounds.Top;
e.Graphics.DrawString(textToPrint, printFont, Brushes.Black,
leftMargin, topMargin);
numberOfPages--;
if (numberOfPages < 1)
e.HasMorePages = false;
else
e.HasMorePages = true;
}
[STAThread]
static void Main()
{
Application.Run(new Form2());
}
}
}
|
|
|
|
|
Thanks to your help I was able to blow away some of the fog in my mind and realize I should be handling my variables differently. The following code has resolved my problem.
using System;
using System.Drawing;
using System.Drawing.Printing;
using System.Windows.Forms;
namespace MultipleCopies
{
public partial class Form2 : Form
{
private PrintDocument printDoc;
private int numberOfPages;
public Form2()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
printDoc = new PrintDocument();
printDoc.PrintPage += new PrintPageEventHandler(printDoc_PrintPage);
PrintDialog dlg = new PrintDialog();
dlg.PrinterSettings = new PrinterSettings();
if (dlg.ShowDialog() == DialogResult.OK) {
printDoc.PrinterSettings.Copies = dlg.PrinterSettings.Copies;
numberOfPages = 2;
printDoc.Print();
}
}
private void printDoc_PrintPage(Object sender, PrintPageEventArgs e)
{
String textToPrint = "Printing copies " + printDoc.PrinterSettings.Copies
+ ", pages " + numberOfPages;
Font printFont = new Font("Courier New", 12);
int leftMargin = e.MarginBounds.Left;
int topMargin = e.MarginBounds.Top;
e.Graphics.DrawString(textToPrint, printFont, Brushes.Black,
leftMargin, topMargin);
numberOfPages--;
if (numberOfPages < 1)
e.HasMorePages = false;
else
e.HasMorePages = true;
}
[STAThread]
static void Main()
{
Application.Run(new Form2());
}
}
}
|
|
|
|
|
I need some assistance in tracking down why my code will not run as a service.
I have been hacking at this for over two weeks on and off with no real progress.
I need to use an old dll to access data.
When I call it from a console app, it works just fine.
Here is a snip of the code that works...
[DllImport("C:\\Program Files\\Omaha_Steaks_NUCAS_Reader\\libhab2.dll")]
public static extern int HABRSCI(string RSCI1, string RSCI2, string RSCI3, string RSCI4, string RSCI5);
static void Main()
{
try
{
//Create Variables for Host Access string
string resbuff = new string(' ', 80);
string reascode = "0000";
HABRSCI("0000", "01", "nucas.txt\0", resbuff, reascode);
}
catch (Exception ex)
{
string zzzz = ex.Message;
}
}
I rewrote as a Service, everything works except the dll call, it just acts as it was never called at all.
Here are some snips from my Service code....
//Set up usage of the .dll for Host Access
[DllImport("C:\\Program Files\\OS_NUCAS_Reader\\libhab2.dll",EntryPoint = "HABRSCI")]
public static extern int HABRSCI(string RSCI1, string RSCI2, string RSCI3, string RSCI4, string RSCI5);
and later, inside of a timer event..
try
{
//Create Variables for Host Access string
string resbuff = new string(' ', 80);
string reascode = "0000";
HABRSCI("0000", "01", "nucas.txt\0", resbuff, reascode);
}
catch (Exception ex)
{
}
This is just ignored!!!
I know the code executes around it, I have even added lines to write to the Event log just before and after the call.
If it works, a text file is created and a records is added to a log file maintained by the dll. none of these are happening so it apears that it ignores the call to the dll when running as Service.
Any assistance would be much appreciated.
Thanks,
Don
|
|
|
|
|
Hi,
I suggest you gather all information to find out what goes wrong, so:
1.
make sure you create a log file, and append all significant progress/trace info to it,
one line at a time.
2.
don't ignore exceptions
catch (Exception ex) {string zzzz = ex.Message;} and catch (Exception ex) {}
don't make sense since you are not doing anything with the exception's information.
Furthermore, you should always use Exception.ToString() keeping all the details.
3.
Make sure your app has an overall try-catch on top of your regular exception processing, so
even if you miss a local exception, you still catch it at the top level. You should apply
this to your main thread (the static main method), as to every thread you create.
4.
check and log all return values
public static extern int HABRSCI(...) promises a result, so store it in an int
and look at it. Maybe it is a status, with some negative value indicating a specific error.
5.
don't trust defaults for P/Invoke; I don't care to remember what calling convention is used,
I specify it explicitly on both sides (managed and unmanaged); example:
[DllImport("Winmm.dll", CallingConvention=CallingConvention.StdCall)]<br />
static extern int sndPlaySound(IntPtr buffer, int dwFlags);
Hope this helps.
Luc Pattyn [Forum Guidelines] [My Articles]
This month's tips:
- before you ask a question here, search CodeProject, then Google;
- the quality and detail of your question reflects on the effectiveness of the help you are likely to get;
- use PRE tags to preserve formatting when showing multi-line code snippets.
|
|
|
|
|
Luc
Good suggestions all.
I may have edited out too much when posting the code...
Anyway, I have run this with lines just before and after the HABRSCI call logging to an eventlog so I know it is getting to this line.
As to exceptions, they never come into play, no errors are happening (I have logging events in those sections also, never happen)
I can watch the app run by monitoring the lines being added to the event log, it loops every three minutes (current setting) and does several things, but the .dll never responds.
I did test it by adding code to return an int, but that always stays at zero in the Service (= no result) but returns either 4,8, or 16 in the Console version (indicates type of response collected by .dll)
If the .dll works, it generates a small text file with result data AND adds a 65 char line record to a text file in the local folder with status and timestamp information. This happens in the console version but not in the service version.
I will try the explicit call in #5 above to see if that helps.
Thanks,
Don
|
|
|
|
|
Hi Don,
some more ideas:
1.
if you have the source of the unmanaged code, you can add logging there too.
what I typically do is make it such that the unmanaged code logs to the managed world,
using a delegate (which becomes a function pointer).
2.
if the DLL has a simpler function somewhere, try that one first; or if you have the source,
add a simple function and try it (e.g. something that takes two ints and returns the product).
Success here proves you are accessing the DLL, and doing some P/Invoke correctly.
3.
I was a little surprised by the explicit NULL char in one of the args; if you try to get
a double NULL to the unmanaged world, I am not sure the marshaling will do that for you.
4.
if the unmanaged code throws an exception, it might just kill the thread without you noticing
(depending on which timer you use, you may get a separate thread).
You said "as if the function was not called", does the code return well from the unmanaged function, i.e. does the next (log) line get executed?
5.
If everything else fails my best guess is the unmanaged code executes but fails maybe
because there is no user, hence no "My Documents" and the like. Good error trapping should
catch that.
Luc Pattyn [Forum Guidelines] [My Articles]
This month's tips:
- before you ask a question here, search CodeProject, then Google;
- the quality and detail of your question reflects on the effectiveness of the help you are likely to get;
- use PRE tags to preserve formatting when showing multi-line code snippets.
|
|
|
|
|
Luc,
Thanks for sparking an idea that did fix prt of the problem.
Your #5 comment did the trick (the "My Documents" bit!)
It appears that while it is running as a console app, any file calls are, unless otherwise directed, sent to the folder where the .exe file is.
In my case, to make this old .dll work, there MUST be a .cfg configuration file AND a file name reference .txt file in the same folder as the libhab2.dll.
As an console app, those were placed there by the installer.
I guess I assumed that this was the case with a Service also.
NOT.....!
All calls are sent to the C:\WINNT\System32 folder.
I placed copies of the .cfg and .txt (the .dll was alredy there) in there and it works!
Now I just have to figure how to redirect the "local" folder of a system login. (I guess I could leave the files in system32 but that feels wrong somehow!)
Error trapping did not help because the .dll just returned with a Zero and no other information. It had been writing to it's own log file, but I did not see it because I was expecting to to be created and added to in the C:\Program Files\OSNUCASReader folder, not C:\WINNT\System32.
If I had done a global search of my HD looking for "hafelog.log", I would have saved a week of hairpulling!
The log only had a line like this:
"20080116115428 23KDGWDLOG F_Dialog e 00085370Internal processing error encountered during routine operations. "
BUT, it would have let me know that the .dll was being called.
I just was not thinking about the System32 folder (too many trees to see the forest I guess)
Anyway, thanks for the suggestions and the spark to get me moving forward.
Don
|
|
|
|
|