Convert windows forms app to web user control (functionality) - c#

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.

Related

How to use Clipboard in C# services?

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.

GetFiles() not returning first file name in directory C#

I am writing a test script to use in a larger script. I need to get the very first file in the Music Directory so I can automate opening wmplayer and playing the first song.
If I hard code the file name and start the Process, it works. However, if someone else wants to use the script, I need to get the first file name. For example, my hard coded version is:
Process.Start("wmplayer.exe", "C:\\Users\\" + username + "\\Music\\A_ChillstepMix.mp3");
When I try to get the first file in the Music folder in my test script, it is returning the one in the picture:
which isn't the correct one! What am I doing wrong? Here is my snippet:
using System;
using System.IO;
using System.Linq;
namespace GetFileTest
{
class Program
{
static void Main(string[] args)
{
String username = Environment.UserName;
String path = #"C:\Users\" + username + #"\Music";
DirectoryInfo di = new DirectoryInfo(path);
string firstFile = di.GetFiles().Select(fi => fi.Name).FirstOrDefault();
Console.WriteLine(firstFile);
}
}
}
I have also tried:
string firstFile = di.GetFiles()[0].ToString();
to no avail. Does it have something to do with the single quotes?
You have to sort the file names before you select the first one as:
di.GetFiles().OrderBy(fi => fi.Name).Select(fi => fi.Name).FirstOrDefault();

open window explorer folder from my results c#

