C# Saving Permanent Data in ProgramFiles - c#

I am creating a desktop app that needs to save permanent data. The easiest way I could think of doing this is by writing important information about the file to a textfile. Just to make the data contained, professional and easily accessed by the app, I decided to put it in a newly created folder in the "Program Files" directory of the users computer. Unfortunately, this is blocked by the computer. It denies the access to my application. I know my code works because I ran the application as an administrator and encountered no errors. It also created the folder in "Program Files" as I wanted. Is there anyway to allow access. I'd also like to get the users' permission first. The code is posted below:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Principal;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace MyAppNameSpace
{
static class DataManager
{
/* Create a dictionary that takes type "string" for its
* key (name) and type "object" for its value */
public static Dictionary<string, object> Data = new Dictionary<string, object>();
public static string FileName { get; private set; }
public static string ProgramFilesFolder;
// A method to clear all game data
public static void Clear()
{
}
public static void Save()
{
foreach (KeyValuePair<string, object> DataPair in Data)
{
}
}
public static string GetData()
{
return File.ReadAllText(FileName);
}
public static void Setup()
{
ProgramFilesFolder = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles) + "/MyAppName";
FileName = ProgramFilesFolder + "/MyAppData";
if (!Directory.Exists(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles) + "/MyAppName/README.txt"))
{
try
{
Directory.CreateDirectory(ProgramFilesFolder);
string text = "DO NOT move this folder. If you must, make sure to keep it " +
"in the same location as the SwingState it is. Also, do not edit the " +
"contents of the data file, which exists in this directory. " +
"This saves all of your progress in your game!";
File.WriteAllText(ProgramFilesFolder + "/README.txt", text);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message + ":" + ex.InnerException);
GameInfo.Game.Close();
}
}
if (!File.Exists(FileName))
{
Data = new Dictionary<string, object>()
{
{ "Name:", null + "," },
{ "Age:", null + "," },
{ "Description:", null + "," },
{ "Gender:", null + "," },
{ "Level:", 1 + "," },
{ "Drawing:", false + "," },
{ "Uploaded:", false + "," },
{ "Template:", false + "," },
{ "Left1:", null + "," },
{ "Left2:", null + "," },
{ "Left3:", null + "," },
{ "Right1:", null + "," },
{ "Right2:", null + "," },
{ "Right3:", null + "," },
{ "Idle:", null + "," },
{ "Template Number:", null + "," }
};
}
else if (File.Exists(FileName))
{
string[] DataText = File.ReadAllText(FileName).Split(',');
foreach (string s in DataText)
{
Data.Add(s.Split(':')[0], s.Split(':')[1]);
}
}
}
}
}

I fixed this by changing the special folder to AppData. Here is the code for that:
ProgramFilesFolder = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + "/MyAppName";
FileName = ProgramFilesFolder + "/MyAppData";
if (!Directory.Exists(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + "/MyAppName/README.txt"))

Related

How to pass a variable with CSharpCodeProvider?

I need to create an EXE file with my application, I can pass strings with manipulating the string format but I cannot pass the other variables that I need to ex:byte array, here is my code if this helps:
using Microsoft.CSharp;
using System;
using System.CodeDom.Compiler;
using System.Windows;
namespace ACompiler.CompWorker
{
class CompilerWorker
{
public static byte[] testarray = SomeClass.SomeArray;
public static string Key = "Testkey12";
public static void Compile()
{
CSharpCodeProvider CompileProvider = new CSharpCodeProvider();
CompilerParameters CompileProviderParameters = new CompilerParameters(new[] { "mscorlib.dll", "System.Core.dll" }, AppDomain.CurrentDomain.BaseDirectory + "Compiled.exe", true);
CompileProviderParameters.GenerateExecutable = true;
string test= #"using System;
namespace Tests
{
class Program
{
static void Main(string[] args)
{
byte[] Content = " + testarray + #";
string Key = """ + Key + #""";
Console.WriteLine(""Key: "" + EKey);
Console.WriteLine(Content);
Console.ReadLine();
}
}
}
";
var Result = CompileProvider.CompileAssemblyFromSource(CompileProviderParameters, test);
}
}
}
Basically I want to move the "testarray" into the compiled app, I hope someone can point me to the right direction!
The trick is to "serialize" the data back in to code the compiler can compile. Try this:
var arrayCode = "new byte[] { " + string.Join(", ", testarray) + " }";
string test = #"using System;
namespace Tests
{
class Program
{
static void Main(string[] args)
{
byte[] Content = " + arrayCode + #";
string Key = """ + Key + #""";
Console.WriteLine(""Key: "" + EKey);
foreach(byte b in Content)
{
Console.WriteLine(b.ToString());
}
Console.ReadLine();
}
}
}
";
Keep in mind, you can't do Console.WriteLine on a byte array object and have it spit out each item. You will have to iterate over the items to print them out. I updated your code to do it the proper way.

