The short answer is no, you cannot prevent someone from editing a .msi file. There are various approaches you can take to minimize the likelihood of someone doing so, or approaches that increase the difficulties associated with any edit, but you cannot fully prevent it.
To answer this better, one must refine the question you are asking. "Protect" sounds like a security sort of question, so it helps to establish at least an armchair threat model. For instance, here are three things you may be trying to prevent:
- an interested user altering the bits that are installed to that user's system
- a corporate user modifying what his system administrators install to the user's machine
- a malicious party altering and providing bits masquerading as your app that someone else mistakenly installs
Of those three, the first isn't really a security boundary, so there's not much you can do. Either it's an install that requires administrative privileges and the user has them, or it's a per-user install that allows users without administrative privileges to use it. In either case, the .msi has no more access to the system than the user who altered it already had.
The second crosses a boundary, but involves someone who should be diligent about verifying signatures, and may likely acquire the installation from the source instead of the user. The third is a clear security concern, and unfortunately involves people you cannot reliably expect to be diligent about verifying signatures.
So what can you do?
- You can sign the .msi file. This leaves indications that the file was altered, if it was. Note that transforms (.mst files) can alter what the .msi does without altering the file itself; however this also affects the representation of the signed status.
- You can try to educate your prospective users about the importance of verifying the digital signature before accepting a UAC prompt. This won't stop someone who's trying to subvert your licensing, but may help someone avoid installing malware instead of your actual program.
- You can wrap the .msi in a signed .exe bootstrap. This makes things harder to access; attempts to use the normal tooling won't work directly, and instead require the altering party to figure out how to extract the .msi file. While that's typically not very difficult, it's at least another hurdle.
- You can try to inject signature verifications into the .msi file. As you say, these are likely to be easy to defeat by further alterations to the .msi file, unless you can couple them with important and hard to duplicate other code. That, of course, merely makes it harder to alter; but not impossible. Again you'll have to consider the .mst case, and whether you want to support administrative installations and installations from those caches.
- You can add relevant signature or other verifications to the app itself. If the .msi file is altered, but it doesn't alter what is installed to the machine, does your app care? The answer depends on what exactly you're trying to protect against; for instance it won't help prevent tag-along malware.
- Consider other packaging or deployment options, whether from Microsoft (like .appx / .msix) or from third parties. Each comes with their own set of advantages and disadvantages, and their own level of susceptibility to each thing I've discussed here.
- Run your app somewhere else; for example, rewrite your app as a web application so that there is no installation. Obviously this can only work for certain kinds of applications, but that list continues to grow.
What you can't do?
- Make all users pay enough attention
- Prevent a malicious party from creating an installer that pretends to be for your app but has only a malicious payload
- Prevent a machine's owner from altering the machine either before or after the .msi runs
- Support all of the ways people use .msi files without just using a .msi file (administrative installs, transforms, "repackaging", various .msi-specific deployment utilities, etc. are all normal use patterns for certain classes of software)
At the end of this exercise, you'll have to decide whether this is a deal breaker for you, or something you can accept. Make sure you understand why someone would want to alter your .msi file, and before focusing on the .msi file itself, consider whether they can have the same effect through non-.msi means. If it's specific to .msi and is a deal breaker, look into other installation technologies. If nothing can prevent the scenario you seek to prevent, perhaps you can find ways to reduce the incentive for people to attempt it.