iv made a web forum, as i have lots of folders on my local drive i can now search for any folders i want on webpage.
Now am looking to add a link to the results of the search so it takes me directly to the folder.
My code in c#:
protected void List_Dirs(string searchStr = null)
{
try
{
MainContentLocal.InnerHtml = "";
string[] directoryList = System.IO.Directory.GetDirectories("\\\\myfiles\\Web");
int x = 0;
foreach (string directory in directoryList)
{
if (searchStr != null && searchStr.Length > 1)
{
UserInfo.Text = "Your Search for : <strong>" + SearchPhrase.Text + "</strong> returns ";
if(directoryP.ToLower().Contains(searchStr.ToLower()))
{
MainContentLocal.InnerHtml += directoryP + "<br />";
x++;
}
}
else
{
MainContentLocal.InnerHtml += directoryP + "<br />";
}
if (searchStr != null && searchStr.Length > 1)
{
UserInfo.Text += "<strong>" + x.ToString() + "</strong> results";
UserInfo.CssClass = "userInfo";
}
}
catch(Exception DirectoryListExp)
{
MainContentLocal.InnerHtml = DirectoryListExp.Message;
}
}
When i enter something is search i will get a list of folders like:
Your Search for : project returns 2 results
job234 project234 Awards
job323 project game
now is there any way for me to click the result so i can open a window explore on the webpage
Thanks
You can create links like project234.
string folder = "\\\\myfiles\\Web";
if (string.IsNullOrWhiteSpace(Request["folder"])) {
// Folder clicked
folder = string.Format("{0}{1}", folder, Request["folder"]);
Process.Start(folder);
}
string[] directoryList = System.IO.Directory.GetDirectories(folder);
Then it will open it on the server. So if it really is local, than it will work. If there is no security problem. But I'm not sure. You can also use file:// links (as Ryan Mrachek notes), but browsers are not happy to let you open them.
If your result is a file, you can open that file programmatically through the Process class by invoking Process.Start("C:\\MyResults.txt"). This will open the results in the default text editor. In the same way, you can also open a web page by inserting passing a Url to Process.Start. I hope this is what wanted.
our file urls are malformed. It should be:
file:///c:/folder/
Please refer to The Bizarre and Unhappy Story of File URLs.
This works for me:
link
When you click Link, a new Windows Explorer window is opened to the specified location. But as you point out, this only works from a file:// URL to begin with.
A detailed explanation of what is going on can be found here. Basically this behavior by design for IE since IE6 SP1/SP2 and the only way you can change it is by explicitly disabling certain security policies using registry settings on the local machine.
So if you're an IT admin and you want to deploy this for your internal corporate LAN, this might be possible (though inadvisable). If you're doing this on some generic, public-facing website, it seems impossible.

Uploading a file to Sitecore keeping the extension in the DisplayName

As the title says, I'm trying to upload a file to somewhere in my Sitecore tree from the web and I want to keep the file's extension in the DisplayName of the item.
I tried using MediaCreator, but it requires a specific filepath which I do not know when I let people select a file using asp:FileUpload. So that's no good.
I'm now using the asp:FileUpload in combination with a pipeline. When I use Sitecore.Pipelines.Upload.Save from Sitecore.Kernel it works except it removes the extension of the file from the DisplayName. So I created a custom pipeline method that looks like this:
using System;
using System.IO;
using Sitecore.Diagnostics;
using Sitecore.IO;
namespace Sitecore.Pipelines.Upload
{
public class CustomSave
{
public void Process(UploadArgs args)
{
foreach (string key in args.Files)
{
var file = args.Files[key];
if (file != null && file.FileName.Length > 0 && file.ContentLength > 0)
{
var filename = FileUtil.MakePath(args.Folder, Path.GetFileName(file.FileName), '/');
try
{
if (!args.Overwrite)
{
filename = FileUtil.GetUniqueFilename(filename);
}
file.SaveAs(filename);
EventDispatcher.DispatchTrace("File has been uploaded: " + filename);
}
catch (Exception ex)
{
Log.Error("Could not save posted file: " + filename, ex, this);
}
}
}
}
}
}
The problem I now face is that it's trying to save to my C:\ disk instead of the Sitecore database.
Any suggestions on how to write to the correct destination?
The end goal, as explained, is to use the client friendly asp:FileUpload to select a file and upload it to a specific path in Sitecore retaining the file's extension in its DisplayName. If you have another way to do that I'd like to hear about it too.
There is a setting that appends file extension to the item name
"Media.IncludeExtensionsInItemNames". If you can live with that, just turn it on.
Otherwise, I'd add a custom processor into "uiUpload" after "Save" one. At that moment you would already have a list of created media items from "args.UploadedItems". You can do your simple manipulations with items in there.

How to search for specific value in Registry keys

How can I search for specific value in the registry keys?
For example I want to search for XXX in
HKEY_CLASSES_ROOT\Installer\Products
any code sample in C# will be appreciated,
thanks
In case you don't want to take a dependency on LogParser (as powerful as it is): I would take a look at the Microsoft.Win32.RegistryKey class (MSDN). Use OpenSubKey to open up HKEY_CLASSES_ROOT\Installer\Products, and then call GetSubKeyNames to, well, get the names of the subkeys.
Open up each of those in turn, call GetValue for the value you're interested in (ProductName, I guess) and compare the result to what you're looking for.
Help here...
Microsoft has a great (but not well known) tool for this - called LogParser
It uses a SQL engine to query all kind of text based data like the Registry,
the Filesystem, the eventlog, AD etc...
To be usable from C#, you need to build an Interop Assembly from the
Logparser.dll COM server using following (adjust LogParser.dll path)
command.
tlbimp "C:\Program Files\Log Parser 2.2\LogParser.dll"
/out:Interop.MSUtil.dll
Following is a small sample, that illustrates how to query for the Value
'VisualStudio' in the \HKLM\SOFTWARE\Microsoft tree.
using System;
using System.Runtime.InteropServices;
using LogQuery = Interop.MSUtil.LogQueryClass;
using RegistryInputFormat = Interop.MSUtil.COMRegistryInputContextClass;
using RegRecordSet = Interop.MSUtil.ILogRecordset;
class Program
{
public static void Main()
{
RegRecordSet rs = null;
try
{
LogQuery qry = new LogQuery();
RegistryInputFormat registryFormat = new RegistryInputFormat();
string query = #"SELECT Path from \HKLM\SOFTWARE\Microsoft where
Value='VisualStudio'";
rs = qry.Execute(query, registryFormat);
for(; !rs.atEnd(); rs.moveNext())
Console.WriteLine(rs.getRecord().toNativeString(","));
}
finally
{
rs.close();
}
}
}
This method will search a specified registry key for the first subkey that contains a specified value. If the key is found then the specified value is returned. Searchign is only one level deep. If you require deeper searching then I suggest modifying this code to make use of recursion. Searching is case-sensitive but again you can modify that if required.
private string SearchKey(string keyname, string data, string valueToFind, string returnValue)
{
RegistryKey uninstallKey = Registry.LocalMachine.OpenSubKey(keyname);
var programs = uninstallKey.GetSubKeyNames();
foreach (var program in programs)
{
RegistryKey subkey = uninstallKey.OpenSubKey(program);
if (string.Equals(valueToFind, subkey.GetValue(data, string.Empty).ToString(), StringComparison.CurrentCulture))
{
return subkey.GetValue(returnValue).ToString();
}
}
return string.Empty;
}
Example usage
// This code will find the version of Chrome (32 bit) installed
string version = this.SearchKey("SOFTWARE\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall", "DisplayName", "Google Chrome", "DisplayVersion");
#Caltor your solution gave me the answer I was looking for. I welcome improvements or a completely different solution that does not involve the registry. I am working with enterprise applications on Windows 10 with devices joined to Azure AD. I want/need to use Windows Hello for devices and for HoloLens 2 in a UWP app. My problem has been getting the AAD userPrincipal name from Windows 10. After a couple days searching and trying lots of code I searched the Windows Registry for my AAD account in the Current User key and found it. With some research it appears that this information is in a specific key. Because you can be joined to multiple directories there may be more than one entry. I was not trying to solve that issue, that is done with the AAD tenant Id. I just needed the AAD userPrincipal name.
My solution de-dups the return list so that I have a list of unique userPrincipal names. App users may have to select an account, this is tolerable for even HoloLens.
using Microsoft.Win32;
using System.Collections.Generic;
using System.Linq;
namespace WinReg
{
public class WinRegistryUserFind
{
// Windows 10 apparently places Office/Azure AAD in the registry at this location
// each login gets a unique key in the registry that ends with the aadrm.com and the values
// are held in a key named Identities and the value we want is the Email data item.
const string regKeyPath = "SOFTWARE\\Classes\\Local Settings\\Software\\Microsoft\\MSIPC";
const string matchOnEnd = "aadrm.com";
const string matchKey = "Identities";
const string matchData = "Email";
public static List<string> GetAADuserFromRegistry()
{
var usersFound = new List<string>();
RegistryKey regKey = Registry.CurrentUser.OpenSubKey(regKeyPath);
var programs = regKey.GetSubKeyNames();
foreach (var program in programs)
{
RegistryKey subkey = regKey.OpenSubKey(program);
if(subkey.Name.EndsWith(matchOnEnd))
{
var value = (subkey.OpenSubKey(matchKey) != null)? (string)subkey.OpenSubKey(matchKey).GetValue(matchData): string.Empty;
if (string.IsNullOrEmpty(value)) continue;
if((from user in usersFound where user == value select user).FirstOrDefault() == null)
usersFound.Add(value) ;
}
}
return usersFound;
}
}
}

Categories