Deserialize CSV with CustomHeaders using ServiceStack.Text: not working?

consider following class:
class Foo {
public string bar { get; set; }
public string rab { get; set; }
public override string ToString()
{
return string.Format("[Foo bar={0}, rab={1}]", bar, rab);
}
}
And following code:
var csv1 =
"bar,rab" + Environment.NewLine +
"a,b" + Environment.NewLine +
"c,d" + Environment.NewLine +
"e,f" + Environment.NewLine;
var csv2 =
"xbar,xrab" + Environment.NewLine +
"a,b" + Environment.NewLine +
"c,d" + Environment.NewLine +
"e,f" + Environment.NewLine;
Console.WriteLine(CsvSerializer.DeserializeFromString<List<Foo>>(csv1).First());
CsvConfig<TMDBEntity>.CustomHeadersMap = new Dictionary<string, string> {
{"bar", "xbar"},
{"rab", "xrab"}
};
Console.WriteLine(CsvSerializer.DeserializeFromString<List<Foo>>(csv2).First());
It is printing:
[Foo bar=a, rab=b]
[Foo bar=, rab=]
while I would expect it to print
[Foo bar=a, rab=b]
[Foo bar=a, rab=b]
Why is it not picking up the custom headers using xbar and xrab?
ServiceStack.Text version is 4.5.14.0
This issue should be resolved from this commit which is available from ServiceStack v5.0.0 that's now available on MyGet.
Note you need to configure CsvConfig<Foo> in order to change how Foo is deserialized, e.g:
CsvConfig<Foo>.CustomHeadersMap = new Dictionary<string, string> {
{"bar", "xbar"},
{"rab", "xrab"}
};

Permissions on a folder

