How to use Clipboard in C# services? - c#

Keep in mind i am using services not Windows Form App.
When I try to use System.Windows.Forms.Clipboard.GetText(); my code
don't go to next step.
means System.Windows.Forms Controls are deprecated
I am Trying to get copied text from Clipboard and change the text then set back to clipboard.
Please Help me.
below is my code
public void working()
{
while (true)
{
// Get text from clipboard
string clipboardtext = System.Windows.Forms.Clipboard.GetText();
string path = "c:\\sample.txt";
using (StreamWriter writer = new StreamWriter(path, true))
{
writer.WriteLine(string.Format("Clip Board Test " + "-" + " " + "Windows Service is called on " + DateTime.Now.ToString("dd/MMM/yyyy hh:mm:ss") + ""));
writer.Close();
System.Windows.Forms.Clipboard.SetDataObject("Hello ClipBoard");
}
Thread.Sleep(ScheduleTime * 6000);
}
}

Windows service is not running in same "scope" as your user GUI, it cannot access to your clipboard or key stroke or anything you do. Services are useful, because they can run without logged user or under different user.
Services are not allowed to access your keystrokes or clipboard also for security reasons.

Related

c# adobe acrobat SDK: file is still locked after SDK quit

I'm working with C# and adobe acrobat SDK.
When the program throws an error due to the pdf already being compressed I want to move the pdf.
However, C# complains that the file is being used by another process and I know it has to do with the SDK and not another program.
After some debugging I found out that compressPDFOperation.Execute is the culprit.
How can I close it so that I can move the file?
try {
// Initial setup, create credentials instance.
Console.WriteLine(".json: " + Directory.GetCurrentDirectory() + "/pdftools-api-credentials.json");
Credentials credentials = Credentials.ServiceAccountCredentialsBuilder()
.FromFile(Directory.GetCurrentDirectory() + "/pdftools-api-credentials.json")
.Build();
// Create an ExecutionContext using credentials and create a new operation instance.
ExecutionContext executionContext = ExecutionContext.Create(credentials);
CompressPDFOperation compressPDFOperation = CompressPDFOperation.CreateNew();
// Set operation input from a source file.
FileRef sourceFileRef = FileRef.CreateFromLocalFile(directory + #"\" + pdfname);
compressPDFOperation.SetInput(sourceFileRef);
// Execute the operation.
FileRef result = compressPDFOperation.Execute(executionContext);
// Save the result to the specified location.
//if pdf is part of a group, the group directory name will be stored in fileGroupDirectory
string fileGroupDirectory = directory.Replace(sourceDir, "");
result.SaveAs(finishedDir + fileGroupDirectory + pdfname);
}
catch (ServiceApiException ex)
{
Console.WriteLine("Exception encountered while executing operation", ex.Message);
if (ex.Message.Contains("The input file is already compressed"))
{
File.Move(file, finishedDir + fileGroupDirectory + fileName);
}
}
I've found a solution , it's not best practice but I don't know an other way to do it.
I've declared all the variables used to execute the compression (sourceFileRef, compressPdfOperation, ...) before the try catch statement and after result.SaveAs(...) I set those variables to null and run the garbage collection.
compressPDFOperation = null;
result = null;
sourceFileRef = null;
executionContext = null;
credentials = null;
GC.Collect();

columns combining when c# appends to csv

We've created a desktop timer that our users are using to track their daily tasks and projects. It outputs data to a .csv file when they close the application. Occasionally they are going to need to manually update the csv file to either take time off or add time. When they have been doing this in the current state after they save all the columns are combined into column A. I am unclear on what is causing this and tried to research encoding but couldn't find anything I could relate to this scenario.
Full form1.cs: full form1.cs code
Code related to csv:
//event handler for the closing event -- the output dump is here so the timer can be used all day and captures even on an accidetnal close
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
//if the file exists we don't need to write the headers so we can skip the additional line write and just append the data created
if (File.Exists(dskPath + "\\" + agentName + ".csv"))
{
using (var file = new StreamWriter(dskPath+"\\" + agentName + ".csv", true, Encoding.UTF8))
{
foreach (var data in TimerData)
{
file.WriteLine(string.Join(",", data.agentID, data.agentStatus, data.statusTime, data.startTime, data.currentDate, data.hydraTask, data.clientname, data.publishdate, data.notes));
}
file.Close();
notifyIcon1.Icon = null;
MessageBox.Show("The file for " + agentName + " has been written to G:\\Communicator Ops\\Population Health\\Pop Process\\Time Tracking\\User Data.", "Application Closed");
}
}
//if the file hasn't been created before we can drop the headers in for the columns
else
{
using (var file = new StreamWriter(dskPath +"\\"+ agentName + ".csv", true, Encoding.UTF8))
{
file.WriteLine(string.Join(",", "Agent ID", "Agent Status", "Status Time", "Start Time", "Current Date", "hydra task number", "Client Name", "Publish Date", "Notes"));
foreach (var data in TimerData)
{
file.WriteLine(string.Join(",", data.agentID, data.agentStatus, data.statusTime, data.startTime, data.currentDate, data.hydraTask, data.clientname, data.publishdate, data.notes));
}
file.Close();
notifyIcon1.Icon = null;
MessageBox.Show("The file for " + agentName + " has been written to your desktop.","Application Closed");
}
}
}
I have a theory about what might be occurring. The C# code looks OK. I think the users are opening the file in a way you were not expecting. I think they are doing the following:
1) Opening Excel and then navigating to the file location. This will cause this dialog to open:
2) They hit Next and get to step 2.
At this step they may be leaving Tab selected as the delimiter which is NOT correct. This is where they may be causing your problem.
They hit Next again
3)
Finally they hit Finish and everything ends up in column A.
If I double click on the desktop icon it seems to work OK. If I select comma as the delimiter, and uncheck Tab, that worked too.
That is my guess. Hopefully this will help you out.

