Introduction
I am trying to make a compression application. The current obstacle I am facing is that whenever I try to compress my file I take a byte array from the file and apply compression algorithm on the byte array itself because of which the metadata of file is lost.
Question
Is there any method by which I can extract the metadata of a file on compression and later on extraction attach the metadata to the extracted file?
Visual Studio : VS2008
Framework : .Net 3.5
Solutions I found:
I have seen in many articles that they say we can use Windows Property System but even after reading the article I have no clue as to how can I implement it.
This website has explained with the code but they didn't give any download link for the DLL.
From this Stackoverflow answer I got this code:-
//creates new class of oledocumentproperties
var doc = new OleDocumentPropertiesClass();
//open your selected file
doc.Open(#"C:\Users\ABC\Desktop\Test\1.jpg", false, dsoFileOpenOptions.dsoOptionDefault);
//you can set properties with summaryproperties.nameOfProperty = value; for example
doc.SummaryProperties.Company = "lol"; //Line 8 : Shows error
doc.SummaryProperties.Author = "me";
//after making changes, you need to use this line to save them
doc.Save();
I get the following error on Line 8
The name is not valid. (Exception from HRESULT: 0x800300FC (STG_E_INVALIDNAME))
Are you sure that the Company property exists in your file metadata?
Try using a known existing property in the metadata of the file you're trying to access, as the ones that are used in the example may just not exist.
As for saving the properties, you can access some basic global ones like CreationTime and LastAccessTime from the System.IO.FileInfo object.
This article seems to describe a method through which you can get more specific properties from files, such as the Camera and CameraManufacturer properties (that isn't identical to the one from the StackOverflow question) like so:
using System;
using Microsoft.WindowsAPICodePack.Shell.PropertySystem;
using Microsoft.WindowsAPICodePack.Shell;
using System.Diagnostics;
class Program {
void getProperty() {
var cameraModel = GetValue(picture.Properties.
GetProperty(SystemProperties.System.Photo.CameraModel));
}
}
with GetValue being:
private static string GetValue(IShellProperty value)
{
if (value == null || value.ValueAsObject == null)
{
return String.Empty;
}
return value.ValueAsObject.ToString();
}
Related
I'm trying to publish a COM add-in for Word and need to have a license file. I'm using Rhino Licensing and the file has no issues during debugging, but when using OneClick to publish the add-in the license is reported as no longer valid. Here is the code for the class I'm using to check the license:
using System;
using System.IO;
using Rhino.Licensing;
namespace Services.Licensing
{
public class LicenseChecker
{
private static string PublicKeyPath;
private static string LicensePath;
public static bool LicenseIsValid(string licPath)
{
bool result = false;
Directory.SetCurrentDirectory(AppDomain.CurrentDomain.BaseDirectory);
String Root = Directory.GetCurrentDirectory();
PublicKeyPath = Root + #"\Licensing\publicKey.xml";
LicensePath = Root + #"\Licensing\license.xml"; //licPath;
// not working on INSTALL, runs fine in debug
try
{
var publicKey = File.ReadAllText(PublicKeyPath);
//Throws an exception if license has been modified
LicenseValidator validator = new LicenseValidator(publicKey, LicensePath);
validator.AssertValidLicense();
if (validator.ExpirationDate > DateTime.Now)
{
result = true;
}
}
catch
{ }
return result;
}
}
}
I'm trying to bundle the license with the exe I'll be giving to a small testing group to save the testers unnecessary trouble managing the license and public key. Currently I have the (valid) license file and public key as embedded resources, set to "copy always."
I'm having the same issue when the license is not bundled with the published exe, but the public key is. When both files are left outside of the solution, there seems to be no problem. Could publishing the solution be changing the byte array of the public key or the license?
I'm using .Net Framework 4.7.2 and Visual Studio 2019.
After a lot of toying, the broad answer seems to be no, ClickOnce publishing does not affect the byte array.
The error seems to be occurring because the ClickOnce is not copying XML files into the Application Files folder it creates at all.
After pulling the licenses into a desktop folder and having the program call them from there, another class that uses XML files to load list items would not initialize, leading me to put Try{} around all functions that use pre-made XML files in my program. Each of these functions returned the Catch{}. I'm assuming that ClickOnce is too simplistic an installer to be used if you are trying to include many/any resource files, especially if they are XML.
My question is not same as below.
Compare Two DLL's
I am trying to compare whether 2 DLLs are equal binaries or not using C# code. If needed I can refer some third party DLL but the comparision must be done by C# code not manual opening tool.
This is my bigger task..
C# Common libraries same location for different WCF services
I have a dll called MyDll.dll at below locations
C:\Source\MyDll.dll
C:\Destination\MyDll.dll
I wrote a method which gets MyDll.dll from C:\Source and drop/replace into C:\Destination but I do not want to blindly replace MyDll.dll in C:\Destination. I want to check whether C:\Source\MyDll.dll and C:\Destination\MyDll.dll are same or not. If not then only replace.
Please remember everything needs to be happening in C# code since this method runs on a start event of windows service.
public void LoadAssembly()
{
string source = #"C:\Source\MyDll.dl"
string destination = #"C:\Destination\MyDll.dll"
// To copy a file to another location and
// overwrite the destination file if it already exists.
System.IO.File.Copy(source, destination, true);
}
Looked at this not use
C# - comparing two .net dlls using reflection
UPDATE
I created below method and I feel it has performance issue depending on how big my dll is. Is there any way I can improve this.
public static bool AreFilesEqual()
{
string source = #"C:\Source\MyDll.dll";
string dest = #"C:\Destination\MyDll.dll";
byte[] sourceFileBytes = File.ReadAllBytes(source);
byte[] destinationFileBytes = File.ReadAllBytes(dest);
// if two files length are not same then they are not equal
if(sourceFileBytes.Length != destinationFileBytes.Length)
{
return false;
}
return sourceFileBytes.SequenceEqual(destinationFileBytes);
}
I know this seems like a simple thing but I can't find any help online.
I want to include a file (.html) along with my Azure function when I publish it using Visual Studio. Then I want to be able to access this file in my Azure function.
Why? It seems like only the .dll gets sent to the server when I publish.
This file will be an .html file that will be an email template. I want to read it in my function and then send emails out.
Any help is much appreciated.
I see I can use [send grid in Azure functions][1], but it looks like I can only send out one email and not multiple emails, which is what I want.
First, you need to add the html file to your project, and in the properties, set Copy to Output Directory to "Copy if newer".
Then in your function code, take in an additional ExecutionContext context parameter (note that this is Microsoft.Azure.WebJobs.ExecutionContext and not System.Threading.ExecutionContext). And when you need to access your html file, you can then write:
string htmlFilePath = Path.Combine(context.FunctionAppDirectory, "test.html");
That's assuming you added the file at the root of your VS project. If you instead added it in some Data folder (better practice), you'd write:
string htmlFilePath = Path.Combine(context.FunctionAppDirectory, "Data", "test.html");
See here for full working sample.
I have the same scenario as you have. However, I cannot access ExecutionContext because it is only available in requests. My scenario needs to get the template included in AzFunc project but not in the context of AzFunc's functions. I got it null when I go with the interface - implementation class approach.
Thanks to this guy, I use IOptions<ExecutionContextOptions> in my class to get the root directory of the Azure Func.
My Azure Func project (NET 6, Azure Function v4)
using Microsoft.Extensions.Options;
using Microsoft.Azure.WebJobs.Host.Bindings;
namespace AzureFuncApi
{
public class TemplateHelper : ITemplateHelper
{
private readonly IOptions<ExecutionContextOptions> _executionContext;
public TemplateHelper (IOptions<ExecutionContextOptions> executionContext)
{
_executionContext = executionContext;
}
public string GetTemplate()
{
var context = _executionContext.Value;
var rootDir = context.AppDirectory; // <-- rootDir of AzFunc
var template = Path.Combine(rootDir, "test.html"); // <-- browse for your template. Here's an example if you place test.html right in the root of your project
// return your template here, raw, or after you do whatever you want with it...
}
}
}
My different project defines the interface and uses it there, independently of the real implementation
namespace DifferentProject
{
public interface ITemplateHelper
{
string GetTemplate(); // Use this to get the template
}
}
I'm searching my assembly (using System.Reflection) for classes that are inherited from a specific class (System.Web.UI.Page).
All these inherited classes have pages in my web.
How can I read .aspx file path too (relative to web root)?
I know I can read this path from .pdb file, however this file does not exists in live server.
Edit
to avoid confusion, here is a sample of my code. doSomeProcess is not exact process. in fact it receives the class itself and analyzes it too. however it is not important for this code sample.
using System;
using System.IO;
using System.Reflection;
namespace ... {
public class FixPaths: System.Web.UI.Page {
void SearhcAssembly(){
Assembly library = Assembly.GetExecutingAssembly();
string FileName = Path.GetFileName(library.Location);
foreach (Type type in library.GetTypes()) {
if (FileName == type.Module.Name) {
if (type.BaseType != null && (type.BaseType.FullName == "System.Web.UI.Page")) {
string NameSpace = type.Namespace;
string ClassName = type.Name;
// -- This need to be changed --
string PageUrl = "/" + type.Namespace.ToLower().Replace(".", "/") + "/" + type.Name + ".aspx";
// -------------------------------------
doSomeProcess(NameSpace, ClassName, PageUrl);
}
}
}
}
}
}
Bob, unfortunately this is not a proper solution. However, as far as we discussed on the comments, it may be the nearest we can get to it.
By reflection, get all the types at your assembly that inherit from Page.
Using a recursive I/O search, look for all *.aspx files under your root folder and keep them in a list (so you can retrieve their full path and so on
Compare the types you found with the files you fetched. This way you can report Pages (classes) that aren't on the right file and ASPX that aren't on the right place.
I couldn't find a relationship between the type and it's source file. Furthermore, we are talking about Pages (declared at the assembly) and ASPX files, which aren't related at all.
If anybody has a better solution, I'd like to take a look at it as well.
Regards
The page's relative path from the root is in the AppRelativeTemplateSourceDirectory property (on the page). Is that what you are after?
How do I load an XNA model from a file path instead of from the content (eg. Model.FromStream but it doesnt exist)?? Texture2D has .FromStream, how can I do the equivalent for Model?
You can use Content.Load<Model>("Path here, make sure you use drive letter");
If you really need to have a FromStream method on Model you can use extension methods (Not exactly a perfect duplicate of FromStream but it should work):
public static Model FromPath(this Model model, ContentManager content, string path)
{
return content.Load<Model>(path);
}
EDIT:
I have just tested the above code and apparently, rather than using the drive letter, you need to match the number of "..\\" in areversePathstring with the number of levels of the root directory of theContentManager. The problem is accessing the full directory of theContentManager` which is private (or protected, I'm not sure). Short of using reflection I don't think that that variable can be accessed. If we do know the full Root Directory Path then this should work:
string reversePath = "";
foreach (string level in Content.FullRootDirectory.Split('\\'))// I know there isn't actually a property 'FullRootDirectory' but for the sake of argument,
{
reversePath += "..\\";
}
reversePath = reversePath.Substring(4);
I've googled a few times and haven't been able to find a way to get the root directory of the ContentManager. I might even ask this as a question here on SO in a bit here.
OK here is the final thing (using the answer from the question linked to above):
Add a reference to System.Windows.Forms to your project
Add the following code to the top of your Game1.cs file:
using System.IO;
using TApplication = System.Windows.Forms.Application;
Add this code wherever you need it, like in LoadContent or an extension method:
string ContentFullPath = Path.Combine(Path.GetDirectoryName(TApplication.ExecutablePath),
Content.RootDirectory);
string reversePath = "";
foreach (string level in ContentFullPath.Split('\\'))
{
reversePath += "..\\";
}
reversePath = reversePath.Substring(3);
Model test = Content.Load<Model>(Path.Combine(ContentFullPath, reversePath) + "*Your file name here*");