I have been looking for some time now and have not been able to find this. How can I set my program up to write or update a file from multiple users but only one group is allowed to open the read what is in the folder?
class Log_File
{
string LogFileDirectory = #"\\server\boiseit$\TechDocs\Headset Tracker\Weekly Charges\Log\Log Files";
string PathToXMLFile = #"\\server\boiseit$\scripts\Mikes Projects\Headset-tracker\config\Config.xml";
string AdditionToLogFile = #"\Who.Did.It_" + DateTime.Now.Month + "-" + DateTime.Now.Day + "-" + DateTime.Now.Year + ".txt";
XML XMLFile = new XML();
public void ConfigCheck()
{
if (!File.Exists(PathToXMLFile))
{
XMLFile.writeToXML(PathToXMLFile, LogFileDirectory + AdditionToLogFile);
}
}
public void CreateLogFile()
{
if (Directory.GetFiles(LogFileDirectory).Count() == 0)
{
XMLFile.writeToXML(PathToXMLFile, LogFileDirectory + AdditionToLogFile);
CreateFileOrAppend("");
}
else if (!File.Exists(XMLFile.readingXML(PathToXMLFile)))
{
XMLFile.writeToXML(PathToXMLFile, LogFileDirectory + AdditionToLogFile);
CreateFileOrAppend("");
}
else
{
FileInfo dateOfLastLogFile = new FileInfo(XMLFile.readingXML(PathToXMLFile));
DateTime dateOfCreation = dateOfLastLogFile.CreationTime;
if (dateOfLastLogFile.CreationTime <= DateTime.Now.AddMonths(-1))
{
XMLFile.writeToXML(PathToXMLFile, LogFileDirectory + AdditionToLogFile);
CreateFileOrAppend("");
}
}
}
public void CreateFileOrAppend(string whoDidIt)
{
using (IsolatedStorageFile storage = IsolatedStorageFile.GetStore((IsolatedStorageScope.Domain | IsolatedStorageScope.Assembly | IsolatedStorageScope.User), null, null))
{
using (StreamWriter myWriter = new StreamWriter(XMLFile.readingXML(PathToXMLFile), true))
{
if (whoDidIt == "")
{
}
else
{
myWriter.WriteLine(whoDidIt);
}
}
}
}
This is my path where it needs to go. I have the special permission to open and write to the folder but my co workers do not. I am not allow to let them have this permission.
If I where to set up a database how would i change this code
LoggedFile.CreateFileOrAppend(Environment.UserName.ToUpper() + "-" + Environment.NewLine + "Replacement Headset To: " + AgentName + Environment.NewLine + "Old Headset Number: " + myDatabase.oldNumber + Environment.NewLine + "New Headset Number: " + HSNumber + Environment.NewLine + "Date: " + DateTime.Now.ToShortDateString() + Environment.NewLine);
I need it to pull current user, the agents name that is being affected the old headset and the new headset, and the time it took place.
While you create file, you have to set access rules to achieve your requirements. .
File.SetAccessControl(string,FileSecurity)
The below link has example
https://msdn.microsoft.com/en-us/library/system.io.file.setaccesscontrol(v=vs.110).aspx
Also the "FileSecurity" class object, which is an input parameter, has functions to set access rules, including group level control.
Below link has example
https://msdn.microsoft.com/en-us/library/system.security.accesscontrol.filesecurity(v=vs.110).aspx
This question will be opened under a new question since I am going to take a different route for recording the data I need Thank you all for the help

NetSuite SuiteTalk "customSearchJoin" access from SOAP XML Response

I am still getting warmed up with NetSuite and have come across an issue I can't crack.
I am building a C# function to pull information from an XML soap response from NetSuite. This XML is the result of a saved search call which contains a section that is a join titled customSearchJoin that I am unsure how to access. Below I will show the XML section and my attempts to access it in the C# function.
I am attempting to access the field with the value of 091736418
XML segment:
<platformCore:searchRow xsi:type="tranSales:TransactionSearchRow" xmlns:tranSales="urn:sales_2014_1.transactions.webservices.netsuite.com">
<tranSales:basic xmlns:platformCommon="urn:common_2014_1.platform.webservices.netsuite.com">
<platformCommon:dateCreated>
<platformCore:searchValue>2015-12-17T08:43:00.000-08:00</platformCore:searchValue>
</platformCommon:dateCreated>
<platformCommon:entity>
<platformCore:searchValue internalId="615"/>
</platformCommon:entity>
</tranSales:basic>
<tranSales:customerMainJoin xmlns:platformCommon="urn:common_2014_1.platform.webservices.netsuite.com">
<platformCommon:altName>
<platformCore:searchValue>Some Specific Customer</platformCore:searchValue>
</platformCommon:altName>
</tranSales:customerMainJoin>
<tranSales:itemJoin xmlns:platformCommon="urn:common_2014_1.platform.webservices.netsuite.com">
<platformCommon:itemId>
<platformCore:searchValue>Some Product</platformCore:searchValue>
</platformCommon:itemId>
</tranSales:itemJoin>
<tranSales:customSearchJoin xmlns:platformCommon="urn:common_2014_1.platform.webservices.netsuite.com">
<platformCommon:customizationRef internalId="167" scriptId="custrecord_itmfulfillmentid"/>
<platformCommon:searchRowBasic xsi:type="platformCommon:CustomRecordSearchRowBasic">
<platformCommon:recType internalId="25"/>
<platformCommon:customFieldList>
<platformCore:customField xsi:type="platformCore:SearchColumnStringCustomField" scriptId="custrecord_ssccbarcode" internalId="169">
<platformCore:searchValue>091736418</platformCore:searchValue>
</platformCore:customField>
</platformCommon:customFieldList>
</platformCommon:searchRowBasic>
</tranSales:customSearchJoin>
</platformCore:searchRow>
C# function:
private void testCustomJoinSearch() {
TransactionSearchAdvanced transSearchAdv = new TransactionSearchAdvanced
{
savedSearchScriptId = "customsearch_savedSearchID"
};
SearchResult searchResult = _service.search(transSearchAdv);
if (searchResult.status.isSuccess)
{
Console.WriteLine("Search Success");
foreach (TransactionSearchRow transSearchRow in searchResult.searchRowList)
{
// declare vars
string transInternalID = "";
string ssccBarcode = "";
//normal field
transInternalID = transSearchRow.basic. internalId[0].searchValue.internalId.ToString();
//joined and custom field ? Not sure this loop is correct
foreach (CustomSearchRowBasic customBasicSearchRow in transSearchRow.customSearchJoin)
{
// ????
};
Console.WriteLine("transInternalID {0}", transInternalID);
Console.WriteLine("ssccBarcode {0}", ssccBarcode);
} // end main search row
}
else
{
Console.WriteLine("Search Failure");
Console.WriteLine(searchResult.status.statusDetail);
}
}
Try xml linq. I fixed your xml that was missing some namespace definitions so I added root and then closed the end tags platformCore:searchRow and root.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
namespace ConsoleApplication70
{
class Program
{
static void Main(string[] args)
{
string xml =
"<?xml version=\"1.0\" encoding=\"utf-8\" ?>" +
"<Root xmlns:platformCore=\"abc\" xmlns:xsi=\"def\">" +
"<platformCore:searchRow xsi:type=\"tranSales:TransactionSearchRow\" xmlns:tranSales=\"urn:sales_2014_1.transactions.webservices.netsuite.com\">" +
"<tranSales:basic xmlns:platformCommon=\"urn:common_2014_1.platform.webservices.netsuite.com\">" +
"<platformCommon:dateCreated>" +
"<platformCore:searchValue>2015-12-17T08:43:00.000-08:00</platformCore:searchValue>" +
"</platformCommon:dateCreated>" +
"<platformCommon:entity>" +
"<platformCore:searchValue internalId=\"615\"/>" +
"</platformCommon:entity>" +
"</tranSales:basic>" +
"<tranSales:customerMainJoin xmlns:platformCommon=\"urn:common_2014_1.platform.webservices.netsuite.com\">" +
"<platformCommon:altName>" +
"<platformCore:searchValue>Some Specific Customer</platformCore:searchValue>" +
"</platformCommon:altName>" +
"</tranSales:customerMainJoin>" +
"<tranSales:itemJoin xmlns:platformCommon=\"urn:common_2014_1.platform.webservices.netsuite.com\">" +
"<platformCommon:itemId>" +
"<platformCore:searchValue>Some Product</platformCore:searchValue>" +
"</platformCommon:itemId>" +
"</tranSales:itemJoin>" +
"<tranSales:customSearchJoin xmlns:platformCommon=\"urn:common_2014_1.platform.webservices.netsuite.com\">" +
"<platformCommon:customizationRef internalId=\"167\" scriptId=\"custrecord_itmfulfillmentid\"/>" +
"<platformCommon:searchRowBasic xsi:type=\"platformCommon:CustomRecordSearchRowBasic\">" +
"<platformCommon:recType internalId=\"25\"/>" +
"<platformCommon:customFieldList>" +
"<platformCore:customField xsi:type=\"platformCore:SearchColumnStringCustomField\" scriptId=\"custrecord_ssccbarcode\" internalId=\"169\">" +
"<platformCore:searchValue>091736418</platformCore:searchValue>" +
"</platformCore:customField>" +
"</platformCommon:customFieldList>" +
"</platformCommon:searchRowBasic>" +
"</tranSales:customSearchJoin>" +
"</platformCore:searchRow>" +
"</Root>";
XDocument doc = XDocument.Parse(xml);
string searchvalue = doc.Descendants().Where(x => x.Name.LocalName == "customSearchJoin")
.Descendants().Where(y => y.Name.LocalName == "searchValue").Select(z => (string)z).FirstOrDefault();
}
}
}
I believe it is something like this:
foreach (CustomSearchRowBasic customBasicSearchRow in transSearchRow.customSearchJoin) {
// ????
CustomRecordSearchRowBasic itmfulfillmentidRecord = customBasicSearchRow.searchRowBasic as CustomRecordSearchRowBasic;
foreach(SearchColumnCustomField customField in itmfulfillmentidRecord.customFieldList) {
if (customField.scriptId == "custrecord_ssccbarcode") {
SearchColumnStringCustomField stringField = customField as SearchColumnStringCustomField;
string itmfulfillmentid = stringField.searchValue;
}
}
}

C# and Metadata File Errors

I've created my own little c# compiler using the tutorial on MSDN, and it's not working properly. I get a few errors, then I fix them, then I get new, different errors, then I fix them, etc etc.
The latest error is really confusing me.
---------------------------
---------------------------
Line number: 0, Error number: CS0006, 'Metadata file 'System.Linq.dll' could not be found;
---------------------------
OK
---------------------------
I do not know what this means.
Can somebody please explain what's going on here?
Here is my code.
MY SAMPLE C# COMPILER CODE:
using System;
namespace JTM
{
public class CSCompiler
{
protected string ot,
rt,
ss, es;
protected bool rg, cg;
public string Compile(String se, String fe, String[] rdas, String[] fs, Boolean rn)
{
System.CodeDom.Compiler.CodeDomProvider CODEPROV = System.CodeDom.Compiler.CodeDomProvider.CreateProvider("CSharp");
ot =
fe;
System.CodeDom.Compiler.CompilerParameters PARAMS = new System.CodeDom.Compiler.CompilerParameters();
// Ensure the compiler generates an EXE file, not a DLL.
PARAMS.GenerateExecutable = true;
PARAMS.OutputAssembly = ot;
foreach (String ay in rdas)
{
if (ay.Contains(".dll"))
PARAMS.ReferencedAssemblies.Add(ay);
else
{
string refd = ay;
refd = refd + ".dll";
PARAMS.ReferencedAssemblies.Add(refd);
}
}
System.CodeDom.Compiler.CompilerResults rs = CODEPROV.CompileAssemblyFromFile(PARAMS, fs);
if (rs.Errors.Count > 0)
{
foreach (System.CodeDom.Compiler.CompilerError COMERR in rs.Errors)
{
es = es +
"Line number: " + COMERR.Line +
", Error number: " + COMERR.ErrorNumber +
", '" + COMERR.ErrorText + ";" +
Environment.NewLine + Environment.NewLine;
}
}
else
{
// Compilation succeeded.
es = "Compilation Succeeded.";
if (rn) System.Diagnostics.Process.Start(ot);
}
return es;
}
}
}
... And here is the app that passes the code to the above class:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
string[] f = { "Form1.cs", "Form1.Designer.cs", "Program.cs" };
string[] ra = { "System.dll", "System.Windows.Forms.dll", "System.Data.dll", "System.Drawing.dll", "System.Deployment.dll", "System.Xml.dll", "System.Linq.dll" };
JTS.CSCompiler CSC = new JTS.CSCompiler();
MessageBox.Show(CSC.Compile(
textBox1.Text, #"Test Application.exe", ra, f, false));
}
}
}
So, as you can see, all the using directives are there. I don't know what this error means. Any help at all is much appreciated.
Thank you
Solution:
Add this:
PARAMS.ReferencedAssemblies.Add(typeof(System.Xml.Linq.Extensions).Assembly.Location);
So the code now looks like this:
namespace JTM
{
public class CSCompiler
{
protected string ot,
rt,
ss, es;
protected bool rg, cg;
public string Compile(String se, String fe, String[] rdas, String[] fs, Boolean rn)
{
System.CodeDom.Compiler.CodeDomProvider CODEPROV = System.CodeDom.Compiler.CodeDomProvider.CreateProvider("CSharp");
ot =
fe;
System.CodeDom.Compiler.CompilerParameters PARAMS = new System.CodeDom.Compiler.CompilerParameters();
// Ensure the compiler generates an EXE file, not a DLL.
PARAMS.GenerateExecutable = true;
PARAMS.OutputAssembly = ot;
PARAMS.ReferencedAssemblies.Add(typeof(System.Xml.Linq.Extensions).Assembly.Location);
foreach (String ay in rdas)
{
if (ay.Contains(".dll"))
PARAMS.ReferencedAssemblies.Add(ay);
else
{
string refd = ay;
refd = refd + ".dll";
PARAMS.ReferencedAssemblies.Add(refd);
}
}
System.CodeDom.Compiler.CompilerResults rs = CODEPROV.CompileAssemblyFromFile(PARAMS, fs);
if (rs.Errors.Count > 0)
{
foreach (System.CodeDom.Compiler.CompilerError COMERR in rs.Errors)
{
es = es +
"Line number: " + COMERR.Line +
", Error number: " + COMERR.ErrorNumber +
", '" + COMERR.ErrorText + ";" +
Environment.NewLine + Environment.NewLine;
}
}
else
{
// Compilation succeeded.
es = "Compilation Succeeded.";
if (rn) System.Diagnostics.Process.Start(ot);
}
return es;
}
}
}

Categories

Resources