How to create a Log with listBox

I'm creating a webapp in c# using visual stdio 2008.
In the page there's a button that starts a quite long (about 1 min) processing.
During this i would like to show what the program is doing in a listbox in the same page but I don't know how to do it beacuse when the process start the page is continuously refreshing so the listbox is always empty even if in the code there are many ListBox.Items.Add("..").
Hope you can help me.
(p.s. sorry for my bad english,I'm italian)
May be your page load is taking time for other reasons, but not sure.
public static void WriteLog(string Error)
{
using (StreamWriter logfile = new StreamWriter(filePath + "Log.txt", true))
{
logfile.WriteLine(DateTime.Now.ToString() + ":" + DateTime.Now.Millisecond.ToString() + " -#: " + Error);
logfile.Close();
}
}
Use this function to log.
Call this function in Page load
WriteLog("Comments");

Sporadic file movement error

I have a program that is a launcher for a mod for a game. The launcher works for most of the people who use it, including myself, but for some there is a strange bug that really has me struggling to fix it, and further more driving me absolutely mental!
The basic idea is that my mod files are contained in a folder, the launcher iterates through these files, reads a certain byte of the file and based on the result either moves the file, or moves the file and writes some text to a certain file, then launches the game. Seemingly simple.
The main launch function looks like this:
private void Launch()
{
using (StreamWriter writer = new StreamWriter(userScriptPath, false, Encoding.Unicode))
{
foreach (string file in Directory.GetFiles(modFolderPath + "\\Files\\", "*.pack"))
{
int p = GetPackType(file);
if (p == 3)
{
if (File.Exists(modFolderPath + "\\Files\\" + Path.GetFileName(file)))
{
File.Move(modFolderPath + "\\Files\\" + Path.GetFileName(file), dataPath + "\\" + Path.GetFileName(file));
}
writer.WriteLine("mod \"" + Path.GetFileName(file) + "\";");
}
else if (p == 4)
{
if (File.Exists(modFolderPath + "\\Files\\" + Path.GetFileName(file)))
{
File.Move(modFolderPath + "\\Files\\" + Path.GetFileName(file), dataPath + "\\" + Path.GetFileName(file));
}
}
}
}
Process game = Process.Start(gamePath);
// There is code here that waits for a minute until the game process is actually found, incase its slow starting up
game.WaitForExit();
RestorePacks(); // <- Method to put back the files after finishing
}
The problem some users are getting is that when launching the mod the game launches but it appears as though the launcher doesn't move the files as the game is still in its normal state, it was very hard to ascertain exactly why this was happening as I had no way of debugging it on their computers and the program was working fine for me and all of my test users.
To try and find out what was going on I added a number of checks and some logging to the launcher so that if the launcher didn't work, I'd at least have an idea why. (Note that no errors are thrown for the users even when it doesn't work)
The checks I added included using File.Exists() after attempting to move a file to make sure it was actually moved, the logging kept a note of move attempts and the result of this check to see if the file was actually moved.
I even added a specific if statement to the Process.Start function checking specifically that a certain file was indeed in the required location before launching the game.
Finally before launching all of the files in the folder where the mod files should now be are written to the log.
All of the logs from users who the launcher didn't work for shared one thing in common the program attempted to move the file, threw no error, and then when checking that the file was indeed moved, the file appeared to be there. But when reaching the point where all of the files in the required directory are written to the log, only one of the required 30+ mod files appear to be in the directory.
An example output log looked something like this:
File moving: modfile1.txt
Checking if file is where we tried to move it to: Yes
File moving: modfile2.txt
Checking if file is where we tried to move it to: Yes
File moving: modfile3.txt
Checking if file is where we tried to move it to: Yes
Writing out all files in directory:
normalgamefile1.txt
normalgamefile2.txt
normalgamefile3.txt
modfile1.txt
After seeing this and noticing it was always only a single file that had moved and no others, and also that the program did think the files were where they where supposed to be, the confusion really started to kick in.
This is the method that reads the file to ascertain what type of file it is:
private int GetPackType(string path)
{
FileStream fs = File.OpenRead(path);
BinaryReader reader = new BinaryReader(fs);
reader.ReadChars(4);
int packType = reader.ReadInt32();
fs.Close();
fs.Dispose();
return packType;
}
As you can probably see, and what I've just noticed is that I've failed to close/dispose of reader, and I'm guessing and somewhat hoping this might be the cause of my problem.
(Note I'm now using Using statements in this method but can't test this fix for quite a while)
SO, if you've read this far thank you, my question is..
Firstly do you have any idea what the problem is? Could it be that reader still might have the file open and has not closed and thus the file can't move, IF SO then why does it work perfectly for me and most others, but not for some? Surely a file still being used elsewhere would throw an error?
I've gone through all the simple stuff like making sure the program is run with administrator privileges, etc.
Thank you greatly for any help!
EDIT
As asked in the comments this is the version of the code with my checks and logging added. Simple stuff, which is why I omitted it, the log simply adds to a string, the string is then printed to file when all is done.
private void Launch()
{
using (StreamWriter writer = new StreamWriter(userScriptPath, false, Encoding.Unicode))
{
foreach (string file in Directory.GetFiles(modFolderPath + "\\Files\\", "*.pack"))
{
int p = GetPackType(file);
if (p == 3)
{
if (File.Exists(modFolderPath + "\\Files\\" + Path.GetFileName(file)))
{
File.Move(modFolderPath + "\\Files\\" + Path.GetFileName(file), dataPath + "\\" + Path.GetFileName(file));
}
log += "Move File: " + Path.GetFileName(file) + "\r\n";
writer.WriteLine("mod \"" + Path.GetFileName(file) + "\";");
log += "Write mod line: " + Path.GetFileName(file) + "\r\n";
}
else if (p == 4)
{
if (File.Exists(modFolderPath + "\\Files\\" + Path.GetFileName(file)))
{
File.Move(modFolderPath + "\\Files\\" + Path.GetFileName(file), dataPath + "\\" + Path.GetFileName(file));
}
log += "Move File: " + Path.GetFileName(file) + "\r\n";
}
// Check the file did actually move
if (File.Exists(dataPath + "\\" + Path.GetFileName(file)) == false)
{
MessageBox.Show("The mod could not launch successfully!\n\nError: Packs failed to move", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
else
{
log += "File Found\r\n";
}
}
}
if (File.Exists(dataPath + "\\_GreatWar5_DB.pack")) // This pack should always be there if things have worked
{
Process game = Process.Start(gamePath);
}
else
{
MessageBox.Show("The mod could not launch successfully!\n\nError: Data pack missing", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
// There is code here waits for a minute until the game process is actually found, incase its slow starting up
game.WaitForExit();
RestorePacks(); // <- Method to put back the files after finishing
}

Convert windows forms app to web user control (functionality)

I have a C# Windows Forms Application that edits a config file. It basically reads a string from an XML file, and allows an admin to edit that string if it needs.
I've been asked to set this up on our server, so that users can log into a website and run the application. I've done next to no web development, and I'm seeing a lot of answers online that say you can't convert a Windows Forms App to a web forms app. But those answers appear to refer specifically to converting the UI.
I'm really only interested in porting the functionality. My UI is just a text box to edit the string, a list view that shows values from the current string, and a button to submit changes. I'm more than happy to design a new UI for my content. But how about the functionality? Can I take my current C# code and just hook it into a web UI? Or do I need to code differently for the web?
Aside from the button_Click and KeyDown functions, I really just have these two:
List what's in the string:
/// <summary>
/// Find current phrases being ignored and list them
/// </summary>
internal void listPhrases()
{
string myFile = Environment.CurrentDirectory + "\\CGEmailCnctr.exe.config";
string strFile = File.ReadAllText(myFile);
var sb = new StringBuilder(strFile);
string getThis = "<add key=\"messageFilter\" value=\"";
string subStr = strFile.Substring(strFile.IndexOf(getThis) + getThis.Length);
string[] igPhrases = subStr.Substring(0, subStr.IndexOf(";\"")).Split(';');
foreach (string s in igPhrases)
{
listView1.Items.Add(s);
}
}
Add to the string:
/// <summary>
/// Checks to see if the phrase is already in the list. If not, then add it.
/// </summary>
/// <param name="addThis"></param>
internal void addPhrase(string addThis)
{
foreach (ListViewItem lvi in listView1.Items)
{
if (addThis == lvi.Text)
{
lvi.Selected = true;
MessageBox.Show("List of phrases already contains \"" + addThis + ".\" Please check the phrase again. \nIf the problem persists, contact your system administrator.");
return;
}
}
string myFile = Environment.CurrentDirectory + "\\CGEmailCnctr.exe.config";
string pattern = "messageFilter";
string pattern2 = ";\"";
string igPhrase = ";" + addThis + ";\"";
string strFile = File.ReadAllText(myFile);
var sb = new StringBuilder(strFile);
//Find messageFilter, the key we need to change, and get the index of it
int index = strFile.IndexOf(pattern);
string after = strFile.Substring(index);
strFile = strFile.Substring(0, index) + strFile.Substring(index).Replace(pattern2, igPhrase);
//MessageBox.Show(strFile);
try
{
File.WriteAllText(myFile, strFile);
MessageBox.Show("Operation complete. Messages with the phrase \"" + addThis + "\" in the subject line will no longer automatically generate ChangeGear tickets.", "Phrase Added");
listView1.Items.Add(addThis);
}
catch (Exception ex)
{
MessageBox.Show("Operation failed. \n" + ex.ToString());
}
}
My using statements, in case they shed light on anything:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows.Forms;
There are a few problems if you try to use this code in Web Forms, the first one is you use of: Environment.CurrentDirectory which may need to use Server.MapPath instead, the other one is that you have calls to the UI directly in your code, for example MessageBox.Show and ListViewItem, the code that hooks up into the UI must require some rethinking, so you have a though road ahead.
You may better try to recreate the application from scratch in Web Forms rather than porting the code, it may be easier that way and will help you to better understand how Web Forms works.

Categories