Can somebody provide me a starting point or code to access an embedded resource using C#?
I have successfully embedded a couple of batch files, scripts and CAD drawings which I would like to run the batch and copy the scripts and CAD files to a location specified in the batch file.
I'm struggling to find how to specify what the item is and set the path within the EXE. The below code is what I thought would work, but it failed and the others I found online all related to XML files.
System.Diagnostics.Process p = new System.Diagnostics.Process();
p.StartInfo.FileName = AppDomain.CurrentDomain.BaseDirectory + "\\Batchfile.bat";
p.Start();
I honestly don't even know if I'm looking at the correct way to do this as this is my first time using either C# or Visual Studio.
Open Solution Explorer add files you want to embed. Right click on the files then click on Properties. In Properties window and change Build Action to Embedded Resource.
After that you should write the embedded resources to file in order to be able to run it.
using System;
using System.Reflection;
using System.IO;
using System.Diagnostics;
namespace YourProject
{
public class MyClass
{
// Other Code...
private void StartProcessWithFile()
{
var assembly = Assembly.GetExecutingAssembly();
//Getting names of all embedded resources
var allResourceNames = assembly.GetManifestResourceNames();
//Selecting first one.
var resourceName = allResourceNames[0];
var pathToFile = Path.GetDirectoryName(AppDomain.CurrentDomain.BaseDirectory) +
resourceName;
using (var stream = assembly.GetManifestResourceStream(resourceName))
using (var fileStream = File.Create(pathToFile))
{
stream.Seek(0, SeekOrigin.Begin);
stream.CopyTo(fileStream);
}
var process = new Process();
process.StartInfo.FileName = pathToFile;
process.Start();
}
}
}
Related
This question already has an answer here:
Editing a file on a Sharepoint Server with C#
(1 answer)
Closed 2 years ago.
I'd like to add a line of text to a text file on a SharePoint folder.
Here's what I tried (Please assume that text.txt already exists):
using System.IO;
namespace WriteText
{
class Program
{
static void Main(string[] args)
{
string path = #"https:\\something_like_this.com\Data\text.txt";
//string path = #"C:\Data\text.txt";
File.AppendAllLines( path, new[]{"Hello"});
}
}
}
... However, I got System.NotSupportedException.
When I copy https:\\something_like_this.com\Data\text.txt and paste to a browser,
I can see the file content. It means that the URL is correct.
Why can't I add a line to the text file?
Incidentally, if the path is #"C:\Data\text.txt", it succeeds to add a line.
This is so simple, but how can I fix this?
Could anyone try my code to add a line to a text file on a https:\\your_own_server.com\...?
Thank you in advance.
You will need to programmatically log in to SharePoint through the API, then download the file, then make your change to the file, then upload it back to SharePoint.
Assuming you are using Visual Studio, you will first want to install the nuget package appropriate for your version of SharePoint (2013, 2016, 2019, Online/O365).
Then try something like this:
using (var clientContext = new ClientContext(url))
{
var list = clientContext.Web.Lists.GetByTitle(listTitle);
var listItem = list.GetItemById(listItemId);
clientContext.Load(list);
clientContext.Load(listItem, i => i.File);
clientContext.ExecuteQuery();
var fileRef = listItem.File.ServerRelativeUrl;
var fileInfo = Microsoft.SharePoint.Client.File.OpenBinaryDirect(clientContext, fileRef);
var fileName = Path.Combine(filePath, (string)listItem.File.Name);
using (var fileStream = System.IO.File.Create())
{
fileInfo.Stream.CopyTo(fileStream);
}
File.AppendAllLines(fileName, new[]{"Hello"}); }
using (var fs = new FileStream(fileName, FileMode.Open))
{
Microsoft.SharePoint.Client.File.SaveBinaryDirect(clientContext, fileRef, fs, true);
}
}
Note that if your library requires checkout, you may also need to programmatically check-out the file before uploading your changed file, then checking it back in.
I am working on a project where I need to deal with some .taz compressed files. Is there a way to decompress and extract those kind of files, in C# dotnet core ?
Thank you !
I found a workaround by using the UNIX command line "gunzip"
gunzip myfilename.taz
gunzip works with files with the following extensions : .gz, -gz, .z, -z, _z or .Z (and also recognizes the special extensions .tgz and .taz as shorthands for .tar.gz and .tar.Z respectively.)
To run this process, I wrote the following code :
public string ExtractFileFromTaz (string tazFilePath)
{
var process = new Process()
{
StartInfo = new ProcessStartInfo
{
FileName = "gunzip",
Arguments = tazFilePath,
RedirectStandardOutput = true,
UseShellExecute = false,
CreateNoWindow = true
}
};
process.Start();
string result = process.StandardOutput.ReadToEnd();
process.WaitForExit();
return result;
}
The resulting output is the file with the .tar extension, which replaced the original .taz file in the same directory.
tar.Z is an archive file that can be created with the help of the UNIX compress utility. Its files are compressed into a tarball (.tar) and then further compressed by use of the now rather antiquated 80s compression algorithm known as LZW.
You can extract these packages with help of the popular SharpZipLib library.
Here's an example of how to open the TAZ file and then write the TAR file it contains to disk. You can of course extract the TAR file in memory right away if the file is feasible in size to be kept in memory in its entirety.
using (var inputStream = File.Open(PATH_TO_TARZ_FILE, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
using (var tazStream = new LzwInputStream(inputStream))
{
using (var outputStream = PATH_TO_OUTPUT_TAR_FILE, 4096))
{
tazStream.CopyTo(outputStream);
}
}
}
I feel like this question might have been answered already but I cannot find an answer that I understand and that is specific to my example, so I'll ask.
I have a C# application that compiles some code and I want to be able to embed a String resource (called someString) that I have inside of my Resources.resx file. Then I want to be able to access that embedded resource in the compiled program. However, I am struggling to access the resource file as when I run the compiled program it says that the Stream cannot be null.
Here is my example code:
string codeString =
#"using System;
using System.IO;
using System.Reflection;
namespace SomeProgram
{
class MyClass
{
static void Main(string[] args)
{
Assembly resourceAssembly = Assembly.GetExecutingAssembly();
StreamReader stream = new StreamReader(resourceAssembly.GetManifestResourceStream(""Resources.someString""));
string someStringValue = stream.ReadToEnd();
Console.WriteLine(someStringValue);
Console.ReadLine();
}
}
}";
// Compiler Code
CodeDomProvider codeProvider = CodeDomProvider.CreateProvider("CSharp");
string outFile = "output.exe";
System.CodeDom.Compiler.CompilerParameters parameters = new CompilerParameters();
parameters.GenerateExecutable = true;
parameters.OutputAssembly = outFile;
parameters.EmbeddedResources.Add("..\\..\\Properties\\Resources.resx");
parameters.EmbeddedResources.Add("..\\..\\Properties\\Resources.Designer.cs");
CompilerResults results = codeProvider.CompileAssemblyFromSource(parameters, codeString);
Am I accessing the embedded resource in the wrong way in the compiled code?
Answer to my own question:
Found a way (that probably isn't the best way to do it) but it involves reading the stream from the embedded resource file and then later parsing it for the required string value.
StreamReader stream = new StreamReader(resourceAssembly.GetManifestResourceStream(""Resources.resx""))
I would like to import to registry a .reg file that exist in project resources.
The way to import a reg file uses the path to the reg file:
Process proc = new Process();
proc = Process.Start("regedit.exe", "/s " + "path\to\file.reg");
Is it possible to do so with a file from resources? how do I get its path?
If it is in the project folder. i-e. The folder in which the project is runnung. you can access it directly : Process.Start("regedit.exe", "/s " + "Filename.reg");
you can get the current path by using
string path =System.AppDomain.CurrentDomain.BaseDirectory; // this will give u the path for debug folder
or
string projectPath= Path.GetDirectoryName(Path.GetDirectoryName(System.IO.Directory.GetCurrentDirectory())); //This will give u the project path.
you can use both and navigate arround to get the path to your desired folder. eg if you want to access a file in the Resource folder inside the project folder u can use projectPath+"\\Resource\\filename.reg"
If the file is embedded resource (and as such is not created on disk), it is best to read it like this and save it to a temporary file using:
var path = System.IO.Path.ChangeExtension(System.IO.Path.GetTempFileName(), "reg");
Process.Start(path);
It may not be necessary to change the extension if you don't start the file directly but use Process.Start("regedit", "/s " + path) like you described in your question. Keep in mind that the file path should be escaped so it's parsed properly as the command line argument, temporary file path, though, will not contain spaces, so it should be okay.
This is not tested code, but you get the steps I hope:
Process proc = new Process();
proc.StartInfo.FileName = "regedit.exe";
proc.StartInfo.Arguments = "/s";
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.RedirectStandardInput = true;
proc.Start();
StreamWriter stdin = myProcess.StandardInput;
var assembly = Assembly.GetExecutingAssembly();
var resourceName = "<regfile>";
using (Stream stream = assembly.GetManifestResourceStream(resourceName))
using (StreamReader reader = new StreamReader(stream))
{
stdin.Write(reader.ReadToEnd());
}
How do I embed an external executable inside my C# Windows Forms application?
Edit: I need to embed it because it's an external free console application (made in C++) from which I read the output values to use in my program. It would be nice and more professional to have it embedded.
Second reason is a requirement to embed a Flash projector file inside a .NET application.
Simplest way, leading on from what Will said:
Add the .exe using Resources.resx
Code this:
string path = Path.Combine(Path.GetTempPath(), "tempfile.exe");
File.WriteAllBytes(path, MyNamespace.Properties.Resources.MyExecutable);
Process.Start(path);
Here is some sample code that would roughly accomplish this, minus error checking of any sort. Also, please make sure that the license of the program to be embedded allows this sort of use.
// extracts [resource] into the the file specified by [path]
void ExtractResource( string resource, string path )
{
Stream stream = GetType().Assembly.GetManifestResourceStream( resource );
byte[] bytes = new byte[(int)stream.Length];
stream.Read( bytes, 0, bytes.Length );
File.WriteAllBytes( path, bytes );
}
string exePath = "c:\temp\embedded.exe";
ExtractResource( "myProj.embedded.exe", exePath );
// run the exe...
File.Delete( exePath );
The only tricky part is getting the right value for the first argument to ExtractResource. It should have the form "namespace.name", where namespace is the default namespace for your project (find this under Project | Properties | Application | Default namespace). The second part is the name of the file, which you'll need to include in your project (make sure to set the build option to "Embedded Resource"). If you put the file under a directory, e.g. Resources, then that name becomes part of the resource name (e.g. "myProj.Resources.Embedded.exe"). If you're having trouble, try opening your compiled binary in Reflector and look in the Resources folder. The names listed here are the names that you would pass to GetManifestResourceStream.
Just add it to your project and set the build option to "Embedded Resource"
This is probably the simplest:
byte[] exeBytes = Properties.Resources.myApp;
string exeToRun = Path.Combine(Path.GetTempPath(), "myApp.exe");
using (FileStream exeFile = new FileStream(exeToRun, FileMode.CreateNew))
exeFile.Write(exeBytes, 0, exeBytes.Length);
Process.Start(exeToRun);
Is the executable a managed assembly? If so you can use ILMerge to merge that assembly with yours.
Here's my version:
Add the file to the project as an existing item, change the properties on the file to "Embedded resource"
To dynamically extract the file to a given location: (this example doesn't test location for write permissions etc)
/// <summary>
/// Extract Embedded resource files to a given path
/// </summary>
/// <param name="embeddedFileName">Name of the embedded resource file</param>
/// <param name="destinationPath">Path and file to export resource to</param>
public static void extractResource(String embeddedFileName, String destinationPath)
{
Assembly currentAssembly = Assembly.GetExecutingAssembly();
string[] arrResources = currentAssembly.GetManifestResourceNames();
foreach (string resourceName in arrResources)
if (resourceName.ToUpper().EndsWith(embeddedFileName.ToUpper()))
{
Stream resourceToSave = currentAssembly.GetManifestResourceStream(resourceName);
var output = File.OpenWrite(destinationPath);
resourceToSave.CopyTo(output);
resourceToSave.Close();
}
}
Add File to VS Project
Mark as "Embedded Resource" -> File properties
Use name to resolve: [Assembly Name].[Name of embedded resource] like "MyFunkyNTServcice.SelfDelete.bat"
Your code has resource bug (file handle not freed!), please correct to:
public static void extractResource(String embeddedFileName, String destinationPath)
{
var currentAssembly = Assembly.GetExecutingAssembly();
var arrResources = currentAssembly.GetManifestResourceNames();
foreach (var resourceName in arrResources)
{
if (resourceName.ToUpper().EndsWith(embeddedFileName.ToUpper()))
{
using (var resourceToSave = currentAssembly.GetManifestResourceStream(resourceName))
{
using (var output = File.OpenWrite(destinationPath))
resourceToSave.CopyTo(output);
resourceToSave.Close();
}
}
}
}
Extract something as string, if needed:
public static string ExtractResourceAsString(String embeddedFileName)
{
var currentAssembly = Assembly.GetExecutingAssembly();
var arrResources = currentAssembly.GetManifestResourceNames();
foreach (var resourceName in arrResources)
{
if (resourceName.ToUpper().EndsWith(embeddedFileName.ToUpper()))
{
using (var resourceToSave = currentAssembly.GetManifestResourceStream(resourceName))
{
using (var output = new MemoryStream())
{
resourceToSave.CopyTo(output);
return Encoding.ASCII.GetString(output.ToArray());
}
}
}
}
return string.Empty;
}